]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_parse.c
cmd: fix stdin command ordering and related stuff
[xonotic/darkplaces.git] / cl_parse.c
index 98c415ab1cfff6b225a6b61abc119d5def358ffd..d9c8fb1775cae277a503b2e3cd6fe394411db29d 100644 (file)
@@ -35,7 +35,7 @@ const char *svc_strings[128] =
 {
        "svc_bad",
        "svc_nop",
-       "svc_disconnect",
+       "svc_disconnect",       // (DP8) [string] null terminated parting message
        "svc_updatestat",
        "svc_version",          // [int] server version
        "svc_setview",          // [short] entity number
@@ -184,6 +184,8 @@ cvar_t cl_readpicture_force = {CF_CLIENT, "cl_readpicture_force", "0", "when ena
 #define RIC_GUNSHOTQUAD        2
 cvar_t cl_sound_ric_gunshot = {CF_CLIENT, "cl_sound_ric_gunshot", "0", "specifies if and when the related cl_sound_ric and cl_sound_tink sounds apply to TE_GUNSHOT/TE_GUNSHOTQUAD, 0 = no sound, 1 = TE_GUNSHOT, 2 = TE_GUNSHOTQUAD, 3 = TE_GUNSHOT and TE_GUNSHOTQUAD"};
 cvar_t cl_sound_r_exp3 = {CF_CLIENT, "cl_sound_r_exp3", "weapons/r_exp3.wav", "sound to play during TE_EXPLOSION and related effects (empty cvar disables sound)"};
+cvar_t snd_cdautopause = {CF_CLIENT | CF_ARCHIVE, "snd_cdautopause", "1", "pause the CD track while the game is paused"};
+
 cvar_t cl_serverextension_download = {CF_CLIENT, "cl_serverextension_download", "0", "indicates whether the server supports the download command"};
 cvar_t cl_joinbeforedownloadsfinish = {CF_CLIENT | CF_ARCHIVE, "cl_joinbeforedownloadsfinish", "1", "if non-zero the game will begin after the map is loaded before other downloads finish"};
 cvar_t cl_nettimesyncfactor = {CF_CLIENT | CF_ARCHIVE, "cl_nettimesyncfactor", "0", "rate at which client time adapts to match server time, 1 = instantly, 0.125 = slowly, 0 = not at all (only applied in bound modes 0, 1, 2, 3)"};
@@ -197,6 +199,13 @@ static void QW_CL_NextUpload_f(cmd_state_t *cmd);
 //static qbool QW_CL_IsUploading(void);
 static void QW_CL_StopUpload_f(cmd_state_t *cmd);
 
+static inline void CL_SetSignonStage_WithMsg(int signon_stage)
+{
+       cls.signon = signon_stage;
+       dpsnprintf(cl_connect_status, sizeof(cl_connect_status), "Connect: signon stage %i of %i", cls.signon, SIGNONS);
+       Con_DPrint(cl_connect_status);
+}
+
 /*
 ==================
 CL_ParseStartSoundPacket
@@ -331,10 +340,7 @@ void CL_KeepaliveMessage (qbool readmessages)
                if(cls.state != ca_dedicated)
                {
                        if(countdownupdate <= 0) // check if time stepped backwards
-                       {
-                               SCR_UpdateLoadingScreenIfShown();
                                countdownupdate = 2;
-                       }
                }
        }
 
@@ -500,7 +506,7 @@ static void CL_SetupWorldModel(void)
        World_Start(&cl.world);
 
        // load or reload .loc file for team chat messages
-       CL_Locs_Reload_f(cmd_client);
+       CL_Locs_Reload_f(cmd_local);
 
        // make sure we send enough keepalives
        CL_KeepaliveMessage(false);
@@ -615,7 +621,7 @@ static void QW_CL_RequestNextDownload(void)
                // if we're still in signon stages, request the next one
                if (cls.signon != SIGNONS)
                {
-                       cls.signon = SIGNONS-1;
+                       CL_SetSignonStage_WithMsg(SIGNONS - 1);
                        // we'll go to SIGNONS when the first entity update is received
                        MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
                        MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "begin %i", cl.qw_servercount));
@@ -843,7 +849,7 @@ static void QW_CL_ParseModelList(void)
                return;
        }
 
-       cls.signon = 2;
+       CL_SetSignonStage_WithMsg(2);
        cls.qw_downloadnumber = 0;
        cls.qw_downloadtype = dl_model;
        QW_CL_RequestNextDownload();
@@ -879,7 +885,7 @@ static void QW_CL_ParseSoundList(void)
                return;
        }
 
-       cls.signon = 2;
+       CL_SetSignonStage_WithMsg(2);
        cls.qw_downloadnumber = 0;
        cls.qw_downloadtype = dl_sound;
        QW_CL_RequestNextDownload();
@@ -899,7 +905,7 @@ static void QW_CL_Changing_f(cmd_state_t *cmd)
 
        S_StopAllSounds();
        cl.intermission = 0;
-       cls.signon = 1; // not active anymore, but not disconnected
+       CL_SetSignonStage_WithMsg(1); // not active anymore, but not disconnected
        Con_Printf("\nChanging map...\n");
 }
 
@@ -940,7 +946,7 @@ void QW_CL_StartUpload(unsigned char *data, int size)
                return;
 
        // abort existing upload if in progress
-       QW_CL_StopUpload_f(cmd_client);
+       QW_CL_StopUpload_f(cmd_local);
 
        Con_DPrintf("Starting upload of %d bytes...\n", size);
 
@@ -949,7 +955,7 @@ void QW_CL_StartUpload(unsigned char *data, int size)
        cls.qw_uploadsize = size;
        cls.qw_uploadpos = 0;
 
-       QW_CL_NextUpload_f(cmd_client);
+       QW_CL_NextUpload_f(cmd_local);
 }
 
 #if 0
@@ -1448,7 +1454,7 @@ static void CL_StopDownload(int size, int crc)
                                Con_Printf("Downloaded \"%s\" (%i bytes, %i CRC)\n", cls.qw_downloadname, size, crc);
                                FS_WriteFile(cls.qw_downloadname, cls.qw_downloadmemory, cls.qw_downloadmemorycursize);
                                extension = FS_FileExtension(cls.qw_downloadname);
-                               if (!strcasecmp(extension, "pak") || !strcasecmp(extension, "pk3"))
+                               if (!strcasecmp(extension, "pak") || !strcasecmp(extension, "pk3") || !strcasecmp(extension, "dpk"))
                                        FS_Rescan();
                        }
                }
@@ -1603,8 +1609,10 @@ CL_SignonReply
 An svc_signonnum has been received, perform a client side setup
 =====================
 */
-static void CL_SignonReply (void)
+static void CL_SignonReply(int signon_stage)
 {
+       CL_SetSignonStage_WithMsg(signon_stage);
+
        Con_DPrintf("CL_SignonReply: %i\n", cls.signon);
 
        switch (cls.signon)
@@ -1616,16 +1624,13 @@ static void CL_SignonReply (void)
                        // (so that the server can see the player name while downloading)
                        CL_SendPlayerInfo();
 
-                       // execute cl_begindownloads next frame
-                       // (after any commands added by svc_stufftext have been executed)
-                       // when done with downloads the "prespawn" will be sent
-                       Cbuf_AddText(cmd_client, "\ncl_begindownloads\n");
-
                        //MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
                        //MSG_WriteString (&cls.netcon->message, "prespawn");
                }
-               else // playing a demo...  make sure loading occurs as soon as possible
-                       CL_BeginDownloads(false);
+               // execute cl_begindownloads next frame
+               // (after any commands added by svc_stufftext have been executed)
+               // when done with downloads the "prespawn" will be sent
+               Cbuf_AddText(cmd_local, "\ncl_begindownloads\n");
                break;
 
        case 2:
@@ -1688,8 +1693,11 @@ static void CL_ParseServerInfo (void)
        {
                SCR_BeginLoadingPlaque(false);
                S_StopAllSounds();
+               // prevent dlcache assets from the previous map from interfering with this one
+               FS_UnloadPacks_dlcache();
                // free q3 shaders so that any newly downloaded shaders will be active
-               Mod_FreeQ3Shaders();
+               // bones_was_here: we free the q3 shaders later in CL_SignonReply
+               //Mod_FreeQ3Shaders();
        }
 
        // check memory integrity
@@ -1785,7 +1793,7 @@ static void CL_ParseServerInfo (void)
                cl.loadfinished = false;
 
                cls.state = ca_connected;
-               cls.signon = 1;
+               CL_SetSignonStage_WithMsg(1);
 
                // note: on QW protocol we can't set up the gameworld until after
                // downloads finish...
@@ -1920,7 +1928,7 @@ static void CL_ParseServerInfo (void)
                        if (cls.demorecording)
                        {
                                // finish the previous level's demo file
-                               CL_Stop_f(cmd_client);
+                               CL_Stop_f(cmd_local);
                        }
 
                        // start a new demo file
@@ -3279,9 +3287,10 @@ extern cvar_t host_timescale;
 extern cvar_t cl_lerpexcess;
 static void CL_NetworkTimeReceived(double newtime)
 {
+       cl.opt_inputs_since_update = 0;
        cl.mtime[1] = cl.mtime[0];
        cl.mtime[0] = newtime;
-       if (cl_nolerp.integer || cls.timedemo || cl.mtime[1] == cl.mtime[0] || cls.signon < SIGNONS)
+       if (cls.timedemo || cl.mtime[1] == cl.mtime[0] || cls.signon < SIGNONS)
                cl.time = cl.mtime[1] = newtime;
        else if (cls.demoplayback)
        {
@@ -3293,7 +3302,7 @@ static void CL_NetworkTimeReceived(double newtime)
        }
        else if (cls.protocol != PROTOCOL_QUAKEWORLD)
        {
-               double timehigh;
+               double timehigh = 0; // hush compiler warning
                cl.mtime[1] = max(cl.mtime[1], cl.mtime[0] - 0.1);
 
                if (developer_extra.integer && vid_activewindow)
@@ -3304,27 +3313,32 @@ static void CL_NetworkTimeReceived(double newtime)
                                Con_DPrintf("--- cl.time > cl.mtime[0] (%f > %f ... %f)\n", cl.time, cl.mtime[1], cl.mtime[0]);
                }
 
-               if (cl_nettimesyncboundmode.integer < 4)
-               {
-                       // doesn't make sense for modes > 3
-                       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;
-               }
-
+selectmode:
                switch (cl_nettimesyncboundmode.integer)
                {
+               default:
+                       Cvar_SetQuick(&cl_nettimesyncboundmode, cl_nettimesyncboundmode.defstring);
+                       goto selectmode;
                case 1:
-                       cl.time = bound(cl.mtime[1], cl.time, cl.mtime[0]);
-                       break;
-
                case 2:
-                       if (cl.time < cl.mtime[1] || cl.time > timehigh)
-                               cl.time = cl.mtime[1];
-                       break;
-
                case 3:
-                       if ((cl.time < cl.mtime[1] && cl.oldtime < cl.mtime[1]) || (cl.time > timehigh && cl.oldtime > timehigh))
-                               cl.time = cl.mtime[1];
+                       // doesn't make sense for modes > 3
+                       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;
+                       switch (cl_nettimesyncboundmode.integer)
+                       {
+                       case 1:
+                               cl.time = bound(cl.mtime[1], cl.time, cl.mtime[0]);
+                               break;
+                       case 2:
+                               if (cl.time < cl.mtime[1] || cl.time > timehigh)
+                                       cl.time = cl.mtime[1];
+                               break;
+                       case 3:
+                               if ((cl.time < cl.mtime[1] && cl.oldtime < cl.mtime[1]) || (cl.time > timehigh && cl.oldtime > timehigh))
+                                       cl.time = cl.mtime[1];
+                               break;
+                       }
                        break;
 
                case 4:
@@ -3391,8 +3405,10 @@ static void CL_NetworkTimeReceived(double newtime)
        // update the csqc's server timestamps, critical for proper sync
        CSQC_UpdateNetworkTimes(cl.mtime[0], cl.mtime[1]);
 
+#ifdef USEODE
        if (cl.mtime[0] > cl.mtime[1])
                World_Physics_Frame(&cl.world, cl.mtime[0] - cl.mtime[1], cl.movevars_gravity);
+#endif
 
        // only lerp entities that also get an update in this frame, when lerp excess is used
        if(cl_lerpexcess.value > 0)
@@ -3529,11 +3545,8 @@ void CL_ParseServerMessage(void)
                                if (cls.demonum != -1)
                                        CL_NextDemo();
                                else
-                               {
-                                       Con_Printf("Server disconnected\n");
-                                       CL_Disconnect();
-                               }
-                               return;
+                                       CL_DisconnectEx(true, "Server disconnected");
+                               break;
 
                        case qw_svc_print:
                                i = MSG_ReadByte(&cl_message);
@@ -3695,7 +3708,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_sellscreen:
-                               Cmd_ExecuteString(cmd_client, "help", src_local, true);
+                               Cmd_ExecuteString(cmd_local, "help", src_local, true);
                                break;
 
                        case qw_svc_smallkick:
@@ -3766,20 +3779,14 @@ void CL_ParseServerMessage(void)
                                EntityFrameQW_CL_ReadFrame(false);
                                // first update is the final signon stage
                                if (cls.signon == SIGNONS - 1)
-                               {
-                                       cls.signon = SIGNONS;
-                                       CL_SignonReply ();
-                               }
+                                       CL_SignonReply(SIGNONS);
                                break;
 
                        case qw_svc_deltapacketentities:
                                EntityFrameQW_CL_ReadFrame(true);
                                // first update is the final signon stage
                                if (cls.signon == SIGNONS - 1)
-                               {
-                                       cls.signon = SIGNONS;
-                                       CL_SignonReply ();
-                               }
+                                       CL_SignonReply(SIGNONS);
                                break;
 
                        case qw_svc_maxspeed:
@@ -3794,9 +3801,9 @@ void CL_ParseServerMessage(void)
 
                        case qw_svc_setpause:
                                cl.paused = MSG_ReadByte(&cl_message) != 0;
-                               if (cl.paused)
+                               if (cl.paused && snd_cdautopause.integer)
                                        CDAudio_Pause ();
-                               else
+                               else if (bgmvolume.value > 0.0f)
                                        CDAudio_Resume ();
                                S_PauseGameSounds (cl.paused);
                                break;
@@ -3839,11 +3846,8 @@ void CL_ParseServerMessage(void)
                                cmdlogname[cmdindex] = temp;
                                SHOWNET("fast update");
                                if (cls.signon == SIGNONS - 1)
-                               {
                                        // first update is the final signon stage
-                                       cls.signon = SIGNONS;
-                                       CL_SignonReply ();
-                               }
+                                       CL_SignonReply(SIGNONS);
                                EntityFrameQuake_ReadEntity (cmd&127);
                                continue;
                        }
@@ -3910,12 +3914,9 @@ void CL_ParseServerMessage(void)
 
                        case svc_disconnect:
                                if (cls.demonum != -1)
-                                       CL_NextDemo ();
+                                       CL_NextDemo();
                                else
-                               {
-                                       Con_Printf ("Server disconnected\n");
-                                       CL_Disconnect ();
-                               }
+                                       CL_DisconnectEx(true, cls.protocol == PROTOCOL_DARKPLACES8 ? MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)) : "Server disconnected");
                                break;
 
                        case svc_print:
@@ -4124,9 +4125,9 @@ void CL_ParseServerMessage(void)
 
                        case svc_setpause:
                                cl.paused = MSG_ReadByte(&cl_message) != 0;
-                               if (cl.paused)
+                               if (cl.paused && snd_cdautopause.integer)
                                        CDAudio_Pause ();
-                               else
+                               else if (bgmvolume.value > 0.0f)
                                        CDAudio_Resume ();
                                S_PauseGameSounds (cl.paused);
                                break;
@@ -4137,8 +4138,7 @@ void CL_ParseServerMessage(void)
                                // reconnect somehow, so allow signon 1 even if at signon 1
                                if (i <= cls.signon && i != 1)
                                        Host_Error ("Received signon %i when at %i", i, cls.signon);
-                               cls.signon = i;
-                               CL_SignonReply ();
+                               CL_SignonReply(i);
                                break;
 
                        case svc_killedmonster:
@@ -4204,7 +4204,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_sellscreen:
-                               Cmd_ExecuteString(cmd_client, "help", src_local, true);
+                               Cmd_ExecuteString(cmd_local, "help", src_local, true);
                                break;
                        case svc_hidelmp:
                                if (gamemode == GAME_TENEBRAE)
@@ -4242,11 +4242,8 @@ void CL_ParseServerMessage(void)
                                break;
                        case svc_entities:
                                if (cls.signon == SIGNONS - 1)
-                               {
                                        // first update is the final signon stage
-                                       cls.signon = SIGNONS;
-                                       CL_SignonReply ();
-                               }
+                                       CL_SignonReply(SIGNONS);
                                if (cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3)
                                        EntityFrame_CL_ReadFrame();
                                else if (cls.protocol == PROTOCOL_DARKPLACES4)
@@ -4307,7 +4304,7 @@ void CL_Parse_DumpPacket(void)
 void CL_Parse_ErrorCleanUp(void)
 {
        CL_StopDownload(0, 0);
-       QW_CL_StopUpload_f(cmd_client);
+       QW_CL_StopUpload_f(cmd_local);
 }
 
 void CL_Parse_Init(void)
@@ -4328,6 +4325,7 @@ void CL_Parse_Init(void)
        Cvar_RegisterVariable(&cl_sound_ric3);
        Cvar_RegisterVariable(&cl_sound_ric_gunshot);
        Cvar_RegisterVariable(&cl_sound_r_exp3);
+       Cvar_RegisterVariable(&snd_cdautopause);
 
        Cvar_RegisterVariable(&cl_joinbeforedownloadsfinish);