]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_parse.c
default gl_lockarrays to 0, I'm not aware of any cards that actually benefit from it
[xonotic/darkplaces.git] / cl_parse.c
index e829ca6cbbbf47b960be1fa8762e0915ee115490..b33fd7e71b7fb84fc44b0bdf114670cc829f5973 100644 (file)
@@ -166,6 +166,7 @@ cvar_t cl_sound_ric3 = {0, "cl_sound_ric3", "weapons/ric3.wav", "sound to play w
 cvar_t cl_sound_r_exp3 = {0, "cl_sound_r_exp3", "weapons/r_exp3.wav", "sound to play during TE_EXPLOSION and related effects (empty cvar disables sound)"};
 cvar_t cl_serverextension_download = {0, "cl_serverextension_download", "0", "indicates whether the server supports the download command"};
 cvar_t cl_joinbeforedownloadsfinish = {0, "cl_joinbeforedownloadsfinish", "1", "if non-zero the game will begin after the map is loaded before other downloads finish"};
+cvar_t cl_nettimesyncmode = {0, "cl_nettimesyncmode", "2", "selects method of time synchronization in client with regard to server packets, values are: 0 = no sync, 1 = exact sync (reset timing each packet), 2 = loose sync (reset timing only if it is out of bounds), 3 = tight sync and bounding"};
 
 static qboolean QW_CL_CheckOrDownloadFile(const char *filename);
 static void QW_CL_RequestNextDownload(void);
@@ -2366,6 +2367,33 @@ void CL_ParseTempEntity(void)
        }
 }
 
+void CL_ParseTrailParticles(void)
+{
+       int entityindex;
+       int effectindex;
+       vec3_t start, end;
+       entityindex = (unsigned short)MSG_ReadShort();
+       if (entityindex >= MAX_EDICTS)
+               entityindex = 0;
+       if (entityindex >= cl.max_entities)
+               CL_ExpandEntities(entityindex);
+       effectindex = (unsigned short)MSG_ReadShort();
+       MSG_ReadVector(start, cls.protocol);
+       MSG_ReadVector(end, cls.protocol);
+       CL_ParticleEffect(effectindex, VectorDistance(start, end), start, end, vec3_origin, vec3_origin, entityindex > 0 ? cl.entities + entityindex : NULL, 0);
+}
+
+void CL_ParsePointParticles(void)
+{
+       int effectindex, count;
+       vec3_t origin, velocity;
+       effectindex = (unsigned short)MSG_ReadShort();
+       MSG_ReadVector(origin, cls.protocol);
+       MSG_ReadVector(velocity, cls.protocol);
+       count = (unsigned short)MSG_ReadShort();
+       CL_ParticleEffect(effectindex, count, origin, origin, velocity, velocity, NULL, 0);
+}
+
 // look for anything interesting like player IP addresses or ping reports
 qboolean CL_ExaminePrintString(const char *text)
 {
@@ -2495,6 +2523,38 @@ qboolean CL_ExaminePrintString(const char *text)
        return true;
 }
 
+static void CL_NetworkTimeReceived(double newtime)
+{
+       if (cl_nolerp.integer || cls.timedemo || (cl.islocalgame && !sv_fixedframeratesingleplayer.integer))
+               cl.mtime[1] = cl.mtime[0] = newtime;
+       else
+       {
+               cl.mtime[1] = max(cl.mtime[0], newtime - 0.1);
+               cl.mtime[0] = newtime;
+       }
+       if (cl_nettimesyncmode.integer == 3)
+               cl.time = cl.mtime[1];
+       if (cl_nettimesyncmode.integer == 2)
+       {
+               if (cl.time < cl.mtime[1] || cl.time > cl.mtime[0])
+                       cl.time = cl.mtime[1];
+       }
+       else if (cl_nettimesyncmode.integer == 1)
+               cl.time = cl.mtime[1];
+       // this packet probably contains a player entity update, so we will need
+       // to update the prediction
+       cl.movement_needupdate = true;
+       // this may get updated later in parsing by svc_clientdata
+       cl.onground = false;
+       // if true the cl.viewangles are interpolated from cl.mviewangles[]
+       // during this frame
+       // (makes spectating players much smoother and prevents mouse movement from turning)
+       cl.fixangle[1] = cl.fixangle[0];
+       cl.fixangle[0] = false;
+       if (!cls.demoplayback)
+               VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
+}
+
 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf("%3i:%s\n", msg_readcount-1, x);
 
 //[515]: csqc
@@ -2545,17 +2605,7 @@ void CL_ParseServerMessage(void)
 
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
        {
-               cl.mtime[1] = cl.mtime[0];
-               cl.mtime[0] = realtime; // qw has no clock
-               cl.time = bound(cl.mtime[1], cl.time, cl.mtime[0]);
-               cl.onground = false; // since there's no clientdata parsing, clear the onground flag here
-               // if true the cl.viewangles are interpolated from cl.mviewangles[]
-               // during this frame
-               // (makes spectating players much smoother and prevents mouse movement from turning)
-               cl.fixangle[1] = cl.fixangle[0];
-               cl.fixangle[0] = false;
-               if (!cls.demoplayback)
-                       VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
+               CL_NetworkTimeReceived(realtime); // qw has no clock
 
                // slightly kill qw player entities each frame
                for (i = 1;i < cl.maxclients;i++)
@@ -2966,17 +3016,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_time:
-                               cl.mtime[1] = cl.mtime[0];
-                               cl.mtime[0] = MSG_ReadFloat ();
-                               cl.time = bound(cl.mtime[1], cl.time, cl.mtime[0]);
-                               cl.movement_needupdate = true;
-                               // if true the cl.viewangles are interpolated from cl.mviewangles[]
-                               // during this frame
-                               // (makes spectating players much smoother and prevents mouse movement from turning)
-                               cl.fixangle[1] = cl.fixangle[0];
-                               cl.fixangle[0] = false;
-                               if (!cls.demoplayback)
-                                       VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
+                               CL_NetworkTimeReceived(MSG_ReadFloat());
                                break;
 
                        case svc_clientdata:
@@ -3300,6 +3340,12 @@ void CL_ParseServerMessage(void)
                        case svc_downloaddata:
                                CL_ParseDownload();
                                break;
+                       case svc_trailparticles:
+                               CL_ParseTrailParticles();
+                               break;
+                       case svc_pointparticles:
+                               CL_ParsePointParticles();
+                               break;
                        }
                }
        }
@@ -3348,6 +3394,8 @@ void CL_Parse_Init(void)
        // server extension cvars set by commands issued from the server during connect
        Cvar_RegisterVariable(&cl_serverextension_download);
 
+       Cvar_RegisterVariable(&cl_nettimesyncmode);
+
        Cmd_AddCommand("nextul", QW_CL_NextUpload, "sends next fragment of current upload buffer (screenshot for example)");
        Cmd_AddCommand("stopul", QW_CL_StopUpload, "aborts current upload (screenshot for example)");
        Cmd_AddCommand("skins", QW_CL_Skins_f, "downloads missing qw skins from server");