2
0
mirror of https://github.com/FWGS/xash3d-fwgs synced 2024-11-22 01:45:19 +01:00

engine: client: switch efrags to dynamic allocation (as suggested on insideqc by @mh)

This commit is contained in:
Alibek Omarov 2024-08-03 10:56:37 +03:00
parent 8be3bdac5d
commit fb7f57cf6a
4 changed files with 60 additions and 50 deletions

View File

@ -532,7 +532,6 @@ typedef struct
#define MAX_MOVIES 8
#define MAX_CDTRACKS 32
#define MAX_CLIENT_SPRITES 512 // SpriteTextures (0-256 hud, 256-512 client)
#define MAX_EFRAGS 8192 // Arcane Dimensions required
#define MAX_REQUESTS 64
#if ! XASH_64BIT

View File

@ -28,10 +28,51 @@ GNU General Public License for more details.
===============================================================================
*/
#define NUM_EFRAGS_ALLOC 64 // alloc 64 efrags (1-2kb each alloc)
static efrag_t **lastlink;
static mnode_t *r_pefragtopnode;
static vec3_t r_emins, r_emaxs;
static cl_entity_t *r_addent;
static int cl_efrags_num;
static efrag_t *cl_efrags;
static efrag_t *CL_AllocEfrags( int num )
{
int i;
efrag_t *efrags;
if( !cl.worldmodel )
{
Host_Error( "%s: called with NULL world\n", __func__ );
return NULL;
}
if( num == 0 )
return NULL;
// set world to be the owner, so it will get automatically cleaned up
efrags = Mem_Calloc( cl.worldmodel->mempool, sizeof( *efrags ) * num );
// initialize linked list
for( i = 0; i < num - 1; i++ )
efrags[i].entnext = &efrags[i + 1];
cl_efrags_num += num;
return efrags;
}
/*
==============
CL_ClearEfrags
==============
*/
void CL_ClearEfrags( void )
{
cl_efrags_num = 0;
cl_efrags = NULL;
}
/*
===================
@ -56,14 +97,11 @@ static void R_SplitEntityOnNode( mnode_t *node )
leaf = (mleaf_t *)node;
// grab an efrag off the free list
ef = clgame.free_efrags;
ef = cl_efrags;
if( !ef )
{
Con_Printf( S_ERROR "too many efrags!\n" );
return; // no free fragments...
}
ef = CL_AllocEfrags( NUM_EFRAGS_ALLOC );
clgame.free_efrags = ef->entnext;
cl_efrags = ef->entnext;
ef->entity = r_addent;
// add the entity link
@ -133,35 +171,29 @@ R_StoreEfrags
*/
void R_StoreEfrags( efrag_t **ppefrag, int framecount )
{
cl_entity_t *pent;
model_t *clmodel;
efrag_t *pefrag;
const efrag_t *pefrag;
cl_entity_t *pent;
model_t *clmodel;
while(( pefrag = *ppefrag ) != NULL )
{
pent = pefrag->entity;
clmodel = pent->model;
switch( clmodel->type )
{
case mod_alias:
case mod_brush:
case mod_studio:
case mod_sprite:
if( pent->visframe != framecount )
{
if( CL_AddVisibleEntity( pent, ET_FRAGMENTED ))
{
// mark that we've recorded this entity for this frame
pent->curstate.messagenum = cl.parsecount;
pent->visframe = framecount;
}
}
// how this could happen?
if( unlikely( clmodel->type < mod_brush || clmodel->type > mod_studio ))
continue;
ppefrag = &pefrag->leafnext;
break;
default:
break;
if( pent->visframe != framecount )
{
if( CL_AddVisibleEntity( pent, ET_FRAGMENTED ))
{
// mark that we've recorded this entity for this frame
pent->curstate.messagenum = cl.parsecount;
pent->visframe = framecount;
}
}
ppefrag = &pefrag->leafnext;
}
}

View File

@ -3064,26 +3064,6 @@ EFRAGS MANAGEMENT
==============================================================
*/
efrag_t cl_efrags[MAX_EFRAGS];
/*
==============
CL_ClearEfrags
==============
*/
void CL_ClearEfrags( void )
{
int i;
memset( cl_efrags, 0, sizeof( cl_efrags ));
// allocate the efrags and chain together into a free list
clgame.free_efrags = cl_efrags;
for( i = 0; i < MAX_EFRAGS - 1; i++ )
clgame.free_efrags[i].entnext = &clgame.free_efrags[i+1];
clgame.free_efrags[i].entnext = NULL;
}
/*
=======================
R_ClearStaticEntities

View File

@ -501,7 +501,6 @@ typedef struct
net_request_t net_requests[MAX_REQUESTS]; // no reason to keep more
efrag_t *free_efrags; // linked efrags
cl_entity_t viewent; // viewmodel
qboolean client_dll_uses_sdl;