make csqc render entities persistent (except the temp ones created by a
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 14 Nov 2009 19:30:37 +0000 (19:30 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 14 Nov 2009 19:30:37 +0000 (19:30 +0000)
builtin), this enables r_cullentities_trace again on most csqc entities,
and allows decals to stick to csqc entities

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9491 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
client.h
clvm_cmds.c
csprogs.c

index 189edda..1e3eed5 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -130,6 +130,7 @@ void CL_ClearState(void)
        cl.num_brushmodel_entities = 0;
 
        // tweak these if the game runs out
+       cl.max_csqcrenderentities = 0;
        cl.max_entities = 256;
        cl.max_static_entities = 256;
        cl.max_effects = 256;
@@ -145,6 +146,7 @@ void CL_ClearState(void)
        cl.num_effects = 0;
        cl.num_beams = 0;
 
+       cl.csqcrenderentities = NULL;
        cl.entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_entities * sizeof(entity_t));
        cl.entities_active = (unsigned char *)Mem_Alloc(cls.levelmempool, cl.max_brushmodel_entities * sizeof(unsigned char));
        cl.static_entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_static_entities * sizeof(entity_t));
@@ -289,6 +291,26 @@ void CL_ExpandEntities(int num)
        }
 }
 
+void CL_ExpandCSQCRenderEntities(int num)
+{
+       int oldmaxcsqcrenderentities;
+       entity_render_t *oldcsqcrenderentities;
+       if (num >= cl.max_csqcrenderentities)
+       {
+               if (num >= MAX_EDICTS)
+                       Host_Error("CL_ExpandEntities: num %i >= %i", num, MAX_EDICTS);
+               oldmaxcsqcrenderentities = cl.max_csqcrenderentities;
+               oldcsqcrenderentities = cl.csqcrenderentities;
+               cl.max_csqcrenderentities = (num & ~255) + 256;
+               cl.csqcrenderentities = (entity_render_t *)Mem_Alloc(cls.levelmempool, cl.max_csqcrenderentities * sizeof(entity_render_t));
+               if (oldcsqcrenderentities)
+               {
+                       memcpy(cl.csqcrenderentities, oldcsqcrenderentities, oldmaxcsqcrenderentities * sizeof(entity_render_t));
+                       Mem_Free(oldcsqcrenderentities);
+               }
+       }
+}
+
 /*
 =====================
 CL_Disconnect
index 9025c88..aefee56 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1023,6 +1023,7 @@ typedef struct client_state_s
        vec3_t playercrouchmaxs;
 
        int max_entities;
+       int max_csqcrenderentities;
        int max_static_entities;
        int max_effects;
        int max_beams;
@@ -1034,6 +1035,7 @@ typedef struct client_state_s
        int max_showlmps;
 
        entity_t *entities;
+       entity_render_t *csqcrenderentities;
        unsigned char *entities_active;
        entity_t *static_entities;
        cl_effect_t *effects;
@@ -1289,6 +1291,7 @@ void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float
 
 void CL_ClearState (void);
 void CL_ExpandEntities(int num);
+void CL_ExpandCSQCRenderEntities(int num);
 void CL_SetInfo(const char *key, const char *value, qboolean send, qboolean allowstarkey, qboolean allowmodel, qboolean quiet);
 
 
index 6e6efed..03f3af9 100644 (file)
@@ -681,7 +681,7 @@ static void VM_CL_getlight (void)
 
 //============================================================================
 //[515]: SCENE MANAGER builtins
-extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed);//csprogs.c
+extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed, int edictnum);//csprogs.c
 
 static void CSQC_R_RecalcView (void)
 {
@@ -750,7 +750,7 @@ void VM_CL_R_AddEntities (void)
                        continue;
                if(!((int)ed->fields.client->drawmask & drawmask))
                        continue;
-               CSQC_AddRenderEdict(ed);
+               CSQC_AddRenderEdict(ed, i);
        }
 
        // callprofile fixing hack: do not include this time in what is counted for CSQC_UpdateView
@@ -762,7 +762,7 @@ void VM_CL_R_AddEntity (void)
 {
        double t = Sys_DoubleTime();
        VM_SAFEPARMCOUNT(1, VM_CL_R_AddEntity);
-       CSQC_AddRenderEdict(PRVM_G_EDICT(OFS_PARM0));
+       CSQC_AddRenderEdict(PRVM_G_EDICT(OFS_PARM0), 0);
        prog->functions[prog->funcoffsets.CSQC_UpdateView].totaltime -= Sys_DoubleTime() - t;
 }
 
index ba3861f..053d439 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
@@ -154,7 +154,7 @@ void CSQC_Think (prvm_edict_t *ed)
 
 extern cvar_t cl_noplayershadow;
 extern cvar_t r_equalize_entities_fullbright;
-qboolean CSQC_AddRenderEdict(prvm_edict_t *ed)
+qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
 {
        int renderflags;
        int c;
@@ -168,9 +168,26 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed)
        if (!model)
                return false;
 
-       entrender = CL_NewTempEntity(0);
-       if (!entrender)
-               return false;
+       if (edictnum)
+       {
+               if (r_refdef.scene.numentities >= r_refdef.scene.maxentities)
+                       return false;
+               entrender = cl.csqcrenderentities + edictnum;
+               r_refdef.scene.entities[r_refdef.scene.numentities++] = entrender;
+               entrender->entitynumber = edictnum;
+               //entrender->shadertime = 0; // shadertime was set by spawn()
+               entrender->alpha = 1;
+               entrender->scale = 1;
+               VectorSet(entrender->colormod, 1, 1, 1);
+               VectorSet(entrender->glowmod, 1, 1, 1);
+               entrender->allowdecals = true;
+       }
+       else
+       {
+               entrender = CL_NewTempEntity(0);
+               if (!entrender)
+                       return false;
+       }
 
        entrender->model = model;
        entrender->skinnum = (int)ed->fields.client->skin;
@@ -715,11 +732,22 @@ void CL_VM_CB_EndIncreaseEdicts(void)
 
 void CL_VM_CB_InitEdict(prvm_edict_t *e)
 {
+       int edictnum = PRVM_NUM_FOR_EDICT(e);
+       entity_render_t *entrender;
+       CL_ExpandCSQCRenderEntities(edictnum);
+       entrender = cl.csqcrenderentities + edictnum;
        e->priv.server->move = false; // don't move on first frame
+       memset(entrender, 0, sizeof(*entrender));
+       entrender->shadertime = cl.time;
 }
 
+extern void R_DecalSystem_Reset(decalsystem_t *decalsystem);
+
 void CL_VM_CB_FreeEdict(prvm_edict_t *ed)
 {
+       entity_render_t *entrender = cl.csqcrenderentities + PRVM_NUM_FOR_EDICT(ed);
+       R_DecalSystem_Reset(&entrender->decalsystem);
+       memset(entrender, 0, sizeof(*entrender));
        World_UnlinkEdict(ed);
        memset(ed->fields.client, 0, sizeof(*ed->fields.client));
        World_Physics_RemoveFromEntity(&cl.world, ed);