gl_refrag.c: Hunk-allocate efrags and trim out unused functionality

git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1394 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
Eric Wasylishen 2017-04-02 19:39:18 +00:00
parent 43b509ba4f
commit a1c95a5978
4 changed files with 50 additions and 88 deletions

View file

@ -51,7 +51,6 @@ cvar_t cl_minpitch = {"cl_minpitch", "-90", CVAR_ARCHIVE}; //johnfitz -- variabl
client_static_t cls;
client_state_t cl;
// FIXME: put these on hunk?
efrag_t cl_efrags[MAX_EFRAGS];
entity_t cl_static_entities[MAX_STATIC_ENTITIES];
lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
dlight_t cl_dlights[MAX_DLIGHTS];
@ -72,8 +71,6 @@ CL_ClearState
*/
void CL_ClearState (void)
{
int i;
if (!sv.active)
Host_ClearMemory ();
@ -83,7 +80,6 @@ void CL_ClearState (void)
SZ_Clear (&cls.message);
// clear other arrays
memset (cl_efrags, 0, sizeof(cl_efrags));
memset (cl_dlights, 0, sizeof(cl_dlights));
memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
memset (cl_temp_entities, 0, sizeof(cl_temp_entities));
@ -93,14 +89,6 @@ void CL_ClearState (void)
cl_max_edicts = CLAMP (MIN_EDICTS,(int)max_edicts.value,MAX_EDICTS);
cl_entities = (entity_t *) Hunk_AllocName (cl_max_edicts*sizeof(entity_t), "cl_entities");
//johnfitz
//
// allocate the efrags and chain together into a free list
//
cl.free_efrags = cl_efrags;
for (i=0 ; i<MAX_EFRAGS-1 ; i++)
cl.free_efrags[i].entnext = &cl.free_efrags[i+1];
cl.free_efrags[i].entnext = NULL;
}
/*
@ -455,8 +443,11 @@ void CL_RelinkEntities (void)
{
if (!ent->model)
{ // empty slot
if (ent->forcelink)
R_RemoveEfrags (ent); // just became empty
// ericw -- efrags are only used for static entities in GLQuake
// ent can't be static, so this is a no-op.
//if (ent->forcelink)
// R_RemoveEfrags (ent); // just became empty
continue;
}

View file

@ -85,8 +85,6 @@ typedef struct
vec3_t start, end;
} beam_t;
#define MAX_EFRAGS 8192 //ericw -- was 2048 //johnfitz -- was 640
#define MAX_MAPSTRING 2048
#define MAX_DEMOS 8
#define MAX_DEMONAME 16
@ -214,6 +212,7 @@ typedef struct
// refresh related state
struct qmodel_s *worldmodel; // cl_entitites[0].model
struct efrag_s *free_efrags;
int num_efrags;
int num_entities; // held in cl_entities array
int num_statics; // held in cl_staticentities array
entity_t viewent; // the gun model
@ -271,7 +270,6 @@ extern cvar_t m_side;
extern client_state_t cl;
// FIXME, allocate dynamically
extern efrag_t cl_efrags[MAX_EFRAGS];
extern entity_t cl_static_entities[MAX_STATIC_ENTITIES];
extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
extern dlight_t cl_dlights[MAX_DLIGHTS];

View file

@ -33,55 +33,57 @@ mnode_t *r_pefragtopnode;
ENTITY FRAGMENT FUNCTIONS
ericw -- GLQuake only uses efrags for static entities, and they're never
removed, so I trimmed out unused functionality and fields in efrag_t.
Now, efrags are just a linked list for each leaf of the static
entities that touch that leaf. The efrags are hunk-allocated so there is no
fixed limit.
This is inspired by MH's tutorial, and code from RMQEngine.
http://forums.insideqc.com/viewtopic.php?t=1930
===============================================================================
*/
efrag_t **lastlink;
vec3_t r_emins, r_emaxs;
entity_t *r_addent;
/*
================
R_RemoveEfrags
#define EXTRA_EFRAGS 128
Call when removing an object from the world or moving it to another position
================
*/
void R_RemoveEfrags (entity_t *ent)
// based on RMQEngine
static efrag_t *R_GetEfrag (void)
{
efrag_t *ef, *old, *walk, **prev;
ef = ent->efrag;
while (ef)
// we could just Hunk_Alloc a single efrag_t and return it, but since
// the struct is so small (2 pointers) allocate groups of them
// to avoid wasting too much space on the hunk allocation headers.
if (cl.free_efrags)
{
prev = &ef->leaf->efrags;
while (1)
{
walk = *prev;
if (!walk)
break;
if (walk == ef)
{ // remove this fragment
*prev = ef->leafnext;
break;
}
else
prev = &walk->leafnext;
}
old = ef;
ef = ef->entnext;
// put it on the free list
old->entnext = cl.free_efrags;
cl.free_efrags = old;
efrag_t *ef = cl.free_efrags;
cl.free_efrags = ef->leafnext;
ef->leafnext = NULL;
cl.num_efrags++;
return ef;
}
else
{
int i;
cl.free_efrags = (efrag_t *) Hunk_AllocName (EXTRA_EFRAGS * sizeof (efrag_t), "efrags");
for (i = 0; i < EXTRA_EFRAGS - 1; i++)
cl.free_efrags[i].leafnext = &cl.free_efrags[i + 1];
cl.free_efrags[i].leafnext = NULL;
// call recursively to get a newly allocated free efrag
return R_GetEfrag ();
}
ent->efrag = NULL;
}
/*
@ -111,29 +113,10 @@ void R_SplitEntityOnNode (mnode_t *node)
leaf = (mleaf_t *)node;
// grab an efrag off the free list
ef = cl.free_efrags;
if (!ef)
{
//johnfitz -- less spammy overflow message
if (!dev_overflows.efrags || dev_overflows.efrags + CONSOLE_RESPAM_TIME < realtime )
{
Con_Printf ("Too many efrags!\n");
dev_overflows.efrags = realtime;
}
//johnfitz
return; // no free fragments...
}
cl.free_efrags = cl.free_efrags->entnext;
ef = R_GetEfrag();
ef->entity = r_addent;
// add the entity link
*lastlink = ef;
lastlink = &ef->entnext;
ef->entnext = NULL;
// set the leaf links
ef->leaf = leaf;
ef->leafnext = leaf->efrags;
leaf->efrags = ef;
@ -168,20 +151,14 @@ R_CheckEfrags -- johnfitz -- check for excessive efrag count
*/
void R_CheckEfrags (void)
{
efrag_t *ef;
int count;
if (cls.signon < 2)
return; //don't spam when still parsing signon packet full of static ents
for (count=MAX_EFRAGS, ef = cl.free_efrags; ef; count--, ef = ef->entnext)
;
if (cl.num_efrags > 640 && dev_peakstats.efrags <= 640)
Con_DWarning ("%i efrags exceeds standard limit of 640.\n", cl.num_efrags);
if (count > 640 && dev_peakstats.efrags <= 640)
Con_DWarning ("%i efrags exceeds standard limit of 640 (max = %d).\n", count, MAX_EFRAGS);
dev_stats.efrags = count;
dev_peakstats.efrags = q_max(count, dev_peakstats.efrags);
dev_stats.efrags = cl.num_efrags;
dev_peakstats.efrags = q_max(cl.num_efrags, dev_peakstats.efrags);
}
/*
@ -199,7 +176,6 @@ void R_AddEfrags (entity_t *ent)
r_addent = ent;
lastlink = &ent->efrag;
r_pefragtopnode = NULL;
entmodel = ent->model;

View file

@ -34,10 +34,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
typedef struct efrag_s
{
struct mleaf_s *leaf;
struct efrag_s *leafnext;
struct entity_s *entity;
struct efrag_s *entnext;
} efrag_t;
//johnfitz -- for lerping
@ -147,7 +145,6 @@ void R_ViewChanged (vrect_t *pvrect, int lineadj, float aspect);
void R_CheckEfrags (void); //johnfitz
void R_AddEfrags (entity_t *ent);
void R_RemoveEfrags (entity_t *ent);
void R_NewMap (void);