From f7cdca7ad2c9b39b772728a5253352e68ed51b3e Mon Sep 17 00:00:00 2001 From: nillerusr Date: Sun, 14 Nov 2021 00:07:58 +0300 Subject: [PATCH] saverestore fixes --- engine/cmodel.cpp | 164 ++++++++++++++++++++--------------------- game/server/player.cpp | 2 + public/datamap.h | 28 ++++--- 3 files changed, 93 insertions(+), 101 deletions(-) diff --git a/engine/cmodel.cpp b/engine/cmodel.cpp index 466d4451..e9af063d 100644 --- a/engine/cmodel.cpp +++ b/engine/cmodel.cpp @@ -539,64 +539,62 @@ struct leafnums_t CCollisionBSPData *pBSPData; }; - - int CM_BoxLeafnums( leafnums_t &context, const Vector ¢er, const Vector &extents, int nodenum ) { - int leafCount = 0; - const int NODELIST_MAX = 1024; - int nodeList[NODELIST_MAX]; - int nodeReadIndex = 0; - int nodeWriteIndex = 0; - cplane_t *plane; - cnode_t *node; - int prev_topnode = -1; - - while (1) - { - if (nodenum < 0) - { - // This handles the case when the box lies completely - // within a single node. In that case, the top node should be - // the parent of the leaf - if (context.leafTopNode == -1) - context.leafTopNode = prev_topnode; - - if (leafCount < context.leafMaxCount) - { - context.pLeafList[leafCount] = -1 - nodenum; - leafCount++; - } - if ( nodeReadIndex == nodeWriteIndex ) - return leafCount; - nodenum = nodeList[nodeReadIndex]; - nodeReadIndex = (nodeReadIndex+1) & (NODELIST_MAX-1); - } - else - { - node = &context.pBSPData->map_rootnode[nodenum]; - plane = node->plane; - // s = BoxOnPlaneSide (leaf_mins, leaf_maxs, plane); - // s = BOX_ON_PLANE_SIDE(*leaf_mins, *leaf_maxs, plane); - float d0 = DotProduct( plane->normal, center ) - plane->dist; - float d1 = DotProductAbs( plane->normal, extents ); - prev_topnode = nodenum; - if (d0 >= d1) - nodenum = node->children[0]; - else if (d0 < -d1) - nodenum = node->children[1]; - else - { // go down both - if (context.leafTopNode == -1) - context.leafTopNode = nodenum; - nodeList[nodeWriteIndex] = node->children[0]; - nodeWriteIndex = (nodeWriteIndex+1) & (NODELIST_MAX-1); - // check for overflow of the ring buffer - Assert(nodeWriteIndex != nodeReadIndex); - nodenum = node->children[1]; - } - } - } + int leafCount = 0; + const int NODELIST_MAX = 1024; + int nodeList[NODELIST_MAX]; + int nodeReadIndex = 0; + int nodeWriteIndex = 0; + cplane_t *plane; + cnode_t *node; + int prev_topnode = -1; + + while (1) + { + if (nodenum < 0) + { + // This handles the case when the box lies completely + // within a single node. In that case, the top node should be + // the parent of the leaf + if (context.leafTopNode == -1) + context.leafTopNode = prev_topnode; + + if (leafCount < context.leafMaxCount) + { + context.pLeafList[leafCount] = -1 - nodenum; + leafCount++; + } + if ( nodeReadIndex == nodeWriteIndex ) + return leafCount; + nodenum = nodeList[nodeReadIndex]; + nodeReadIndex = (nodeReadIndex+1) & (NODELIST_MAX-1); + } + else + { + node = &context.pBSPData->map_rootnode[nodenum]; + plane = node->plane; + // s = BoxOnPlaneSide (leaf_mins, leaf_maxs, plane); + // s = BOX_ON_PLANE_SIDE(*leaf_mins, *leaf_maxs, plane); + float d0 = DotProduct( plane->normal, center ) - plane->dist; + float d1 = DotProductAbs( plane->normal, extents ); + prev_topnode = nodenum; + if (d0 >= d1) + nodenum = node->children[0]; + else if (d0 < -d1) + nodenum = node->children[1]; + else + { // go down both + if (context.leafTopNode == -1) + context.leafTopNode = nodenum; + nodeList[nodeWriteIndex] = node->children[0]; + nodeWriteIndex = (nodeWriteIndex+1) & (NODELIST_MAX-1); + // check for overflow of the ring buffer + Assert(nodeWriteIndex != nodeReadIndex); + nodenum = node->children[1]; + } + } + } } int CM_BoxLeafnums ( const Vector& mins, const Vector& maxs, int *list, int listsize, int *topnode) @@ -2666,38 +2664,32 @@ bool CM_HeadnodeVisible (int nodenum, const byte *visbits, int vissize ) // *visbits - pvs or pas of some cluster // Output : true if visible, false if not //----------------------------------------------------------------------------- -#define MAX_BOX_LEAVES 256 -int CM_BoxVisible( const Vector& mins, const Vector& maxs, const byte *visbits, int vissize ) -{ - int leafList[MAX_BOX_LEAVES]; - int topnode; - - // FIXME: Could save a loop here by traversing the tree in this routine like the code above - int count = CM_BoxLeafnums( mins, maxs, leafList, MAX_BOX_LEAVES, &topnode ); - for ( int i = 0; i < count; i++ ) - { - int cluster = CM_LeafCluster( leafList[i] ); - int offset = cluster>>3; - - if ( offset == -1 ) - { - return false; - } - - if ( offset > vissize || offset < 0 ) - { - Sys_Error( "CM_BoxVisible: cluster %i, offset %i out of bounds %i\n", cluster, offset, vissize ); - } - - if (visbits[cluster>>3] & (1<<(cluster&7))) - { - return true; - } - } - return false; +#define MAX_BOX_LEAVES 256 +int CM_BoxVisible( const Vector& mins, const Vector& maxs, const byte *visbits, int vissize ) +{ + int leafList[MAX_BOX_LEAVES]; + int topnode; + + // FIXME: Could save a loop here by traversing the tree in this routine like the code above + int count = CM_BoxLeafnums( mins, maxs, leafList, MAX_BOX_LEAVES, &topnode ); + for ( int i = 0; i < count; i++ ) + { + int cluster = CM_LeafCluster( leafList[i] ); + int offset = cluster>>3; + + if ( offset > vissize ) + { + Sys_Error( "CM_BoxVisible: cluster %i, offset %i out of bounds %i\n", cluster, offset, vissize ); + } + + if (visbits[cluster>>3] & (1<<(cluster&7))) + { + return true; + } + } + return false; } - //----------------------------------------------------------------------------- // Returns the world-space center of an entity //----------------------------------------------------------------------------- diff --git a/game/server/player.cpp b/game/server/player.cpp index 7dea1f50..b5d4debc 100644 --- a/game/server/player.cpp +++ b/game/server/player.cpp @@ -3380,12 +3380,14 @@ void CBasePlayer::PhysicsSimulate( void ) pi->m_nNumCmds = commandsToRun; } } +#if 0 else if ( GetTimeSinceLastUserCommand() > sv_player_usercommand_timeout.GetFloat() ) { // no usercommand from player after some threshold // server should start RunNullCommand as if client sends an empty command so that Think and gamestate related things run properly RunNullCommand(); } +#endif // Restore the true server clock // FIXME: Should this occur after simulation of children so diff --git a/public/datamap.h b/public/datamap.h index 909d67f5..936f4436 100644 --- a/public/datamap.h +++ b/public/datamap.h @@ -128,11 +128,9 @@ DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) ) #define ARRAYSIZE2D(p) (sizeof(p)/sizeof(p[0][0])) #define SIZE_OF_ARRAY(p) _ARRAYSIZE(p) -// Normal offset of is invalid on non-array-types, this is dubious as hell. The rest of the codebase converted to the -// legit offsetof from the C headers, so we'll use the old impl here to avoid exposing temptation to others -#define _hacky_datamap_offsetof(s,m) ((size_t)&(((s *)0)->m)) +#define _offsetof(s,m) ((size_t)&(((s *)0)->m)) -#define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, count, flags, mapname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, tolerance } +#define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, { _offsetof(classNameTypedef, name), 0 }, count, flags, mapname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, tolerance } #define DEFINE_FIELD_NULL { FIELD_VOID,0, {0,0},0,0,0,0,0,0} #define DEFINE_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_SAVE, NULL, 0 ) #define DEFINE_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 ) @@ -144,35 +142,35 @@ DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) ) #define DEFINE_ENTITY_GLOBAL_FIELD(name,fieldtype) _FIELD(edict_t, name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE | FTYPEDESC_GLOBAL, #name, 0 ) #define DEFINE_GLOBAL_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_SAVE, NULL, 0 ) #define DEFINE_GLOBAL_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 ) -#define DEFINE_CUSTOM_FIELD(name,datafuncs) { FIELD_CUSTOM, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, datafuncs, NULL } -#define DEFINE_CUSTOM_KEYFIELD(name,datafuncs,mapname) { FIELD_CUSTOM, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, mapname, datafuncs, NULL } +#define DEFINE_CUSTOM_FIELD(name,datafuncs) { FIELD_CUSTOM, #name, { _offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, datafuncs, NULL } +#define DEFINE_CUSTOM_KEYFIELD(name,datafuncs,mapname) { FIELD_CUSTOM, #name, { _offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, mapname, datafuncs, NULL } #define DEFINE_AUTO_ARRAY2D(name,fieldtype) _FIELD(name, fieldtype, ARRAYSIZE2D(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, NULL, 0 ) // Used by byteswap datadescs #define DEFINE_BITFIELD(name,fieldtype,bitcount) DEFINE_ARRAY(name,fieldtype,((bitcount+FIELD_BITS(fieldtype)-1)&~(FIELD_BITS(fieldtype)-1)) / FIELD_BITS(fieldtype) ) #define DEFINE_INDEX(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_INDEX, NULL, 0 ) #define DEFINE_EMBEDDED( name ) \ - { FIELD_EMBEDDED, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name.m_DataMap), sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f } + { FIELD_EMBEDDED, #name, { _offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name.m_DataMap), sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f } #define DEFINE_EMBEDDED_OVERRIDE( name, overridetype ) \ - { FIELD_EMBEDDED, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &((overridetype *)0)->m_DataMap, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f } + { FIELD_EMBEDDED, #name, { _offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &((overridetype *)0)->m_DataMap, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f } #define DEFINE_EMBEDDEDBYREF( name ) \ - { FIELD_EMBEDDED, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( *(((classNameTypedef *)0)->name) ), NULL, 0, 0.0f } + { FIELD_EMBEDDED, #name, { _offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( *(((classNameTypedef *)0)->name) ), NULL, 0, 0.0f } #define DEFINE_EMBEDDED_ARRAY( name, count ) \ - { FIELD_EMBEDDED, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, count, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f } + { FIELD_EMBEDDED, #name, { _offsetof(classNameTypedef, name), 0 }, count, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f } #define DEFINE_EMBEDDED_AUTO_ARRAY( name ) \ - { FIELD_EMBEDDED, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, SIZE_OF_ARRAY( ((classNameTypedef *)0)->name ), FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f } + { FIELD_EMBEDDED, #name, { _offsetof(classNameTypedef, name), 0 }, SIZE_OF_ARRAY( ((classNameTypedef *)0)->name ), FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f } #ifndef NO_ENTITY_PREDICTION #define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) \ - { FIELD_EMBEDDED, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &fieldtype::m_PredMap } + { FIELD_EMBEDDED, #name, { _offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &fieldtype::m_PredMap } #define DEFINE_PRED_TYPEDESCRIPTION_PTR( name, fieldtype ) \ - { FIELD_EMBEDDED, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &fieldtype::m_PredMap } + { FIELD_EMBEDDED, #name, { _offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &fieldtype::m_PredMap } #else @@ -193,7 +191,7 @@ DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) ) //#define DEFINE_DATA( name, fieldextname, flags ) _FIELD(name, fieldtype, 1, flags, extname ) // INPUTS -#define DEFINE_INPUT( name, fieldtype, inputname ) { fieldtype, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_INPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, inputname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ) } +#define DEFINE_INPUT( name, fieldtype, inputname ) { fieldtype, #name, { _offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_INPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, inputname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ) } #define DEFINE_INPUTFUNC( fieldtype, inputname, inputfunc ) { fieldtype, #inputfunc, { NULL, NULL }, 1, FTYPEDESC_INPUT, inputname, NULL, static_cast (&classNameTypedef::inputfunc) } // OUTPUTS @@ -201,7 +199,7 @@ DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) ) // we know the output type from the variable itself, so it doesn't need to be specified here class ISaveRestoreOps; extern ISaveRestoreOps *eventFuncs; -#define DEFINE_OUTPUT( name, outputname ) { FIELD_CUSTOM, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_OUTPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, outputname, eventFuncs } +#define DEFINE_OUTPUT( name, outputname ) { FIELD_CUSTOM, #name, { _offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_OUTPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, outputname, eventFuncs } // replaces EXPORT table for portability and non-DLL based systems (xbox) #define DEFINE_FUNCTION_RAW( function, func_type ) { FIELD_VOID, nameHolder.GenerateName(#function), { NULL, NULL }, 1, FTYPEDESC_FUNCTIONTABLE, NULL, NULL, (inputfunc_t)((func_type)(&classNameTypedef::function)) }