]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_main.c
dynamically grow maxtempentities
[xonotic/darkplaces.git] / cl_main.c
index 6ca122d1189bd8c8e915bdcd0ea45cf2aff86f67..e5f6fef1cd9c2166375966332043f379e6e7968a 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -171,7 +171,7 @@ void CL_ClearState(void)
                cl.entities[i].state_current = defaultstate;
        }
 
-       if (gamemode == GAME_NEXUIZ)
+       if (gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
        {
                VectorSet(cl.playerstandmins, -16, -16, -24);
                VectorSet(cl.playerstandmaxs, 16, 16, 45);
@@ -297,6 +297,7 @@ void CL_ExpandEntities(int num)
 
 void CL_ExpandCSQCRenderEntities(int num)
 {
+       int i;
        int oldmaxcsqcrenderentities;
        entity_render_t *oldcsqcrenderentities;
        if (num >= cl.max_csqcrenderentities)
@@ -310,6 +311,9 @@ void CL_ExpandCSQCRenderEntities(int num)
                if (oldcsqcrenderentities)
                {
                        memcpy(cl.csqcrenderentities, oldcsqcrenderentities, oldmaxcsqcrenderentities * sizeof(entity_render_t));
+                       for (i = 0;i < r_refdef.scene.numentities;i++)
+                               if(r_refdef.scene.entities[i] >= oldcsqcrenderentities && r_refdef.scene.entities[i] < (oldcsqcrenderentities + oldmaxcsqcrenderentities))
+                                       r_refdef.scene.entities[i] = cl.csqcrenderentities + (r_refdef.scene.entities[i] - oldcsqcrenderentities);
                        Mem_Free(oldcsqcrenderentities);
                }
        }
@@ -407,7 +411,7 @@ CL_EstablishConnection
 Host should be either "local" or a net address
 =====================
 */
-void CL_EstablishConnection(const char *host)
+void CL_EstablishConnection(const char *host, int firstarg)
 {
        if (cls.state == ca_dedicated)
                return;
@@ -434,7 +438,24 @@ void CL_EstablishConnection(const char *host)
                cls.connect_trying = true;
                cls.connect_remainingtries = 3;
                cls.connect_nextsendtime = 0;
+
+               // only NOW, set connect_userinfo
+               if(firstarg >= 0)
+               {
+                       int i;
+                       *cls.connect_userinfo = 0;
+                       for(i = firstarg; i+2 <= Cmd_Argc(); i += 2)
+                               InfoString_SetValue(cls.connect_userinfo, sizeof(cls.connect_userinfo), Cmd_Argv(i), Cmd_Argv(i+1));
+               }
+               else if(firstarg < -1)
+               {
+                       // -1: keep as is (reconnect)
+                       // -2: clear
+                       *cls.connect_userinfo = 0;
+               }
+
                M_Update_Return_Reason("Trying to connect...");
+
                // run several network frames to jump into the game quickly
                //if (sv.active)
                //{
@@ -609,6 +630,14 @@ static float CL_LerpPoint(void)
 void CL_ClearTempEntities (void)
 {
        r_refdef.scene.numtempentities = 0;
+       // grow tempentities buffer on request
+       if (r_refdef.scene.expandtempentities)
+       {
+               Con_Printf("CL_NewTempEntity: grow maxtempentities from %i to %i\n", r_refdef.scene.maxtempentities, r_refdef.scene.maxtempentities * 2);
+               r_refdef.scene.maxtempentities *= 2;
+               r_refdef.scene.tempentities = (entity_render_t *)Mem_Realloc(cls.permanentmempool, r_refdef.scene.tempentities, sizeof(entity_render_t) * r_refdef.scene.maxtempentities);
+               r_refdef.scene.expandtempentities = false;
+       }
 }
 
 entity_render_t *CL_NewTempEntity(double shadertime)
@@ -618,7 +647,10 @@ entity_render_t *CL_NewTempEntity(double shadertime)
        if (r_refdef.scene.numentities >= r_refdef.scene.maxentities)
                return NULL;
        if (r_refdef.scene.numtempentities >= r_refdef.scene.maxtempentities)
+       {
+               r_refdef.scene.expandtempentities = true; // will be reallocated next frame since current frame may have pointers set already
                return NULL;
+       }
        render = &r_refdef.scene.tempentities[r_refdef.scene.numtempentities++];
        memset (render, 0, sizeof(*render));
        r_refdef.scene.entities[r_refdef.scene.numentities++] = render;
@@ -905,6 +937,7 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat
        int frame;
        float origin[3], angles[3], lerp;
        entity_t *t;
+       entity_render_t *r;
        //entity_persistent_t *p = &e->persistent;
        //entity_render_t *r = &e->render;
        // skip inactive entities and world
@@ -937,22 +970,33 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat
                        return;
                t = cl.entities + e->state_current.tagentity;
                // if the tag entity is inactive, skip it
-               if (!t->state_current.active)
-                       return;
-               // update the parent first
-               CL_UpdateNetworkEntity(t, recursionlimit - 1, interpolate);
+               if (t->state_current.active)
+               {
+                       // update the parent first
+                       CL_UpdateNetworkEntity(t, recursionlimit - 1, interpolate);
+                       r = &t->render;
+               }
+               else
+               {
+                       // it may still be a CSQC entity... trying to use its
+                       // info from last render frame (better than nothing)
+                       if(!cl.csqc_server2csqcentitynumber[e->state_current.tagentity])
+                               return;
+                       r = cl.csqcrenderentities + cl.csqc_server2csqcentitynumber[e->state_current.tagentity];
+                       if(!r->entitynumber)
+                               return; // neither CSQC nor legacy entity... can't attach
+               }
                // make relative to the entity
-               matrix = &t->render.matrix;
+               matrix = &r->matrix;
                // some properties of the tag entity carry over
-               e->render.flags |= t->render.flags & (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL);
+               e->render.flags |= r->flags & (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL);
                // if a valid tagindex is used, make it relative to that tag instead
-               // FIXME: use a model function to get tag info (need to handle skeletal)
-               if (e->state_current.tagentity && e->state_current.tagindex >= 1 && t->render.model)
+               if (e->state_current.tagentity && e->state_current.tagindex >= 1 && r->model)
                {
-                       if(!Mod_Alias_GetTagMatrix(t->render.model, t->render.frameblend, t->render.skeleton, e->state_current.tagindex - 1, &blendmatrix)) // i.e. no error
+                       if(!Mod_Alias_GetTagMatrix(r->model, r->frameblend, r->skeleton, e->state_current.tagindex - 1, &blendmatrix)) // i.e. no error
                        {
                                // concat the tag matrices onto the entity matrix
-                               Matrix4x4_Concat(&tempmatrix, &t->render.matrix, &blendmatrix);
+                               Matrix4x4_Concat(&tempmatrix, &r->matrix, &blendmatrix);
                                // use the constructed tag matrix
                                matrix = &tempmatrix;
                        }
@@ -1159,7 +1203,7 @@ void CL_UpdateNetworkEntityTrail(entity_t *e)
        {
                if (e->render.effects & EF_BRIGHTFIELD)
                {
-                       if (gamemode == GAME_NEXUIZ)
+                       if (gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
                                trailtype = EFFECT_TR_NEXUIZPLASMA;
                        else
                                CL_EntityParticles(e);
@@ -1355,7 +1399,13 @@ void CL_LinkNetworkEntity(entity_t *e)
                        return;
                // if the tag entity is inactive, skip it
                if (!cl.entities[e->state_current.tagentity].state_current.active)
-                       return;
+               {
+                       if(!cl.csqc_server2csqcentitynumber[e->state_current.tagentity])
+                               return;
+                       if(!cl.csqcrenderentities[cl.csqc_server2csqcentitynumber[e->state_current.tagentity]].entitynumber)
+                               return;
+                       // if we get here, it's properly csqc networked and attached
+               }
        }
 
        // create entity dlights associated with this entity
@@ -1378,7 +1428,7 @@ void CL_LinkNetworkEntity(entity_t *e)
        {
                if (e->render.effects & EF_BRIGHTFIELD)
                {
-                       if (gamemode == GAME_NEXUIZ)
+                       if (gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
                                trailtype = EFFECT_TR_NEXUIZPLASMA;
                }
                if (e->render.effects & EF_DIMLIGHT)
@@ -1423,7 +1473,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                trace_t trace;
                matrix4x4_t tempmatrix;
                Matrix4x4_Transform(&e->render.matrix, muzzleflashorigin, v2);
-               trace = CL_TraceLine(origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, NULL, false);
+               trace = CL_TraceLine(origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, NULL, false, false);
                Matrix4x4_Normalize(&tempmatrix, &e->render.matrix);
                Matrix4x4_SetOrigin(&tempmatrix, trace.endpos[0], trace.endpos[1], trace.endpos[2]);
                Matrix4x4_Scale(&tempmatrix, 150, 1);
@@ -1842,7 +1892,7 @@ void CL_UpdateWorld(void)
        r_refdef.scene.numlights = 0;
        r_refdef.view.matrix = identitymatrix;
        r_refdef.view.quality = 1;
-
+               
        cl.num_brushmodel_entities = 0;
 
        if (cls.state == ca_connected && cls.signon == SIGNONS)
@@ -2322,6 +2372,7 @@ CL_Init
 */
 void CL_Init (void)
 {
+
        cls.levelmempool = Mem_AllocPool("client (per-level memory)", 0, NULL);
        cls.permanentmempool = Mem_AllocPool("client (long term memory)", 0, NULL);
 
@@ -2330,7 +2381,8 @@ void CL_Init (void)
        r_refdef.scene.maxentities = MAX_EDICTS + 256 + 512;
        r_refdef.scene.entities = (entity_render_t **)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t *) * r_refdef.scene.maxentities);
 
-       r_refdef.scene.maxtempentities = MAX_TEMPENTITIES; // FIXME: make this grow
+       // max temp entities
+       r_refdef.scene.maxtempentities = MAX_TEMPENTITIES;
        r_refdef.scene.tempentities = (entity_render_t *)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t) * r_refdef.scene.maxtempentities);
 
        CL_InitInput ();