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:
Bill Currie 2010-12-03 18:21:07 +09:00
parent 3b08ac89d0
commit a4b97e9e2e
12 changed files with 74 additions and 22 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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)
{

View file

@ -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++)

View file

@ -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++)

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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++)

View file

@ -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

View file

@ -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;