From db835ff25fdb58a0afe6d02faa208313c2d8cb80 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 2 Sep 2024 02:19:37 +0300 Subject: [PATCH 1/3] server: use string_t type where it was intended to be used, without broken engine headers * It must be safest commit in this branch, as we only replace int by string_t, which is already int by default. --- dlls/bigmomma.cpp | 20 ++++++++++---------- dlls/client.cpp | 2 +- dlls/h_cycler.cpp | 2 +- dlls/maprules.cpp | 2 +- dlls/player.cpp | 2 +- dlls/rpg.cpp | 2 +- dlls/saverestore.h | 2 +- dlls/scripted.cpp | 8 ++++---- dlls/scripted.h | 4 ++-- dlls/triggers.cpp | 2 +- dlls/util.cpp | 2 +- dlls/util.h | 2 +- dlls/weapons.cpp | 4 ++-- dlls/weapons.h | 2 +- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/dlls/bigmomma.cpp b/dlls/bigmomma.cpp index d668f5bd7b..82beb8cd54 100644 --- a/dlls/bigmomma.cpp +++ b/dlls/bigmomma.cpp @@ -182,7 +182,7 @@ class CBigMomma : public CBaseMonster Schedule_t *GetScheduleOfType( int Type ); void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); - void NodeStart( int iszNextNode ); + void NodeStart( string_t iszNextNode ); void NodeReach( void ); BOOL ShouldGoToNode( void ); @@ -191,7 +191,7 @@ class CBigMomma : public CBaseMonster void HandleAnimEvent( MonsterEvent_t *pEvent ); void LayHeadcrab( void ); - int GetNodeSequence( void ) + string_t GetNodeSequence( void ) { CBaseEntity *pTarget = m_hTargetEnt; if( pTarget ) @@ -201,7 +201,7 @@ class CBigMomma : public CBaseMonster return 0; } - int GetNodePresequence( void ) + string_t GetNodePresequence( void ) { CInfoBM *pTarget = (CInfoBM *)(CBaseEntity *)m_hTargetEnt; if( pTarget ) @@ -682,7 +682,7 @@ void CBigMomma::Activate( void ) Remember( bits_MEMORY_ADVANCE_NODE ); // Start 'er up } -void CBigMomma::NodeStart( int iszNextNode ) +void CBigMomma::NodeStart( string_t iszNextNode ) { pev->netname = iszNextNode; @@ -904,16 +904,16 @@ void CBigMomma::StartTask( Task_t *pTask ) case TASK_PLAY_NODE_PRESEQUENCE: case TASK_PLAY_NODE_SEQUENCE: { - int sequence; + string_t sequence_string; if( pTask->iTask == TASK_PLAY_NODE_SEQUENCE ) - sequence = GetNodeSequence(); + sequence_string = GetNodeSequence(); else - sequence = GetNodePresequence(); + sequence_string = GetNodePresequence(); - ALERT( at_aiconsole, "BM: Playing node sequence %s\n", STRING( sequence ) ); - if( sequence ) + ALERT( at_aiconsole, "BM: Playing node sequence %s\n", STRING( sequence_string ) ); + if( sequence_string ) { - sequence = LookupSequence( STRING( sequence ) ); + int sequence = LookupSequence( STRING( sequence_string ) ); if( sequence != -1 ) { pev->sequence = sequence; diff --git a/dlls/client.cpp b/dlls/client.cpp index 7e77f7b5b4..b6c5c7df6f 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -501,7 +501,7 @@ void ClientCommand( edict_t *pEntity ) { if( g_enable_cheats->value != 0 ) { - int iszItem = ALLOC_STRING( CMD_ARGV( 1 ) ); // Make a copy of the classname + string_t iszItem = ALLOC_STRING( CMD_ARGV( 1 ) ); // Make a copy of the classname GetClassPtr( (CBasePlayer *)pev )->GiveNamedItem( STRING( iszItem ) ); } } diff --git a/dlls/h_cycler.cpp b/dlls/h_cycler.cpp index 94f9884bbd..9f7fd98157 100644 --- a/dlls/h_cycler.cpp +++ b/dlls/h_cycler.cpp @@ -305,7 +305,7 @@ class CWeaponCycler : public CBasePlayerWeapon void SecondaryAttack( void ); BOOL Deploy( void ); void Holster( int skiplocal = 0 ); - int m_iszModel; + string_t m_iszModel; int m_iModel; }; diff --git a/dlls/maprules.cpp b/dlls/maprules.cpp index 519f7d2a78..4ba0e6e29c 100644 --- a/dlls/maprules.cpp +++ b/dlls/maprules.cpp @@ -39,7 +39,7 @@ class CRuleEntity : public CBaseEntity virtual int Restore( CRestore &restore ); static TYPEDESCRIPTION m_SaveData[]; - void SetMaster( int iszMaster ) { m_iszMaster = iszMaster; } + void SetMaster( string_t iszMaster ) { m_iszMaster = iszMaster; } protected: BOOL CanFireForActivator( CBaseEntity *pActivator ); diff --git a/dlls/player.cpp b/dlls/player.cpp index bd508e3de5..6629f49aa1 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -3353,7 +3353,7 @@ void CBasePlayer::GiveNamedItem( const char *pszName ) { edict_t *pent; - int istr = MAKE_STRING( pszName ); + string_t istr = MAKE_STRING( pszName ); pent = CREATE_NAMED_ENTITY( istr ); if( FNullEnt( pent ) ) diff --git a/dlls/rpg.cpp b/dlls/rpg.cpp index 4e39ec2c50..9663899c52 100644 --- a/dlls/rpg.cpp +++ b/dlls/rpg.cpp @@ -564,7 +564,7 @@ void CRpg::UpdateSpot( void ) #if !CLIENT_DLL if( m_fSpotActive ) { - if (m_pPlayer->pev->viewmodel == 0) + if( FStringNull( m_pPlayer->pev->viewmodel )) return; if( !m_pSpot ) diff --git a/dlls/saverestore.h b/dlls/saverestore.h index 993deadeef..2804e1ecd5 100644 --- a/dlls/saverestore.h +++ b/dlls/saverestore.h @@ -59,7 +59,7 @@ class CSave : public CSaveRestoreBuffer void WriteTime( const char *pname, const float *value, int count ); // Save a float (timevalue) void WriteData( const char *pname, int size, const char *pdata ); // Save a binary data block void WriteString( const char *pname, const char *pstring ); // Save a null-terminated string - void WriteString( const char *pname, const int *stringId, int count ); // Save a null-terminated string (engine string) + void WriteString( const char *pname, const string_t *stringId, int count ); // Save a null-terminated string (engine string) void WriteVector( const char *pname, const Vector &value ); // Save a vector void WriteVector( const char *pname, const float *value, int count ); // Save a vector void WritePositionVector( const char *pname, const Vector &value ); // Offset for landmark if necessary diff --git a/dlls/scripted.cpp b/dlls/scripted.cpp index 9071eebb2a..89de109a80 100644 --- a/dlls/scripted.cpp +++ b/dlls/scripted.cpp @@ -471,9 +471,9 @@ void CCineMonster::CineThink( void ) } // lookup a sequence name and setup the target monster to play it -BOOL CCineMonster::StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty ) +BOOL CCineMonster::StartSequence( CBaseMonster *pTarget, string_t iszSeq, BOOL completeOnEmpty ) { - if( !iszSeq && completeOnEmpty ) + if( FStringNull( iszSeq ) && completeOnEmpty ) { SequenceDone( pTarget ); return FALSE; @@ -503,9 +503,9 @@ BOOL CCineMonster::StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL comple // lookup a sequence name and setup the target monster to play it // overridden for CCineAI because it's ok for them to not have an animation sequence // for the monster to play. For a regular Scripted Sequence, that situation is an error. -BOOL CCineAI::StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty ) +BOOL CCineAI::StartSequence( CBaseMonster *pTarget, string_t iszSeq, BOOL completeOnEmpty ) { - if( iszSeq == 0 && completeOnEmpty ) + if( FStringNull( iszSeq ) && completeOnEmpty ) { // no sequence was provided. Just let the monster proceed, however, we still have to fire any Sequence target // and remove any non-repeatable CineAI entities here ( because there is code elsewhere that handles those tasks, but diff --git a/dlls/scripted.h b/dlls/scripted.h index 5666a0822f..054f5c58e1 100644 --- a/dlls/scripted.h +++ b/dlls/scripted.h @@ -70,7 +70,7 @@ class CCineMonster : public CBaseMonster void ReleaseEntity( CBaseMonster *pEntity ); void CancelScript( void ); - virtual BOOL StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty ); + virtual BOOL StartSequence( CBaseMonster *pTarget, string_t iszSeq, BOOL completeOnEmpty ); virtual BOOL FCanOverrideState ( void ); void SequenceDone ( CBaseMonster *pMonster ); virtual void FixScriptMonsterSchedule( CBaseMonster *pMonster ); @@ -98,7 +98,7 @@ class CCineMonster : public CBaseMonster class CCineAI : public CCineMonster { - BOOL StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty ); + BOOL StartSequence( CBaseMonster *pTarget, string_t iszSeq, BOOL completeOnEmpty ); void PossessEntity( void ); BOOL FCanOverrideState ( void ); virtual void FixScriptMonsterSchedule( CBaseMonster *pMonster ); diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index 19699786a6..37e0752e59 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -345,7 +345,7 @@ void CMultiManager::Spawn( void ) if( m_flTargetDelay[i] < m_flTargetDelay[i - 1] ) { // Swap out of order elements - int name = m_iTargetName[i]; + string_t name = m_iTargetName[i]; float delay = m_flTargetDelay[i]; m_iTargetName[i] = m_iTargetName[i - 1]; m_flTargetDelay[i] = m_flTargetDelay[i - 1]; diff --git a/dlls/util.cpp b/dlls/util.cpp index 85566cd3a6..cebf1ad573 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1827,7 +1827,7 @@ void CSave::WriteString( const char *pname, const char *pdata ) #endif } -void CSave::WriteString( const char *pname, const int *stringId, int count ) +void CSave::WriteString( const char *pname, const string_t *stringId, int count ) { int i, size; #if TOKENIZE diff --git a/dlls/util.h b/dlls/util.h index 1fe4d41891..b28f06ddf8 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -166,7 +166,7 @@ inline BOOL FNullEnt(entvars_t* pev) { return pev == NULL || FNullEnt(OFFSET( // Testing strings for nullity #define iStringNull 0 -inline BOOL FStringNull(int iString) { return iString == iStringNull; } +inline BOOL FStringNull(string_t iString) { return iString == iStringNull; } #define cchMapNameMost 32 diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 3ff1a15f35..3276fe2879 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -60,7 +60,7 @@ MULTIDAMAGE gMultiDamage; // you the maximum amount of that type of ammunition that a // player can carry. //========================================================= -int MaxAmmoCarry( int iszName ) +int MaxAmmoCarry( string_t iszName ) { for( int i = 0; i < MAX_WEAPONS; i++ ) { @@ -1465,7 +1465,7 @@ BOOL CWeaponBox::PackWeapon( CBasePlayerItem *pWeapon ) //========================================================= // CWeaponBox - PackAmmo //========================================================= -BOOL CWeaponBox::PackAmmo( int iszName, int iCount ) +BOOL CWeaponBox::PackAmmo( string_t iszName, int iCount ) { int iMaxCarry; diff --git a/dlls/weapons.h b/dlls/weapons.h index 4db8381f31..2de959a89c 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -440,7 +440,7 @@ class CWeaponBox : public CBaseEntity BOOL HasWeapon( CBasePlayerItem *pCheckItem ); BOOL PackWeapon( CBasePlayerItem *pWeapon ); - BOOL PackAmmo( int iszName, int iCount ); + BOOL PackAmmo( string_t iszName, int iCount ); CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES];// one slot for each From 6255ffbe27e239e5d864b45fc64c23d8edd0b48e Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 2 Sep 2024 02:32:46 +0300 Subject: [PATCH 2/3] engine: start breaking engine headers * Entity Interface call pfnCreateNamedEntity actually accepts string_t * viewmodel and weaponmodel in entvars_t are actually used as string_t --- common/const.h | 1 - engine/eiface.h | 6 +++--- engine/progdefs.h | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/common/const.h b/common/const.h index 3e2989f5f5..96f89d6a34 100644 --- a/common/const.h +++ b/common/const.h @@ -735,7 +735,6 @@ enum }; typedef unsigned int func_t; -typedef int string_t; typedef unsigned char byte; typedef unsigned short word; diff --git a/engine/eiface.h b/engine/eiface.h index 2863319e34..ae58591975 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -117,7 +117,7 @@ typedef struct enginefuncs_s void (*pfnAngleVectors)( const float *rgflVector, float *forward, float *right, float *up ); edict_t* (*pfnCreateEntity)( void ); void (*pfnRemoveEntity)( edict_t* e ); - edict_t* (*pfnCreateNamedEntity)( int className ); + edict_t* (*pfnCreateNamedEntity)( string_t className ); void (*pfnMakeStatic)( edict_t *ent ); int (*pfnEntIsOnFloor)( edict_t *e ); int (*pfnDropToFloor)( edict_t* e ); @@ -160,8 +160,8 @@ typedef struct enginefuncs_s void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, int cb ); void* (*pfnPvEntPrivateData)( edict_t *pEdict ); void (*pfnFreeEntPrivateData)( edict_t *pEdict ); - const char *(*pfnSzFromIndex)( int iString ); - int (*pfnAllocString)( const char *szValue ); + const char *(*pfnSzFromIndex)( string_t iString ); + string_t (*pfnAllocString)( const char *szValue ); struct entvars_s *(*pfnGetVarsOfEnt)( edict_t *pEdict ); edict_t* (*pfnPEntityOfEntOffset)( int iEntOffset ); int (*pfnEntOffsetOfPEntity)( const edict_t *pEdict ); diff --git a/engine/progdefs.h b/engine/progdefs.h index d8dd62e6fd..34d54bfe16 100644 --- a/engine/progdefs.h +++ b/engine/progdefs.h @@ -85,8 +85,8 @@ typedef struct entvars_s int modelindex; string_t model; - int viewmodel; // player's viewmodel - int weaponmodel; // what other players see + string_t viewmodel; // player's viewmodel + string_t weaponmodel; // what other players see vec3_t absmin; // BB max translated to world coord vec3_t absmax; // BB max translated to world coord @@ -144,7 +144,7 @@ typedef struct entvars_s int flags; int colormap; // lowbyte topcolor, highbyte bottomcolor - int team; + string_t team; float max_health; float teleport_time; From 432ee6d451c666272f62e8561feb42befdf9816b Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 4 Sep 2024 04:14:56 +0300 Subject: [PATCH 3/3] server: real ABI2 implementation * we define a new class called string_t that's only allowed to be converted from and to ptrdiff_t * it specifically doesn't allow conversion to int on 64-bit platform only to ptrdiff_t. For now it just checks defined XASH_64BIT macro but check better be remade with some std::enable_if magic * mark ABI2 binaries with _st64 prefix --- cl_dll/hl/hl_weapons.cpp | 10 ++++++--- cl_dll/util_vector.h | 2 +- cmake/LibraryNaming.cmake | 4 ++++ common/const.h | 35 ++++++++++++++++++++++++++++++ dlls/extdll.h | 1 - dlls/util.h | 20 +++++++---------- scripts/waifulib/library_naming.py | 3 +++ 7 files changed, 58 insertions(+), 17 deletions(-) diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index 4f119f02fa..fdcf0a8ae2 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -98,7 +98,9 @@ bool bIsMultiplayer( void ) //Just loads a v_ model. void LoadVModel( const char *szViewModel, CBasePlayer *m_pPlayer ) { - gEngfuncs.CL_LoadModel( szViewModel, &m_pPlayer->pev->viewmodel ); + int index = m_pPlayer->pev->viewmodel.ExplicitInt(); + gEngfuncs.CL_LoadModel( szViewModel, &index ); + m_pPlayer->pev->viewmodel = index; } /* @@ -213,7 +215,9 @@ BOOL CBasePlayerWeapon::DefaultDeploy( const char *szViewModel, const char *szWe if( !CanDeploy() ) return FALSE; - gEngfuncs.CL_LoadModel( szViewModel, &m_pPlayer->pev->viewmodel ); + int index = m_pPlayer->pev->viewmodel.ExplicitInt(); + gEngfuncs.CL_LoadModel( szViewModel, &index ); + m_pPlayer->pev->viewmodel = index; SendWeaponAnim( iAnim, skiplocal, body ); @@ -878,7 +882,7 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm } // Copy in results of prediction code - to->client.viewmodel = player.pev->viewmodel; + to->client.viewmodel = player.pev->viewmodel.ExplicitInt(); to->client.fov = player.pev->fov; to->client.weaponanim = player.pev->weaponanim; to->client.m_flNextAttack = player.m_flNextAttack; diff --git a/cl_dll/util_vector.h b/cl_dll/util_vector.h index 6d900446a6..5e75ea1d45 100644 --- a/cl_dll/util_vector.h +++ b/cl_dll/util_vector.h @@ -27,9 +27,9 @@ #else #include #endif + // Header file containing definition of globalvars_t and entvars_t typedef unsigned int func_t; // -typedef int string_t; // from engine's pr_comp.h; typedef float vec_t; // needed before including progdefs.h //========================================================= diff --git a/cmake/LibraryNaming.cmake b/cmake/LibraryNaming.cmake index d71919fa2c..443f2d3e68 100644 --- a/cmake/LibraryNaming.cmake +++ b/cmake/LibraryNaming.cmake @@ -189,6 +189,10 @@ else() set(POSTFIX "") endif() +if(CMAKE_SIZEOF_VOID_P AND NOT XASH_ARCH_ONLY_USES_ABI2) + set(POSTFIX "${POSTFIX}_st64") +endif() + message(STATUS "Library postfix: " ${POSTFIX}) set(CMAKE_RELEASE_POSTFIX ${POSTFIX}) diff --git a/common/const.h b/common/const.h index 96f89d6a34..394de15060 100644 --- a/common/const.h +++ b/common/const.h @@ -15,6 +15,9 @@ #pragma once #if !defined(CONST_H) #define CONST_H + +#include // ptrdiff_t + // // Constants shared by the engine and dlls // This header file included by engine files and DLL files. @@ -736,6 +739,38 @@ enum typedef unsigned int func_t; +#if __cplusplus +class string_t +{ + ptrdiff_t offset; +public: + // only construct from ptrdiff_t + string_t( ptrdiff_t offset ) : offset( offset ) {} + string_t() : offset( 0 ) {} + + // as string_t sometimes used as a storage, we allow explicit conversion to an int + // as a method + int ExplicitInt() + { + return (int) offset; + } + + // for null checks + operator bool() const { return offset != 0; } + + // only convert to ptrdiff_t + operator ptrdiff_t() const + { + return offset; + } +#if XASH_64BIT + operator int() const = delete; +#endif +}; +#else // ! __cplusplus +typedef ptrdiff_t string_t; +#endif + typedef unsigned char byte; typedef unsigned short word; diff --git a/dlls/extdll.h b/dlls/extdll.h index 9541ee163f..77a3c80c26 100644 --- a/dlls/extdll.h +++ b/dlls/extdll.h @@ -78,7 +78,6 @@ typedef int BOOL; // Header file containing definition of globalvars_t and entvars_t typedef unsigned int func_t; -typedef int string_t; // from engine's pr_comp.h; typedef float vec_t; // needed before including progdefs.h // Vector class diff --git a/dlls/util.h b/dlls/util.h index b28f06ddf8..441a9d6e0b 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -33,20 +33,16 @@ inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin, ent extern globalvars_t *gpGlobals; // Use this instead of ALLOC_STRING on constant strings -#define STRING(offset) (const char *)(gpGlobals->pStringBase + (int)offset) +inline const char *STRING( string_t offset ) +{ + return gpGlobals->pStringBase + (ptrdiff_t)offset; +} -#if !XASH_64BIT || CLIENT_DLL -#define MAKE_STRING(str) ((int)(long int)str - (int)(long int)STRING(0)) -#else -static inline int MAKE_STRING(const char *szValue) +inline string_t MAKE_STRING( const char *szValue ) { - long long ptrdiff = szValue - STRING(0); - if( ptrdiff > INT_MAX || ptrdiff < INT_MIN ) - return ALLOC_STRING( szValue ); - else - return (int)ptrdiff; + ptrdiff_t ptrdiff = szValue - STRING( 0 ); + return string_t( ptrdiff ); } -#endif inline edict_t *FIND_ENTITY_BY_CLASSNAME(edict_t *entStart, const char *pszName) { @@ -166,7 +162,7 @@ inline BOOL FNullEnt(entvars_t* pev) { return pev == NULL || FNullEnt(OFFSET( // Testing strings for nullity #define iStringNull 0 -inline BOOL FStringNull(string_t iString) { return iString == iStringNull; } +inline BOOL FStringNull(string_t iString) { return (ptrdiff_t)iString == iStringNull; } #define cchMapNameMost 32 diff --git a/scripts/waifulib/library_naming.py b/scripts/waifulib/library_naming.py index ac2faf6f9f..268ed14cfb 100644 --- a/scripts/waifulib/library_naming.py +++ b/scripts/waifulib/library_naming.py @@ -172,4 +172,7 @@ def configure(conf): else: conf.env.POSTFIX = '' + if conf.env.DEST_SIZEOF_VOID_P == 8 and not conf.env.XASH_ARCH_USES_ONLY_ABI2: + conf.env.POSTFIX += '_st64' + conf.end_msg(conf.env.POSTFIX)