]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_parse.c
refactor timing, so that timing code is in sys_shared.c.
[xonotic/darkplaces.git] / cl_parse.c
index a9f82d2703d08f4d7c813a24082189f640df7312..57941d354f8285a350ff8f231d12ffd251800c33 100644 (file)
@@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "cl_collision.h"
 #include "csprogs.h"
 #include "libcurl.h"
+#include "utf8lib.h"
 
 char *svc_strings[128] =
 {
@@ -391,10 +392,12 @@ void CL_ParseEntityLump(char *entdata)
                        r_refdef.fog_start = 0;
                        r_refdef.fog_alpha = 1;
                        r_refdef.fog_end = 16384;
+                       r_refdef.fog_height = 1<<30;
+                       r_refdef.fog_fadedepth = 128;
 #if _MSC_VER >= 1400
 #define sscanf sscanf_s
 #endif
-                       sscanf(value, "%f %f %f %f %f %f %f", &r_refdef.fog_density, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue, &r_refdef.fog_alpha, &r_refdef.fog_start, &r_refdef.fog_end);
+                       sscanf(value, "%f %f %f %f %f %f %f %f %f", &r_refdef.fog_density, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue, &r_refdef.fog_alpha, &r_refdef.fog_start, &r_refdef.fog_end, &r_refdef.fog_height, &r_refdef.fog_fadedepth);
                }
                else if (!strcmp("fog_density", key))
                        r_refdef.fog_density = atof(value);
@@ -410,6 +413,10 @@ void CL_ParseEntityLump(char *entdata)
                        r_refdef.fog_start = atof(value);
                else if (!strcmp("fog_end", key))
                        r_refdef.fog_end = atof(value);
+               else if (!strcmp("fog_height", key))
+                       r_refdef.fog_height = atof(value);
+               else if (!strcmp("fog_fadedepth", key))
+                       r_refdef.fog_fadedepth = atof(value);
        }
 }
 
