Added a better way to debug hitboxes & new waf script

This commit is contained in:
Kamay Xutax 2024-07-15 06:51:22 +02:00
parent 7625fd7947
commit e360866bf5
28 changed files with 785 additions and 95 deletions

View file

@ -2128,6 +2128,8 @@ void CL_SendMove( void )
void CL_Move(float accumulated_extra_samples, bool bFinalTick )
{
CL_ReadPackets(bFinalTick);
if ( !cl.IsConnected() )
return;

View file

@ -2103,7 +2103,6 @@ void SV_CreateBaseline (void)
ALIGN4 char packedData[MAX_PACKEDENTITY_DATA] ALIGN4_POST;
bf_write writeBuf( "SV_CreateBaseline->writeBuf", packedData, sizeof( packedData ) );
// create basline from zero values
if ( !SendTable_Encode(
pSendTable,

View file

@ -106,7 +106,8 @@ void SV_EnsureInstanceBaseline( ServerClass *pServerClass, int iEdict, const voi
// Pack the entity....
//-----------------------------------------------------------------------------
static inline void SV_PackEntity(
static inline void SV_PackEntity(
int clientEntityIndex,
int edictIdx,
edict_t* edict,
ServerClass* pServerClass,
@ -144,6 +145,7 @@ static inline void SV_PackEntity(
unsigned char tempData[ sizeof( CSendProxyRecipients ) * MAX_DATATABLE_PROXIES ];
CUtlMemory< CSendProxyRecipients > recip( (CSendProxyRecipients*)tempData, pSendTable->m_pPrecalc->GetNumDataTableProxies() );
g_pVEngineServer->SetSendTableCurrentEntityIndex(clientEntityIndex);
if( !SendTable_Encode( pSendTable, edict->GetUnknown(), &writeBuf, edictIdx, &recip, false ) )
{
Host_Error( "SV_PackEntity: SendTable_Encode returned false (ent %d).\n", edictIdx );
@ -393,10 +395,11 @@ struct PackWork_t
int nIdx;
edict_t *pEdict;
CFrameSnapshot *pSnapshot;
int clientIndex;
static void Process( PackWork_t &item )
{
SV_PackEntity( item.nIdx, item.pEdict, item.pSnapshot->m_pEntities[ item.nIdx ].m_pClass, item.pSnapshot );
SV_PackEntity(item.clientIndex, item.nIdx, item.pEdict, item.pSnapshot->m_pEntities[ item.nIdx ].m_pClass, item.pSnapshot );
}
};
@ -440,7 +443,8 @@ void PackEntities_Normal(
PackWork_t w;
w.nIdx = index;
w.pEdict = edict;
w.pSnapshot = snapshot;
w.pSnapshot = snapshot;
w.clientIndex = client->m_nEntityIndex;
workItems.AddToTail( w );
break;
@ -459,7 +463,7 @@ void PackEntities_Normal(
for ( int i = 0; i < c; ++i )
{
PackWork_t &w = workItems[ i ];
SV_PackEntity( w.nIdx, w.pEdict, w.pSnapshot->m_pEntities[ w.nIdx ].m_pClass, w.pSnapshot );
SV_PackEntity(w.clientIndex, w.nIdx, w.pEdict, w.pSnapshot->m_pEntities[ w.nIdx ].m_pClass, w.pSnapshot );
}
}

View file

@ -82,7 +82,8 @@ void InvalidateSharedEdictChangeInfos()
}
g_SharedEdictChangeInfo.m_nChangeInfos = 0;
}
// TODO_ENHANCED: HACK!
int g_SendTableEntityIndex = -1;
// ---------------------------------------------------------------------- //
// Globals.
@ -1753,6 +1754,16 @@ private:
virtual ISpatialPartition *CreateSpatialPartition( const Vector& worldmin, const Vector& worldmax ) { return ::CreateSpatialPartition( worldmin, worldmax ); }
virtual void DestroySpatialPartition( ISpatialPartition *pPartition ) { ::DestroySpatialPartition( pPartition ); }
virtual void SetSendTableCurrentEntityIndex(int index) OVERRIDE
{
g_SendTableEntityIndex = index;
}
virtual int GetSendTableCurrentEntityIndex() OVERRIDE
{
return g_SendTableEntityIndex;
}
};
// Backwards-compat shim that inherits newest then provides overrides for the legacy behavior
@ -1823,6 +1834,7 @@ void CVEngineServer::PlaybackTempEntity( IRecipientFilter& filter, float delay,
ALIGN4 unsigned char data[ CEventInfo::MAX_EVENT_DATA ] ALIGN4_POST;
bf_write buffer( "PlaybackTempEntity", data, sizeof(data) );
SetSendTableCurrentEntityIndex(-1);
// write all properties, if init or reliable message delta against zero values
if( !SendTable_Encode( pST, pSender, &buffer, classID, NULL, false ) )
{

View file

@ -5,9 +5,11 @@
// $NoKeywords: $
//===========================================================================//
#include "cbase.h"
#include "c_baseplayer.h"
#include "c_baseanimating.h"
#include "c_sprite.h"
#include "cdll_client_int.h"
#include "iconvar.h"
#include "interpolatedvar.h"
#include "model_types.h"
#include "bone_setup.h"
@ -196,7 +198,10 @@ IMPLEMENT_CLIENTCLASS_DT(C_BaseAnimating, DT_BaseAnimating, CBaseAnimating)
RecvPropFloat( RECVINFO( m_fadeMinDist ) ),
RecvPropFloat( RECVINFO( m_fadeMaxDist ) ),
RecvPropFloat( RECVINFO( m_flFadeScale ) ),
RecvPropFloat( RECVINFO( m_flFadeScale ) ),
RecvPropArray3( RECVINFO_ARRAY(m_vecHitboxServerPositions), RecvPropVector(RECVINFO(m_vecHitboxServerPositions[0]))),
RecvPropArray3( RECVINFO_ARRAY(m_angHitboxServerAngles), RecvPropQAngles(RECVINFO(m_angHitboxServerAngles[0]))),
END_RECV_TABLE()
@ -4986,6 +4991,7 @@ void C_BaseAnimating::UpdateClientSideAnimation()
}
}
ConVar cl_showhitboxes("cl_showhitboxes", "0", FCVAR_CHEAT|FCVAR_DEVELOPMENTONLY);
void C_BaseAnimating::Simulate()
{
@ -5007,6 +5013,12 @@ void C_BaseAnimating::Simulate()
{
ClearRagdoll();
}
if (cl_showhitboxes.GetBool() && IsPlayer() && (this != C_BasePlayer::GetLocalPlayer()))
{
DrawClientHitboxes(gpGlobals->frametime, true);
DrawServerHitboxes(gpGlobals->frametime, true);
}
}
@ -5607,6 +5619,42 @@ void C_BaseAnimating::DrawClientHitboxes( float duration /*= 0.0f*/, bool monoco
}
}
//-----------------------------------------------------------------------------
// Purpose: Draw the current hitboxes
//-----------------------------------------------------------------------------
void C_BaseAnimating::DrawServerHitboxes( float duration /*= 0.0f*/, bool monocolor /*= false*/ )
{
CStudioHdr *pStudioHdr = GetModelPtr();
if ( !pStudioHdr )
return;
mstudiohitboxset_t *set =pStudioHdr->pHitboxSet( m_nHitboxSet );
if ( !set )
return;
Vector position;
QAngle angles;
int r = 0;
int g = 255;
int b = 0;
for ( int i = 0; i < set->numhitboxes; i++ )
{
mstudiobbox_t *pbox = set->pHitbox( i );
if ( !monocolor )
{
int j = (pbox->group % 8);
r = ( int ) ( 255.0f * hullcolor[j][0] );
g = ( int ) ( 255.0f * hullcolor[j][1] );
b = ( int ) ( 255.0f * hullcolor[j][2] );
}
debugoverlay->AddBoxOverlay( m_vecHitboxServerPositions[i], pbox->bbmin, pbox->bbmax, m_angHitboxServerAngles[i], r, g, b, 0 ,duration );
}
}
//-----------------------------------------------------------------------------
// Purpose:

View file

@ -370,6 +370,7 @@ public:
char const *GetHitboxSetName( void );
int GetHitboxSetCount( void );
void DrawClientHitboxes( float duration = 0.0f, bool monocolor = false );
void DrawServerHitboxes( float duration = 0.0f, bool monocolor = false );
C_BaseAnimating* FindFollowedEntity();
@ -639,6 +640,8 @@ private:
mutable CStudioHdr *m_pStudioHdr;
mutable MDLHandle_t m_hStudioHdr;
CThreadFastMutex m_StudioHdrInitLock;
Vector m_vecHitboxServerPositions[MAXSTUDIOBONES];
QAngle m_angHitboxServerAngles[MAXSTUDIOBONES];
};
enum

View file

@ -438,6 +438,8 @@ C_BasePlayer::C_BasePlayer() : m_iv_vecViewOffset( "C_BasePlayer::m_iv_vecViewOf
m_nForceVisionFilterFlags = 0;
ListenForGameEvent( "base_player_teleported" );
m_nTickBaseFireBullet = -1;
}
//-----------------------------------------------------------------------------
@ -2125,6 +2127,12 @@ void C_BasePlayer::Simulate()
{
ResetLatched();
}
if (m_nTickBaseFireBullet <= m_nTickBase && m_nTickBaseFireBullet != -1)
{
DrawServerHitboxes(60.0f, true);
m_nTickBaseFireBullet = -1;
}
}
//-----------------------------------------------------------------------------

View file

@ -636,6 +636,8 @@ public:
bool ShouldGoSouth( Vector vNPCForward, Vector vNPCRight ); //Such a bad name.
void SetOldPlayerZ( float flOld ) { m_flOldPlayerZ = flOld; }
int m_nTickBaseFireBullet;
};
EXTERN_RECV_TABLE(DT_BasePlayer);

View file

@ -9,6 +9,7 @@
#include "c_user_message_register.h"
#include "cdll_client_int.h"
#include "dt_recv.h"
#include "iconvar.h"
#include "interpolatedvar.h"
#include "shareddefs.h"
#include "studio.h"
@ -2148,7 +2149,6 @@ const Vector& C_CSPlayer::GetRenderOrigin( void )
return BaseClass::GetRenderOrigin();
}
void C_CSPlayer::Simulate( void )
{
if( this != C_BasePlayer::GetLocalPlayer() )
@ -2226,10 +2226,6 @@ void C_CSPlayer::Simulate( void )
}
BaseClass::Simulate();
static ConVar cl_showhitboxes("cl_showhitboxes", "-1");
if (cl_showhitboxes.GetInt() == index)
DrawClientHitboxes(0.0f, true);
}
void C_CSPlayer::PostThink()

