]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_parse.c
corrected a few LittleLongs to LittleFloat in md3 loading (EEP those were bad)
[xonotic/darkplaces.git] / cl_parse.c
index 9863aa3c75e07d65d63c4d19f98327c0b2b76a73..f0beef03a680ace737a90864e05ea1bfe6080641 100644 (file)
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // cl_parse.c  -- parse a message received from the server
 
 #include "quakedef.h"
+#include "cl_collision.h"
 
 char *svc_strings[128] =
 {
@@ -99,6 +100,8 @@ cvar_t demo_nehahra = {0, "demo_nehahra", "0"};
 qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
 int dpprotocol; // LordHavoc: version of network protocol, or 0 if not DarkPlaces
 
+mempool_t *cl_scores_mempool;
+
 /*
 ==================
 CL_ParseStartSoundPacket
@@ -164,59 +167,49 @@ When the client is taking a long time to load stuff, send keepalive messages
 so the server doesn't disconnect.
 ==================
 */
+
+static qbyte olddata[NET_MAXMESSAGE];
 void CL_KeepaliveMessage (void)
 {
-       float   time;
+       float time;
        static float lastmsg;
-       int             ret;
-       int             c;
-       sizebuf_t       old;
-       qbyte           olddata[8192];
-
-       if (sv.active)
-               return;         // no need if server is local
-       if (cls.demoplayback)
+       int oldreadcount;
+       qboolean oldbadread;
+       sizebuf_t old;
+
+       // no need if server is local and definitely not if this is a demo
+       if (sv.active || cls.demoplayback)
                return;
 
 // read messages from server, should just be nops
+       oldreadcount = msg_readcount;
+       oldbadread = msg_badread;
        old = net_message;
-       memcpy (olddata, net_message.data, net_message.cursize);
+       memcpy(olddata, net_message.data, net_message.cursize);
 
-       do
-       {
-               ret = CL_GetMessage ();
-               switch (ret)
-               {
-               default:
-                       Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
-               case 0:
-                       break;  // nothing waiting
-               case 1:
-                       Host_Error ("CL_KeepaliveMessage: received a message");
-                       break;
-               case 2:
-                       c = MSG_ReadByte();
-                       if (c != svc_nop)
-                               Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
-                       break;
-               }
-       } while (ret);
+       NetConn_ClientFrame();
 
+       msg_readcount = oldreadcount;
+       msg_badread = oldbadread;
        net_message = old;
-       memcpy (net_message.data, olddata, net_message.cursize);
-
-// check time
-       time = Sys_DoubleTime ();
-       if (time - lastmsg < 5)
-               return;
-       lastmsg = time;
-
-// write out a nop
-       Con_Printf ("--> client to server keepalive\n");
+       memcpy(net_message.data, olddata, net_message.cursize);
 
-       MSG_WriteByte (&cls.message, clc_nop);
-       NET_SendMessage (cls.netcon, &cls.message);
-       SZ_Clear (&cls.message);
+       if (cls.netcon && NetConn_CanSendMessage(cls.netcon) && (time = Sys_DoubleTime()) - lastmsg >= 5)
+       {
+               sizebuf_t       msg;
+               qbyte           buf[4];
+               lastmsg = time;
+               // write out a nop
+               // LordHavoc: must use unreliable because reliable could kill the sigon message!
+               Con_Printf("--> client to server keepalive\n");
+               msg.data = buf;
+               msg.maxsize = sizeof(buf);
+               msg.cursize = 0;
+               MSG_WriteChar(&msg, svc_nop);
+               NetConn_SendUnreliableMessage(cls.netcon, &msg);
+               // try not to utterly crush the computer with work, that's just rude
+               Sys_Sleep();
+       }
 }
 
 void CL_ParseEntityLump(char *entdata)
@@ -228,13 +221,13 @@ void CL_ParseEntityLump(char *entdata)
        data = entdata;
        if (!data)
                return;
-       if (!COM_ParseToken(&data))
+       if (!COM_ParseToken(&data, false))
                return; // error
        if (com_token[0] != '{')
                return; // error
        while (1)
        {
-               if (!COM_ParseToken(&data))
+               if (!COM_ParseToken(&data, false))
                        return; // error
                if (com_token[0] == '}')
                        break; // end of worldspawn
@@ -244,7 +237,7 @@ void CL_ParseEntityLump(char *entdata)
                        strcpy(key, com_token);
                while (key[strlen(key)-1] == ' ') // remove trailing spaces
                        key[strlen(key)-1] = 0;
-               if (!COM_ParseToken(&data))
+               if (!COM_ParseToken(&data, false))
                        return; // error
                strcpy(value, com_token);
                if (!strcmp("sky", key))
@@ -359,6 +352,7 @@ void CL_ParseServerInfo (void)
                Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
                return;
        }
+       Mem_EmptyPool(cl_scores_mempool);
        cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
 
 // parse gametype
@@ -381,41 +375,48 @@ void CL_ParseServerInfo (void)
        // disable until we get textures for it
        R_ResetSkyBox();
 
-       memset (cl.model_precache, 0, sizeof(cl.model_precache));
-       memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
+       memset(cl.model_precache, 0, sizeof(cl.model_precache));
+       memset(cl.sound_precache, 0, sizeof(cl.sound_precache));
 
-       // touch all of the precached models that are still loaded so we can free
-       // anything that isn't needed
-       Mod_ClearUsed();
+       // parse model precache list
        for (nummodels=1 ; ; nummodels++)
        {
-               CL_KeepaliveMessage ();
-               str = MSG_ReadString ();
+               str = MSG_ReadString();
                if (!str[0])
                        break;
                if (nummodels==MAX_MODELS)
                        Host_Error ("Server sent too many model precaches\n");
                if (strlen(str) >= MAX_QPATH)
                        Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
-               strcpy (parse_model_precache[nummodels], str);
-               Mod_TouchModel (str);
+               strcpy(parse_model_precache[nummodels], str);
        }
-
-       // do the same for sounds
+       // parse sound precache list
        for (numsounds=1 ; ; numsounds++)
        {
-               CL_KeepaliveMessage ();
-               str = MSG_ReadString ();
+               str = MSG_ReadString();
                if (!str[0])
                        break;
                if (numsounds==MAX_SOUNDS)
-                       Host_Error ("Server sent too many sound precaches\n");
+                       Host_Error("Server sent too many sound precaches\n");
                if (strlen(str) >= MAX_QPATH)
-                       Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
-               strcpy (parse_sound_precache[numsounds], str);
-               S_TouchSound (str);
+                       Host_Error("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
+               strcpy(parse_sound_precache[numsounds], str);
        }
 
+       // touch all of the precached models that are still loaded so we can free
+       // anything that isn't needed
+       Mod_ClearUsed();
+       for (i = 1;i < nummodels;i++)
+       {
+               CL_KeepaliveMessage();
+               Mod_TouchModel(parse_model_precache[i]);
+       }
+       // do the same for sounds
+       for (i = 1;i < numsounds;i++)
+       {
+               CL_KeepaliveMessage();
+               S_TouchSound(parse_sound_precache[i]);
+       }
        // purge anything that was not touched
        Mod_PurgeUnused();
 
@@ -423,15 +424,15 @@ void CL_ParseServerInfo (void)
 
        // world model
        CL_KeepaliveMessage ();
-       cl.model_precache[1] = Mod_ForName (parse_model_precache[1], false, false, true);
+       cl.model_precache[1] = Mod_ForName(parse_model_precache[1], false, false, true);
        if (cl.model_precache[1] == NULL)
                Con_Printf("Map %s not found\n", parse_model_precache[1]);
 
        // normal models
        for (i=2 ; i<nummodels ; i++)
        {
-               CL_KeepaliveMessage ();
-               if ((cl.model_precache[i] = Mod_ForName (parse_model_precache[i], false, false, false)) == NULL)
+               CL_KeepaliveMessage();
+               if ((cl.model_precache[i] = Mod_ForName(parse_model_precache[i], false, false, false)) == NULL)
                        Con_Printf("Model %s not found\n", parse_model_precache[i]);
        }
 
@@ -439,8 +440,8 @@ void CL_ParseServerInfo (void)
        S_BeginPrecaching ();
        for (i=1 ; i<numsounds ; i++)
        {
-               CL_KeepaliveMessage ();
-               cl.sound_precache[i] = S_PrecacheSound (parse_sound_precache[i], true);
+               CL_KeepaliveMessage();
+               cl.sound_precache[i] = S_PrecacheSound(parse_sound_precache[i], true);
        }
        S_EndPrecaching ();
 
@@ -451,6 +452,7 @@ void CL_ParseServerInfo (void)
        ent->render.model = cl.worldmodel = cl.model_precache[1];
        //ent->render.scale = 1;
        ent->render.alpha = 1;
+       ent->render.flags = RENDER_SHADOW;
        Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, 0, 0, 0, 0, 0, 0, 1);
        Matrix4x4_Invert_Simple(&ent->render.inversematrix, &ent->render.matrix);
        CL_BoundingBoxForEntity(&ent->render);
@@ -459,7 +461,7 @@ void CL_ParseServerInfo (void)
 
        cl_num_entities = 1;
 
-       R_NewMap ();
+       R_Modules_NewMap();
        CL_CGVM_Start();
 
        // noclip is turned off at start
@@ -530,7 +532,7 @@ void CL_MoveLerpEntityStates(entity_t *ent)
                // not a monster
                ent->persistent.lerpstarttime = cl.mtime[1];
                // no lerp if it's singleplayer
-               if (sv.active && svs.maxclients == 1 && !ent->state_current.flags & RENDER_STEP)
+               if (sv.active && svs.maxclients == 1)
                        ent->persistent.lerpdeltatime = 0;
                else
                        ent->persistent.lerpdeltatime = cl.mtime[0] - cl.mtime[1];
@@ -653,23 +655,26 @@ void CL_ParseUpdate (int bits)
 static entity_frame_t entityframe;
 void CL_ReadEntityFrame(void)
 {
-       entity_t *ent;
-       int i;
-       EntityFrame_Read(&cl.entitydatabase);
-       EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
-       for (i = 0;i < entityframe.numentities;i++)
+       if (dpprotocol == DPPROTOCOL_VERSION3)
        {
-               // copy the states
-               ent = &cl_entities[entityframe.entitydata[i].number];
-               ent->state_previous = ent->state_current;
-               ent->state_current = entityframe.entitydata[i];
-               CL_MoveLerpEntityStates(ent);
-               // the entity lives again...
-               entlife[ent->state_current.number] = 2;
-               cl_entities_active[ent->state_current.number] = true;
+               int i;
+               entity_t *ent;
+               EntityFrame_Read(&cl.entitydatabase);
+               EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
+               for (i = 0;i < entityframe.numentities;i++)
+               {
+                       // copy the states
+                       ent = &cl_entities[entityframe.entitydata[i].number];
+                       ent->state_previous = ent->state_current;
+                       ent->state_current = entityframe.entitydata[i];
+                       CL_MoveLerpEntityStates(ent);
+                       // the entity lives again...
+                       entlife[ent->state_current.number] = 2;
+                       cl_entities_active[ent->state_current.number] = true;
+               }
        }
-       VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
-       VectorCopy(entityframe.eye, cl.viewentoriginnew);
+       else
+               EntityFrame4_CL_ReadFrame(&cl.entitydatabase4);
 }
 
 void CL_EntityUpdateSetup(void)
@@ -678,18 +683,21 @@ void CL_EntityUpdateSetup(void)
 
 void CL_EntityUpdateEnd(void)
 {
-       int i;
-       // disable entities that disappeared this frame
-       for (i = 1;i < MAX_EDICTS;i++)
+       if (dpprotocol != DPPROTOCOL_VERSION4)
        {
-               // clear only the entities that were active last frame but not this
-               // frame, don't waste time clearing all entities (which would cause
-               // cache misses)
-               if (entlife[i])
+               int i;
+               // disable entities that disappeared this frame
+               for (i = 1;i < MAX_EDICTS;i++)
                {
-                       entlife[i]--;
-                       if (!entlife[i])
-                               cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
+                       // clear only the entities that were active last frame but not this
+                       // frame, don't waste time clearing all entities (which would cause
+                       // cache misses)
+                       if (entlife[i])
+                       {
+                               entlife[i]--;
+                               if (!entlife[i])
+                                       cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
+                       }
                }
        }
 }
@@ -990,7 +998,7 @@ void CL_ParseBeam (model_t *m, int lightning)
        Con_Printf ("beam list overflow!\n");
 }
 