@@ -420,7 +427,7 @@ static const vec3_t defaultmaxs = {4096, 4096, 4096};
 static void CL_SetupWorldModel(void)
 {
        // update the world model
-       cl.entities[0].render.model = cl.worldmodel = cl.model_precache[1];
+       cl.entities[0].render.model = cl.worldmodel = CL_GetModelByIndex(1);
        CL_UpdateRenderEntity(&cl.entities[0].render);
 
        // set up csqc world for collision culling
@@ -428,6 +435,7 @@ static void CL_SetupWorldModel(void)
                World_SetSize(&cl.world, cl.worldmodel->name, cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
        else
                World_SetSize(&cl.world, "", defaultmins, defaultmaxs);
+       World_Start(&cl.world);
 
        // load or reload .loc file for team chat messages
        CL_Locs_Reload_f();
@@ -1081,13 +1089,18 @@ void CL_BeginDownloads(qboolean aborteddownload)
                        }
                        CL_KeepaliveMessage(true);
 
-                       if(cl.loadmodel_current == 1)
+                       // if running a local game, calling Mod_ForName is a completely wasted effort...
+                       if (sv.active)
+                               cl.model_precache[cl.loadmodel_current] = sv.models[cl.loadmodel_current];
+                       else
                        {
-                               // they'll be soon loaded, but make sure we apply freshly downloaded shaders from a curled pk3
-                               Mod_FreeQ3Shaders();
+                               if(cl.loadmodel_current == 1)
+                               {
+                                       // they'll be soon loaded, but make sure we apply freshly downloaded shaders from a curled pk3
+                                       Mod_FreeQ3Shaders();
+                               }
+                               cl.model_precache[cl.loadmodel_current] = Mod_ForName(cl.model_name[cl.loadmodel_current], false, false, cl.model_name[cl.loadmodel_current][0] == '*' ? cl.model_name[1] : NULL);
                        }
-
-                       cl.model_precache[cl.loadmodel_current] = Mod_ForName(cl.model_name[cl.loadmodel_current], false, false, cl.model_name[cl.loadmodel_current][0] == '*' ? cl.model_name[1] : NULL);
                        SCR_PopLoadingScreen(false);
                        if (cl.model_precache[cl.loadmodel_current] && cl.model_precache[cl.loadmodel_current]->Draw && cl.loadmodel_current == 1)
                        {
@@ -1373,7 +1386,7 @@ void CL_StopDownload(int size, int crc)
 void CL_ParseDownload(void)
 {
        int i, start, size;
-       unsigned char data[65536];
+       static unsigned char data[NET_MAXMESSAGE];
        start = MSG_ReadLong();
        size = (unsigned short)MSG_ReadShort();
 
@@ -1501,8 +1514,7 @@ An svc_signonnum has been received, perform a client side setup
 */
 static void CL_SignonReply (void)
 {
-       if (developer.integer >= 100)
-               Con_Printf("CL_SignonReply: %i\n", cls.signon);
+       Con_DPrintf("CL_SignonReply: %i\n", cls.signon);
 
        switch (cls.signon)
        {
@@ -1662,7 +1674,7 @@ void CL_ParseServerInfo (void)
                cl.movevars_airaccel_sideways_friction = 0;
 
                // seperate the printfs so the server message can have a color
-               Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n\2%s\n", str);
+               Con_Printf("\n\n<===================================>\n\n\2%s\n", str);
 
                // check memory integrity
                Mem_CheckSentinelsGlobal();
@@ -1707,7 +1719,7 @@ void CL_ParseServerInfo (void)
 
        // seperate the printfs so the server message can have a color
                if (cls.protocol != PROTOCOL_NEHAHRAMOVIE) // no messages when playing the Nehahra movie
-                       Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n\2%s\n", str);
+                       Con_Printf("\n<===================================>\n\n\2%s\n", str);
 
                // check memory integrity
                Mem_CheckSentinelsGlobal();
@@ -1839,7 +1851,7 @@ void CL_ValidateState(entity_state_t *s)
        if (!(s->flags & RENDER_COLORMAPPED) && s->colormap > cl.maxclients)
                Con_DPrintf("CL_ValidateState: colormap (%i) > cl.maxclients (%i)\n", s->colormap, cl.maxclients);
 
-       model = cl.model_precache[s->modelindex];
+       model = CL_GetModelByIndex(s->modelindex);
        if (model && model->type && s->frame >= model->numframes)
                Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\" (which has %i frames)\n", s->frame, model->name, model->numframes);
        if (model && model->type && s->skin > 0 && s->skin >= model->numskins && !(s->lightpflags & PFLAGS_FULLDYNAMIC))
@@ -1892,6 +1904,14 @@ void CL_MoveLerpEntityStates(entity_t *ent)
 
                // note that this case must do everything the following case does too
        }
+       else if ((ent->state_previous.effects & EF_RESTARTANIM_BIT) != (ent->state_current.effects & EF_RESTARTANIM_BIT))
+       {
+               ent->render.framegroupblend[1] = ent->render.framegroupblend[0];
+               ent->render.framegroupblend[1].lerp = 1;
+               ent->render.framegroupblend[0].frame = ent->state_current.frame;
+               ent->render.framegroupblend[0].start = cl.time;
+               ent->render.framegroupblend[0].lerp = 0;
+       }
        else if (DotProduct(odelta, odelta) > 1000*1000
                || (cl.fixangle[0] && !cl.fixangle[1])
                || (ent->state_previous.tagindex != ent->state_current.tagindex)
@@ -2124,7 +2144,7 @@ void CL_ParseStatic (int large)
        }
 
 // copy it to the current state
-       ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
+       ent->render.model = CL_GetModelByIndex(ent->state_baseline.modelindex);
        ent->render.framegroupblend[0].frame = ent->state_baseline.frame;
        ent->render.framegroupblend[0].lerp = 1;
        // make torchs play out of sync
@@ -2137,6 +2157,7 @@ void CL_ParseStatic (int large)
        //VectorCopy (ent->state_baseline.angles, ent->render.angles);
 
        Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, ent->state_baseline.origin[0], ent->state_baseline.origin[1], ent->state_baseline.origin[2], ent->state_baseline.angles[0], ent->state_baseline.angles[1], ent->state_baseline.angles[2], 1);
+       ent->render.allowdecals = true;
        CL_UpdateRenderEntity(&ent->render);
 }
 
@@ -2832,8 +2853,8 @@ static void CL_IPLog_Add(const char *address, const char *name, qboolean checkex
                return;
        if (!cl_iplog_loaded)
                CL_IPLog_Load();
-       if (developer.integer >= 100)
-               Con_Printf("CL_IPLog_Add(\"%s\", \"%s\", %i, %i);\n", address, name, checkexisting, addtofile);
+       if (developer_extra.integer)
+               Con_DPrintf("CL_IPLog_Add(\"%s\", \"%s\", %i, %i);\n", address, name, checkexisting, addtofile);
        // see if it already exists
        if (checkexisting)
        {
@@ -2841,8 +2862,8 @@ static void CL_IPLog_Add(const char *address, const char *name, qboolean checkex
                {
                        if (!strcmp(cl_iplog_items[i].address, address) && !strcmp(cl_iplog_items[i].name, name))
                        {
-                               if (developer.integer >= 100)
-                                       Con_Printf("... found existing \"%s\" \"%s\"\n", cl_iplog_items[i].address, cl_iplog_items[i].name);
+                               if (developer_extra.integer)
+                                       Con_DPrintf("... found existing \"%s\" \"%s\"\n", cl_iplog_items[i].address, cl_iplog_items[i].name);
                                return;
                        }
                }
@@ -2873,8 +2894,8 @@ static void CL_IPLog_Add(const char *address, const char *name, qboolean checkex
                // TODO: this ought to open the one in the userpath version of the base
                // gamedir, not the current gamedir
                Log_Printf(cl_iplog_name.string, "%s %s\n", address, name);
-               if (developer.integer >= 100)
-                       Con_Printf("CL_IPLog_Add: appending this line to %s: %s %s\n", cl_iplog_name.string, address, name);
+               if (developer_extra.integer)
+                       Con_DPrintf("CL_IPLog_Add: appending this line to %s: %s %s\n", cl_iplog_name.string, address, name);
        }
 }
 
@@ -2994,7 +3015,7 @@ qboolean CL_ExaminePrintString(const char *text)
        if (cl.parsingtextmode == CL_PARSETEXTMODE_PING)
        {
                // if anything goes wrong, we'll assume this is not a ping report
-               qboolean expected = cl.parsingtextexpectingpingforscores;
+               qboolean expected = cl.parsingtextexpectingpingforscores != 0;
                cl.parsingtextexpectingpingforscores = 0;
                cl.parsingtextmode = CL_PARSETEXTMODE_NONE;
                t = text;
@@ -3125,12 +3146,12 @@ static void CL_NetworkTimeReceived(double newtime)
        else if (cls.protocol != PROTOCOL_QUAKEWORLD)
        {
                cl.mtime[1] = max(cl.mtime[1], cl.mtime[0] - 0.1);
-               if (developer.integer >= 100 && vid_activewindow)
+               if (developer_extra.integer && vid_activewindow)
                {
                        if (cl.time < cl.mtime[1] - (cl.mtime[0] - cl.mtime[1]))
-                               Con_Printf("--- cl.time < cl.mtime[1] (%f < %f ... %f)\n", cl.time, cl.mtime[1], cl.mtime[0]);
+                               Con_DPrintf("--- cl.time < cl.mtime[1] (%f < %f ... %f)\n", cl.time, cl.mtime[1], cl.mtime[0]);
                        else if (cl.time > cl.mtime[0] + (cl.mtime[0] - cl.mtime[1]))
-                               Con_Printf("--- cl.time > cl.mtime[0] (%f > %f ... %f)\n", cl.time, cl.mtime[1], cl.mtime[0]);
+                               Con_DPrintf("--- cl.time > cl.mtime[0] (%f > %f ... %f)\n", cl.time, cl.mtime[1], cl.mtime[0]);
                }
                cl.time += (cl.mtime[1] - cl.time) * bound(0, cl_nettimesyncfactor.value, 1);
                timehigh = cl.mtime[1] + (cl.mtime[0] - cl.mtime[1]) * cl_nettimesyncboundtolerance.value;
@@ -3186,6 +3207,9 @@ static void CL_NetworkTimeReceived(double newtime)
                VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
        // update the csqc's server timestamps, critical for proper sync
        CSQC_UpdateNetworkTimes(cl.mtime[0], cl.mtime[1]);
+
+       if (cl.mtime[0] > cl.mtime[1])
+               World_Physics_Frame(&cl.world, cl.mtime[0] - cl.mtime[1], cl.movevars_gravity);
 }
 
 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf("%3i:%s(%i)\n", msg_readcount-1, x, cmd);
@@ -3213,6 +3237,7 @@ void CL_ParseServerMessage(void)
        char            *cmdlogname[32], *temp;
        int                     cmdindex, cmdcount = 0;
        qboolean        qwplayerupdatereceived;
+       qboolean        strip_pqc;
 
        // LordHavoc: moved demo message writing from before the packet parse to
        // after the packet parse so that CL_Stop_f can be called by cl_autodemo
@@ -3576,7 +3601,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_setpause:
-                               cl.paused = MSG_ReadByte ();
+                               cl.paused = MSG_ReadByte () != 0;
                                if (cl.paused)
                                        CDAudio_Pause ();
                                else
@@ -3605,6 +3630,7 @@ void CL_ParseServerMessage(void)
 
                        if (cmd == -1)
                        {
+                               R_TimeReport("END OF MESSAGE");
                                SHOWNET("END OF MESSAGE");
                                break;          // end of message
                        }
@@ -3709,7 +3735,42 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_stufftext:
-                               CL_VM_Parse_StuffCmd(MSG_ReadString ());        //[515]: csqc
+                               temp = MSG_ReadString();
+                               /* if(utf8_enable.integer)
+                               {
+                                       strip_pqc = true;
+                                       // we can safely strip and even
+                                       // interpret these in utf8 mode
+                               }
+                               else */ switch(cls.protocol)
+                               {
+                                       case PROTOCOL_QUAKE:
+                                       case PROTOCOL_QUAKEDP:
+                                               // maybe add other protocols if
+                                               // so desired, but not DP7
+                                               strip_pqc = true;
+                                               break;
+                                       case PROTOCOL_DARKPLACES7:
+                                       default:
+                                               // ProQuake does not support
+                                               // these protocols
+                                               strip_pqc = false;
+                                               break;
+                               }
+                               if(strip_pqc)
+                               {
+                                       // skip over ProQuake messages,
+                                       // TODO actually interpret them
+                                       // (they are sbar team score
+                                       // updates), see proquake cl_parse.c
+                                       if(*temp == 0x01)
+                                       {
+                                               ++temp;
+                                               while(*temp >= 0x01 && *temp <= 0x1F)
+                                                       ++temp;
+                                       }
+                               }
+                               CL_VM_Parse_StuffCmd(temp);     //[515]: csqc
                                break;
 
                        case svc_damage:
@@ -3867,7 +3928,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_setpause:
-                               cl.paused = MSG_ReadByte ();
+                               cl.paused = MSG_ReadByte () != 0;
                                if (cl.paused)
                                        CDAudio_Pause ();
                                else
@@ -4014,22 +4075,29 @@ void CL_ParseServerMessage(void)
                                CL_ParsePointParticles1();
                                break;
                        }
+                       R_TimeReport(svc_strings[cmd]);
                }
        }
 
        if (cls.signon == SIGNONS)
                CL_UpdateItemsAndWeapon();
+       R_TimeReport("UpdateItems");
 
        EntityFrameQuake_ISeeDeadEntities();
+       R_TimeReport("ISeeDeadEntities");
 
        CL_UpdateMoveVars();
+       R_TimeReport("UpdateMoveVars");
 
        parsingerror = false;
 
        // LordHavoc: this was at the start of the function before cl_autodemo was
        // implemented
        if (cls.demorecording)
+       {
                CL_WriteDemoMessage (&net_message);
+               R_TimeReport("WriteDemo");
+       }
 }
 
 void CL_Parse_DumpPacket(void)