View file

@ -12,6 +12,7 @@
#include <cmath>
#include <cstdio>
#include "bone_setup.h"
#include "convar.h"
#include "studio.h"
#include "util_shared.h"
#include "c_baseplayer.h"
@ -1315,7 +1316,7 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
cmd->has_simulation[pEntity->index] = true;
cmd->simulationtimes[pEntity->index] = pEntity->m_flInterpolatedSimulationTime;
if (pEntity->index < 1 and pEntity->index > MAX_PLAYERS)
if (pEntity->index < 1 && pEntity->index > MAX_PLAYERS)
{
continue;
}
@ -1331,6 +1332,17 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
cmd->animationdata[pBasePlayer->index].m_flUninterpolatedSimulationTime = pBasePlayer->m_flSimulationTime;
}
static ConVarRef cl_showhitboxes("cl_showhitboxes");
if (cl_showhitboxes.GetBool())
{
cmd->debug_hitboxes = true;
}
else
{
cmd->debug_hitboxes = false;
}
pVerified->m_cmd = *cmd;
pVerified->m_crc = cmd->GetChecksum();
}

View file

@ -8,6 +8,13 @@
#include "baseanimating.h"
#include "animation.h"
#include "activitylist.h"
#include "dt_common.h"
#include "dt_send.h"
#include "edict.h"
#include "enginecallback.h"
#include "entitylist_base.h"
#include "mathlib/vector.h"
#include "shareddefs.h"
#include "studio.h"
#include "bone_setup.h"
#include "mathlib/mathlib.h"
@ -27,6 +34,7 @@
#include "datacache/idatacache.h"
#include "smoke_trail.h"
#include "props.h"
#include "util.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -148,6 +156,53 @@ int CInfoLightingRelative::UpdateTransmitState( void )
return SetTransmitState( FL_EDICT_ALWAYS );
}
void* SendTableProxy_HitboxServerPositions(
const SendProp* pProp,
const void* pStructBase,
const void* pData,
CSendProxyRecipients* pRecipients,
int objectID)
{
auto index = engine->GetSendTableCurrentEntityIndex();
if (index == -1)
{
return (void*)pData;
}
CBaseEntity* entity = UTIL_EntityByIndex(index);
if (!entity)
{
return (void*)pData;
}
return ((Vector*)pData + entity->entindex() * MAXSTUDIOBONES);
}
void* SendTableProxy_HitboxServerAngles(const SendProp* pProp,
const void* pStructBase,
const void* pData,
CSendProxyRecipients* pRecipients,
int objectID)
{
auto index = engine->GetSendTableCurrentEntityIndex();
if (index == -1)
{
return (void*)pData;
}
CBaseEntity* entity = UTIL_EntityByIndex(index);
if (!entity)
{
return (void*)pData;
}
return ((QAngle*)pData + entity->entindex() * MAXSTUDIOBONES);
}
static CIKSaveRestoreOps s_IKSaveRestoreOp;
@ -254,6 +309,8 @@ IMPLEMENT_SERVERCLASS_ST(CBaseAnimating, DT_BaseAnimating)
SendPropFloat( SENDINFO( m_fadeMinDist ), 0, SPROP_NOSCALE ),
SendPropFloat( SENDINFO( m_fadeMaxDist ), 0, SPROP_NOSCALE ),
SendPropFloat( SENDINFO( m_flFadeScale ), 0, SPROP_NOSCALE ),
SendPropArray3 (SENDINFO_NAME(m_vecHitboxServerPositions[0][0], m_vecHitboxServerPositions), MAXSTUDIOBONES, SendPropVector(SENDINFO_NAME(m_vecHitboxServerPositions[0][0], m_vecHitboxServerPositions[0]) ), SendTableProxy_HitboxServerPositions),
SendPropArray3 (SENDINFO_NAME(m_angHitboxServerAngles[0][0], m_angHitboxServerAngles), MAXSTUDIOBONES, SendPropQAngles(SENDINFO_NAME(m_angHitboxServerAngles[0][0], m_angHitboxServerAngles[0]) ), SendTableProxy_HitboxServerAngles),
END_SEND_TABLE()
@ -282,6 +339,15 @@ CBaseAnimating::CBaseAnimating()
m_fadeMaxDist = 0;
m_flFadeScale = 0.0f;
m_fBoneCacheFlags = 0;
for (int i = 0; i <= MAX_PLAYERS; i++)
{
for (int j = 0; j < MAXSTUDIOBONES; j++)
{
m_vecHitboxServerPositions[i][j] = vec3_origin;
m_angHitboxServerAngles[i][j] = vec3_angle;
}
}
}
CBaseAnimating::~CBaseAnimating()
@ -2983,6 +3049,31 @@ static Vector hullcolor[8] =
Vector( 1.0, 1.0, 1.0 )
};
void CBaseAnimating::RecordServerHitboxes( CBasePlayer* player )
{
CStudioHdr *pStudioHdr = GetModelPtr();
if ( !pStudioHdr )
return;
mstudiohitboxset_t *set =pStudioHdr->pHitboxSet( m_nHitboxSet );
if ( !set )
return;
Vector position;
QAngle angles;
const auto localPlayerIndex = player->entindex();
for ( int i = 0; i < set->numhitboxes; i++ )
{
mstudiobbox_t *pbox = set->pHitbox( i );
GetBonePosition(pbox->bone, position, angles);
m_vecHitboxServerPositions[localPlayerIndex][i] = position;
m_angHitboxServerAngles[localPlayerIndex][i] = angles;
}
}
//-----------------------------------------------------------------------------
// Purpose: Send the current hitboxes for this model to the client ( to compare with
// r_drawentities 3 client side boxes ).