-void CL_ParseTempEntity (void)
+void CL_ParseTempEntity(void)
 {
        int type;
        vec3_t pos;
@@ -1002,137 +1010,131 @@ void CL_ParseTempEntity (void)
        float velspeed, radius;
        qbyte *tempcolor;
 
-       type = MSG_ReadByte ();
+       type = MSG_ReadByte();
        switch (type)
        {
        case TE_WIZSPIKE:
                // spike hitting wall
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
-               CL_AllocDlight (NULL, pos, 50, 0.25f, 1.00f, 0.25f, 250, 0.2);
-               CL_RunParticleEffect (pos, vec3_origin, 20, 30);
-               S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
+               CL_FindNonSolidLocation(pos, pos, 4);
+               CL_AllocDlight(NULL, pos, 50, 0.25f, 1.00f, 0.25f, 250, 0.2);
+               CL_RunParticleEffect(pos, vec3_origin, 20, 30);
+               S_StartSound(-1, 0, cl_sfx_wizhit, pos, 1, 1);
                break;
 
        case TE_KNIGHTSPIKE:
                // spike hitting wall
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
-               CL_AllocDlight (NULL, pos, 50, 1.0f, 0.60f, 0.20f, 250, 0.2);
-               CL_RunParticleEffect (pos, vec3_origin, 226, 20);
-               S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
+               CL_FindNonSolidLocation(pos, pos, 4);
+               CL_AllocDlight(NULL, pos, 50, 1.0f, 0.60f, 0.20f, 250, 0.2);
+               CL_RunParticleEffect(pos, vec3_origin, 226, 20);
+               S_StartSound(-1, 0, cl_sfx_knighthit, pos, 1, 1);
                break;
 
        case TE_SPIKE:
                // spike hitting wall
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+               CL_FindNonSolidLocation(pos, pos, 4);
                // LordHavoc: changed to spark shower
                CL_SparkShower(pos, vec3_origin, 15);
-               if ( rand() % 5 )
-                       S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
+               if (rand() % 5)
+                       S_StartSound(-1, 0, cl_sfx_tink1, pos, 1, 1);
                else
                {
                        rnd = rand() & 3;
                        if (rnd == 1)
-                               S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric1, pos, 1, 1);
                        else if (rnd == 2)
-                               S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric2, pos, 1, 1);
                        else
-                               S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric3, pos, 1, 1);
                }
                break;
        case TE_SPIKEQUAD:
                // quad spike hitting wall
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+               CL_FindNonSolidLocation(pos, pos, 4);
                // LordHavoc: changed to spark shower
                CL_SparkShower(pos, vec3_origin, 15);
