From: havoc Date: Sat, 3 Aug 2002 20:34:59 +0000 (+0000) Subject: Lots of speedups and cleanups in client code, dynamically allocated cl_entities ... X-Git-Tag: RELEASE_0_2_0_RC1~388 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=a76b746a4cd4e319c9629348ad2fb6563ef49393;hp=b44563794a2f0644800fdf82f2a848888de6c10b Lots of speedups and cleanups in client code, dynamically allocated cl_entities (and friends), rearranged some things - sorry this commit is vague, but it's mostly just a lot of rearrangement, cleanup, etc... git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2175 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cgamevm.c b/cgamevm.c index eb4f5e1f..d921b752 100644 --- a/cgamevm.c +++ b/cgamevm.c @@ -130,7 +130,7 @@ void CGVM_Draw_Entity(const cgdrawentity_t *e) return; if (cgvm_renderentity >= CGVM_RENDERENTITIES - || r_refdef.numentities >= MAX_VISEDICTS) + || r_refdef.numentities >= r_refdef.maxentities) return; r = cgvm_renderentities + cgvm_renderentity; @@ -262,6 +262,7 @@ int CGVM_Model(const char *name) void CGVM_Stain(const float *origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2) { - R_Stain((float *)origin, radius, cr1, cg1, cb1, ca1, cr2, cg2, cb2, ca2); + if (cl_stainmaps.integer) + R_Stain((float *)origin, radius, cr1, cg1, cb1, ca1, cr2, cg2, cb2, ca2); } diff --git a/cl_collision.c b/cl_collision.c index ea667b65..6457fbf2 100644 --- a/cl_collision.c +++ b/cl_collision.c @@ -28,48 +28,6 @@ typedef struct physentity_s physentity_t; */ -static entity_render_t *traceline_entity[MAX_EDICTS]; -static int traceline_entities; - -// builds list of entities for TraceLine to check later -void CL_TraceLine_ScanForBModels(void) -{ - int i; - entity_render_t *ent; - model_t *model; - traceline_entities = 0; - for (i = 1;i < MAX_EDICTS;i++) - { - ent = &cl_entities[i].render; - model = ent->model; - // look for embedded brush models only - if (model && model->name[0] == '*') - { - if (model->type == mod_brush) - { - traceline_entity[traceline_entities++] = ent; - if (ent->angles[0] || ent->angles[2]) - { - // pitch or roll - VectorAdd(ent->origin, model->rotatedmins, ent->mins); - VectorAdd(ent->origin, model->rotatedmaxs, ent->maxs); - } - else if (ent->angles[1]) - { - // yaw - VectorAdd(ent->origin, model->yawmins, ent->mins); - VectorAdd(ent->origin, model->yawmaxs, ent->maxs); - } - else - { - VectorAdd(ent->origin, model->normalmins, ent->mins); - VectorAdd(ent->origin, model->normalmaxs, ent->maxs); - } - } - } - } -} - int cl_traceline_endcontents; float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels) @@ -87,7 +45,7 @@ float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int cl_traceline_endcontents = trace.endcontents; maxfrac = trace.fraction; - if (hitbmodels && traceline_entities) + if (hitbmodels && cl_num_brushmodel_entities) { int n; entity_render_t *ent; @@ -100,9 +58,9 @@ float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int tracemaxs[2] = max(start[2], end[2]); // look for embedded bmodels - for (n = 0;n < traceline_entities;n++) + for (n = 0;n < cl_num_brushmodel_entities;n++) { - ent = traceline_entity[n]; + ent = cl_brushmodel_entities[n]; if (ent->mins[0] > tracemaxs[0] || ent->maxs[0] < tracemins[0] || ent->mins[1] > tracemaxs[1] || ent->maxs[1] < tracemins[1] || ent->mins[2] > tracemaxs[2] || ent->maxs[2] < tracemins[2]) diff --git a/cl_collision.h b/cl_collision.h index ec4a89f0..370349c2 100644 --- a/cl_collision.h +++ b/cl_collision.h @@ -6,9 +6,6 @@ // (leafs matching contents are considered empty, others are solid) extern int cl_traceline_endcontents; // set by TraceLine -// need to call this sometime before using TraceLine with hitbmodels -void CL_TraceLine_ScanForBModels(void); - float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels); #endif diff --git a/cl_light.c b/cl_light.c index 9ab6ea32..5d0bcec6 100644 --- a/cl_light.c +++ b/cl_light.c @@ -1,8 +1,6 @@ #include "quakedef.h" -dlight_t cl_dlights[MAX_DLIGHTS]; - /* =============== CL_AllocDlight @@ -14,6 +12,7 @@ void CL_AllocDlight (entity_render_t *ent, vec3_t org, float radius, float red, int i; dlight_t *dl; + /* // first look for an exact key match if (ent) { @@ -22,6 +21,7 @@ void CL_AllocDlight (entity_render_t *ent, vec3_t org, float radius, float red, if (dl->ent == ent) goto dlightsetup; } + */ // then look for anything else dl = cl_dlights; @@ -34,7 +34,7 @@ void CL_AllocDlight (entity_render_t *ent, vec3_t org, float radius, float red, dlightsetup: memset (dl, 0, sizeof(*dl)); - dl->ent = ent; + //dl->ent = ent; VectorCopy(org, dl->origin); dl->radius = radius; dl->color[0] = red; diff --git a/cl_main.c b/cl_main.c index d25fd390..78c41e34 100644 --- a/cl_main.c +++ b/cl_main.c @@ -55,34 +55,33 @@ cvar_t cl_stainmaps = {CVAR_SAVE, "cl_stainmaps", "1"}; mempool_t *cl_scores_mempool; mempool_t *cl_refdef_mempool; +mempool_t *cl_entities_mempool; client_static_t cls; client_state_t cl; -// FIXME: put these on hunk? -entity_t cl_entities[MAX_EDICTS]; -entity_t cl_static_entities[MAX_STATIC_ENTITIES]; -lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; - -typedef struct effect_s -{ - int active; - vec3_t origin; - float starttime; - float framerate; - int modelindex; - int startframe; - int endframe; - // these are for interpolation - int frame; - double frame1time; - double frame2time; -} -cl_effect_t; - -#define MAX_EFFECTS 256 - -static cl_effect_t cl_effect[MAX_EFFECTS]; +int cl_max_entities; +int cl_max_static_entities; +int cl_max_temp_entities; +int cl_max_effects; +int cl_max_beams; +int cl_max_dlights; +int cl_max_lightstyle; +int cl_max_brushmodel_entities; + +entity_t *cl_entities; +entity_t *cl_static_entities; +entity_t *cl_temp_entities; +cl_effect_t *cl_effects; +beam_t *cl_beams; +dlight_t *cl_dlights; +lightstyle_t *cl_lightstyle; +entity_render_t **cl_brushmodel_entities; + +int cl_num_entities; +int cl_num_static_entities; +int cl_num_temp_entities; +int cl_num_brushmodel_entities; /* ===================== @@ -92,29 +91,49 @@ CL_ClearState */ void CL_ClearState (void) { - int i; + int i; if (!sv.active) Host_ClearMemory (); Mem_EmptyPool(cl_scores_mempool); + Mem_EmptyPool(cl_entities_mempool); // wipe the entire cl structure memset (&cl, 0, sizeof(cl)); SZ_Clear (&cls.message); -// clear other arrays - memset(cl_entities, 0, sizeof(cl_entities)); - memset(cl_lightstyle, 0, sizeof(cl_lightstyle)); - memset(cl_temp_entities, 0, sizeof(cl_temp_entities)); - memset(cl_beams, 0, sizeof(cl_beams)); - memset(cl_dlights, 0, sizeof(cl_dlights)); - memset(cl_effect, 0, sizeof(cl_effect)); + cl_num_entities = 0; + cl_num_static_entities = 0; + cl_num_temp_entities = 0; + cl_num_brushmodel_entities = 0; + + // tweak these if the game runs out + cl_max_entities = MAX_EDICTS; + cl_max_static_entities = 256; + cl_max_temp_entities = 512; + cl_max_effects = 256; + cl_max_beams = 24; + cl_max_dlights = MAX_DLIGHTS; + cl_max_lightstyle = MAX_LIGHTSTYLES; + cl_max_brushmodel_entities = MAX_EDICTS; + + cl_entities = Mem_Alloc(cl_entities_mempool, cl_max_entities * sizeof(entity_t)); + cl_static_entities = Mem_Alloc(cl_entities_mempool, cl_max_static_entities * sizeof(entity_t)); + cl_temp_entities = Mem_Alloc(cl_entities_mempool, cl_max_temp_entities * sizeof(entity_t)); + cl_effects = Mem_Alloc(cl_entities_mempool, cl_max_effects * sizeof(cl_effect_t)); + cl_beams = Mem_Alloc(cl_entities_mempool, cl_max_beams * sizeof(beam_t)); + cl_dlights = Mem_Alloc(cl_entities_mempool, cl_max_dlights * sizeof(dlight_t)); + cl_lightstyle = Mem_Alloc(cl_entities_mempool, cl_max_lightstyle * sizeof(lightstyle_t)); + cl_brushmodel_entities = Mem_Alloc(cl_entities_mempool, cl_max_brushmodel_entities * sizeof(entity_render_t *)); + CL_Screen_NewMap(); + CL_Particles_Clear(); + // LordHavoc: have to set up the baseline info for alpha and other stuff - for (i = 0;i < MAX_EDICTS;i++) + for (i = 0;i < cl_max_entities;i++) { ClearStateToDefault(&cl_entities[i].state_baseline); ClearStateToDefault(&cl_entities[i].state_previous); @@ -124,47 +143,6 @@ void CL_ClearState (void) CL_CGVM_Clear(); } -void CL_LerpUpdate(entity_t *e) -{ - entity_persistent_t *p; - entity_render_t *r; - p = &e->persistent; - r = &e->render; - - if (p->modelindex != e->state_current.modelindex) - { - // reset all interpolation information - p->modelindex = e->state_current.modelindex; - p->frame1 = p->frame2 = e->state_current.frame; - p->frame1time = p->frame2time = cl.time; - p->framelerp = 1; - } - else if (p->frame2 != e->state_current.frame) - { - // transition to new frame - p->frame1 = p->frame2; - p->frame1time = p->frame2time; - p->frame2 = e->state_current.frame; - p->frame2time = cl.time; - p->framelerp = 0; - } - else - { - // update transition - p->framelerp = (cl.time - p->frame2time) * 10; - p->framelerp = bound(0, p->framelerp, 1); - } - - r->model = cl.model_precache[e->state_current.modelindex]; - Mod_CheckLoaded(r->model); - r->frame = e->state_current.frame; - r->frame1 = p->frame1; - r->frame2 = p->frame2; - r->framelerp = p->framelerp; - r->frame1time = p->frame1time; - r->frame2time = p->frame2time; -} - /* ===================== CL_Disconnect @@ -259,31 +237,66 @@ CL_PrintEntities_f */ static void CL_PrintEntities_f (void) { - entity_t *ent; - int i, j; - char name[32]; + entity_t *ent; + int i, j; + char name[32]; - for (i = 0, ent = cl_entities;i < MAX_EDICTS /*cl.num_entities*/;i++, ent++) + for (i = 0, ent = cl_entities;i < cl_num_entities;i++, ent++) { if (!ent->state_current.active) continue; - if (!ent->render.model) - continue; - Con_Printf ("%3i:", i); - if (!ent->render.model) - { - Con_Printf ("EMPTY\n"); - continue; - } - strncpy(name, ent->render.model->name, 25); + if (ent->render.model) + strncpy(name, ent->render.model->name, 25); + else + strcpy(name, "--no model--"); name[25] = 0; for (j = strlen(name);j < 25;j++) name[j] = ' '; - Con_Printf ("%s:%04i (%5i %5i %5i) [%3i %3i %3i] %4.2f %5.3f\n", name, ent->render.frame, (int) ent->render.origin[0], (int) ent->render.origin[1], (int) ent->render.origin[2], (int) ent->render.angles[0] % 360, (int) ent->render.angles[1] % 360, (int) ent->render.angles[2] % 360, ent->render.scale, ent->render.alpha); + Con_Printf ("%3i: %s:%04i (%5i %5i %5i) [%3i %3i %3i] %4.2f %5.3f\n", i, name, ent->render.frame, (int) ent->render.origin[0], (int) ent->render.origin[1], (int) ent->render.origin[2], (int) ent->render.angles[0] % 360, (int) ent->render.angles[1] % 360, (int) ent->render.angles[2] % 360, ent->render.scale, ent->render.alpha); } } +void CL_LerpUpdate(entity_t *e) +{ + entity_persistent_t *p; + entity_render_t *r; + p = &e->persistent; + r = &e->render; + + if (p->modelindex != e->state_current.modelindex) + { + // reset all interpolation information + p->modelindex = e->state_current.modelindex; + p->frame1 = p->frame2 = e->state_current.frame; + p->frame1time = p->frame2time = cl.time; + p->framelerp = 1; + } + else if (p->frame2 != e->state_current.frame) + { + // transition to new frame + p->frame1 = p->frame2; + p->frame1time = p->frame2time; + p->frame2 = e->state_current.frame; + p->frame2time = cl.time; + p->framelerp = 0; + } + else + { + // update transition + p->framelerp = (cl.time - p->frame2time) * 10; + p->framelerp = bound(0, p->framelerp, 1); + } + + r->model = cl.model_precache[e->state_current.modelindex]; + Mod_CheckLoaded(r->model); + r->frame = e->state_current.frame; + r->frame1 = p->frame1; + r->frame2 = p->frame2; + r->framelerp = p->framelerp; + r->frame1time = p->frame1time; + r->frame2time = p->frame2time; +} /* =============== @@ -295,7 +308,7 @@ should be put at. */ static float CL_LerpPoint (void) { - float f; + float f; // dropped packet, or start of demo if (cl.mtime[1] < cl.mtime[0] - 0.1) @@ -318,7 +331,7 @@ static float CL_LerpPoint (void) static void CL_RelinkStaticEntities(void) { int i; - for (i = 0;i < cl.num_statics && r_refdef.numentities < MAX_VISEDICTS;i++) + for (i = 0;i < cl_num_static_entities && r_refdef.numentities < r_refdef.maxentities;i++) { Mod_CheckLoaded(cl_static_entities[i].render.model); r_refdef.entities[r_refdef.numentities++] = &cl_static_entities[i].render; @@ -332,10 +345,10 @@ CL_RelinkEntities */ static void CL_RelinkNetworkEntities() { - entity_t *ent; - int i, glowcolor, effects; - float f, d, bobjrotate, bobjoffset, dlightradius, glowsize, lerp; - vec3_t oldorg, neworg, delta, dlightcolor; + entity_t *ent; + int i, effects, temp; + float f, d, bobjrotate, bobjoffset, dlightradius, lerp; + vec3_t oldorg, neworg, delta, dlightcolor, v, v2, mins, maxs; bobjrotate = ANGLEMOD(100*cl.time); if (cl_itembobheight.value) @@ -343,8 +356,8 @@ static void CL_RelinkNetworkEntities() else bobjoffset = 0; -// start on the entity after the world - for (i = 1, ent = cl_entities + 1;i < MAX_EDICTS /*cl.num_entities*/;i++, ent++) + // start on the entity after the world + for (i = 1, ent = cl_entities + 1;i < MAX_EDICTS;i++, ent++) { // if the object wasn't included in the latest packet, remove it if (!ent->state_current.active) @@ -454,8 +467,6 @@ static void CL_RelinkNetworkEntities() { if (ent->render.model) { - vec3_t mins, maxs; - int temp; mins[0] = neworg[0] - 16.0f; mins[1] = neworg[1] - 16.0f; mins[2] = neworg[2] - 16.0f; @@ -475,8 +486,6 @@ static void CL_RelinkNetworkEntities() { if (ent->render.model) { - vec3_t mins, maxs; - int temp; mins[0] = neworg[0] - 16.0f; mins[1] = neworg[1] - 16.0f; mins[2] = neworg[2] - 16.0f; @@ -496,8 +505,6 @@ static void CL_RelinkNetworkEntities() if (ent->persistent.muzzleflash > 0) { - vec3_t v, v2; - AngleVectors (ent->render.angles, v, NULL, NULL); v2[0] = v[0] * 18 + neworg[0]; @@ -547,7 +554,7 @@ static void CL_RelinkNetworkEntities() } else if (ent->render.model->flags & EF_GRENADE) { - if (ent->render.alpha == -1) // LordHavoc: Nehahra dem compatibility + if (ent->render.alpha == -1) // LordHavoc: Nehahra dem compatibility (cigar smoke) CL_RocketTrail (oldorg, neworg, 7, ent); else CL_RocketTrail (oldorg, neworg, 1, ent); @@ -562,28 +569,23 @@ static void CL_RelinkNetworkEntities() } } // LordHavoc: customizable glow - glowsize = ent->state_current.glowsize; // FIXME: interpolate? - glowcolor = ent->state_current.glowcolor; - if (glowsize) + if (ent->state_current.glowsize) { - qbyte *tempcolor = (qbyte *)&d_8to24table[glowcolor]; // * 4 for the expansion from 0-255 to 0-1023 range, // / 255 to scale down byte colors - glowsize *= (4.0f / 255.0f); - VectorMA(dlightcolor, glowsize, tempcolor, dlightcolor); + VectorMA(dlightcolor, ent->state_current.glowsize * (4.0f / 255.0f), (qbyte *)&d_8to24table[ent->state_current.glowcolor], dlightcolor); } // LordHavoc: customizable trail if (ent->render.flags & RENDER_GLOWTRAIL) - CL_RocketTrail2 (oldorg, neworg, glowcolor, ent); + CL_RocketTrail2 (oldorg, neworg, ent->state_current.glowcolor, ent); if (dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) { - vec3_t vec; - VectorCopy(neworg, vec); + VectorCopy(neworg, v); // hack to make glowing player light shine on their gun if (i == cl.viewentity && !chase_active.integer) - vec[2] += 30; - CL_AllocDlight (NULL, vec, 1, dlightcolor[0], dlightcolor[1], dlightcolor[2], 0, 0); + v[2] += 30; + CL_AllocDlight (NULL, v, 1, dlightcolor[0], dlightcolor[1], dlightcolor[2], 0, 0); } if (chase_active.integer) @@ -601,8 +603,33 @@ static void CL_RelinkNetworkEntities() continue; if (effects & EF_NODRAW) continue; - if (r_refdef.numentities < MAX_VISEDICTS) + + if (ent->render.angles[0] || ent->render.angles[2]) + { + // pitch or roll + VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs); + } + else if (ent->render.angles[1]) + { + // yaw + VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs); + } + else + { + VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs); + } + + if (r_refdef.numentities < r_refdef.maxentities) r_refdef.entities[r_refdef.numentities++] = &ent->render; + + if (ent->render.model->name[0] == '*' && ent->render.model->type == mod_brush) + cl_brushmodel_entities[cl_num_brushmodel_entities++] = &ent->render; + + if (cl_num_entities < i + 1) + cl_num_entities = i + 1; } } @@ -635,7 +662,7 @@ void CL_LerpPlayer(float frac) d -= 360; else if (d < -180) d += 360; - cl.viewangles[i] = cl.mviewangles[1][i] + frac*d; + cl.viewangles[i] = cl.mviewangles[1][i] + frac * d; } } } @@ -646,7 +673,7 @@ void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float cl_effect_t *e; if (!modelindex) // sanity check return; - for (i = 0, e = cl_effect;i < MAX_EFFECTS;i++, e++) + for (i = 0, e = cl_effects;i < cl_max_effects;i++, e++) { if (e->active) continue; @@ -669,10 +696,10 @@ static void CL_RelinkEffects() { int i, intframe; cl_effect_t *e; - entity_t *vis; + entity_t *ent; float frame; - for (i = 0, e = cl_effect;i < MAX_EFFECTS;i++, e++) + for (i = 0, e = cl_effects;i < cl_max_effects;i++, e++) { if (e->active) { @@ -692,43 +719,71 @@ static void CL_RelinkEffects() e->frame2time = cl.time; } - if (r_draweffects.integer && (vis = CL_NewTempEntity())) + // if we're drawing effects, get a new temp entity + // (NewTempEntity adds it to the render entities list for us) + if (r_draweffects.integer && (ent = CL_NewTempEntity())) { // interpolation stuff - vis->render.frame1 = intframe; - vis->render.frame2 = intframe + 1; - if (vis->render.frame2 >= e->endframe) - vis->render.frame2 = -1; // disappear - vis->render.framelerp = frame - intframe; - vis->render.frame1time = e->frame1time; - vis->render.frame2time = e->frame2time; + ent->render.frame1 = intframe; + ent->render.frame2 = intframe + 1; + if (ent->render.frame2 >= e->endframe) + ent->render.frame2 = -1; // disappear + ent->render.framelerp = frame - intframe; + ent->render.frame1time = e->frame1time; + ent->render.frame2time = e->frame2time; // normal stuff - VectorCopy(e->origin, vis->render.origin); - vis->render.model = cl.model_precache[e->modelindex]; - vis->render.frame = vis->render.frame2; - vis->render.colormap = -1; // no special coloring - vis->render.scale = 1; - vis->render.alpha = 1; + VectorCopy(e->origin, ent->render.origin); + ent->render.model = cl.model_precache[e->modelindex]; + ent->render.frame = ent->render.frame2; + ent->render.colormap = -1; // no special coloring + ent->render.scale = 1; + ent->render.alpha = 1; + + if (ent->render.angles[0] || ent->render.angles[2]) + { + // pitch or roll + VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs); + } + else if (ent->render.angles[1]) + { + // yaw + VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs); + } + else + { + VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs); + } } } } } +void CL_RelinkWorld (void) +{ + if (cl_num_entities < 1) + cl_num_entities = 1; + cl_brushmodel_entities[cl_num_brushmodel_entities++] = &cl_entities[0].render; +} + void CL_RelinkEntities (void) { float frac; // fraction from previous network update to current - frac = CL_LerpPoint (); + frac = CL_LerpPoint(); - CL_DecayLights (); + CL_ClearTempEntities(); + CL_DecayLights(); + CL_RelinkWorld(); + CL_RelinkBeams(); CL_RelinkStaticEntities(); CL_RelinkNetworkEntities(); - CL_TraceLine_ScanForBModels(); CL_RelinkEffects(); CL_MoveParticles(); - CL_UpdateTEnts(); CL_LerpPlayer(frac); } @@ -770,6 +825,9 @@ int CL_ReadFromServer (void) Con_Printf ("\n"); r_refdef.numentities = 0; + cl_num_entities = 0; + cl_num_brushmodel_entities = 0; + if (cls.state == ca_connected && cl.worldmodel) { CL_RelinkEntities (); @@ -918,10 +976,16 @@ CL_Init void CL_Init (void) { cl_scores_mempool = Mem_AllocPool("client player info"); - + cl_entities_mempool = Mem_AllocPool("client entities"); cl_refdef_mempool = Mem_AllocPool("refdef"); + memset(&r_refdef, 0, sizeof(r_refdef)); - r_refdef.entities = Mem_Alloc(cl_refdef_mempool, sizeof(entity_render_t *) * MAX_VISEDICTS); + // max entities sent to renderer per frame + r_refdef.maxentities = MAX_EDICTS + 256 + 512; + r_refdef.entities = Mem_Alloc(cl_refdef_mempool, sizeof(entity_render_t *) * r_refdef.maxentities); + // 256k drawqueue buffer + r_refdef.maxdrawqueuesize = 256 * 1024; + r_refdef.drawqueue = Mem_Alloc(cl_refdef_mempool, r_refdef.maxdrawqueuesize); SZ_Alloc (&cls.message, 1024, "cls.message"); diff --git a/cl_parse.c b/cl_parse.c index 902c2af1..5837a1cf 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -293,7 +293,7 @@ An svc_signonnum has been received, perform a client side setup */ static void CL_SignonReply (void) { - char str[8192]; + //char str[8192]; Con_DPrintf ("CL_SignonReply: %i\n", cls.signon); @@ -318,8 +318,9 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon); } MSG_WriteByte (&cls.message, clc_stringcmd); - sprintf (str, "spawn %s", cls.spawnparms); - MSG_WriteString (&cls.message, str); + //sprintf (str, "spawn %s", cls.spawnparms); + //MSG_WriteString (&cls.message, str); + MSG_WriteString (&cls.message, "spawn"); break; case 3: @@ -340,11 +341,12 @@ CL_ParseServerInfo */ void CL_ParseServerInfo (void) { - char *str; - int i; - int nummodels, numsounds; - char model_precache[MAX_MODELS][MAX_QPATH]; - char sound_precache[MAX_SOUNDS][MAX_QPATH]; + char *str; + int i; + int nummodels, numsounds; + char model_precache[MAX_MODELS][MAX_QPATH]; + char sound_precache[MAX_SOUNDS][MAX_QPATH]; + entity_t *ent; Con_DPrintf ("Serverinfo packet received.\n"); // @@ -465,9 +467,31 @@ void CL_ParseServerInfo (void) S_EndPrecaching (); // local state - cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1]; - cl_entities[0].render.scale = 1; - cl_entities[0].render.alpha = 1; + ent = &cl_entities[0]; + memset(ent, 0, sizeof(entity_t)); + ent->render.model = cl.worldmodel = cl.model_precache[1]; + ent->render.scale = 1; + ent->render.alpha = 1; + + if (ent->render.angles[0] || ent->render.angles[2]) + { + // pitch or roll + VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs); + } + else if (ent->render.angles[1]) + { + // yaw + VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs); + } + else + { + VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs); + } + + cl_num_entities = 1; R_NewMap (); @@ -863,9 +887,9 @@ void CL_ParseStatic (int large) { entity_t *ent; - if (cl.num_statics >= MAX_STATIC_ENTITIES) + if (cl_num_static_entities >= cl_max_static_entities) Host_Error ("Too many static entities"); - ent = &cl_static_entities[cl.num_statics++]; + ent = &cl_static_entities[cl_num_static_entities++]; CL_ParseBaseline (ent, large); // copy it to the current state @@ -882,11 +906,29 @@ void CL_ParseStatic (int large) ent->render.alpha = 1; VectorCopy (ent->state_baseline.origin, ent->render.origin); - VectorCopy (ent->state_baseline.angles, ent->render.angles); + VectorCopy (ent->state_baseline.angles, ent->render.angles); + + if (ent->render.angles[0] || ent->render.angles[2]) + { + // pitch or roll + VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs); + } + else if (ent->render.angles[1]) + { + // yaw + VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs); + } + else + { + VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins); + VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs); + } // This is definitely cheating... if (ent->render.model == NULL) - cl.num_statics--; + cl_num_static_entities--; } /* diff --git a/cl_particles.c b/cl_particles.c index c6a110e8..b2e25248 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -861,7 +861,8 @@ void CL_MoveParticles (void) if (p->bounce < 0) { // assume it's blood (lame, but...) - R_Stain(v, 64, 32, 16, 16, p->alpha * p->scalex * (1.0f / 100.0f), 192, 48, 48, p->alpha * p->scalex * (1.0f / 100.0f)); + if (cl_stainmaps.integer) + R_Stain(v, 64, 32, 16, 16, p->alpha * p->scalex * (1.0f / 100.0f), 192, 48, 48, p->alpha * p->scalex * (1.0f / 100.0f)); p->die = -1; freeparticles[j++] = p; continue; diff --git a/cl_screen.c b/cl_screen.c index 4d88c529..bbe08834 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -480,7 +480,7 @@ void DrawQ_Pic(float x, float y, char *picname, float width, float height, float if (alpha < (1.0f / 255.0f)) return; size = sizeof(*dq) + ((strlen(picname) + 1 + 3) & ~3); - if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE) + if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize) return; red = bound(0, red, 1); green = bound(0, green, 1); @@ -518,7 +518,7 @@ void DrawQ_String(float x, float y, char *string, int maxlen, float scalex, floa if (x >= vid.conwidth || y >= vid.conheight || x < (-scalex * maxlen) || y < (-scaley)) return; size = sizeof(*dq) + ((len + 1 + 3) & ~3); - if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE) + if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize) return; red = bound(0, red, 1); green = bound(0, green, 1); @@ -546,7 +546,7 @@ void DrawQ_Fill (float x, float y, float w, float h, float red, float green, flo if (alpha < (1.0f / 255.0f)) return; size = sizeof(*dq) + 4; - if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE) + if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize) return; red = bound(0, red, 1); green = bound(0, green, 1); @@ -578,7 +578,7 @@ void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags) size += sizeof(float[3]) * mesh->numvertices; size += sizeof(float[2]) * mesh->numvertices; size += sizeof(float[4]) * mesh->numvertices; - if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE) + if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize) return; dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize); dq->size = size; diff --git a/cl_screen.h b/cl_screen.h index 57552be4..da063b8d 100644 --- a/cl_screen.h +++ b/cl_screen.h @@ -3,8 +3,6 @@ #define CL_SCREEN_H // drawqueue stuff for use by client to feed 2D art to renderer -#define MAX_DRAWQUEUE 262144 - #define DRAWQUEUE_PIC 0 #define DRAWQUEUE_STRING 1 #define DRAWQUEUE_MESH 2 diff --git a/cl_tent.c b/cl_tent.c index 987ff449..f81fa76a 100644 --- a/cl_tent.c +++ b/cl_tent.c @@ -21,22 +21,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -int num_temp_entities; -entity_t cl_temp_entities[MAX_TEMP_ENTITIES]; -beam_t cl_beams[MAX_BEAMS]; - -model_t *cl_model_bolt = NULL; -model_t *cl_model_bolt2 = NULL; -model_t *cl_model_bolt3 = NULL; -model_t *cl_model_beam = NULL; - -sfx_t *cl_sfx_wizhit; -sfx_t *cl_sfx_knighthit; -sfx_t *cl_sfx_tink1; -sfx_t *cl_sfx_ric1; -sfx_t *cl_sfx_ric2; -sfx_t *cl_sfx_ric3; -sfx_t *cl_sfx_r_exp3; +model_t *cl_model_bolt = NULL; +model_t *cl_model_bolt2 = NULL; +model_t *cl_model_bolt3 = NULL; +model_t *cl_model_beam = NULL; + +sfx_t *cl_sfx_wizhit; +sfx_t *cl_sfx_knighthit; +sfx_t *cl_sfx_tink1; +sfx_t *cl_sfx_ric1; +sfx_t *cl_sfx_ric2; +sfx_t *cl_sfx_ric3; +sfx_t *cl_sfx_r_exp3; /* ================= @@ -61,29 +57,30 @@ CL_ParseBeam */ void CL_ParseBeam (model_t *m) { - int ent; - vec3_t start, end; - beam_t *b; - int i; + int i, ent; + vec3_t start, end; + beam_t *b; ent = MSG_ReadShort (); MSG_ReadVector(start); MSG_ReadVector(end); -// override any beam with the same entity - for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + // override any beam with the same entity + for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++) + { if (b->entity == ent) { - b->entity = ent; + //b->entity = ent; b->model = m; b->endtime = cl.time + 0.2; VectorCopy (start, b->start); VectorCopy (end, b->end); return; } + } -// find a free beam - for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + // find a free beam + for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++) { if (!b->model || b->endtime < cl.time) { @@ -95,7 +92,7 @@ void CL_ParseBeam (model_t *m) return; } } - Con_Printf ("beam list overflow!\n"); + Con_Printf ("beam list overflow!\n"); } @@ -106,34 +103,37 @@ CL_ParseTEnt */ void CL_ParseTEnt (void) { - int type; - vec3_t pos; - vec3_t dir; - vec3_t pos2; - vec3_t color; - int rnd; - int colorStart, colorLength, count; - float velspeed, radius; + int type; + vec3_t pos; + vec3_t dir; + vec3_t pos2; + vec3_t color; + int rnd; + int colorStart, colorLength, count; + float velspeed, radius; qbyte *tempcolor; type = MSG_ReadByte (); switch (type) { - case TE_WIZSPIKE: // spike hitting wall + case TE_WIZSPIKE: + // spike hitting wall MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); CL_RunParticleEffect (pos, vec3_origin, 20, 30); S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1); break; - case TE_KNIGHTSPIKE: // spike hitting wall + case TE_KNIGHTSPIKE: + // spike hitting wall MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); CL_RunParticleEffect (pos, vec3_origin, 226, 20); S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1); break; - case TE_SPIKE: // spike hitting wall + case TE_SPIKE: + // spike hitting wall MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); // LordHavoc: changed to spark shower @@ -151,7 +151,8 @@ void CL_ParseTEnt (void) S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); } break; - case TE_SPIKEQUAD: // quad spike hitting wall + case TE_SPIKEQUAD: + // quad spike hitting wall MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); // LordHavoc: changed to spark shower @@ -171,7 +172,8 @@ void CL_ParseTEnt (void) S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); } break; - case TE_SUPERSPIKE: // super spike hitting wall + case TE_SUPERSPIKE: + // super spike hitting wall MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); // LordHavoc: changed to dust shower @@ -189,7 +191,8 @@ void CL_ParseTEnt (void) S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); } break; - case TE_SUPERSPIKEQUAD: // quad super spike hitting wall + case TE_SUPERSPIKEQUAD: + // quad super spike hitting wall MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); // LordHavoc: changed to dust shower @@ -209,24 +212,27 @@ void CL_ParseTEnt (void) } break; // LordHavoc: added for improved blood splatters - case TE_BLOOD: // blood puff + case TE_BLOOD: + // blood puff MSG_ReadVector(pos); dir[0] = MSG_ReadChar (); dir[1] = MSG_ReadChar (); dir[2] = MSG_ReadChar (); - count = MSG_ReadByte (); // amount of particles + count = MSG_ReadByte (); CL_BloodPuff(pos, dir, count); break; - case TE_BLOOD2: // blood puff + case TE_BLOOD2: + // blood puff MSG_ReadVector(pos); CL_BloodPuff(pos, vec3_origin, 10); break; - case TE_SPARK: // spark shower + case TE_SPARK: + // spark shower MSG_ReadVector(pos); dir[0] = MSG_ReadChar (); dir[1] = MSG_ReadChar (); dir[2] = MSG_ReadChar (); - count = MSG_ReadByte (); // amount of particles + count = MSG_ReadByte (); Mod_FindNonSolidLocation(pos, cl.worldmodel); CL_SparkShower(pos, dir, count); break; @@ -237,14 +243,16 @@ void CL_ParseTEnt (void) CL_PlasmaBurn(pos); break; // LordHavoc: added for improved gore - case TE_BLOODSHOWER: // vaporized body + case TE_BLOODSHOWER: + // vaporized body MSG_ReadVector(pos); // mins MSG_ReadVector(pos2); // maxs velspeed = MSG_ReadCoord (); // speed count = MSG_ReadShort (); // number of particles CL_BloodShower(pos, pos2, velspeed, count); break; - case TE_PARTICLECUBE: // general purpose particle effect + case TE_PARTICLECUBE: + // general purpose particle effect MSG_ReadVector(pos); // mins MSG_ReadVector(pos2); // maxs MSG_ReadVector(dir); // dir @@ -255,7 +263,8 @@ void CL_ParseTEnt (void) CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength, velspeed); break; - case TE_PARTICLERAIN: // general purpose particle effect + case TE_PARTICLERAIN: + // general purpose particle effect MSG_ReadVector(pos); // mins MSG_ReadVector(pos2); // maxs MSG_ReadVector(dir); // dir @@ -264,7 +273,8 @@ void CL_ParseTEnt (void) CL_ParticleRain(pos, pos2, dir, count, colorStart, 0); break; - case TE_PARTICLESNOW: // general purpose particle effect + case TE_PARTICLESNOW: + // general purpose particle effect MSG_ReadVector(pos); // mins MSG_ReadVector(pos2); // maxs MSG_ReadVector(dir); // dir @@ -273,21 +283,24 @@ void CL_ParseTEnt (void) CL_ParticleRain(pos, pos2, dir, count, colorStart, 1); break; - case TE_GUNSHOT: // bullet hitting wall + case TE_GUNSHOT: + // bullet hitting wall MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); // LordHavoc: changed to dust shower CL_SparkShower(pos, vec3_origin, 15); break; - case TE_GUNSHOTQUAD: // quad bullet hitting wall + case TE_GUNSHOTQUAD: + // quad bullet hitting wall MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); CL_SparkShower(pos, vec3_origin, 15); CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2); break; - case TE_EXPLOSION: // rocket explosion + case TE_EXPLOSION: + // rocket explosion MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); CL_ParticleExplosion (pos, false); @@ -296,7 +309,8 @@ void CL_ParseTEnt (void) S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; - case TE_EXPLOSIONQUAD: // quad rocket explosion + case TE_EXPLOSIONQUAD: + // quad rocket explosion MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); CL_ParticleExplosion (pos, false); @@ -304,7 +318,8 @@ void CL_ParseTEnt (void) S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; - case TE_EXPLOSION3: // Nehahra movie colored lighting explosion + case TE_EXPLOSION3: + // Nehahra movie colored lighting explosion MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); CL_ParticleExplosion (pos, false); @@ -312,7 +327,8 @@ void CL_ParseTEnt (void) S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; - case TE_EXPLOSIONRGB: // colored lighting explosion + case TE_EXPLOSIONRGB: + // colored lighting explosion MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); CL_ParticleExplosion (pos, false); @@ -323,7 +339,8 @@ void CL_ParseTEnt (void) S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; - case TE_TAREXPLOSION: // tarbaby explosion + case TE_TAREXPLOSION: + // tarbaby explosion MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); CL_BlobExplosion (pos); @@ -357,26 +374,30 @@ void CL_ParseTEnt (void) CL_Flames(pos, dir, count); break; - case TE_LIGHTNING1: // lightning bolts + case TE_LIGHTNING1: + // lightning bolts if (!cl_model_bolt) cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, false, false); CL_ParseBeam (cl_model_bolt); break; - case TE_LIGHTNING2: // lightning bolts + case TE_LIGHTNING2: + // lightning bolts if (!cl_model_bolt2) cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, false, false); CL_ParseBeam (cl_model_bolt2); break; - case TE_LIGHTNING3: // lightning bolts + case TE_LIGHTNING3: + // lightning bolts if (!cl_model_bolt3) cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, false, false); CL_ParseBeam (cl_model_bolt3); break; // PGM 01/21/97 - case TE_BEAM: // grappling hook beam + case TE_BEAM: + // grappling hook beam if (!cl_model_beam) cl_model_beam = Mod_ForName("progs/beam.mdl", true, false, false); CL_ParseBeam (cl_model_beam); @@ -403,7 +424,8 @@ void CL_ParseTEnt (void) // CL_TeleportSplash (pos); break; - case TE_EXPLOSION2: // color mapped explosion + case TE_EXPLOSION2: + // color mapped explosion MSG_ReadVector(pos); Mod_FindNonSolidLocation(pos, cl.worldmodel); colorStart = MSG_ReadByte (); @@ -420,6 +442,11 @@ void CL_ParseTEnt (void) } +void CL_ClearTempEntities (void) +{ + cl_num_temp_entities = 0; +} + /* ================= CL_NewTempEntity @@ -427,13 +454,13 @@ CL_NewTempEntity */ entity_t *CL_NewTempEntity (void) { - entity_t *ent; + entity_t *ent; - if (r_refdef.numentities >= MAX_VISEDICTS) + if (r_refdef.numentities >= r_refdef.maxentities) return NULL; - if (num_temp_entities >= MAX_TEMP_ENTITIES) + if (cl_num_temp_entities >= cl_max_temp_entities) return NULL; - ent = &cl_temp_entities[num_temp_entities++]; + ent = &cl_temp_entities[cl_num_temp_entities++]; memset (ent, 0, sizeof(*ent)); r_refdef.entities[r_refdef.numentities++] = &ent->render; @@ -443,26 +470,17 @@ entity_t *CL_NewTempEntity (void) return ent; } - -/* -================= -CL_UpdateTEnts -================= -*/ -void CL_UpdateTEnts (void) +void CL_RelinkBeams (void) { - int i; - beam_t *b; - vec3_t dist, org; - float d; - entity_t *ent; - float yaw, pitch; - float forward; - - num_temp_entities = 0; - -// update lightning - for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + int i; + beam_t *b; + vec3_t dist, org; + float d; + entity_t *ent; + float yaw, pitch; + float forward; + + for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++) { if (!b->model || b->endtime < cl.time) continue; @@ -487,7 +505,7 @@ void CL_UpdateTEnts (void) yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI); if (yaw < 0) yaw += 360; - + forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]); pitch = (int) (atan2(dist[2], forward) * 180 / M_PI); if (pitch < 0) @@ -512,6 +530,4 @@ void CL_UpdateTEnts (void) d -= 30; } } - } - diff --git a/client.h b/client.h index 278bd92e..2457c2f9 100644 --- a/client.h +++ b/client.h @@ -22,6 +22,61 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef CLIENT_H #define CLIENT_H +// LordHavoc: 256 dynamic lights +#define MAX_DLIGHTS 256 +// LordHavoc: this affects the lighting scale of the whole game +#define LIGHTOFFSET 1024.0f +// max lights shining on one entity +#define MAXENTLIGHTS 128 + +extern int cl_max_entities; +extern int cl_max_static_entities; +extern int cl_max_temp_entities; +extern int cl_max_effects; +extern int cl_max_beams; + +typedef struct effect_s +{ + int active; + vec3_t origin; + float starttime; + float framerate; + int modelindex; + int startframe; + int endframe; + // these are for interpolation + int frame; + double frame1time; + double frame2time; +} +cl_effect_t; + +typedef struct +{ + int entity; + struct model_s *model; + float endtime; + vec3_t start, end; +} +beam_t; + +typedef struct +{ + // location + vec3_t origin; + // stop lighting after this time + float die; + // color of light + vec3_t color; + // brightness (not really radius anymore) + float radius; + // drop this each second + float decay; + // the entity that spawned this light (can be NULL if it will never be replaced) + //entity_render_t *ent; +} +dlight_t; + typedef struct frameblend_s { int frame; @@ -29,8 +84,6 @@ typedef struct frameblend_s } frameblend_t; -#define MAXENTLIGHTS 128 - // LordHavoc: disregard the following warning, entlights stuff is semi-persistent... // LordHavoc: nothing in this structure is persistent, it may be overwritten by the client every frame, for persistent data use entity_lerp_t. typedef struct entity_render_s @@ -179,16 +232,6 @@ typedef struct #define SIGNONS 4 // signon messages to receive before connected -#define MAX_BEAMS 24 -typedef struct -{ - int entity; - struct model_s *model; - float endtime; - vec3_t start, end; -} -beam_t; - #define MAX_MAPSTRING 2048 #define MAX_DEMOS 8 #define MAX_DEMONAME 16 @@ -207,33 +250,44 @@ cactive_t; // typedef struct { - cactive_t state; + cactive_t state; // personalization data sent to server - char mapstring[MAX_QPATH]; - char spawnparms[MAX_MAPSTRING]; // to restart a level + char mapstring[MAX_QPATH]; + // to restart a level + //char spawnparms[MAX_MAPSTRING]; // demo loop control - int demonum; // -1 = don't play demos - char demos[MAX_DEMOS][MAX_DEMONAME]; // when not playing + // -1 = don't play demos + int demonum; + // list of demos in loop + char demos[MAX_DEMOS][MAX_DEMONAME]; // demo recording info must be here, because record is started before // entering a map (and clearing client_state_t) - qboolean demorecording; - qboolean demoplayback; - qboolean timedemo; - int forcetrack; // -1 = use normal cd track - QFile *demofile; - int td_lastframe; // to meter out one message a frame - int td_startframe; // host_framecount at start - double td_starttime; // realtime at second frame of timedemo (LordHavoc: changed to double) - qboolean demopaused; // LordHavoc: pausedemo + qboolean demorecording; + qboolean demoplayback; + qboolean timedemo; + // -1 = use normal cd track + int forcetrack; + QFile *demofile; + // to meter out one message a frame + int td_lastframe; + // host_framecount at start + int td_startframe; + // realtime at second frame of timedemo (LordHavoc: changed to double) + double td_starttime; + // LordHavoc: pausedemo + qboolean demopaused; // connection information - int signon; // 0 to SIGNONS - struct qsocket_s *netcon; - sizebuf_t message; // writing buffer to send to server + // 0 to SIGNONS + int signon; + // network socket + struct qsocket_s *netcon; + // writing buffer to send to server + sizebuf_t message; } client_static_t; @@ -245,93 +299,119 @@ extern client_static_t cls; // typedef struct { - int movemessages; // since connecting to this server - // throw out the first couple, so the player - // doesn't accidentally do something the - // first frame - float sendnoptime; // send a clc_nop periodically until connected - usercmd_t cmd; // last command sent to the server + // when connecting to the server throw out the first couple move messages + // so the player doesn't accidentally do something the first frame + int movemessages; -// information for local display - int stats[MAX_CL_STATS]; // health, etc - int items; // inventory bit flags - float item_gettime[32]; // cl.time of acquiring item, for blinking - float faceanimtime; // use anim frame if cl.time < this + // send a clc_nop periodically until connected + float sendnoptime; + + // last command sent to the server + usercmd_t cmd; - cshift_t cshifts[NUM_CSHIFTS]; // color shifts for damage, powerups - cshift_t prev_cshifts[NUM_CSHIFTS]; // and content types +// information for local display + // health, etc + int stats[MAX_CL_STATS]; + // inventory bit flags + int items; + // cl.time of acquiring item, for blinking + float item_gettime[32]; + // use pain anim frame if cl.time < this + float faceanimtime; + + // color shifts for damage, powerups + cshift_t cshifts[NUM_CSHIFTS]; + // and content types + cshift_t prev_cshifts[NUM_CSHIFTS]; // the client maintains its own idea of view angles, which are // sent to the server each frame. The server sets punchangle when -// the view is temporarliy offset, and an angle reset commands at the start +// the view is temporarily offset, and an angle reset commands at the start // of each level and after teleporting. - vec3_t mviewangles[2]; // during demo playback viewangles is lerped - // between these - vec3_t viewangles; - vec3_t mvelocity[2]; // update by server, used for lean+bob - // (0 is newest) - vec3_t velocity; // lerped between mvelocity[0] and [1] + // during demo playback viewangles is lerped between these + vec3_t mviewangles[2]; + // either client controlled, or lerped from demo mviewangles + vec3_t viewangles; - vec3_t punchangle; // temporary offset - vec3_t punchvector; // LordHavoc: origin view kick + // update by server, used for lean+bob (0 is newest) + vec3_t mvelocity[2]; + // lerped between mvelocity[0] and [1] + vec3_t velocity; -// pitch drifting vars - float idealpitch; - float pitchvel; - qboolean nodrift; - float driftmove; - double laststop; + // temporary offset + vec3_t punchangle; + // LordHavoc: origin view kick + vec3_t punchvector; - float viewheight; - float crouch; // local amount for smoothing stepups +// pitch drifting vars + float idealpitch; + float pitchvel; + qboolean nodrift; + float driftmove; + double laststop; - qboolean paused; // send over by server - qboolean onground; - qboolean inwater; + float viewheight; + // local amount for smoothing stepups + //float crouch; - int intermission; // don't change view angle, full screen, etc - int completed_time; // latched at intermission start + // sent by server + qboolean paused; + qboolean onground; + qboolean inwater; - double mtime[2]; // the timestamp of last two messages - double time; // clients view of time, should be between - // servertime and oldservertime to generate - // a lerp point for other data - double oldtime; // previous cl.time, time-oldtime is used - // to decay light values and smooth step ups + // don't change view angle, full screen, etc + int intermission; + // latched at intermission start + int completed_time; - double frametime; + // the timestamp of the last two messages + double mtime[2]; + // clients view of time, time should be between mtime[0] and mtime[1] to + // generate a lerp point for other data, oldtime is the previous frame's + // value of time, frametime is the difference between time and oldtime + double time, oldtime, frametime; - float last_received_message; // (realtime) for net trouble icon + // copy of realtime from last recieved message, for net trouble icon + float last_received_message; -// // information that is static for the entire time connected to a server -// - struct model_s *model_precache[MAX_MODELS]; - struct sfx_s *sound_precache[MAX_SOUNDS]; + struct model_s *model_precache[MAX_MODELS]; + struct sfx_s *sound_precache[MAX_SOUNDS]; - char levelname[40]; // for display on solo scoreboard - int viewentity; // cl_entitites[cl.viewentity] = player - int maxclients; - int gametype; + // for display on solo scoreboard + char levelname[40]; + // cl_entitites[cl.viewentity] = player + int viewentity; + int maxclients; + int gametype; // refresh related state - struct model_s *worldmodel; // cl_entitites[0].model - int num_statics; // held in cl_staticentities array - entity_t viewent; // the gun model - int cdtrack, looptrack; // cd audio + // cl_entitites[0].model + struct model_s *worldmodel; + + // the gun model + entity_t viewent; + + // cd audio + int cdtrack, looptrack; // frag scoreboard - scoreboard_t *scores; // [cl.maxclients] - vec3_t viewentorigin; - float viewzoom; // LordHavoc: sniping zoom, QC controlled - float viewzoomold, viewzoomnew; // for interpolation + // [cl.maxclients] + scoreboard_t *scores; + + // used by view code for setting up eye position + vec3_t viewentorigin; + // LordHavoc: sniping zoom, QC controlled + float viewzoom; + // for interpolation + float viewzoomold, viewzoomnew; // entity database stuff - vec3_t viewentoriginold, viewentoriginnew; + vec3_t viewentoriginold, viewentoriginnew; entity_database_t entitydatabase; } client_state_t; @@ -379,21 +459,26 @@ extern cvar_t r_draweffects; extern cvar_t cl_explosions; extern cvar_t cl_stainmaps; +// these are updated by +extern int cl_num_entities; +extern int cl_num_static_entities; +extern int cl_num_temp_entities; +extern int cl_num_brushmodel_entities; -// LordHavoc: raised these from 64 and 128 to 512 and 256 -#define MAX_TEMP_ENTITIES 512 // lightning bolts, effects, etc -#define MAX_STATIC_ENTITIES 256 // torches, etc +extern entity_t *cl_entities; +extern entity_t *cl_static_entities; +extern entity_t *cl_temp_entities; +extern entity_render_t **cl_brushmodel_entities; +extern cl_effect_t *cl_effects; +extern beam_t *cl_beams; +extern dlight_t *cl_dlights; +extern lightstyle_t *cl_lightstyle; -extern client_state_t cl; -// FIXME, allocate dynamically -extern entity_t cl_entities[MAX_EDICTS]; -extern entity_t cl_static_entities[MAX_STATIC_ENTITIES]; -extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; -extern entity_t cl_temp_entities[MAX_TEMP_ENTITIES]; -extern beam_t cl_beams[MAX_BEAMS]; +extern client_state_t cl; -#include "cl_light.h" +extern void CL_AllocDlight (entity_render_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime); +extern void CL_DecayLights (void); //============================================================================= @@ -428,8 +513,9 @@ void CL_SendMove (usercmd_t *cmd); void CL_LerpUpdate(entity_t *e); void CL_ParseTEnt (void); -void CL_UpdateTEnts (void); +void CL_RelinkBeams (void); +void CL_ClearTempEntities (void); entity_t *CL_NewTempEntity (void); void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate); @@ -518,8 +604,6 @@ void R_NewExplosion(vec3_t org); #include "cl_screen.h" -#define MAX_VISEDICTS (MAX_EDICTS + MAX_STATIC_ENTITIES + MAX_TEMP_ENTITIES) - typedef struct { // area to render in @@ -536,11 +620,13 @@ typedef struct // weapon model entity_render_t viewent; - int numentities; entity_render_t **entities; + int numentities; + int maxentities; - qbyte drawqueue[MAX_DRAWQUEUE]; + qbyte *drawqueue; int drawqueuesize; + int maxdrawqueuesize; } refdef_t; diff --git a/gl_rsurf.c b/gl_rsurf.c index 8a56010f..ec47445d 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -333,9 +333,9 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, origin, radius, icolor); // look for embedded bmodels - for (n = 1;n < MAX_EDICTS;n++) + for (n = 0;n < cl_num_brushmodel_entities;n++) { - ent = &cl_entities[n].render; + ent = cl_brushmodel_entities[n]; model = ent->model; if (model && model->name[0] == '*') { diff --git a/makefile b/makefile index ebc44f03..2aacb9a6 100644 --- a/makefile +++ b/makefile @@ -48,15 +48,16 @@ NOPROFILEOPTIMIZATIONS= #this is used to ensure that all released versions are free of warnings. #normal compile -OPTIMIZATIONS= -O6 -fno-strict-aliasing -ffast-math -funroll-loops $(NOPROFILEOPTIMIZATIONS) -fexpensive-optimizations $(CPUOPTIMIZATIONS) -CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include -I/usr/include/glide $(OPTIMIZATIONS) $(PROFILEOPTION) +#OPTIMIZATIONS= -O6 -fno-strict-aliasing -ffast-math -funroll-loops $(NOPROFILEOPTIMIZATIONS) -fexpensive-optimizations $(CPUOPTIMIZATIONS) +#CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include -I/usr/include/glide $(OPTIMIZATIONS) $(PROFILEOPTION) #debug compile -#OPTIMIZATIONS= -#CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include -ggdb $(OPTIMIZATIONS) $(PROFILEOPTION) +OPTIMIZATIONS= +CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include -ggdb $(OPTIMIZATIONS) $(PROFILEOPTION) #LordHavoc: what is XIE? XFree 4.1.0 doesn't need it and 4.2.0 seems to be missing it entirely #LDFLAGS= -L/usr/X11R6/lib -lm -lX11 -lXext -lXIE -lXxf86dga -lXxf86vm -lGL -ldl $(SOUNDLIB) $(PROFILEOPTION) -LDFLAGS= -L/usr/X11R6/lib -lm -lX11 -lXext -lXxf86dga -lXxf86vm -lGL -ldl $(SOUNDLIB) $(PROFILEOPTION) +#LDFLAGS= -L/usr/X11R6/lib -lm -lX11 -lXext -lXxf86dga -lXxf86vm -lGL -ldl $(SOUNDLIB) $(PROFILEOPTION) +LDFLAGS= -L/usr/X11R6/lib -lm -lX11 -lXext -lXxf86dga -lXxf86vm -ldl $(SOUNDLIB) $(PROFILEOPTION) #if you don't need the -3dfx version, use this line all: builddate darkplaces-glx diff --git a/r_light.c b/r_light.c index a55de971..861547c9 100644 --- a/r_light.c +++ b/r_light.c @@ -125,7 +125,7 @@ void R_BuildLightList(void) rd->cullradius = 2048.0f; rd->cullradius2 = rd->cullradius * rd->cullradius; rd->lightsubtract = 1.0f / rd->cullradius2; - rd->ent = cd->ent; + //rd->ent = cd->ent; r_numdlights++; c_dlights++; // count every dlight in use } @@ -830,6 +830,7 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo { if (!(modeldlightbits[i >> 5] & (1 << (i & 31)))) continue; + /* if (currentrenderentity == r_dlight[i].ent) { f = (1.0f / LIGHTOFFSET) - nl->lightsubtract; @@ -838,6 +839,7 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo } else { + */ // transform the light into the model's coordinate system if (worldcoords) VectorCopy(r_dlight[i].origin, nl->origin); @@ -854,7 +856,7 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo nl->offset = LIGHTOFFSET; nl++; nearlights++; - } + //} } } else diff --git a/r_light.h b/r_light.h index cdbde025..1c28cb7f 100644 --- a/r_light.h +++ b/r_light.h @@ -9,7 +9,7 @@ typedef struct vec3_t light; // the brightness of the light vec_t cullradius; // only for culling comparisons vec_t lightsubtract; // to avoid sudden brightness change at cullradius, subtract this - entity_render_t *ent; // owner of this light +// entity_render_t *ent; // owner of this light } rdlight_t;