View file

@ -16,7 +16,7 @@
#include "datacache/idatacache.h"
#include "tier0/threadtools.h"
class CBasePlayer;
struct animevent_t;
struct matrix3x4_t;
class CIKContext;
@ -263,7 +263,8 @@ public:
virtual int DrawDebugTextOverlays( void );
// See note in code re: bandwidth usage!!!
void DrawServerHitboxes( float duration = 0.0f, bool monocolor = false );
void RecordServerHitboxes( CBasePlayer* player );
void DrawServerHitboxes( float duration = 0.0f, bool monocolor = false );
void DrawRawSkeleton( matrix3x4_t boneToWorld[], int boneMask, bool noDepthTest = true, float duration = 0.0f, bool monocolor = false );
void SetModelScale( float scale, float change_duration = 0.0f );
@ -390,6 +391,9 @@ private:
CNetworkArray( float, m_flPoseParameter, NUM_POSEPAREMETERS ); // must be private so manual mode works!
CNetworkArray( float, m_flEncodedController, NUM_BONECTRLS ); // bone controller setting (0..1)
Vector m_vecHitboxServerPositions[MAX_PLAYERS+1][MAXSTUDIOBONES];
QAngle m_angHitboxServerAngles[MAX_PLAYERS +1][MAXSTUDIOBONES];
// Client-side animation (useful for looping animation objects)
CNetworkVar( bool, m_bClientSideAnimation );
CNetworkVar( bool, m_bClientSideFrameReset );

View file

@ -5,6 +5,7 @@
//=============================================================================//
#include "cbase.h"
#include "baseplayer_shared.h"
#include "baseentity.h"
#include "convar.h"
#include "ilagcompensationmanager.h"
@ -17,6 +18,8 @@
#include "movehelper_server.h"
#include "iservervehicle.h"
#include "tier0/vprof.h"
#include "util.h"
#include "util_shared.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -343,19 +346,28 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper
gpGlobals->frametime = playerFrameTime;
gpGlobals->curtime = (player->m_nTickBase - 1) * TICK_INTERVAL;
// Run post think first, this will let some space for client side interpolation.
RunPostThink( player );
// Set globals appropriately
gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL;
extern ConVar sv_showhitboxes;
if (sv_showhitboxes.GetInt() >= 0)
if (ucmd->debug_hitboxes)
{
lagcompensation->StartLagCompensation( player, player->GetCurrentCommand() );
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer* lagPlayer = UTIL_PlayerByIndex(i);
if (!lagPlayer)
continue;
lagPlayer->RecordServerHitboxes( player );
}
lagcompensation->FinishLagCompensation( player );
}
}
// Run post think first, this will let some space for client side interpolation.
RunPostThink( player );
// Set globals appropriately
gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL;
// Prevent hacked clients from sending us invalid view angles to try to get leaf server code to crash
if ( !ucmd->viewangles.IsValid() || !IsEntityQAngleReasonable(ucmd->viewangles) )

View file