-               CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
-               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
-               if ( rand() % 5 )
-                       S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
+               CL_AllocDlight(NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
+               S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               if (rand() % 5)
+                       S_StartSound(-1, 0, cl_sfx_tink1, pos, 1, 1);
                else
                {
                        rnd = rand() & 3;
                        if (rnd == 1)
-                               S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric1, pos, 1, 1);
                        else if (rnd == 2)
-                               S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric2, pos, 1, 1);
                        else
-                               S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric3, pos, 1, 1);
                }
                break;
        case TE_SUPERSPIKE:
                // super spike hitting wall
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+               CL_FindNonSolidLocation(pos, pos, 4);
                // LordHavoc: changed to dust shower
                CL_SparkShower(pos, vec3_origin, 30);
-               if ( rand() % 5 )
-                       S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
+               if (rand() % 5)
+                       S_StartSound(-1, 0, cl_sfx_tink1, pos, 1, 1);
                else
                {
                        rnd = rand() & 3;
                        if (rnd == 1)
-                               S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric1, pos, 1, 1);
                        else if (rnd == 2)
-                               S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric2, pos, 1, 1);
                        else
-                               S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric3, pos, 1, 1);
                }
                break;
        case TE_SUPERSPIKEQUAD:
                // quad super spike hitting wall
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+               CL_FindNonSolidLocation(pos, pos, 4);
                // LordHavoc: changed to dust shower
                CL_SparkShower(pos, vec3_origin, 30);
-               CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
-               if ( rand() % 5 )
-                       S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
+               CL_AllocDlight(NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
+               if (rand() % 5)
+                       S_StartSound(-1, 0, cl_sfx_tink1, pos, 1, 1);
                else
                {
                        rnd = rand() & 3;
                        if (rnd == 1)
-                               S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric1, pos, 1, 1);
                        else if (rnd == 2)
-                               S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric2, pos, 1, 1);
                        else
-                               S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
+                               S_StartSound(-1, 0, cl_sfx_ric3, pos, 1, 1);
                }
                break;
                // LordHavoc: added for improved blood splatters
        case TE_BLOOD:
                // blood puff
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
-               dir[0] = MSG_ReadChar ();
-               dir[1] = MSG_ReadChar ();
-               dir[2] = MSG_ReadChar ();
-               count = MSG_ReadByte ();
+               CL_FindNonSolidLocation(pos, pos, 4);
+               dir[0] = MSG_ReadChar();
+               dir[1] = MSG_ReadChar();
+               dir[2] = MSG_ReadChar();
+               count = MSG_ReadByte();
                CL_BloodPuff(pos, dir, count);
                break;
-       case TE_BLOOD2:
-               // blood puff
-               MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
-               CL_BloodPuff(pos, vec3_origin, 10);
-               break;
        case TE_SPARK:
                // spark shower
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
-               dir[0] = MSG_ReadChar ();
-               dir[1] = MSG_ReadChar ();
-               dir[2] = MSG_ReadChar ();
-               count = MSG_ReadByte ();
+               CL_FindNonSolidLocation(pos, pos, 4);
+               dir[0] = MSG_ReadChar();
+               dir[1] = MSG_ReadChar();
+               dir[2] = MSG_ReadChar();
+               count = MSG_ReadByte();
                CL_SparkShower(pos, dir, count);
                break;
        case TE_PLASMABURN:
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
-               CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
+               CL_FindNonSolidLocation(pos, pos, 4);
+               CL_AllocDlight(NULL, pos, 200, 1, 1, 1, 1000, 0.2);
                CL_PlasmaBurn(pos);
                break;
                // LordHavoc: added for improved gore
@@ -1140,8 +1142,8 @@ void CL_ParseTempEntity (void)
                // vaporized body
                MSG_ReadVector(pos); // mins
                MSG_ReadVector(pos2); // maxs
-               velspeed = MSG_ReadCoord (); // speed
-               count = MSG_ReadShort (); // number of particles
+               velspeed = MSG_ReadCoord(); // speed
+               count = MSG_ReadShort(); // number of particles
                CL_BloodShower(pos, pos2, velspeed, count);
                break;
        case TE_PARTICLECUBE:
@@ -1149,10 +1151,10 @@ void CL_ParseTempEntity (void)
                MSG_ReadVector(pos); // mins
                MSG_ReadVector(pos2); // maxs
                MSG_ReadVector(dir); // dir
-               count = MSG_ReadShort (); // number of particles
-               colorStart = MSG_ReadByte (); // color
-               colorLength = MSG_ReadByte (); // gravity (1 or 0)
-               velspeed = MSG_ReadCoord (); // randomvel
+               count = MSG_ReadShort(); // number of particles
+               colorStart = MSG_ReadByte(); // color
+               colorLength = MSG_ReadByte(); // gravity (1 or 0)
+               velspeed = MSG_ReadCoord(); // randomvel
                CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength, velspeed);
                break;
 
@@ -1161,8 +1163,8 @@ void CL_ParseTempEntity (void)
                MSG_ReadVector(pos); // mins
                MSG_ReadVector(pos2); // maxs
                MSG_ReadVector(dir); // dir
-               count = MSG_ReadShort (); // number of particles
-               colorStart = MSG_ReadByte (); // color
+               count = MSG_ReadShort(); // number of particles
+               colorStart = MSG_ReadByte(); // color
                CL_ParticleRain(pos, pos2, dir, count, colorStart, 0);
                break;
 
@@ -1171,15 +1173,15 @@ void CL_ParseTempEntity (void)
                MSG_ReadVector(pos); // mins
                MSG_ReadVector(pos2); // maxs
                MSG_ReadVector(dir); // dir
-               count = MSG_ReadShort (); // number of particles
-               colorStart = MSG_ReadByte (); // color
+               count = MSG_ReadShort(); // number of particles
+               colorStart = MSG_ReadByte(); // color
                CL_ParticleRain(pos, pos2, dir, count, colorStart, 1);
                break;
 
        case TE_GUNSHOT:
                // bullet hitting wall
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+               CL_FindNonSolidLocation(pos, pos, 4);
                // LordHavoc: changed to dust shower
                CL_SparkShower(pos, vec3_origin, 15);
                break;
@@ -1187,77 +1189,77 @@ void CL_ParseTempEntity (void)
        case TE_GUNSHOTQUAD:
                // quad bullet hitting wall
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+               CL_FindNonSolidLocation(pos, pos, 4);
                CL_SparkShower(pos, vec3_origin, 15);
-               CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
+               CL_AllocDlight(NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
                break;
 
        case TE_EXPLOSION:
                // rocket explosion
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
-               CL_ParticleExplosion (pos);
+               CL_FindNonSolidLocation(pos, pos, 10);
+               CL_ParticleExplosion(pos);
                // LordHavoc: boosted color from 1.0, 0.8, 0.4 to 1.25, 1.0, 0.5
-               CL_AllocDlight (NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5);
-               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               CL_AllocDlight(NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5);
+               S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
        case TE_EXPLOSIONQUAD:
                // quad rocket explosion
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
-               CL_ParticleExplosion (pos);
-               CL_AllocDlight (NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5);
-               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               CL_FindNonSolidLocation(pos, pos, 10);
+               CL_ParticleExplosion(pos);
+               CL_AllocDlight(NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5);
+               S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
        case TE_EXPLOSION3:
                // Nehahra movie colored lighting explosion
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
-               CL_ParticleExplosion (pos);
-               CL_AllocDlight (NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5);
-               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               CL_FindNonSolidLocation(pos, pos, 10);
+               CL_ParticleExplosion(pos);
+               CL_AllocDlight(NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5);
+               S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
        case TE_EXPLOSIONRGB:
                // colored lighting explosion
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
-               CL_ParticleExplosion (pos);
+               CL_FindNonSolidLocation(pos, pos, 10);
+               CL_ParticleExplosion(pos);
                color[0] = MSG_ReadByte() * (1.0 / 255.0);
                color[1] = MSG_ReadByte() * (1.0 / 255.0);
                color[2] = MSG_ReadByte() * (1.0 / 255.0);
-               CL_AllocDlight (NULL, pos, 350, color[0], color[1], color[2], 700, 0.5);
-               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               CL_AllocDlight(NULL, pos, 350, color[0], color[1], color[2], 700, 0.5);
+               S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
        case TE_TAREXPLOSION:
                // tarbaby explosion
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
-               CL_BlobExplosion (pos);
+               CL_FindNonSolidLocation(pos, pos, 10);
+               CL_BlobExplosion(pos);
 
-               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
-               CL_AllocDlight (NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5);
-               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               CL_AllocDlight(NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5);
                break;
 
        case TE_SMALLFLASH:
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
-               CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
+               CL_FindNonSolidLocation(pos, pos, 10);
+               CL_AllocDlight(NULL, pos, 200, 1, 1, 1, 1000, 0.2);
                break;
 
        case TE_CUSTOMFLASH:
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+               CL_FindNonSolidLocation(pos, pos, 4);
                radius = MSG_ReadByte() * 8;
                velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0);
                color[0] = MSG_ReadByte() * (1.0 / 255.0);
                color[1] = MSG_ReadByte() * (1.0 / 255.0);
                color[2] = MSG_ReadByte() * (1.0 / 255.0);
