#include "cl_collision.h"
#include "cl_video.h"
#include "image.h"
+#include "r_shadow.h"
// we need to declare some mouse variables here, because the menu system
// references them even when on a unix system.
int cl_max_dlights;
int cl_max_lightstyle;
int cl_max_brushmodel_entities;
+int cl_activedlights;
entity_t *cl_entities;
qbyte *cl_entities_active;
cl_max_dlights = MAX_DLIGHTS;
cl_max_lightstyle = MAX_LIGHTSTYLES;
cl_max_brushmodel_entities = MAX_EDICTS;
+ cl_activedlights = 0;
cl_entities = (entity_t *)Mem_Alloc(cl_mempool, cl_max_entities * sizeof(entity_t));
cl_entities_active = (qbyte *)Mem_Alloc(cl_mempool, cl_max_brushmodel_entities * sizeof(qbyte));
if (ent)
{
dl = cl_dlights;
- for (i = 0;i < MAX_DLIGHTS;i++, dl++)
+ for (i = 0;i < cl_activedlights;i++, dl++)
if (dl->ent == ent)
goto dlightsetup;
}
// then look for anything else
dl = cl_dlights;
- for (i = 0;i < MAX_DLIGHTS;i++, dl++)
+ for (i = 0;i < cl_activedlights;i++, dl++)
if (!dl->radius)
goto dlightsetup;
+ // if we hit the end of the active dlights and found no gaps, add a new one
+ if (i < MAX_DLIGHTS)
+ {
+ cl_activedlights = i + 1;
+ goto dlightsetup;
+ }
// unable to find one
return;
dl->specularscale = specularscale;
}
+// called before entity relinking
void CL_DecayLights(void)
{
- int i;
+ int i, oldmax;
dlight_t *dl;
- float time;
+ float time, f;
time = cl.time - cl.oldtime;
- for (i = 0, dl = cl_dlights;i < MAX_DLIGHTS;i++, dl++)
+ oldmax = cl_activedlights;
+ cl_activedlights = 0;
+ for (i = 0, dl = cl_dlights;i < oldmax;i++, dl++)
+ {
if (dl->radius)
- dl->radius = (cl.time < dl->die) ? max(0, dl->radius - time * dl->decay) : 0;
+ {
+ f = dl->radius - time * dl->decay;
+ if (cl.time < dl->die && f > 0)
+ {
+ dl->radius = dl->radius - time * dl->decay;
+ cl_activedlights = i + 1;
+ }
+ else
+ dl->radius = 0;
+ }
+ }
+}
+
+// called after entity relinking
+void CL_UpdateLights(void)
+{
+ int i, j, k, l;
+ dlight_t *dl;
+ float frac, f;
+
+ r_refdef.numlights = 0;
+ if (r_dynamic.integer)
+ {
+ for (i = 0, dl = cl_dlights;i < cl_activedlights;i++, dl++)
+ {
+ if (dl->radius)
+ {
+ R_RTLight_Update(dl, false);
+ r_refdef.lights[r_refdef.numlights++] = dl;
+ }
+ }
+ }
+
+// light animations
+// 'm' is normal light, 'a' is no light, 'z' is double bright
+ f = cl.time * 10;
+ i = (int)floor(f);
+ frac = f - i;
+ for (j = 0;j < MAX_LIGHTSTYLES;j++)
+ {
+ if (!cl_lightstyle || !cl_lightstyle[j].length)
+ {
+ r_refdef.lightstylevalue[j] = 256;
+ continue;
+ }
+ k = i % cl_lightstyle[j].length;
+ l = (i-1) % cl_lightstyle[j].length;
+ k = cl_lightstyle[j].map[k] - 'a';
+ l = cl_lightstyle[j].map[l] - 'a';
+ r_refdef.lightstylevalue[j] = ((k*frac)+(l*(1-frac)))*22;
+ }
}
#define MAXVIEWMODELS 32
e->render.model = cl.model_precache[e->state_current.modelindex];
if (e->render.model)
{
- Mod_CheckLoaded(e->render.model);
// if model is alias or this is a tenebrae-like dlight, reverse pitch direction
if (e->render.model->type == mod_alias || (e->state_current.lightpflags & PFLAGS_FULLDYNAMIC))
angles[0] = -angles[0];
entity_t *e;
for (i = 0, e = cl_static_entities;i < cl_num_static_entities && r_refdef.numentities < r_refdef.maxentities;i++, e++)
{
- Mod_CheckLoaded(e->render.model);
e->render.flags = 0;
// transparent stuff can't be lit during the opaque stage
if (e->render.effects & (EF_ADDITIVE | EF_NODEPTHTEST) || e->render.alpha < 1)
// run cgame code (which can add more entities)
CL_CGVM_Frame();
+ CL_UpdateLights();
+
// update view blend
V_CalcViewBlend();
}