]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_main.c
removed \n from all Host_Error, Sys_Error, PRVM_ERROR, PF_ERROR calls, since Host_Err...
[xonotic/darkplaces.git] / cl_main.c
index 9436dbebbbbab2acee20e720ae9d0050258bdbe6..fa5356618b2e699b0c5aa9a01633ac2033109a6e 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #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.
@@ -83,9 +84,10 @@ int cl_max_beams;
 int cl_max_dlights;
 int cl_max_lightstyle;
 int cl_max_brushmodel_entities;
+int cl_activedlights;
 
 entity_t *cl_entities;
-qbyte *cl_entities_active;
+unsigned char *cl_entities_active;
 entity_t *cl_static_entities;
 entity_t *cl_temp_entities;
 cl_effect_t *cl_effects;
@@ -101,7 +103,7 @@ int cl_num_brushmodel_entities;
 
 // keep track of quake entities because they need to be killed if they get stale
 extern int cl_lastquakeentity;
-extern qbyte cl_isquakeentity[MAX_EDICTS];
+extern unsigned char cl_isquakeentity[MAX_EDICTS];
 
 /*
 =====================
@@ -150,16 +152,17 @@ void CL_ClearState(void)
        cl_max_dlights = MAX_DLIGHTS;
        cl_max_lightstyle = MAX_LIGHTSTYLES;
        cl_max_brushmodel_entities = MAX_EDICTS;
-
-       cl_entities = Mem_Alloc(cl_mempool, cl_max_entities * sizeof(entity_t));
-       cl_entities_active = Mem_Alloc(cl_mempool, cl_max_brushmodel_entities * sizeof(qbyte));
-       cl_static_entities = Mem_Alloc(cl_mempool, cl_max_static_entities * sizeof(entity_t));
-       cl_temp_entities = Mem_Alloc(cl_mempool, cl_max_temp_entities * sizeof(entity_t));
-       cl_effects = Mem_Alloc(cl_mempool, cl_max_effects * sizeof(cl_effect_t));
-       cl_beams = Mem_Alloc(cl_mempool, cl_max_beams * sizeof(beam_t));
-       cl_dlights = Mem_Alloc(cl_mempool, cl_max_dlights * sizeof(dlight_t));
-       cl_lightstyle = Mem_Alloc(cl_mempool, cl_max_lightstyle * sizeof(lightstyle_t));
-       cl_brushmodel_entities = Mem_Alloc(cl_mempool, cl_max_brushmodel_entities * sizeof(int));
+       cl_activedlights = 0;
+
+       cl_entities = (entity_t *)Mem_Alloc(cl_mempool, cl_max_entities * sizeof(entity_t));
+       cl_entities_active = (unsigned char *)Mem_Alloc(cl_mempool, cl_max_brushmodel_entities * sizeof(unsigned char));
+       cl_static_entities = (entity_t *)Mem_Alloc(cl_mempool, cl_max_static_entities * sizeof(entity_t));
+       cl_temp_entities = (entity_t *)Mem_Alloc(cl_mempool, cl_max_temp_entities * sizeof(entity_t));
+       cl_effects = (cl_effect_t *)Mem_Alloc(cl_mempool, cl_max_effects * sizeof(cl_effect_t));
+       cl_beams = (beam_t *)Mem_Alloc(cl_mempool, cl_max_beams * sizeof(beam_t));
+       cl_dlights = (dlight_t *)Mem_Alloc(cl_mempool, cl_max_dlights * sizeof(dlight_t));
+       cl_lightstyle = (lightstyle_t *)Mem_Alloc(cl_mempool, cl_max_lightstyle * sizeof(lightstyle_t));
+       cl_brushmodel_entities = (int *)Mem_Alloc(cl_mempool, cl_max_brushmodel_entities * sizeof(int));
 
        cl_lastquakeentity = 0;
        memset(cl_isquakeentity, 0, sizeof(cl_isquakeentity));
@@ -199,13 +202,13 @@ void CL_ExpandEntities(int num)
        if (num >= cl_max_entities)
        {
                if (!cl_entities)
-                       Sys_Error("CL_ExpandEntities: cl_entities not initialized\n");
+                       Sys_Error("CL_ExpandEntities: cl_entities not initialized");
                if (num >= MAX_EDICTS)
-                       Host_Error("CL_ExpandEntities: num %i >= %i\n", num, MAX_EDICTS);
+                       Host_Error("CL_ExpandEntities: num %i >= %i", num, MAX_EDICTS);
                oldmaxentities = cl_max_entities;
                oldentities = cl_entities;
                cl_max_entities = (num & ~255) + 256;
-               cl_entities = Mem_Alloc(cl_mempool, cl_max_entities * sizeof(entity_t));
+               cl_entities = (entity_t *)Mem_Alloc(cl_mempool, cl_max_entities * sizeof(entity_t));
                memcpy(cl_entities, oldentities, oldmaxentities * sizeof(entity_t));
                Mem_Free(oldentities);
                for (i = oldmaxentities;i < cl_max_entities;i++)
@@ -423,7 +426,7 @@ static float CL_LerpPoint(void)
 
        // LordHavoc: lerp in listen games as the server is being capped below the client (usually)
        f = cl.mtime[0] - cl.mtime[1];
-       if (!f || cl_nolerp.integer || cls.timedemo || cl.islocalgame)
+       if (!f || cl_nolerp.integer || cls.timedemo || (cl.islocalgame && !sv_fixedframeratesingleplayer.integer))
        {
                cl.time = cl.mtime[0];
                return 1;
@@ -492,7 +495,7 @@ void CL_AllocDlight(entity_render_t *ent, matrix4x4_t *matrix, float radius, flo
        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;
        }
@@ -500,9 +503,15 @@ void CL_AllocDlight(entity_render_t *ent, matrix4x4_t *matrix, float radius, flo
 
 // 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;
@@ -539,16 +548,70 @@ dlightsetup:
        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
@@ -592,15 +655,15 @@ void CL_LinkNetworkEntity(entity_t *e)
                if (e->state_current.flags & RENDER_COLORMAPPED)
                {
                        int cb;
-                       qbyte *cbcolor;
+                       unsigned char *cbcolor;
                        e->render.colormap = e->state_current.colormap;
                        cb = (e->render.colormap & 0xF) << 4;cb += (cb >= 128 && cb < 224) ? 4 : 12;
-                       cbcolor = (qbyte *) (&palette_complete[cb]);
+                       cbcolor = (unsigned char *) (&palette_complete[cb]);
                        e->render.colormap_pantscolor[0] = cbcolor[0] * (1.0f / 255.0f) * e->render.colormod[0];
                        e->render.colormap_pantscolor[1] = cbcolor[1] * (1.0f / 255.0f) * e->render.colormod[1];
                        e->render.colormap_pantscolor[2] = cbcolor[2] * (1.0f / 255.0f) * e->render.colormod[2];
                        cb = (e->render.colormap & 0xF0);cb += (cb >= 128 && cb < 224) ? 4 : 12;
-                       cbcolor = (qbyte *) (&palette_complete[cb]);
+                       cbcolor = (unsigned char *) (&palette_complete[cb]);
                        e->render.colormap_shirtcolor[0] = cbcolor[0] * (1.0f / 255.0f) * e->render.colormod[0];
                        e->render.colormap_shirtcolor[1] = cbcolor[1] * (1.0f / 255.0f) * e->render.colormod[1];
                        e->render.colormap_shirtcolor[2] = cbcolor[2] * (1.0f / 255.0f) * e->render.colormod[2];
@@ -608,15 +671,15 @@ void CL_LinkNetworkEntity(entity_t *e)
                else if (e->state_current.colormap && cl.scores != NULL)
                {
                        int cb;
-                       qbyte *cbcolor;
+                       unsigned char *cbcolor;
                        e->render.colormap = cl.scores[e->state_current.colormap - 1].colors; // color it
                        cb = (e->render.colormap & 0xF) << 4;cb += (cb >= 128 && cb < 224) ? 4 : 12;
-                       cbcolor = (qbyte *) (&palette_complete[cb]);
+                       cbcolor = (unsigned char *) (&palette_complete[cb]);
                        e->render.colormap_pantscolor[0] = cbcolor[0] * (1.0f / 255.0f) * e->render.colormod[0];
                        e->render.colormap_pantscolor[1] = cbcolor[1] * (1.0f / 255.0f) * e->render.colormod[1];
                        e->render.colormap_pantscolor[2] = cbcolor[2] * (1.0f / 255.0f) * e->render.colormod[2];
                        cb = (e->render.colormap & 0xF0);cb += (cb >= 128 && cb < 224) ? 4 : 12;
-                       cbcolor = (qbyte *) (&palette_complete[cb]);
+                       cbcolor = (unsigned char *) (&palette_complete[cb]);
                        e->render.colormap_shirtcolor[0] = cbcolor[0] * (1.0f / 255.0f) * e->render.colormod[0];
                        e->render.colormap_shirtcolor[1] = cbcolor[1] * (1.0f / 255.0f) * e->render.colormod[1];
                        e->render.colormap_shirtcolor[2] = cbcolor[2] * (1.0f / 255.0f) * e->render.colormod[2];
@@ -708,7 +771,6 @@ void CL_LinkNetworkEntity(entity_t *e)
                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];
@@ -931,7 +993,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                        // * 4 for the expansion from 0-255 to 0-1023 range,
                        // / 255 to scale down byte colors
                        dlightradius = max(dlightradius, e->state_current.glowsize * 4);
-                       VectorMA(dlightcolor, (1.0f / 255.0f), (qbyte *)&palette_complete[e->state_current.glowcolor], dlightcolor);
+                       VectorMA(dlightcolor, (1.0f / 255.0f), (unsigned char *)&palette_complete[e->state_current.glowcolor], dlightcolor);
                }
                // make the glow dlight
                if (dlightradius > 0 && (dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) && !(e->render.flags & RENDER_VIEWMODEL))
@@ -1015,7 +1077,6 @@ static void CL_RelinkStaticEntities(void)
        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)
@@ -1325,6 +1386,8 @@ int CL_ReadFromServer(void)
                // run cgame code (which can add more entities)
                CL_CGVM_Frame();
 
+               CL_UpdateLights();
+
                // update view blend
                V_CalcViewBlend();
        }
@@ -1442,10 +1505,10 @@ void CL_Init (void)
        memset(&r_refdef, 0, sizeof(r_refdef));
        // max entities sent to renderer per frame
        r_refdef.maxentities = MAX_EDICTS + 256 + 512;
-       r_refdef.entities = Mem_Alloc(cl_mempool, sizeof(entity_render_t *) * r_refdef.maxentities);
+       r_refdef.entities = (entity_render_t **)Mem_Alloc(cl_mempool, sizeof(entity_render_t *) * r_refdef.maxentities);
        // 256k drawqueue buffer
        r_refdef.maxdrawqueuesize = 256 * 1024;
-       r_refdef.drawqueue = Mem_Alloc(cl_mempool, r_refdef.maxdrawqueuesize);
+       r_refdef.drawqueue = (unsigned char *)Mem_Alloc(cl_mempool, r_refdef.maxdrawqueuesize);
 
        cls.message.data = cls.message_buf;
        cls.message.maxsize = sizeof(cls.message_buf);