mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-09 01:01:07 +00:00
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:
parent
43b509ba4f
commit
a1c95a5978
4 changed files with 50 additions and 88 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue