]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_main.c
some cleanup of Mod_Alias_GetMesh_Vertex3f
[xonotic/darkplaces.git] / cl_main.c
index d677dbb3d1720b14d48b32aee3772d1945d3580f..22acc719e757b6e6a0850b787265f085d88ca8d2 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -49,6 +49,9 @@ cvar_t m_side = {CVAR_SAVE, "m_side","0.8","mouse side speed multiplier"};
 
 cvar_t freelook = {CVAR_SAVE, "freelook", "1","mouse controls pitch instead of forward/back"};
 
+cvar_t cl_autodemo = {0, "cl_autodemo", "0", "records every game played, using the date/time and map name to name the demo file" };
+cvar_t cl_autodemo_nameformat = {0, "cl_autodemo_nameformat", "%Y-%m-%d_%H-%M", "The format of the cl_autodemo filename, followed by the map name" };
+
 cvar_t r_draweffects = {0, "r_draweffects", "1","renders temporary sprite effects"};
 
 cvar_t cl_explosions_alpha_start = {CVAR_SAVE, "cl_explosions_alpha_start", "1.5","starting alpha of an explosion shell"};
@@ -89,27 +92,8 @@ void CL_ClearState(void)
        int i;
        entity_t *ent;
 
-       if (cl.entities) Mem_Free(cl.entities);cl.entities = NULL;
-       if (cl.csqcentities) Mem_Free(cl.csqcentities);cl.csqcentities = NULL;  //[515]: csqc
-       if (cl.entities_active) Mem_Free(cl.entities_active);cl.entities_active = NULL;
-       if (cl.csqcentities_active) Mem_Free(cl.csqcentities_active);cl.csqcentities_active = NULL;     //[515]: csqc
-       if (cl.static_entities) Mem_Free(cl.static_entities);cl.static_entities = NULL;
-       if (cl.temp_entities) Mem_Free(cl.temp_entities);cl.temp_entities = NULL;
-       if (cl.effects) Mem_Free(cl.effects);cl.effects = NULL;
-       if (cl.beams) Mem_Free(cl.beams);cl.beams = NULL;
-       if (cl.dlights) Mem_Free(cl.dlights);cl.dlights = NULL;
-       if (cl.lightstyle) Mem_Free(cl.lightstyle);cl.lightstyle = NULL;
-       if (cl.brushmodel_entities) Mem_Free(cl.brushmodel_entities);cl.brushmodel_entities = NULL;
-       if (cl.entitydatabase) EntityFrame_FreeDatabase(cl.entitydatabase);cl.entitydatabase = NULL;
-       if (cl.entitydatabase4) EntityFrame4_FreeDatabase(cl.entitydatabase4);cl.entitydatabase4 = NULL;
-       if (cl.entitydatabaseqw) EntityFrameQW_FreeDatabase(cl.entitydatabaseqw);cl.entitydatabaseqw = NULL;
-       if (cl.scores) Mem_Free(cl.scores);cl.scores = NULL;
-       if (cl.particles) Mem_Free(cl.particles);cl.particles = NULL;
-
-       if (!sv.active)
-               Host_ClearMemory ();
-
 // wipe the entire cl structure
+       Mem_EmptyPool(cls.levelmempool);
        memset (&cl, 0, sizeof(cl));
 
        S_StopAllSounds();
@@ -148,18 +132,18 @@ void CL_ClearState(void)
        cl.num_effects = 0;
        cl.num_beams = 0;
 
-       cl.entities = (entity_t *)Mem_Alloc(cls.mempool, cl.max_entities * sizeof(entity_t));
-       cl.csqcentities = (entity_t *)Mem_Alloc(cls.mempool, cl.max_csqcentities * sizeof(entity_t));   //[515]: csqc
-       cl.entities_active = (unsigned char *)Mem_Alloc(cls.mempool, cl.max_brushmodel_entities * sizeof(unsigned char));
-       cl.csqcentities_active = (unsigned char *)Mem_Alloc(cls.mempool, cl.max_brushmodel_entities * sizeof(unsigned char));   //[515]: csqc
-       cl.static_entities = (entity_t *)Mem_Alloc(cls.mempool, cl.max_static_entities * sizeof(entity_t));
-       cl.temp_entities = (entity_t *)Mem_Alloc(cls.mempool, cl.max_temp_entities * sizeof(entity_t));
-       cl.effects = (cl_effect_t *)Mem_Alloc(cls.mempool, cl.max_effects * sizeof(cl_effect_t));
-       cl.beams = (beam_t *)Mem_Alloc(cls.mempool, cl.max_beams * sizeof(beam_t));
-       cl.dlights = (dlight_t *)Mem_Alloc(cls.mempool, cl.max_dlights * sizeof(dlight_t));
-       cl.lightstyle = (lightstyle_t *)Mem_Alloc(cls.mempool, cl.max_lightstyle * sizeof(lightstyle_t));
-       cl.brushmodel_entities = (int *)Mem_Alloc(cls.mempool, cl.max_brushmodel_entities * sizeof(int));
-       cl.particles = (particle_t *) Mem_Alloc(cls.mempool, cl.max_particles * sizeof(particle_t));
+       cl.entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_entities * sizeof(entity_t));
+       cl.csqcentities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_csqcentities * sizeof(entity_t));      //[515]: csqc
+       cl.entities_active = (unsigned char *)Mem_Alloc(cls.levelmempool, cl.max_brushmodel_entities * sizeof(unsigned char));
+       cl.csqcentities_active = (unsigned char *)Mem_Alloc(cls.levelmempool, cl.max_brushmodel_entities * sizeof(unsigned char));      //[515]: csqc
+       cl.static_entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_static_entities * sizeof(entity_t));
+       cl.temp_entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_temp_entities * sizeof(entity_t));
+       cl.effects = (cl_effect_t *)Mem_Alloc(cls.levelmempool, cl.max_effects * sizeof(cl_effect_t));
+       cl.beams = (beam_t *)Mem_Alloc(cls.levelmempool, cl.max_beams * sizeof(beam_t));
+       cl.dlights = (dlight_t *)Mem_Alloc(cls.levelmempool, cl.max_dlights * sizeof(dlight_t));
+       cl.lightstyle = (lightstyle_t *)Mem_Alloc(cls.levelmempool, cl.max_lightstyle * sizeof(lightstyle_t));
+       cl.brushmodel_entities = (int *)Mem_Alloc(cls.levelmempool, cl.max_brushmodel_entities * sizeof(int));
+       cl.particles = (particle_t *) Mem_Alloc(cls.levelmempool, cl.max_particles * sizeof(particle_t));
 
        // LordHavoc: have to set up the baseline info for alpha and other stuff
        for (i = 0;i < cl.max_entities;i++)
@@ -230,7 +214,7 @@ void CL_ExpandEntities(int num)
                oldmaxentities = cl.max_entities;
                oldentities = cl.entities;
                cl.max_entities = (num & ~255) + 256;
-               cl.entities = (entity_t *)Mem_Alloc(cls.mempool, cl.max_entities * sizeof(entity_t));
+               cl.entities = (entity_t *)Mem_Alloc(cls.levelmempool, 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++)
@@ -255,7 +239,7 @@ void CL_ExpandCSQCEntities(int num)
                oldmaxentities = cl.max_csqcentities;
                oldentities = cl.csqcentities;
                cl.max_csqcentities = (num & ~255) + 256;
-               cl.csqcentities = Mem_Alloc(cls.mempool, cl.max_csqcentities * sizeof(entity_t));
+               cl.csqcentities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_csqcentities * sizeof(entity_t));
                memcpy(cl.csqcentities, oldentities, oldmaxentities * sizeof(entity_t));
                Mem_Free(oldentities);
                for (i = oldmaxentities;i < cl.max_csqcentities;i++)
@@ -421,44 +405,45 @@ static void CL_PrintEntities_f(void)
 //static const vec3_t nomodelmaxs = {16, 16, 16};
 void CL_BoundingBoxForEntity(entity_render_t *ent)
 {
-       if (ent->model)
+       model_t *model = ent->model;
+       if (model)
        {
                //if (ent->angles[0] || ent->angles[2])
                if (ent->matrix.m[2][0] != 0 || ent->matrix.m[2][1] != 0)
                {
                        // pitch or roll
-                       ent->mins[0] = ent->matrix.m[0][3] + ent->model->rotatedmins[0];
-                       ent->mins[1] = ent->matrix.m[1][3] + ent->model->rotatedmins[1];
-                       ent->mins[2] = ent->matrix.m[2][3] + ent->model->rotatedmins[2];
-                       ent->maxs[0] = ent->matrix.m[0][3] + ent->model->rotatedmaxs[0];
-                       ent->maxs[1] = ent->matrix.m[1][3] + ent->model->rotatedmaxs[1];
-                       ent->maxs[2] = ent->matrix.m[2][3] + ent->model->rotatedmaxs[2];
-                       //VectorAdd(ent->origin, ent->model->rotatedmins, ent->mins);
-                       //VectorAdd(ent->origin, ent->model->rotatedmaxs, ent->maxs);
+                       ent->mins[0] = ent->matrix.m[0][3] + model->rotatedmins[0];
+                       ent->mins[1] = ent->matrix.m[1][3] + model->rotatedmins[1];
+                       ent->mins[2] = ent->matrix.m[2][3] + model->rotatedmins[2];
+                       ent->maxs[0] = ent->matrix.m[0][3] + model->rotatedmaxs[0];
+                       ent->maxs[1] = ent->matrix.m[1][3] + model->rotatedmaxs[1];
+                       ent->maxs[2] = ent->matrix.m[2][3] + model->rotatedmaxs[2];
+                       //VectorAdd(ent->origin, model->rotatedmins, ent->mins);
+                       //VectorAdd(ent->origin, model->rotatedmaxs, ent->maxs);
                }
                //else if (ent->angles[1])
                else if (ent->matrix.m[0][1] != 0 || ent->matrix.m[1][0] != 0)
                {
                        // yaw
-                       ent->mins[0] = ent->matrix.m[0][3] + ent->model->yawmins[0];
-                       ent->mins[1] = ent->matrix.m[1][3] + ent->model->yawmins[1];
-                       ent->mins[2] = ent->matrix.m[2][3] + ent->model->yawmins[2];
-                       ent->maxs[0] = ent->matrix.m[0][3] + ent->model->yawmaxs[0];
-                       ent->maxs[1] = ent->matrix.m[1][3] + ent->model->yawmaxs[1];
-                       ent->maxs[2] = ent->matrix.m[2][3] + ent->model->yawmaxs[2];
-                       //VectorAdd(ent->origin, ent->model->yawmins, ent->mins);
-                       //VectorAdd(ent->origin, ent->model->yawmaxs, ent->maxs);
+                       ent->mins[0] = ent->matrix.m[0][3] + model->yawmins[0];
+                       ent->mins[1] = ent->matrix.m[1][3] + model->yawmins[1];
+                       ent->mins[2] = ent->matrix.m[2][3] + model->yawmins[2];
+                       ent->maxs[0] = ent->matrix.m[0][3] + model->yawmaxs[0];
+                       ent->maxs[1] = ent->matrix.m[1][3] + model->yawmaxs[1];
+                       ent->maxs[2] = ent->matrix.m[2][3] + model->yawmaxs[2];
+                       //VectorAdd(ent->origin, model->yawmins, ent->mins);
+                       //VectorAdd(ent->origin, model->yawmaxs, ent->maxs);
                }
                else
                {
-                       ent->mins[0] = ent->matrix.m[0][3] + ent->model->normalmins[0];
-                       ent->mins[1] = ent->matrix.m[1][3] + ent->model->normalmins[1];
-                       ent->mins[2] = ent->matrix.m[2][3] + ent->model->normalmins[2];
-                       ent->maxs[0] = ent->matrix.m[0][3] + ent->model->normalmaxs[0];
-                       ent->maxs[1] = ent->matrix.m[1][3] + ent->model->normalmaxs[1];
-                       ent->maxs[2] = ent->matrix.m[2][3] + ent->model->normalmaxs[2];
-                       //VectorAdd(ent->origin, ent->model->normalmins, ent->mins);
-                       //VectorAdd(ent->origin, ent->model->normalmaxs, ent->maxs);
+                       ent->mins[0] = ent->matrix.m[0][3] + model->normalmins[0];
+                       ent->mins[1] = ent->matrix.m[1][3] + model->normalmins[1];
+                       ent->mins[2] = ent->matrix.m[2][3] + model->normalmins[2];
+                       ent->maxs[0] = ent->matrix.m[0][3] + model->normalmaxs[0];
+                       ent->maxs[1] = ent->matrix.m[1][3] + model->normalmaxs[1];
+                       ent->maxs[2] = ent->matrix.m[2][3] + model->normalmaxs[2];
+                       //VectorAdd(ent->origin, model->normalmins, ent->mins);
+                       //VectorAdd(ent->origin, model->normalmaxs, ent->maxs);
                }
        }
        else
@@ -679,7 +664,7 @@ void CL_UpdateLights(void)
                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;
+               r_refdef.lightstylevalue[j] = (unsigned short)(((k*frac)+(l*(1-frac)))*22);
        }
 }
 
@@ -758,8 +743,9 @@ void CL_LinkNetworkEntity(entity_t *e)
 {
        matrix4x4_t *matrix, blendmatrix, tempmatrix, matrix2;
        //matrix4x4_t dlightmatrix;
-       int j, k, l, trailtype, temp;
-       float origin[3], angles[3], delta[3], lerp, dlightcolor[3], dlightradius, mins[3], maxs[3], v2[3], d;
+       int j, k, l;
+       effectnameindex_t trailtype;
+       float origin[3], angles[3], delta[3], lerp, dlightcolor[3], dlightradius, v2[3], d;
        entity_t *t;
        model_t *model;
        trace_t trace;
@@ -911,7 +897,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                if (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))
+                       if (e->render.model->type == mod_alias)
                                angles[0] = -angles[0];
                        if ((e->render.model->flags & EF_ROTATE) && (!e->state_current.tagentity && !(e->render.flags & RENDER_VIEWMODEL)))
                        {
@@ -921,9 +907,12 @@ void CL_LinkNetworkEntity(entity_t *e)
                        }
                        // transfer certain model flags to effects
                        e->render.effects |= e->render.model->flags2 & (EF_FULLBRIGHT | EF_ADDITIVE);
-                       if (cl_prydoncursor.integer && (e->render.effects & EF_SELECTABLE) && cl.cmd.cursor_entitynumber == e->state_current.number)
+                       if ((e->render.effects & EF_SELECTABLE) && cl.cmd.cursor_entitynumber == e->state_current.number)
                                VectorScale(e->render.colormod, 2, e->render.colormod);
                }
+               // if model is alias or this is a tenebrae-like dlight, reverse pitch direction
+               else if (e->state_current.lightpflags & PFLAGS_FULLDYNAMIC)
+                       angles[0] = -angles[0];
 
                // animation lerp
                if (e->render.frame2 == e->state_current.frame)
@@ -973,7 +962,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                        origin[1] = e->render.matrix.m[1][3];
                        origin[2] = e->render.matrix.m[2][3];
                }
-               trailtype = -1;
+               trailtype = EFFECT_NONE;
                dlightradius = 0;
                dlightcolor[0] = 0;
                dlightcolor[1] = 0;
@@ -984,13 +973,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                        if (e->render.effects & EF_BRIGHTFIELD)
                        {
                                if (gamemode == GAME_NEXUIZ)
-                               {
-                                       dlightradius = max(dlightradius, 200);
-                                       dlightcolor[0] += 0.75f;
-                                       dlightcolor[1] += 1.50f;
-                                       dlightcolor[2] += 3.00f;
-                                       trailtype = 8;
-                               }
+                                       trailtype = EFFECT_TR_NEXUIZPLASMA;
                                else
                                        CL_EntityParticles(e);
                        }
@@ -1026,38 +1009,9 @@ void CL_LinkNetworkEntity(entity_t *e)
                                dlightcolor[2] += 1.50f;
                        }
                        if (e->render.effects & EF_FLAME)
-                       {
-                               mins[0] = origin[0] - 16.0f;
-                               mins[1] = origin[1] - 16.0f;
-                               mins[2] = origin[2] - 16.0f;
-                               maxs[0] = origin[0] + 16.0f;
-                               maxs[1] = origin[1] + 16.0f;
-                               maxs[2] = origin[2] + 16.0f;
-                               // how many flames to make
-                               temp = (int) (cl.time * 300) - (int) (cl.oldtime * 300);
-                               CL_FlameCube(mins, maxs, temp);
-                               d = lhrandom(0.75f, 1);
-                               dlightradius = max(dlightradius, 200);
-                               dlightcolor[0] += d * 2.0f;
-                               dlightcolor[1] += d * 1.5f;
-                               dlightcolor[2] += d * 0.5f;
-                       }
+                               CL_ParticleEffect(EFFECT_EF_FLAME, cl.time - cl.oldtime, origin, origin, vec3_origin, vec3_origin, NULL, 0);
                        if (e->render.effects & EF_STARDUST)
-                       {
-                               mins[0] = origin[0] - 16.0f;
-                               mins[1] = origin[1] - 16.0f;
-                               mins[2] = origin[2] - 16.0f;
-                               maxs[0] = origin[0] + 16.0f;
-                               maxs[1] = origin[1] + 16.0f;
-                               maxs[2] = origin[2] + 16.0f;
-                               // how many particles to make
-                               temp = (int) (cl.time * 200) - (int) (cl.oldtime * 200);
-                               CL_Stardust(mins, maxs, temp);
-                               dlightradius = max(dlightradius, 200);
-                               dlightcolor[0] += 1.0f;
-                               dlightcolor[1] += 0.7f;
-                               dlightcolor[2] += 0.3f;
-                       }
+                               CL_ParticleEffect(EFFECT_EF_STARDUST, cl.time - cl.oldtime, origin, origin, vec3_origin, vec3_origin, NULL, 0);
                        if (e->render.effects & (EF_FLAG1QW | EF_FLAG2QW))
                        {
                                // these are only set on player entities
@@ -1080,56 +1034,22 @@ void CL_LinkNetworkEntity(entity_t *e)
                if (e->render.model && e->render.model->flags && (!e->state_current.tagentity && !(e->render.flags & RENDER_VIEWMODEL)))
                {
                        if (e->render.model->flags & EF_GIB)
-                               trailtype = 2;
+                               trailtype = EFFECT_TR_BLOOD;
                        else if (e->render.model->flags & EF_ZOMGIB)
-                               trailtype = 4;
+                               trailtype = EFFECT_TR_SLIGHTBLOOD;
                        else if (e->render.model->flags & EF_TRACER)
-                       {
-                               trailtype = 3;
-                               //dlightradius = max(dlightradius, 100);
-                               //dlightcolor[0] += 0.25f;
-                               //dlightcolor[1] += 1.00f;
-                               //dlightcolor[2] += 0.25f;
-                       }
+                               trailtype = EFFECT_TR_WIZSPIKE;
                        else if (e->render.model->flags & EF_TRACER2)
-                       {
-                               trailtype = 5;
-                               //dlightradius = max(dlightradius, 100);
-                               //dlightcolor[0] += 1.00f;
-                               //dlightcolor[1] += 0.60f;
-                               //dlightcolor[2] += 0.20f;
-                       }
+                               trailtype = EFFECT_TR_KNIGHTSPIKE;
                        else if (e->render.model->flags & EF_ROCKET)
-                       {
-                               trailtype = 0;
-                               dlightradius = max(dlightradius, 200);
-                               dlightcolor[0] += 3.00f;
-                               dlightcolor[1] += 1.50f;
-                               dlightcolor[2] += 0.50f;
-                       }
+                               trailtype = EFFECT_TR_ROCKET;
                        else if (e->render.model->flags & EF_GRENADE)
                        {
                                // LordHavoc: e->render.alpha == -1 is for Nehahra dem compatibility (cigar smoke)
-                               trailtype = e->render.alpha == -1 ? 7 : 1;
+                               trailtype = e->render.alpha == -1 ? EFFECT_TR_NEHAHRASMOKE : EFFECT_TR_GRENADE;
                        }
                        else if (e->render.model->flags & EF_TRACER3)
-                       {
-                               trailtype = 6;
-                               if (gamemode == GAME_PRYDON)
-                               {
-                                       dlightradius = max(dlightradius, 100);
-                                       dlightcolor[0] += 0.30f;
-                                       dlightcolor[1] += 0.60f;
-                                       dlightcolor[2] += 1.20f;
-                               }
-                               else
-                               {
-                                       dlightradius = max(dlightradius, 200);
-                                       dlightcolor[0] += 1.20f;
-                                       dlightcolor[1] += 0.50f;
-                                       dlightcolor[2] += 1.00f;
-                               }
-                       }
+                               trailtype = EFFECT_TR_VORESPIKE;
                }
                // LordHavoc: customizable glow
                if (e->state_current.glowsize)
@@ -1163,9 +1083,19 @@ void CL_LinkNetworkEntity(entity_t *e)
                }
                // do trails
                if (e->render.flags & RENDER_GLOWTRAIL)
-                       trailtype = 9;
-               if (trailtype >= 0)
-                       CL_RocketTrail(e->persistent.trail_origin, origin, trailtype, e->state_current.glowcolor, e);
+                       trailtype = EFFECT_TR_GLOWTRAIL;
+               if (trailtype)
+               {
+                       float len;
+                       vec3_t vel;
+                       VectorSubtract(e->state_current.origin, e->state_previous.origin, vel);
+                       len = e->state_current.time - e->state_previous.time;
+                       if (len > 0)
+                               len = 1.0f / len;
+                       VectorScale(vel, len, vel);
+                       len = VectorDistance(origin, e->persistent.trail_origin);
+                       CL_ParticleEffect(trailtype, len, e->persistent.trail_origin, origin, vel, vel, e, e->state_current.glowcolor);
+               }
                VectorCopy(origin, e->persistent.trail_origin);
                // tenebrae's sprites are all additive mode (weird)
                if (gamemode == GAME_TENEBRAE && e->render.model && e->render.model->type == mod_sprite)
@@ -1357,7 +1287,7 @@ static void CL_RelinkEffects(void)
                if (e->active)
                {
                        frame = (cl.time - e->starttime) * e->framerate + e->startframe;
-                       intframe = frame;
+                       intframe = (int)frame;
                        if (intframe < 0 || intframe >= e->endframe)
                        {
                                memset(e, 0, sizeof(*e));
@@ -1558,6 +1488,7 @@ void CL_LerpPlayer(float frac)
 
 void CSQC_RelinkAllEntities (int drawmask)
 {
+       cl.num_brushmodel_entities = 0;
        CL_RelinkNetworkEntities(drawmask);
        if(drawmask & ENTMASK_ENGINE)
        {
@@ -1596,7 +1527,6 @@ int CL_ReadFromServer(void)
        r_refdef.extraupdate = !r_speeds.integer;
        r_refdef.numentities = 0;
        r_refdef.viewentitymatrix = identitymatrix;
-       cl.num_brushmodel_entities = 0;
 
        if (cls.state == ca_connected && cls.signon == SIGNONS)
        {
@@ -1611,6 +1541,7 @@ int CL_ReadFromServer(void)
                CL_ClientMovement_Replay();
                if(!csqc_loaded)        //[515]: csqc
                {
+                       cl.num_brushmodel_entities = 0;
                        CL_RelinkNetworkEntities(65535);
 
                        // move particles
@@ -1703,7 +1634,8 @@ void CL_Shutdown (void)
        CL_Particles_Shutdown();
        CL_Parse_Shutdown();
 
-       Mem_FreePool (&cls.mempool);
+       Mem_FreePool (&cls.permanentmempool);
+       Mem_FreePool (&cls.levelmempool);
 }
 
 /*
@@ -1713,12 +1645,13 @@ CL_Init
 */
 void CL_Init (void)
 {
-       cls.mempool = Mem_AllocPool("client", 0, NULL);
+       cls.levelmempool = Mem_AllocPool("client (per-level memory)", 0, NULL);
+       cls.permanentmempool = Mem_AllocPool("client (long term memory)", 0, NULL);
 
        memset(&r_refdef, 0, sizeof(r_refdef));
        // max entities sent to renderer per frame
        r_refdef.maxentities = MAX_EDICTS + 256 + 512;
-       r_refdef.entities = (entity_render_t **)Mem_Alloc(cls.mempool, sizeof(entity_render_t *) * r_refdef.maxentities);
+       r_refdef.entities = (entity_render_t **)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t *) * r_refdef.maxentities);
 
        CL_InitInput ();
 
@@ -1758,6 +1691,9 @@ void CL_Init (void)
        Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "watch a demo file");
        Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "play back a demo as fast as possible and save statistics to benchmark.log");
 
+       Cvar_RegisterVariable (&cl_autodemo);
+       Cvar_RegisterVariable (&cl_autodemo_nameformat);
+
        Cmd_AddCommand ("fog", CL_Fog_f, "set global fog parameters (density red green blue)");
 
        // LordHavoc: added pausedemo