-               CL_AllocDlight (NULL, pos, radius, color[0], color[1], color[2], radius / velspeed, velspeed);
+               CL_AllocDlight(NULL, pos, radius, color[0], color[1], color[2], radius / velspeed, velspeed);
                break;
 
        case TE_FLAMEJET:
@@ -1271,21 +1273,21 @@ void CL_ParseTempEntity (void)
                // lightning bolts
                if (!cl_model_bolt)
                        cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, false, false);
-               CL_ParseBeam (cl_model_bolt, true);
+               CL_ParseBeam(cl_model_bolt, true);
                break;
 
        case TE_LIGHTNING2:
                // lightning bolts
                if (!cl_model_bolt2)
                        cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, false, false);
-               CL_ParseBeam (cl_model_bolt2, true);
+               CL_ParseBeam(cl_model_bolt2, true);
                break;
 
        case TE_LIGHTNING3:
                // lightning bolts
                if (!cl_model_bolt3)
                        cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, false, false);
-               CL_ParseBeam (cl_model_bolt3, false);
+               CL_ParseBeam(cl_model_bolt3, false);
                break;
 
 // PGM 01/21/97
@@ -1293,40 +1295,40 @@ void CL_ParseTempEntity (void)
                // grappling hook beam
                if (!cl_model_beam)
                        cl_model_beam = Mod_ForName("progs/beam.mdl", true, false, false);
-               CL_ParseBeam (cl_model_beam, false);
+               CL_ParseBeam(cl_model_beam, false);
                break;
 // PGM 01/21/97
 
 // LordHavoc: for compatibility with the Nehahra movie...
        case TE_LIGHTNING4NEH:
-               CL_ParseBeam (Mod_ForName(MSG_ReadString(), true, false, false), false);
+               CL_ParseBeam(Mod_ForName(MSG_ReadString(), true, false, false), false);
                break;
 
        case TE_LAVASPLASH:
-               pos[0] = MSG_ReadCoord ();
-               pos[1] = MSG_ReadCoord ();
-               pos[2] = MSG_ReadCoord ();
-               CL_LavaSplash (pos);
+               pos[0] = MSG_ReadCoord();
+               pos[1] = MSG_ReadCoord();
+               pos[2] = MSG_ReadCoord();
+               CL_LavaSplash(pos);
                break;
 
        case TE_TELEPORT:
-               pos[0] = MSG_ReadCoord ();
-               pos[1] = MSG_ReadCoord ();
-               pos[2] = MSG_ReadCoord ();
-               CL_AllocDlight (NULL, pos, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f);
-//             CL_TeleportSplash (pos);
+               pos[0] = MSG_ReadCoord();
+               pos[1] = MSG_ReadCoord();
+               pos[2] = MSG_ReadCoord();
+               CL_AllocDlight(NULL, pos, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f);
+//             CL_TeleportSplash(pos);
                break;
 
        case TE_EXPLOSION2:
                // color mapped explosion
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
-               colorStart = MSG_ReadByte ();
-               colorLength = MSG_ReadByte ();
-               CL_ParticleExplosion2 (pos, colorStart, colorLength);
+               CL_FindNonSolidLocation(pos, pos, 10);
+               colorStart = MSG_ReadByte();
+               colorLength = MSG_ReadByte();
+               CL_ParticleExplosion2(pos, colorStart, colorLength);
                tempcolor = (qbyte *)&palette_complete[(rand()%colorLength) + colorStart];
-               CL_AllocDlight (NULL, pos, 350, tempcolor[0] * (1.0f / 255.0f), tempcolor[1] * (1.0f / 255.0f), tempcolor[2] * (1.0f / 255.0f), 700, 0.5);
-               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               CL_AllocDlight(NULL, pos, 350, tempcolor[0] * (1.0f / 255.0f), tempcolor[1] * (1.0f / 255.0f), tempcolor[2] * (1.0f / 255.0f), 700, 0.5);
+               S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
        case TE_TEI_G3:
@@ -1340,30 +1342,30 @@ void CL_ParseTempEntity (void)
        case TE_TEI_SMOKE:
                MSG_ReadVector(pos);
                MSG_ReadVector(dir);
-               count = MSG_ReadByte ();
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 4);
+               count = MSG_ReadByte();
+               CL_FindNonSolidLocation(pos, pos, 4);
                CL_Tei_Smoke(pos, dir, count);
                break;
 
        case TE_TEI_BIGEXPLOSION:
                MSG_ReadVector(pos);
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 10);
-               CL_ParticleExplosion (pos);
-               CL_AllocDlight (NULL, pos, 500, 1.25f, 1.0f, 0.5f, 500, 9999);
-               S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+               CL_FindNonSolidLocation(pos, pos, 10);
+               CL_ParticleExplosion(pos);
+               CL_AllocDlight(NULL, pos, 500, 1.25f, 1.0f, 0.5f, 500, 9999);
+               S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1);
                break;
 
        case TE_TEI_PLASMAHIT:
                MSG_ReadVector(pos);
                MSG_ReadVector(dir);
-               count = MSG_ReadByte ();
-               Mod_FindNonSolidLocation(pos, pos, cl.worldmodel, 5);
+               count = MSG_ReadByte();
+               CL_FindNonSolidLocation(pos, pos, 5);
                CL_Tei_PlasmaHit(pos, dir, count);
-               CL_AllocDlight (NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999);
+               CL_AllocDlight(NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999);
                break;
 
        default:
-               Host_Error ("CL_ParseTempEntity: bad type %d (hex %02X)", type, type);
+               Host_Error("CL_ParseTempEntity: bad type %d (hex %02X)", type, type);
        }
 }
 
@@ -1377,7 +1379,7 @@ CL_ParseServerMessage
 =====================
 */
 int parsingerror = false;
-void CL_ParseServerMessage (void)
+void CL_ParseServerMessage(void)
 {
        int                     cmd;
        int                     i, entitiesupdated;
@@ -1385,11 +1387,16 @@ void CL_ParseServerMessage (void)
        char            *cmdlogname[32], *temp;
        int                     cmdindex, cmdcount = 0;
 
+       if (cls.demorecording)
+               CL_WriteDemoMessage ();
+
+       cl.last_received_message = realtime;
+
 //
 // if recording demos, copy the message out
 //
        if (cl_shownet.integer == 1)
-               Con_Printf ("%i ",net_message.cursize);
+               Con_Printf ("%f %i\n", realtime, net_message.cursize);
        else if (cl_shownet.integer == 2)
                Con_Printf ("------------------\n");
 
@@ -1397,7 +1404,7 @@ void CL_ParseServerMessage (void)
 //
 // parse the message
 //
-       MSG_BeginReading ();
+       //MSG_BeginReading ();
 
        entitiesupdated = false;
 
@@ -1474,6 +1481,8 @@ void CL_ParseServerMessage (void)
                        break;
 
                case svc_nop:
+                       if (cls.signon < SIGNONS)
+                               Con_Printf("<-- server to client keepalive\n");
                        break;
 
                case svc_time:
@@ -1536,7 +1545,9 @@ void CL_ParseServerMessage (void)
                        break;
 
                case svc_setview:
-                       cl.viewentity = MSG_ReadShort ();
+                       cl.viewentity = (unsigned short)MSG_ReadShort ();
+                       if (cl.viewentity >= MAX_EDICTS)
+                               Host_Error("svc_setview >= MAX_EDICTS\n");
                        // LordHavoc: assume first setview recieved is the real player entity
                        if (!cl.playerentity)
                                cl.playerentity = cl.viewentity;
@@ -1736,6 +1747,7 @@ void CL_Parse_DumpPacket(void)
 void CL_Parse_Init(void)
 {
        // LordHavoc: added demo_nehahra cvar
+       cl_scores_mempool = Mem_AllocPool("client player info");
        Cvar_RegisterVariable (&demo_nehahra);
        if (gamemode == GAME_NEHAHRA)
                Cvar_SetValue("demo_nehahra", 1);