@ -12,6 +12,7 @@
#include "igamesystem.h"
#include "ilagcompensationmanager.h"
#include "inetchannelinfo.h"
#include "util.h"
#include "utllinkedlist.h"
#include "BaseAnimatingOverlay.h"
#include "tier0/vprof.h"
@ -33,7 +34,6 @@ ConVar sv_unlag( "sv_unlag", "1", FCVAR_DEVELOPMENTONLY, "Enables player lag com
ConVar sv_maxunlag( "sv_maxunlag", "1.0", FCVAR_DEVELOPMENTONLY, "Maximum lag compensation in seconds", true, 0.0f, true, 1.0f );
ConVar sv_lagflushbonecache( "sv_lagflushbonecache", "1", FCVAR_DEVELOPMENTONLY, "Flushes entity bone cache on lag compensation" );
ConVar sv_unlag_fixstuck( "sv_unlag_fixstuck", "0", FCVAR_DEVELOPMENTONLY, "Disallow backtracking a player for lag compensation if it will cause them to become stuck" );
ConVar sv_showhitboxes( "sv_showhitboxes", "-1");
//-----------------------------------------------------------------------------
// Purpose:
@ -428,7 +428,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, CUserCmd *c
recordSim = &trackSim->Element(currSim);
if (recordSim->m_flSimulationTime
<= animationData->m_flUninterpolatedSimulationTime and !foundAnimationData)
<= animationData->m_flUninterpolatedSimulationTime && !foundAnimationData)
{
recordAnim = recordSim;
foundAnimationData = true;
@ -455,7 +455,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, CUserCmd *c
Assert( recordAnim );
Assert( recordSim );
if ( !recordSim or !recordAnim )
if ( !recordSim || !recordAnim )
{
if ( sv_unlag_debug.GetBool() )
{
@ -677,9 +677,6 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, CUserCmd *c
m_bNeedToRestore = true; // we changed at least one player
restore->m_fFlags = flags; // we need to restore these flags
change->m_fFlags = flags; // we have changed these flags
if (sv_showhitboxes.GetInt() == pPlayer->entindex())
pPlayer->DrawServerHitboxes(0.0f, true);
}

View file

@ -33,7 +33,6 @@
#include "props_shared.h"
ConVar sv_showimpacts("sv_showimpacts", "0", FCVAR_REPLICATED, "Shows client (red) and server (blue) bullet impact point (1=both, 2=client-only, 3=server-only)" );
ConVar sv_showplayerhitboxes( "sv_showplayerhitboxes", "0", FCVAR_REPLICATED, "Show lag compensated hitboxes for the specified player index whenever a player fires." );
ConVar weapon_accuracy_nospread( "weapon_accuracy_nospread", "0", FCVAR_REPLICATED );
#define CS_MASK_SHOOT (MASK_SOLID|CONTENTS_DEBRIS)
@ -409,23 +408,22 @@ void CCSPlayer::FireBullet(
bool bFirstHit = true;
CBasePlayer *lastPlayerHit = NULL;
if( sv_showplayerhitboxes.GetInt() > 0 )
{
CBasePlayer *lagPlayer = UTIL_PlayerByIndex( sv_showplayerhitboxes.GetInt() );
if( lagPlayer )
{
#ifdef CLIENT_DLL
DevMsg("Client:");
lagPlayer->DrawClientHitboxes(60, true);
#else
DevMsg("Server:");
lagPlayer->DrawServerHitboxes(60, true);
#endif
DevMsg("%s => %f %f %f\n", lagPlayer->GetPlayerName(), lagPlayer->GetAbsOrigin().x, lagPlayer->GetAbsOrigin().y, lagPlayer->GetAbsOrigin().z);
static ConVarRef cl_showhitboxes("cl_showhitboxes");
if( cl_showhitboxes.GetBool() )
{
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *lagPlayer = UTIL_PlayerByIndex( i );
if( lagPlayer && !lagPlayer->IsLocalPlayer() && IsLocalPlayer())
{
lagPlayer->DrawClientHitboxes(60, true);
lagPlayer->m_nTickBaseFireBullet = int(lagPlayer->GetTimeBase() / TICK_INTERVAL);
}
}
}
#endif
MDLCACHE_CRITICAL_SECTION();
while ( fCurrentDamage > 0 )
{
@ -496,7 +494,7 @@ void CCSPlayer::FireBullet(
if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
{
C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
player->DrawClientHitboxes( 4, true );
player->DrawClientHitboxes( 60, true );
}
}
#else
@ -508,7 +506,7 @@ void CCSPlayer::FireBullet(
if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
{
CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
player->DrawServerHitboxes( 60, false );
player->DrawServerHitboxes( 60, true );
}
}
#endif

View file

@ -13,6 +13,7 @@
#include "ilagcompensationmanager.h"
#endif
ConVar debug_screenshot_bullet_position("debug_screenshot_bullet_position", "0");
ConVar weapon_accuracy_logging( "weapon_accuracy_logging", "0", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY | FCVAR_ARCHIVE );
#ifdef CLIENT_DLL
@ -285,7 +286,6 @@ void FX_FireBullets(
y1[iBullet] = fRadius1 * sinf(fTheta1);
}
static ConVar debug_screenshot_bullet_position("debug_screenshot_bullet_position", "0");
for ( int iBullet=0; iBullet < pWeaponInfo->m_iBullets; iBullet++ )
{
if (debug_screenshot_bullet_position.GetBool())

View file

@ -215,6 +215,16 @@ void WriteUsercmd( bf_write *buf, const CUserCmd *to, const CUserCmd *from )
}
}
if ( to->debug_hitboxes != from->debug_hitboxes )
{
buf->WriteOneBit( 1 );
buf->WriteOneBit( to->debug_hitboxes );
}
else
{
buf->WriteOneBit( 0 );
}
#if defined( HL2_CLIENT_DLL )
if ( to->entitygroundcontact.Count() != 0 )
{
@ -364,6 +374,11 @@ void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from )
}
}
if ( buf->ReadOneBit() )
{
move->debug_hitboxes = buf->ReadOneBit();
}
#if defined( HL2_DLL )
if ( buf->ReadOneBit() )
{

View file

@ -106,7 +106,7 @@ public:
{
animationdata[i] = {};
}
debug_hitboxes = false;
#if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL )
entitygroundcontact.RemoveAll();
#endif
@ -144,6 +144,7 @@ public:
{
animationdata[i] = src.animationdata[i];
}
debug_hitboxes = src.debug_hitboxes;
#if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL )
entitygroundcontact = src.entitygroundcontact;
#endif
@ -178,6 +179,7 @@ public:
CRC32_ProcessBuffer(&crc, has_animation, sizeof(has_animation));
CRC32_ProcessBuffer( &crc, simulationtimes, sizeof( simulationtimes ) );
CRC32_ProcessBuffer(&crc, animationdata, sizeof(animationdata));
CRC32_ProcessBuffer(&crc, &debug_hitboxes, sizeof(debug_hitboxes));
CRC32_Final( &crc );
return crc;
@ -192,6 +194,7 @@ public:
upmove = 0.f;
buttons = 0;
impulse = 0;
debug_hitboxes = false;
}
// For matching server and client commands for debugging
@ -231,6 +234,7 @@ public:
bool has_animation[MAX_EDICTS];
float simulationtimes[MAX_EDICTS];
ClientSideAnimationData animationdata[MAX_PLAYERS+1];
bool debug_hitboxes;
// Back channel to communicate IK state
#if defined( HL2_DLL ) || defined( HL2_CLIENT_DLL )

View file

@ -445,6 +445,8 @@ public:
virtual eFindMapResult FindMap( /* in/out */ char *pMapName, int nMapNameMax ) = 0;
virtual void SetPausedForced( bool bPaused, float flDuration = -1.f ) = 0;
virtual void SetSendTableCurrentEntityIndex(int index) = 0;
virtual int GetSendTableCurrentEntityIndex() = 0;
};
// These only differ in new items added to the end

View file

@ -0,0 +1,15 @@
##################################
#
# GitHub Releases
#
##################################
set +x
# Disabled until GitHub sends prereleases to email
wget -O upload.sh "https://raw.githubusercontent.com/FWGS/uploadtool/master/upload.sh"
chmod +x upload.sh
export GITHUB_TOKEN=$GH_TOKEN
./upload.sh $*

337
scripts/waifulib/android.py Normal file
View file

@ -0,0 +1,337 @@
#!/usr/bin/env python
# encoding: utf-8
# a1batross, 2019
import os
from waflib import *
from waflib.Tools import javaw
android_sdk_home_env = ['ANDROID_SDK_HOME', 'ANDROID_SDK']
# d8 started to roll out in 28
D8_BUILD_TOOLS_MAJOR_VER = 28
def options(opt):
grp = opt.add_option_group('Android options')
grp.add_option('--termux', dest='termux', default=False, action='store_true',
help='configure to use tools included in termux')
return
def add_paths_to_path(paths):
save_path = os.environ['PATH']
os.environ['PATH'] = os.pathsep.join(paths) + os.pathsep + save_path
def get_latest_build_tools_version(sdk):
build_tools_path = os.path.join(sdk, 'build-tools')
dirs = os.listdir(build_tools_path)
dirs.sort(reverse=True)
return dirs[0]
def get_build_tools(sdk, ver):
return os.path.join(sdk, 'build-tools', ver)
def configure(conf):
conf.load('java')
paths = []
if not conf.options.termux:
conf.start_msg('Checking environment variables')
sdk = None
for i in android_sdk_home_env:
if i in os.environ:
sdk = conf.env.ANDROID_SDK_HOME_ENV = os.environ[i]
break
if not sdk:
conf.fatal('Can\'t find path to SDK. Check if ANDROID_SDK_HOME environment variable is set')
return
conf.end_msg('ok')
btv = get_latest_build_tools_version(sdk)
conf.msg('Detected build-tools version', btv)
paths += [os.path.join(sdk, 'tools'), get_build_tools(sdk, btv)]
conf.env.BUILD_TOOLS_VERSION = [int(x) for x in btv.split('.')]
else:
conf.env.BUILD_TOOLS_VERSION = [ 0, 0, 0 ]
paths += os.environ['PATH'].split(os.pathsep) # just in case we have installed tools
conf.env.termux = conf.options.termux
# mandatory
for i in ['zipalign', 'apksigner', 'zip']:
conf.find_program(i, path_list = paths)
# optional
try:
conf.find_program('aapt2', path_list = paths)
except Errors.ConfigurationError:
conf.find_program('aapt', path_list = paths)
# optional
# if conf.env.BUILD_TOOLS_VERSION[0] >= D8_BUILD_TOOLS_MAJOR_VER:
try:
conf.find_program('d8', path_list = paths)
# else:
except Errors.ConfigurationError:
conf.find_program('dx', path_list = paths)
class aapt2compile(javaw.JTask):
color = 'GREEN'
run_str = 'mkdir -p ${RESOUTFILE} && ${AAPT2} compile -v ${SRC} -o ${RESOUTFILE}'
vars = ['AAPT2', 'RESOUTFILE', 'RESDIR']
def uid(self):
"""
Hash by resource directory path
"""
return Utils.h_list([self.__class__.__name__, self.generator.outdir.abspath(), self.env.RESDIR])
def runnable_status(self):
"""
Waits for dependent tasks to be complete, then read the file system to find the input nodes.
"""
for t in self.run_after:
if not t.hasrun:
return Task.ASK_LATER
if not self.inputs:
root = self.generator.outdir.ctx.root
resdir = root.make_node(self.env.RESDIR)
self.inputs = resdir.ant_glob('**/*', quiet=True)
return super(aapt2compile, self).runnable_status()
def post_run(self):
"""
List class files created
"""
for node in self.generator.outdir.ant_glob('**/*.flat', quiet=True):
self.generator.bld.node_sigs[node] = self.uid()
self.generator.bld.task_sigs[self.uid()] = self.cache_sig
class aapt2link(javaw.JTask):
color = 'GREEN' # android green :)
run_str = '${AAPT2} link -v ${AAPT2_LINKFLAGS} -o ${TGT} -A ${ASSETSDIR} --manifest ${MANIFEST} --java ${OUTRDIR} -I ${CLASSPATH_ANDROID} ${SRC}'
vars = ['AAPT2', 'ASSETSDIR', 'MANIFEST', 'OUTRDIR', 'CLASSPATH_ANDROID']
def runnable_status(self):
"""
Waits for dependent tasks to be complete, then read the file system to find the input nodes.
"""
for t in self.run_after:
if not t.hasrun:
return Task.ASK_LATER
if not self.inputs:
root = self.generator.outdir.ctx.root
resdir = root.make_node(self.env.RESOUTFILE)
self.inputs = resdir.ant_glob('**/*.flat', quiet=True)
return super(aapt2link, self).runnable_status()
class aaptpackage(javaw.JTask):
color = 'GREEN' # androis green :)
run_str = 'mkdir -p ${OUTRDIR} && ${AAPT} p -v -F ${TGT} -J ${OUTRDIR} -A ${ASSETSDIR} -I ${CLASSPATH_ANDROID} -M ${MANIFEST} -S ${RESDIR}'
vars = ['AAPT', 'OUTRDIR', 'ASSETSDIR', 'CLASSPATH_ANDROID', 'MANIFEST', 'RESDIR' ]
def runnable_status(self):
"""
Waits for dependent tasks to be complete, then read the file system to find the input nodes.
"""
for t in self.run_after:
if not t.hasrun:
return Task.ASK_LATER
if not self.inputs:
root = self.generator.outdir.ctx.root
resdir = root.make_node(self.env.RESDIR)
self.inputs = resdir.ant_glob('**/*', quiet=True)
return super(aaptpackage, self).runnable_status()
class DexerTask(javaw.JTask): # base dexer
color = 'GREEN'
def runnable_status(self):
for t in self.run_after:
if not t.hasrun:
return Task.ASK_LATER
if not self.inputs:
self.inputs = self.generator.outdir.ant_glob('**/*.class', quiet=True)
return super(DexerTask, self).runnable_status()
class d8(DexerTask):
# can't use TGT instead of OUTDIR here, because Google code monkeys don't know what __output__ should mean
run_str = '${D8} ${SRC} ${D8_FLAGS} --output ${OUTDIR} --lib ${CLASSPATH_ANDROID} ${D8_CLASSPATH}'
vars = ['D8', 'D8_FLAGS', 'OUTDIR', 'CLASSPATH_ANDROID', 'D8_CLASSPATH' ]
class dx(DexerTask):
run_str = '${DX} --dex ${D8_FLAGS} --output=${TGT} ${SRC} ${DX_CLASSPATH}'
vars = ['DX', 'D8_FLAGS', 'OUTDIR']
def custom_runnable_status(self):
if not self.inputs:
outrdir = self.srcdir[0].ctx.root.make_node(self.env.OUTRDIR)
self.srcdir.append(outrdir)
return self.old_runnable_status()
setattr(javaw.javac, 'old_runnable_status', getattr(javaw.javac, 'runnable_status', None))
setattr(javaw.javac, 'runnable_status', custom_runnable_status)
class apkjni(Task.Task):
color = 'BLUE'
run_str = '${ZIP} -ru ${OUTAPK_UNALIGNED_NOCLASSES_NOJNI} ${JNIDIR} --out ${TGT}'
vars = ['ZIP', 'JNIDIR', 'OUTAPK_UNALIGNED_NOCLASSES_NOJNI']
def runnable_status(self):
"""
Waits for dependent tasks to be complete, then read the file system to find the input nodes.
"""
for t in self.run_after:
if not t.hasrun:
return Task.ASK_LATER
# I could use SRC here, but I need to track changes of OUTAPK_UNALIGNED_NOCLASSES_NOJNI also
self.inputs += self.generator.outdir.ant_glob('{0}/**/*'.format(self.env.JNIDIR), quiet=True)
return super(apkjni, self).runnable_status()
class apkdex(Task.Task):
color = 'GREEN' # android green :)
run_str = '${ZIP} -uj ${SRC} --out ${TGT}'
vars = ['ZIP']
class apkalign(Task.Task):
color = 'GREEN' # android green :)
run_str = '${ZIPALIGN} -f -v 4 ${SRC} ${TGT}'
vars = ['ZIPALIGN']
class SignerTask(Task.Task):
color = 'GREEN'
vars = ['APKSIGNER', 'KEYSTORE', 'KS_ALIAS', 'KS_PASS', 'KEY_PASS']
class apksigner(SignerTask):
run_str = '${APKSIGNER} sign --ks ${KEYSTORE} --ks-key-alias ${KS_ALIAS} --ks-pass ${KS_PASS} --key-pass ${KEY_PASS} --in ${SRC} --out ${TGT}'
class apksigner_termux(SignerTask):
run_str = '${APKSIGNER} ${KEYSTORE} ${SRC} ${TGT}'
@TaskGen.feature('android')
@TaskGen.before_method('apply_java')
def apply_aapt(self):
# Build resources, generate R.java and create empty APK
outdir = getattr(self, 'outdir', None)
if outdir:
if not isinstance(outdir, Node.Node):
outdir = self.path.get_bld().make_node(self.outdir)
else:
outdir = self.path.get_bld()
outdir.mkdir()
self.outdir = outdir
srcdir = self.path.find_dir('.')
sdk = self.env.ANDROID_SDK_HOME_ENV
self.env.RESDIR = os.path.join(srcdir.abspath(), getattr(self, 'resdir', 'res'))
self.env.ASSETSDIR = os.path.join(srcdir.abspath(), getattr(self, 'assetsdir', 'assets'))
self.env.MANIFEST = os.path.join(srcdir.abspath(), getattr(self, 'manifest', 'AndroidManifest.xml'))
try:
self.env.JNIDIR = self.jni
except AttributeError:
pass
self.env.OUTAPK_SIGNED = self.name + '-signed.apk'
self.env.OUTAPK = self.name + '.apk'
self.env.OUTAPK_UNALIGNED = self.name + '.unaligned.apk'
self.env.OUTAPK_UNALIGNED_NOCLASSES = self.name + '.unaligned.noclasses.apk'
if self.env.JNIDIR:
self.env.OUTAPK_UNALIGNED_NOCLASSES_NOJNI = self.name + '.unaligned.noclasses.nojni.apk'
else:
self.env.OUTAPK_UNALIGNED_NOCLASSES_NOJNI = self.env.OUTAPK_UNALIGNED_NOCLASSES
if self.env.BUILD_TOOLS_VERSION[0] > 27:
self.env.append_unique('AAPT2_LINKFLAGS', '--allow-reserved-package-id')
self.env.OUTRDIR = os.path.join(outdir.abspath(), getattr(self, 'gendir', 'gen')) # build/gen
self.env.RESOUTFILE = os.path.join(outdir.abspath(), 'compiled')
self.env.OUTDIR = outdir.abspath()
self.env.TARGET_API = getattr(self, 'target_api', 10) # Android 2.3.3 TODO: parse AndroidManifest.xml to get target API!
if self.env.termux:
classpath = os.path.join(os.environ['PREFIX'], 'share', 'java', 'android.jar')
else: classpath = os.path.join(sdk, 'platforms', 'android-' + str(self.env.TARGET_API), 'android.jar')
self.env.CLASSPATH_ANDROID = classpath
tgt = self.outdir.make_node(self.env.OUTAPK_UNALIGNED_NOCLASSES_NOJNI)
if self.env.AAPT:
self.aapt2link_task = self.create_task('aaptpackage', tgt=tgt, cwd=outdir)
else:
self.aapt2compile_task = self.create_task('aapt2compile', cwd=outdir)
self.aapt2link_task = self.create_task('aapt2link', tgt=tgt, cwd=outdir)
self.aapt2link_task.set_run_after(self.aapt2compile_task) # we don't know *.flat outputs from aapt2compile yet
@TaskGen.feature('android')
@TaskGen.after_method('apply_java')
def apply_d8(self):
self.javac_task.set_run_after(self.aapt2link_task) # we don't know R.java yet
if getattr(self, 'debug', False):
self.env.D8_FLAGS = '--debug'
elif self.env.D8: self.env.D8_FLAGS = '--release'
self.d8_task = self.create_task('d8' if self.env.D8 else 'dx',
tgt=self.outdir.make_node('classes.dex'),
cwd=self.outdir)
self.d8_task.set_run_after(self.javac_task) # we don't know javac outputs
if self.env.JNIDIR:
self.apkjni_task = self.create_task('apkjni',
src=self.outdir.make_node(self.env.OUTAPK_UNALIGNED_NOCLASSES_NOJNI),
tgt=self.outdir.make_node(self.env.OUTAPK_UNALIGNED_NOCLASSES),
cwd=self.outdir)
self.apkdex_task = self.create_task('apkdex',
[self.outdir.make_node(self.env.OUTAPK_UNALIGNED_NOCLASSES), self.d8_task.outputs[0]],
self.outdir.make_node(self.env.OUTAPK_UNALIGNED),
cwd=self.outdir)
self.apkalign_task = self.create_task('apkalign',
self.outdir.make_node(self.env.OUTAPK_UNALIGNED),
self.outdir.make_node(self.env.OUTAPK),
cwd=self.outdir)
# signing is optional
try:
self.env.KEYSTORE = self.keystore.abspath()
if 'debug' in self.env.KEYSTORE:
self.env.KS_ALIAS = 'androiddebugkey'
self.env.KS_PASS = self.env.KEY_PASS = 'pass:android'
else:
self.env.KS_ALIAS = self.ks_alias
self.env.KS_PASS = self.ks_pass
self.env.KEY_PASS = self.key_pass
self.apksigner_task = self.create_task('apksigner' if not self.env.termux else 'apksigner_termux',
self.outdir.make_node(self.env.OUTAPK),
self.outdir.make_node(self.env.OUTAPK_SIGNED))
except AttributeError:
pass
@TaskGen.feature('android')
@TaskGen.after_method('set_classpath')
def set_android_classpath(self):
if len(self.env.CLASSPATH) == 0:
self.env.D8_CLASSPATH = ''
else:
self.env.D8_CLASSPATH = '--classpath' + os.pathsep.join(self.env.CLASSPATH) + os.pathsep # old classpath without android.jar for d8
for x in self.tasks:
x.env.CLASSPATH = self.env.CLASSPATH_ANDROID + x.env.CLASSPATH

View file

@ -151,3 +151,25 @@ def get_targets(bld):
for target in targets:
targets += get_deps(bld, target)
return targets
@Configure.conf
def check_pkg(conf, package, uselib_store, fragment, fatal = True, *k, **kw):
errormsg = '{0} not available! Install {0} development package. Also you may need to set PKG_CONFIG_PATH environment variable'.format(package)
confmsg = 'Checking for \'{0}\' sanity'.format(package)
errormsg2 = '{0} isn\'t installed correctly. Make sure you installed proper development package for target architecture'.format(package)
try:
conf.check_cfg(package=package, args='--cflags --libs', uselib_store=uselib_store, *k, **kw )
except conf.errors.ConfigurationError:
if fatal:
conf.fatal(errormsg)
return False
try:
conf.check_cxx(fragment=fragment, use=uselib_store, msg=confmsg, *k, **kw)
except conf.errors.ConfigurationError:
if fatal:
conf.fatal(errormsg2)
return False
return True

View file

@ -14,34 +14,48 @@
import subprocess
from waflib import Configure, Logs
def run_git(conf, argv):
try:
stdout = conf.cmd_and_log([conf.env.GIT[0]] + argv, cwd = conf.srcnode)
data = stdout.strip()
except Exception as e:
Logs.debug(str(e))
return None
if len(data) == 0:
return None
return data
@Configure.conf
def get_git_version(conf):
# try grab the current version number from git
node = conf.path.find_node('.git')
node = conf.srcnode.find_node('.git')
if not node:
Logs.debug('can\'t find .git in conf.srcnode')
return None
try:
stdout = conf.cmd_and_log([conf.env.GIT[0], 'describe', '--dirty', '--always'],
cwd = node.parent)
version = stdout.strip()
except Exception as e:
version = ''
Logs.debug(str(e))
if len(version) == 0:
version = None
return run_git(conf, ['describe', '--dirty', '--always'])
return version
@Configure.conf
def get_git_branch(conf):
node = conf.srcnode.find_node('.git')
if not node:
Logs.debug('can\'t find .git in conf.srcnode')
return None
return run_git(conf, ['rev-parse', '--abbrev-ref', 'HEAD'])
def configure(conf):
if conf.find_program('git', mandatory = False):
conf.start_msg('Checking git hash')
ver = conf.get_git_version()
if not conf.find_program('git', mandatory = False):
return
if ver:
conf.env.GIT_VERSION = ver
conf.end_msg(conf.env.GIT_VERSION)
else:
conf.end_msg('no', color='YELLOW')
conf.start_msg('Git commit hash')
conf.env.GIT_VERSION = conf.get_git_version()
conf.end_msg(conf.env.GIT_VERSION)
conf.start_msg('Git branch')
conf.env.GIT_BRANCH = conf.get_git_branch()
conf.end_msg(conf.env.GIT_BRANCH)

View file

@ -120,7 +120,7 @@ def options(opt):
:type opt: waflib.Options.OptionsContext
'''
opt.add_option('--msdev', dest='msdev', default=False, action='store_true', help='select msdev for export/import actions')
opt.add_option('--clean', dest='clean', default=False, action='store_true', help='delete exported files')
opt.add_option('--msdev-clean', dest='msdev_clean', default=False, action='store_true', help='delete exported msdev files')
def configure(conf):
@ -159,7 +159,7 @@ class MsDevContext(BuildContext):
pass
self.msdev = True
if self.options.clean:
if self.options.msdev_clean:
cleanup(self)
else:
export(self)

View file

@ -42,7 +42,7 @@ def sdl2_configure_path(conf, path):
]
libpath = 'lib'
if conf.env.COMPILER_CC == 'msvc':
if conf.env.DEST_CPU in ['x86_64', 'amd64']:
if conf.env.DEST_CPU == 'x86_64':
libpath = 'lib/x64'
else:
libpath = 'lib/' + conf.env.DEST_CPU
@ -56,21 +56,25 @@ def configure(conf):
conf.end_msg('yes: {0}, {1}, {2}'.format(conf.env.LIB_SDL2, conf.env.LIBPATH_SDL2, conf.env.INCLUDES_SDL2))
else:
try:
conf.check_cfg(
path='sdl2-config',
args='--cflags --libs',
package='',
msg='Checking for library SDL2',
uselib_store='SDL2')
conf.check_cfg(package='sdl2', args='--cflags --libs',
msg='Checking for SDL2 (pkg-config)')
except conf.errors.ConfigurationError:
conf.env.HAVE_SDL2 = 0
try:
if not conf.env.SDL2CONFIG:
conf.find_program('sdl2-config', var='SDL2CONFIG')
conf.check_cfg(path=conf.env.SDL2CONFIG, args='--cflags --libs',
msg='Checking for SDL2 (sdl2-config)', package='',
uselib_store='SDL2')
except conf.errors.ConfigurationError:
conf.env.HAVE_SDL2 = 0
if not conf.env.HAVE_SDL2 and conf.env.CONAN:
if not conf.env.SDL2_VERSION:
version = '2.0.10'
else:
version = conf.env.SDL2_VERSION
conf.load('conan')
conf.add_conan_remote('bincrafters', 'https://api.bintray.com/conan/bincrafters/public-conan')
conf.add_dependency('sdl2/%s@bincrafters/stable' % version, options = { 'shared': 'True' } )
@ -86,7 +90,7 @@ def configure(conf):
SDL_Init( SDL_INIT_EVERYTHING );
return 0;
}''',
msg = 'Checking for library SDL2 sanity',
msg = 'Checking for SDL2 sanity',
use = 'SDL2',
execute = False)
except conf.errors.ConfigurationError:

View file

@ -0,0 +1,82 @@
#! /usr/bin/env python
# Modified: Alibek Omarov <a1ba.omarov@gmail.com>
# Originally taken from Thomas Nagy's blogpost
"""
Strip executables upon installation
"""
import shutil, os
from waflib import Build, Utils, Context, Errors, Logs
def options(opt):
grp = opt.option_groups['Installation and uninstallation options']
grp.add_option('--strip', dest='strip', action='store_true', default=False,
help='strip binaries. You must pass this flag to install command [default: %(default)s]')
grp.add_option('--strip-to-file', dest='strip_to_file', action='store_true', default=False,
help='strip debug information to file *.debug. Implies --strip. You must pass this flag to install command [default: %(default)s]')
def configure(conf):
if conf.env.DEST_BINFMT not in ['elf', 'mac-o']:
return
if not conf.env.STRIPFLAGS:
conf.env.STRIPFLAGS = os.environ['STRIPFLAGS'] if 'STRIPFLAGS' in os.environ else []
try: conf.find_program('strip', var='STRIP')
except:
Logs.warn('Couldn\'t find strip, --strip install option will be unavailable!')
return
# a1ba: I am lazy to add `export OBJCOPY=` everywhere in my scripts
# so just try to deduce which objcopy we have
k = conf.env.STRIP[0].rfind('-')
if k >= 0:
objcopy_name = conf.env.STRIP[0][:k] + '-objcopy'
try: conf.find_program(objcopy_name, var='OBJCOPY')
except: pass
if 'OBJCOPY' not in conf.env:
try: conf.find_program('objcopy', var='OBJCOPY')
except: Logs.warn('Couldn\'t find objcopy, --strip-to-file will be unavailable!')
def copy_fun(self, src, tgt):
inst_copy_fun(self, src, tgt)
if not self.generator.bld.options.strip and not self.generator.bld.options.strip_to_file:
return
if self.env.DEST_BINFMT not in ['elf', 'mac-o']: # don't strip unknown formats or PE
return
if getattr(self.generator, 'link_task', None) and self.generator.link_task.outputs[0] in self.inputs:
tgt_debug = tgt + '.debug'
strip_cmd = self.env.STRIP + self.env.STRIPFLAGS + [tgt]
ocopy_cmd = self.env.OBJCOPY + ['--only-keep-debug', tgt, tgt_debug]
ocopy_debuglink_cmd = self.env.OBJCOPY + ['--add-gnu-debuglink=%s' % tgt_debug, tgt]
c1 = Logs.colors.NORMAL
c2 = Logs.colors.CYAN
c3 = Logs.colors.YELLOW
c4 = Logs.colors.BLUE
try:
if self.generator.bld.options.strip_to_file:
self.generator.bld.cmd_and_log(ocopy_cmd, output=Context.BOTH, quiet=Context.BOTH)
if not self.generator.bld.progress_bar:
Logs.info('%s+ objcopy --only-keep-debug %s%s%s %s%s%s', c1, c4, tgt, c1, c3, tgt_debug, c1)
self.generator.bld.cmd_and_log(strip_cmd, output=Context.BOTH, quiet=Context.BOTH)
if not self.generator.bld.progress_bar:
f1 = os.path.getsize(src)
f2 = os.path.getsize(tgt)
Logs.info('%s+ strip %s%s%s (%d bytes change)', c1, c2, tgt, c1, f2 - f1)
if self.generator.bld.options.strip_to_file:
self.generator.bld.cmd_and_log(ocopy_debuglink_cmd, output=Context.BOTH, quiet=Context.BOTH)
if not self.generator.bld.progress_bar:
Logs.info('%s+ objcopy --add-gnu-debuglink=%s%s%s %s%s%s', c1, c3, tgt_debug, c1, c2, tgt, c1)
except Errors.WafError as e:
print(e.stdout, e.stderr)
inst_copy_fun = Build.inst.copy_fun
Build.inst.copy_fun = copy_fun

View file

@ -53,7 +53,7 @@ def remove_waifulib(path):
sys.path.remove(waifulib)
@opt
def add_subproject(ctx, names):
def add_subproject(ctx, names, prepend = None):
names_lst = Utils.to_list(names)
for name in names_lst:
@ -126,8 +126,11 @@ def add_subproject(ctx, dirs, prepend = None):
if prepend:
subprj_path.append(prepend)
conf_name = prj
if os.path.isabs(prj):
conf_name = prj.replace('/','_').replace('\\','_')
subprj_path.append(prj)
subprj_path.append(conf_name)
saveenv = ctx.env
@ -160,8 +163,12 @@ def add_subproject(ctx, dirs, prepend = None):
if prepend:
subprj_path.append(prepend)
conf_name = prj
if os.path.isabs(prj):
conf_name = prj.replace('/','_').replace('\\','_')
subprj_path.append(prj)
subprj_path.append(conf_name)
saveenv = ctx.env
try:
ctx.env = ctx.all_envs['_'.join(subprj_path)]

16
waf vendored

File diff suppressed because one or more lines are too long