mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 15:01:41 +00:00
Dynamic entity allocation. Unlimited static entities.
Entities can now be allocated dynamically. They are freed whenever a new map is loaded. Use the dynamic entities for static entities.
This commit is contained in:
parent
3b08ac89d0
commit
a4b97e9e2e
12 changed files with 74 additions and 22 deletions
|
@ -202,6 +202,8 @@ void R_LoadSkys (const char *);
|
|||
void R_ClearEfrags (void);
|
||||
void R_ClearEnts (void);
|
||||
void R_EnqueueEntity (struct entity_s *ent);
|
||||
struct entity_s *R_AllocEntity (void);
|
||||
void R_FreeAllEntities (void);
|
||||
|
||||
dlight_t *R_AllocDlight (int key);
|
||||
void R_DecayLights (double frametime);
|
||||
|
|
|
@ -168,6 +168,8 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
|
|||
memset (&r_worldentity, 0, sizeof (r_worldentity));
|
||||
r_worldentity.model = worldmodel;
|
||||
|
||||
R_FreeAllEntities ();
|
||||
|
||||
// clear out efrags in case the level hasn't been reloaded
|
||||
for (i = 0; i < r_worldentity.model->numleafs; i++)
|
||||
r_worldentity.model->leafs[i].efrags = NULL;
|
||||
|
|
|
@ -49,9 +49,61 @@ static __attribute__ ((used)) const char rcsid[] =
|
|||
|
||||
#include "r_dynamic.h"
|
||||
|
||||
#define ENT_POOL_SIZE 32
|
||||
|
||||
typedef struct entity_pool_s {
|
||||
struct entity_pool_s *next;
|
||||
entity_t entities[ENT_POOL_SIZE];
|
||||
} entity_pool_t;
|
||||
|
||||
entity_t *r_ent_queue;
|
||||
static entity_t **vis_tail = &r_ent_queue;
|
||||
|
||||
static entity_pool_t *entity_pools = 0;
|
||||
static entity_pool_t **entpool_tail = &entity_pools;
|
||||
static entity_t *free_entities;
|
||||
|
||||
entity_t *
|
||||
R_AllocEntity (void)
|
||||
{
|
||||
entity_pool_t *pool;
|
||||
entity_t *ent;
|
||||
int i;
|
||||
|
||||
if ((ent = free_entities)) {
|
||||
free_entities = ent->next;
|
||||
ent->next = 0;
|
||||
return ent;
|
||||
}
|
||||
|
||||
pool = malloc (sizeof (entity_pool_t));
|
||||
pool->next = 0;
|
||||
*entpool_tail = pool;
|
||||
entpool_tail = &pool->next;
|
||||
|
||||
for (ent = pool->entities, i = 0; i < ENT_POOL_SIZE - 1; i++, ent++)
|
||||
ent->next = ent + 1;
|
||||
ent->next = 0;
|
||||
free_entities = entity_pools->entities;
|
||||
|
||||
return R_AllocEntity ();
|
||||
}
|
||||
|
||||
void
|
||||
R_FreeAllEntities (void)
|
||||
{
|
||||
entity_pool_t *pool;
|
||||
entity_t *ent;
|
||||
int i;
|
||||
|
||||
for (pool = entity_pools; pool; pool = pool->next) {
|
||||
for (ent = pool->entities, i = 0; i < ENT_POOL_SIZE - 1; i++, ent++)
|
||||
ent->next = ent + 1;
|
||||
ent->next = pool->next ? pool->entities : 0;
|
||||
}
|
||||
free_entities = entity_pools ? entity_pools->entities : 0;
|
||||
}
|
||||
|
||||
void
|
||||
R_ClearEnts (void)
|
||||
{
|
||||
|
|
|
@ -192,6 +192,8 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
|
|||
memset (&r_worldentity, 0, sizeof (r_worldentity));
|
||||
r_worldentity.model = worldmodel;
|
||||
|
||||
R_FreeAllEntities ();
|
||||
|
||||
// clear out efrags in case the level hasn't been reloaded
|
||||
// FIXME: is this one short?
|
||||
for (i = 0; i < r_worldentity.model->numleafs; i++)
|
||||
|
|
|
@ -220,6 +220,8 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
|
|||
memset (&r_worldentity, 0, sizeof (r_worldentity));
|
||||
r_worldentity.model = worldmodel;
|
||||
|
||||
R_FreeAllEntities ();
|
||||
|
||||
// clear out efrags in case the level hasn't been reloaded
|
||||
// FIXME: is this one short?
|
||||
for (i = 0; i < r_worldentity.model->numleafs; i++)
|
||||
|
|
|
@ -208,7 +208,6 @@ typedef struct
|
|||
// refresh related state
|
||||
struct model_s *worldmodel; // cl_entitites[0].model
|
||||
int num_entities; // held in cl_entities array
|
||||
int num_statics; // held in cl_staticentities array
|
||||
entity_t viewent; // the gun model
|
||||
|
||||
int cdtrack, looptrack; // cd audio
|
||||
|
@ -280,14 +279,11 @@ extern struct cvar_s *cl_cshift_powerup;
|
|||
|
||||
extern struct cvar_s *noskins;
|
||||
|
||||
#define MAX_STATIC_ENTITIES 512 // torches, etc
|
||||
|
||||
extern client_state_t cl;
|
||||
|
||||
// FIXME, allocate dynamically
|
||||
extern entity_t cl_entities[MAX_EDICTS];
|
||||
extern cl_entity_state_t cl_baselines[MAX_EDICTS];
|
||||
extern entity_t cl_static_entities[MAX_STATIC_ENTITIES];
|
||||
|
||||
extern int fps_count;
|
||||
|
||||
|
|
|
@ -87,7 +87,6 @@ client_state_t cl;
|
|||
// FIXME: put these on hunk?
|
||||
entity_t cl_entities[MAX_EDICTS];
|
||||
cl_entity_state_t cl_baselines[MAX_EDICTS];
|
||||
entity_t cl_static_entities[MAX_STATIC_ENTITIES];
|
||||
|
||||
|
||||
void
|
||||
|
|
|
@ -778,13 +778,10 @@ CL_ParseStatic (int version)
|
|||
{
|
||||
cl_entity_state_t state;
|
||||
entity_t *ent;
|
||||
int i;
|
||||
|
||||
i = cl.num_statics;
|
||||
if (i >= MAX_STATIC_ENTITIES)
|
||||
Host_Error ("Too many static entities");
|
||||
ent = &cl_static_entities[i];
|
||||
cl.num_statics++;
|
||||
ent = R_AllocEntity ();
|
||||
CL_Init_Entity (ent);
|
||||
|
||||
CL_ParseBaseline (&state, version);
|
||||
|
||||
// copy it to the current state
|
||||
|
|
|
@ -293,7 +293,6 @@ typedef struct
|
|||
// refresh related state
|
||||
struct model_s *worldmodel; // cl_entitites[0].model
|
||||
int num_entities; // stored bottom up in cl_entities array
|
||||
int num_statics; // stored top down in cl_entitiers
|
||||
|
||||
int cdtrack; // cd audio
|
||||
|
||||
|
@ -345,13 +344,11 @@ extern struct cvar_s *skin;
|
|||
|
||||
extern struct cvar_s *cl_fb_players;
|
||||
|
||||
#define MAX_STATIC_ENTITIES 128 // torches, etc
|
||||
|
||||
extern client_state_t cl;
|
||||
|
||||
// FIXME, allocate dynamically
|
||||
extern entity_state_t cl_baselines[MAX_EDICTS];
|
||||
extern entity_t cl_static_entities[MAX_STATIC_ENTITIES];
|
||||
extern entity_t *cl_static_entities;
|
||||
|
||||
extern qboolean nomaster;
|
||||
extern char *server_version; // version of server we connected to
|
||||
|
|
|
@ -672,9 +672,7 @@ CL_Record (const char *argv1)
|
|||
SZ_Clear (&buf);
|
||||
}
|
||||
// spawnstatic
|
||||
for (i = 0; i < cl.num_statics; i++) {
|
||||
ent = cl_static_entities + i;
|
||||
|
||||
for (ent = cl_static_entities; ent; ent = ent->next) {
|
||||
MSG_WriteByte (&buf, svc_spawnstatic);
|
||||
|
||||
for (j = 1; j < MAX_MODELS; j++)
|
||||
|
|
|
@ -195,7 +195,6 @@ entity_state_t cl_entities[UPDATE_BACKUP][MAX_DEMO_PACKET_ENTITIES];
|
|||
|
||||
entity_state_t cl_baselines[MAX_EDICTS];
|
||||
efrag_t cl_efrags[MAX_EFRAGS];
|
||||
entity_t cl_static_entities[MAX_STATIC_ENTITIES];
|
||||
|
||||
double connect_time = -1; // for connection retransmits
|
||||
|
||||
|
|
|
@ -175,6 +175,9 @@ float r_gravity;
|
|||
|
||||
extern cvar_t *hud_scoreboard_uid;
|
||||
|
||||
entity_t *cl_static_entities;
|
||||
static entity_t **cl_static_tail;
|
||||
|
||||
|
||||
int
|
||||
CL_CalcNet (void)
|
||||
|
@ -262,6 +265,8 @@ CL_CheckOrDownloadFile (const char *filename)
|
|||
static void
|
||||
CL_NewMap (const char *mapname)
|
||||
{
|
||||
cl_static_entities = 0;
|
||||
cl_static_tail = &cl_static_entities;
|
||||
R_NewMap (cl.worldmodel, cl.model_precache, MAX_MODELS);
|
||||
Team_NewMap ();
|
||||
Con_NewMap ();
|
||||
|
@ -920,11 +925,12 @@ CL_ParseStatic (void)
|
|||
|
||||
CL_ParseBaseline (&es);
|
||||
|
||||
if (cl.num_statics >= MAX_STATIC_ENTITIES) //FIXME nuke!!!
|
||||
Host_Error ("Too many static entities");
|
||||
ent = &cl_static_entities[cl.num_statics++];
|
||||
ent = R_AllocEntity ();
|
||||
CL_Init_Entity (ent);
|
||||
|
||||
*cl_static_tail = ent;
|
||||
cl_static_tail = &ent->next;
|
||||
|
||||
// copy it to the current state
|
||||
ent->model = cl.model_precache[es.modelindex];
|
||||
ent->frame = es.frame;
|
||||
|
|
Loading…
Reference in a new issue