]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
rewrote timing code, now a much better and very different sleeping method, no longer...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 18 Apr 2006 05:49:22 +0000 (05:49 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 18 Apr 2006 05:49:22 +0000 (05:49 +0000)
changed timing code to have independent sleeping for client and server frames in a listen server
changed console execution to occur in sync with server frames if a server is running, this fixes frikbot loading of .way files
eliminated several host_* variables, replaced host_realframetime with cl.realframetime (which is how long since the last client frame)
removed the clamping of sys_ticrate to >= 0.1, so now sys_ticrate 0 is allowed (run as fast as possible), as well as silly values like 0.001
removed serverprofile cvar as it was not easy to preserve it in the rewritten timing
merged Host_FilterTime, Host_ServerFrame, Host_Frame, _Host_Frame into Host_Main (which also calls Host_Init), this eliminates some duplicate code in all the sys_ modules

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6300 d7cf8633-e32d-0410-b094-e92efae38249

19 files changed:
cl_demo.c
cl_input.c
cl_main.c
cl_parse.c
cl_screen.c
client.h
gl_rmain.c
host.c
netconn.c
quakedef.h
server.h
snd_main.c
sv_main.c
sys_linux.c
sys_sdl.c
sys_win.c
vid_shared.c
vid_wgl.c
view.c

index b3ac4e92c97c04381246c67d7a7d8620aed434b9..1e7773fb1d46b707780aa6c4c05c1a8b77af87df 100644 (file)
--- a/cl_demo.c
+++ b/cl_demo.c
@@ -164,11 +164,11 @@ void CL_ReadDemoMessage(void)
                                        cls.td_starttime = realtime;
                                if (host_framecount > cls.td_startframe + 2)
                                {
                                        cls.td_starttime = realtime;
                                if (host_framecount > cls.td_startframe + 2)
                                {
-                                       cls.td_minframetime = min(cls.td_minframetime, host_realframetime);
-                                       cls.td_maxframetime = max(cls.td_maxframetime, host_realframetime);
+                                       cls.td_minframetime = min(cls.td_minframetime, cl.realframetime);
+                                       cls.td_maxframetime = max(cls.td_maxframetime, cl.realframetime);
                                }
                                else
                                }
                                else
-                                       cls.td_minframetime = cls.td_maxframetime = host_realframetime;
+                                       cls.td_minframetime = cls.td_maxframetime = cl.realframetime;
                        }
                        else if (cl.time <= cl.mtime[0])
                        {
                        }
                        else if (cl.time <= cl.mtime[0])
                        {
index 5adcfb5bd8e74fb03a489201811598208aade2c6..cff67be27fa6e2e5e3e0c81ee7c4f2dbcd12b907 100644 (file)
@@ -304,9 +304,9 @@ void CL_AdjustAngles (void)
        float   up, down;
 
        if (in_speed.state & 1)
        float   up, down;
 
        if (in_speed.state & 1)
-               speed = host_realframetime * cl_anglespeedkey.value;
+               speed = cl.realframetime * cl_anglespeedkey.value;
        else
        else
-               speed = host_realframetime;
+               speed = cl.realframetime;
 
        if (!(in_strafe.state & 1))
        {
 
        if (!(in_strafe.state & 1))
        {
index 22acc719e757b6e6a0850b787265f085d88ca8d2..c8f058e8556ec27aeb0ba8560e6881d2a300facf 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1028,7 +1028,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                        tempmatrix.m[1][3] = trace.endpos[1];
                        tempmatrix.m[2][3] = trace.endpos[2];
                        CL_AllocDlight(NULL, &tempmatrix, 100, e->persistent.muzzleflash, e->persistent.muzzleflash, e->persistent.muzzleflash, 0, 0, 0, -1, true, 0, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
                        tempmatrix.m[1][3] = trace.endpos[1];
                        tempmatrix.m[2][3] = trace.endpos[2];
                        CL_AllocDlight(NULL, &tempmatrix, 100, e->persistent.muzzleflash, e->persistent.muzzleflash, e->persistent.muzzleflash, 0, 0, 0, -1, true, 0, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
-                       e->persistent.muzzleflash -= cl.frametime * 10;
+                       e->persistent.muzzleflash -= (cl.time - cl.oldtime) * 10;
                }
                // LordHavoc: if the model has no flags, don't check each
                if (e->render.model && e->render.model->flags && (!e->state_current.tagentity && !(e->render.flags & RENDER_VIEWMODEL)))
                }
                // LordHavoc: if the model has no flags, don't check each
                if (e->render.model && e->render.model->flags && (!e->state_current.tagentity && !(e->render.flags & RENDER_VIEWMODEL)))
@@ -1563,6 +1563,9 @@ int CL_ReadFromServer(void)
 
                // update view blend
                V_CalcViewBlend();
 
                // update view blend
                V_CalcViewBlend();
+
+               // update the r_refdef time again because cl.time may have changed
+               r_refdef.time = cl.time;
        }
 
        return 0;
        }
 
        return 0;
index 25340976d32605f8af2c832f8668ceee8717aa44..866a551ea8906c68952658e148467af740d0274e 100644 (file)
@@ -2104,7 +2104,7 @@ void CL_ParseServerMessage(void)
                cl.qw_num_nails = 0;
 
                // fade weapon view kick
                cl.qw_num_nails = 0;
 
                // fade weapon view kick
-               cl.qw_weaponkick = min(cl.qw_weaponkick + 10 * cl.frametime, 0);
+               cl.qw_weaponkick = min(cl.qw_weaponkick + 10 * (cl.time - cl.oldtime), 0);
 
                while (1)
                {
 
                while (1)
                {
index 5d9544bd8e8175f8740e0d55a815e4d777d925d8..99e29b968696dc70f7cb4c30e539974317b2f988 100644 (file)
@@ -157,7 +157,7 @@ void SCR_CheckDrawCenterString (void)
        if (scr_center_lines > scr_erase_lines)
                scr_erase_lines = scr_center_lines;
 
        if (scr_center_lines > scr_erase_lines)
                scr_erase_lines = scr_center_lines;
 
-       scr_centertime_off -= host_frametime;
+       scr_centertime_off -= cl.realframetime;
 
        // don't draw if this is a normal stats-screen intermission,
        // only if it is not an intermission, or a finale intermission
 
        // don't draw if this is a normal stats-screen intermission,
        // only if it is not an intermission, or a finale intermission
@@ -186,7 +186,7 @@ void SCR_DrawTurtle (void)
        if (!scr_showturtle.integer)
                return;
 
        if (!scr_showturtle.integer)
                return;
 
-       if (host_frametime < 0.1)
+       if (cl.realframetime < 0.1)
        {
                count = 0;
                return;
        {
                count = 0;
                return;
@@ -356,14 +356,13 @@ void SCR_SetUpToDrawConsole (void)
        {
                if (scr_con_current > conlines)
                {
        {
                if (scr_con_current > conlines)
                {
-                       scr_con_current -= scr_conspeed.value*host_realframetime;
+                       scr_con_current -= scr_conspeed.value*cl.realframetime;
                        if (scr_con_current < conlines)
                                scr_con_current = conlines;
                        if (scr_con_current < conlines)
                                scr_con_current = conlines;
-
                }
                else if (scr_con_current < conlines)
                {
                }
                else if (scr_con_current < conlines)
                {
-                       scr_con_current += scr_conspeed.value*host_realframetime;
+                       scr_con_current += scr_conspeed.value*cl.realframetime;
                        if (scr_con_current > conlines)
                                scr_con_current = conlines;
                }
                        if (scr_con_current > conlines)
                                scr_con_current = conlines;
                }
index 223d61a70487b93e01ca85b40ccb5774846d7ed2..0b0dc300fffa0414c984ad895629fb523266f27e 100644 (file)
--- a/client.h
+++ b/client.h
@@ -707,7 +707,10 @@ typedef struct client_state_s
        // clients view of time, time should be between mtime[0] and mtime[1] to
        // generate a lerp point for other data, oldtime is the previous frame's
        // value of time, frametime is the difference between time and oldtime
        // clients view of time, time should be between mtime[0] and mtime[1] to
        // generate a lerp point for other data, oldtime is the previous frame's
        // value of time, frametime is the difference between time and oldtime
-       double time, oldtime, frametime;
+       double time, oldtime;
+       // how long it has been since the previous client frame in real time
+       // (not game time, for that use cl.time - cl.oldtime)
+       double realframetime;
 
        // copy of realtime from last recieved message, for net trouble icon
        float last_received_message;
 
        // copy of realtime from last recieved message, for net trouble icon
        float last_received_message;
index 043a1a1a402e7689270a9332b5fa2eb8e9c3e8fd..4b68e50e6cca6ad9c64c3f297f4170dfab56fe1c 100644 (file)
@@ -863,17 +863,20 @@ void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture,
        }
        else
        {
        }
        else
        {
-               if (modellighting)
-                       permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
-               else if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && lightmaptexture)
+               if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
                {
                {
-                       if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
-                               permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
-                       else
+                       if (modellighting)
+                               permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
+                       else if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && lightmaptexture)
+                       {
+                               if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
+                                       permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
+                               else
+                                       permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
+                       }
+                       else if (r_glsl_deluxemapping.integer >= 2) // fake mode
                                permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
                }
                                permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
                }
-               else if (r_glsl_deluxemapping.integer >= 2) // fake mode
-                       permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
                if (texture->skin.glow)
                        permutation |= SHADERPERMUTATION_GLOW;
        }
                if (texture->skin.glow)
                        permutation |= SHADERPERMUTATION_GLOW;
        }
diff --git a/host.c b/host.c
index 85be9d5d34ec3e572b44a093efbffc7ea688fbbe..6defd6dd63fca685b35b3f02d52afbb7817b255f 100644 (file)
--- a/host.c
+++ b/host.c
@@ -43,13 +43,8 @@ int host_framecount = 0;
 // LordHavoc: set when quit is executed
 qboolean host_shuttingdown = false;
 
 // LordHavoc: set when quit is executed
 qboolean host_shuttingdown = false;
 
-double host_frametime;
-// LordHavoc: the real frametime, before slowmo and clamping are applied (used for console scrolling)
-double host_realframetime;
-// the real time, without any slowmo or clamping
+// the real time since application started, without any slowmo or clamping
 double realtime;
 double realtime;
-// realtime from previous frame
-double oldrealtime;
 
 // current client
 client_t *host_client;
 
 // current client
 client_t *host_client;
@@ -70,7 +65,6 @@ cvar_t sv_echobprint = {CVAR_SAVE, "sv_echobprint", "1", "prints gamecode bprint
 
 cvar_t sys_ticrate = {CVAR_SAVE, "sys_ticrate","0.05", "how long a server frame is in seconds, 0.05 is 20fps server rate, 0.1 is 10fps (can not be set higher than 0.1), 0 runs as many server frames as possible (makes games against bots a little smoother, overwhelms network players)"};
 cvar_t sv_fixedframeratesingleplayer = {0, "sv_fixedframeratesingleplayer", "0", "allows you to use server-style timing system in singleplayer (don't run faster than sys_ticrate)"};
 
 cvar_t sys_ticrate = {CVAR_SAVE, "sys_ticrate","0.05", "how long a server frame is in seconds, 0.05 is 20fps server rate, 0.1 is 10fps (can not be set higher than 0.1), 0 runs as many server frames as possible (makes games against bots a little smoother, overwhelms network players)"};
 cvar_t sv_fixedframeratesingleplayer = {0, "sv_fixedframeratesingleplayer", "0", "allows you to use server-style timing system in singleplayer (don't run faster than sys_ticrate)"};
-cvar_t serverprofile = {0, "serverprofile","0", "print some timings on server code"};
 
 cvar_t fraglimit = {CVAR_NOTIFY, "fraglimit","0", "ends level if this many frags is reached by any player"};
 cvar_t timelimit = {CVAR_NOTIFY, "timelimit","0", "ends level at this time (in minutes)"};
 
 cvar_t fraglimit = {CVAR_NOTIFY, "fraglimit","0", "ends level if this many frags is reached by any player"};
 cvar_t timelimit = {CVAR_NOTIFY, "timelimit","0", "ends level at this time (in minutes)"};
@@ -208,7 +202,7 @@ void Host_ServerOptions (void)
 
        svs.clients = (client_t *)Mem_Alloc(sv_mempool, sizeof(client_t) * svs.maxclients);
 
 
        svs.clients = (client_t *)Mem_Alloc(sv_mempool, sizeof(client_t) * svs.maxclients);
 
-       if (svs.maxclients > 1 && !deathmatch.integer)
+       if (svs.maxclients > 1 && !deathmatch.integer && !coop.integer)
                Cvar_SetValueQuick(&deathmatch, 1);
 }
 
                Cvar_SetValueQuick(&deathmatch, 1);
 }
 
@@ -218,7 +212,7 @@ Host_InitLocal
 ======================
 */
 void Host_SaveConfig_f(void);
 ======================
 */
 void Host_SaveConfig_f(void);
-void Host_InitLocal (void)
+static void Host_InitLocal (void)
 {
        Cmd_AddCommand("saveconfig", Host_SaveConfig_f, "save settings to config.cfg immediately (also automatic when quitting)");
 
 {
        Cmd_AddCommand("saveconfig", Host_SaveConfig_f, "save settings to config.cfg immediately (also automatic when quitting)");
 
@@ -231,7 +225,6 @@ void Host_InitLocal (void)
 
        Cvar_RegisterVariable (&sys_ticrate);
        Cvar_RegisterVariable (&sv_fixedframeratesingleplayer);
 
        Cvar_RegisterVariable (&sys_ticrate);
        Cvar_RegisterVariable (&sv_fixedframeratesingleplayer);
-       Cvar_RegisterVariable (&serverprofile);
 
        Cvar_RegisterVariable (&fraglimit);
        Cvar_RegisterVariable (&timelimit);
 
        Cvar_RegisterVariable (&fraglimit);
        Cvar_RegisterVariable (&timelimit);
@@ -521,90 +514,6 @@ void Host_ShutdownServer(void)
 
 //============================================================================
 
 
 //============================================================================
 
-/*
-===================
-Host_FilterTime
-
-Returns false if the time is too short to run a frame
-===================
-*/
-qboolean Host_FilterTime (double time)
-{
-       double timecap, timeleft;
-       realtime += time;
-
-       if (sys_ticrate.value < 0.00999 || sys_ticrate.value > 0.10001)
-               Cvar_SetValue("sys_ticrate", bound(0.01, sys_ticrate.value, 0.1));
-       if (slowmo.value < 0)
-               Cvar_SetValue("slowmo", 0);
-       if (host_framerate.value < 0.00001 && host_framerate.value != 0)
-               Cvar_SetValue("host_framerate", 0);
-       if (cl_maxfps.value < 1)
-               Cvar_SetValue("cl_maxfps", 1);
-
-       if (cls.timedemo)
-       {
-               // disable time effects during timedemo
-               cl.frametime = host_realframetime = host_frametime = realtime - oldrealtime;
-               oldrealtime = realtime;
-               return true;
-       }
-
-       // check if framerate is too high
-       // default to sys_ticrate (server framerate - presumably low) unless we
-       // have a good reason to run faster
-       timecap = host_framerate.value;
-       if (!timecap)
-               timecap = sys_ticrate.value;
-       if (cls.state != ca_dedicated)
-       {
-               if (cls.capturevideo_active)
-                       timecap = 1.0 / cls.capturevideo_framerate;
-               else if (vid_activewindow)
-                       timecap = 1.0 / cl_maxfps.value;
-       }
-
-       timeleft = timecap - (realtime - oldrealtime);
-       if (timeleft > 0)
-       {
-#if 0
-               if (timeleft * 1000 >= 10)
-                       Sys_Sleep(1);
-#else
-               int msleft;
-               // don't totally hog the CPU
-               // try to hit exactly a steady framerate by not sleeping the full amount
-               msleft = (int)floor(timeleft * 1000);
-               if (msleft >= 10)
-                       Sys_Sleep(msleft - 9);
-#endif
-               return false;
-       }
-
-       // LordHavoc: copy into host_realframetime as well
-       host_realframetime = host_frametime = realtime - oldrealtime;
-       oldrealtime = realtime;
-
-       if (cls.capturevideo_active && !cls.capturevideo_soundfile)
-               host_frametime = timecap;
-
-       // apply slowmo scaling
-       host_frametime *= slowmo.value;
-
-       // host_framerate overrides all else
-       if (host_framerate.value)
-               host_frametime = host_framerate.value;
-
-       // never run a frame longer than 1 second
-       if (host_frametime > 1)
-               host_frametime = 1;
-
-       cl.frametime = host_frametime;
-
-       return true;
-}
-
-
 /*
 ===================
 Host_GetConsoleCommands
 /*
 ===================
 Host_GetConsoleCommands
@@ -625,81 +534,6 @@ void Host_GetConsoleCommands (void)
        }
 }
 
        }
 }
 
-/*
-==================
-Host_ServerFrame
-
-==================
-*/
-void Host_ServerFrame (void)
-{
-       // execute one or more server frames, with an upper limit on how much
-       // execution time to spend on server frames to avoid freezing the game if
-       // the server is overloaded, this execution time limit means the game will
-       // slow down if the server is taking too long.
-       int framecount, framelimit = 100;
-       double advancetime, aborttime;
-       if (!sv.active)
-       {
-               sv.timer = 0;
-               return;
-       }
-       sv.timer += host_realframetime;
-
-       // run the world state
-       // don't allow simulation to run too fast or too slow or logic glitches can occur
-
-       // setup the VM frame
-       SV_VM_Begin();
-       // stop running server frames if the wall time reaches this value
-       aborttime = Sys_DoubleTime() + 0.1;
-       for (framecount = 0;framecount < framelimit && sv.timer > 0;framecount++)
-       {
-               if (sys_ticrate.value <= 0)
-                       advancetime = sv.timer;
-               else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer)
-                       advancetime = min(sv.timer, sys_ticrate.value);
-               else
-                       advancetime = sys_ticrate.value;
-               advancetime = min(advancetime, 0.1);
-               sv.timer -= advancetime;
-
-               // only advance time if not paused
-               // the game also pauses in singleplayer when menu or console is used
-               sv.frametime = advancetime * slowmo.value;
-               if (host_framerate.value)
-                       sv.frametime = host_framerate.value;
-               if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive)))
-                       sv.frametime = 0;
-
-
-               // move things around and think unless paused
-               if (sv.frametime)
-                       SV_Physics();
-
-               // send all messages to the clients
-               SV_SendClientMessages();
-
-               // clear the general datagram
-               SV_ClearDatagram();
-
-               // if this server frame took too long, break out of the loop
-               if (Sys_DoubleTime() >= aborttime)
-                       break;
-       }
-
-       // end the server VM frame
-       SV_VM_End();
-
-       // send an heartbeat if enough time has passed since the last one
-       NetConn_Heartbeat(0);
-
-       // if we fell behind too many frames just don't worry about it
-       if (sv.timer > 0)
-               sv.timer = 0;
-}
-
-
 /*
 ==================
 Host_Frame
 /*
 ==================
 Host_Frame
@@ -707,146 +541,270 @@ Host_Frame
 Runs all active servers
 ==================
 */
 Runs all active servers
 ==================
 */
-void _Host_Frame (float time)
+static void Host_Init(void);
+void Host_Main(void)
 {
 {
-       static double time1 = 0;
-       static double time2 = 0;
-       static double time3 = 0;
-       int pass1, pass2, pass3;
-
-       if (setjmp(host_abortframe))
-               return;                 // something bad happened, or the server disconnected
-
-       // decide the simulation time
-       if (!Host_FilterTime(time))
-               return;
-
-       // keep the random time dependent
-       rand();
-
-       cl.islocalgame = NetConn_IsLocalGame();
-
-       // get new key events
-       Sys_SendKeyEvents();
-
-       // Collect input into cmd
-       CL_Move();
-
-       // process console commands
-       Cbuf_Execute();
-
-       // if running the server locally, make intentions now
-       //if (cl.islocalgame)
-       //      CL_SendCmd();
+       double frameoldtime, framenewtime, frametime, cl_timer, sv_timer;
 
 
-//-------------------
-//
-// server operations
-//
-//-------------------
+       Host_Init();
 
 
-       // receive server packets now, which might contain rcon commands, which
-       // may change level or other such things we don't want to have happen in
-       // the middle of Host_Frame
-       NetConn_ServerFrame();
-
-       // check for commands typed to the host
-       Host_GetConsoleCommands();
-
-       if (sv.active)
-               Host_ServerFrame();
+       cl_timer = 0;
+       sv_timer = 0;
 
 
-//-------------------
-//
-// client operations
-//
-//-------------------
-
-       cl.oldtime = cl.time;
-       cl.time += cl.frametime;
-
-       NetConn_ClientFrame();
-
-       if (cls.state == ca_connected)
+       framenewtime = Sys_DoubleTime();
+       for (;;)
        {
        {
-               CL_ReadFromServer();
-               // if running the server remotely, send intentions now after
-               // the incoming messages have been read
-               //if (!cl.islocalgame)
-               //      CL_SendCmd();
-       }
-
-       //ui_update();
-
-       CL_VideoFrame();
+               static double time1 = 0;
+               static double time2 = 0;
+               static double time3 = 0;
+
+               frameoldtime = framenewtime;
+               framenewtime = Sys_DoubleTime();
+               frametime = framenewtime - frameoldtime;
+               realtime += frametime;
+
+               // if there is some time remaining from last frame, rest the timers
+               if (cl_timer >= 0)
+                       cl_timer = 0;
+               if (sv_timer >= 0)
+                       sv_timer = 0;
+
+               // accumulate the new frametime into the timers
+               cl_timer += frametime;
+               sv_timer += frametime;
+
+               if (setjmp(host_abortframe))
+                       continue;                       // something bad happened, or the server disconnected
+
+               if (slowmo.value < 0)
+                       Cvar_SetValue("slowmo", 0);
+               if (host_framerate.value < 0.00001 && host_framerate.value != 0)
+                       Cvar_SetValue("host_framerate", 0);
+               if (cl_maxfps.value < 1)
+                       Cvar_SetValue("cl_maxfps", 1);
+
+               // if the accumulators haven't become positive yet, keep waiting
+               if (!cls.timedemo && cl_timer <= 0 && sv_timer <= 0)
+               {
+                       double wait;
+                       int msleft;
+                       if (cls.state == ca_dedicated)
+                               wait = sv_timer;
+                       else if (!sv.active)
+                               wait = cl_timer;
+                       else
+                               wait = max(cl_timer, sv_timer);
+                       msleft = (int)floor(wait * -1000.0);
+                       if (msleft >= 1)
+                               Sys_Sleep(msleft);
+                       continue;
+               }
 
 
-       // update video
-       if (host_speeds.integer)
-               time1 = Sys_DoubleTime();
+               // keep the random time dependent
+               rand();
 
 
-       CL_UpdateScreen();
+               cl.islocalgame = NetConn_IsLocalGame();
 
 
-       if (host_speeds.integer)
-               time2 = Sys_DoubleTime();
+               // get new key events
+               Sys_SendKeyEvents();
 
 
-       // update audio
-       if(csqc_usecsqclistener)
-       {
-               S_Update(&csqc_listenermatrix);
-               csqc_usecsqclistener = false;
-       }
-       else
-               S_Update(&r_refdef.viewentitymatrix);
-
-       CDAudio_Update();
-
-       if (host_speeds.integer)
-       {
-               pass1 = (int)((time1 - time3)*1000000);
-               time3 = Sys_DoubleTime();
-               pass2 = (int)((time2 - time1)*1000000);
-               pass3 = (int)((time3 - time2)*1000000);
-               Con_Printf("%6ius total %6ius server %6ius gfx %6ius snd\n",
-                                       pass1+pass2+pass3, pass1, pass2, pass3);
-       }
-
-       host_framecount++;
-}
+               // when a server is running we only execute console commands on server frames
+               // (this mainly allows frikbot .way config files to work properly by staying in sync with the server qc)
+               // otherwise we execute them on all frames
+               if (sv_timer > 0 || !sv.active)
+               {
+                       // process console commands
+                       Cbuf_Execute();
+               }
 
 
-void Host_Frame (float time)
-{
-       double time1, time2;
-       static double timetotal;
-       static int timecount;
-       int i, c, m;
+               NetConn_UpdateSockets();
 
 
-       if (!serverprofile.integer)
-       {
-               _Host_Frame (time);
-               return;
-       }
+       //-------------------
+       //
+       // server operations
+       //
+       //-------------------
 
 
-       time1 = Sys_DoubleTime ();
-       _Host_Frame (time);
-       time2 = Sys_DoubleTime ();
+               if (sv_timer > 0)
+               {
+                       if (!sv.active)
+                       {
+                               // if there is no server, run server timing at 10fps
+                               sv_timer -= 0.1;
+                       }
+                       else
+                       {
+                               // execute one or more server frames, with an upper limit on how much
+                               // execution time to spend on server frames to avoid freezing the game if
+                               // the server is overloaded, this execution time limit means the game will
+                               // slow down if the server is taking too long.
+                               int framecount, framelimit = 1;
+                               double advancetime, aborttime = 0;
+
+                               // receive server packets now, which might contain rcon commands, which
+                               // may change level or other such things we don't want to have happen in
+                               // the middle of Host_Frame
+                               NetConn_ServerFrame();
+
+                               // check for commands typed to the host
+                               Host_GetConsoleCommands();
+
+                               // run the world state
+                               // don't allow simulation to run too fast or too slow or logic glitches can occur
+
+                               // stop running server frames if the wall time reaches this value
+                               if (sys_ticrate.value <= 0 || (cl.islocalgame && !sv_fixedframeratesingleplayer.integer))
+                                       advancetime = sv_timer;
+                               else
+                               {
+                                       advancetime = sys_ticrate.value;
+                                       // listen servers can run multiple server frames per client frame
+                                       if (cls.state == ca_connected)
+                                       {
+                                               framelimit = 10;
+                                               aborttime = Sys_DoubleTime() + 0.1;
+                                       }
+                               }
+                               advancetime = min(advancetime, 0.1);
+
+                               // only advance time if not paused
+                               // the game also pauses in singleplayer when menu or console is used
+                               sv.frametime = advancetime * slowmo.value;
+                               if (host_framerate.value)
+                                       sv.frametime = host_framerate.value;
+                               if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive)))
+                                       sv.frametime = 0;
+
+                               // setup the VM frame
+                               SV_VM_Begin();
+
+                               for (framecount = 0;framecount < framelimit && sv_timer > 0;framecount++)
+                               {
+                                       sv_timer -= advancetime;
+
+                                       // move things around and think unless paused
+                                       if (sv.frametime)
+                                               SV_Physics();
+
+                                       // send all messages to the clients
+                                       SV_SendClientMessages();
+
+                                       // clear the general datagram
+                                       SV_ClearDatagram();
+
+                                       // if this server frame took too long, break out of the loop
+                                       if (framelimit > 1 && Sys_DoubleTime() >= aborttime)
+                                               break;
+                               }
+
+                               // end the server VM frame
+                               SV_VM_End();
+
+                               // send an heartbeat if enough time has passed since the last one
+                               NetConn_Heartbeat(0);
+                       }
+               }
 
 
-       timetotal += time2 - time1;
-       timecount++;
+       //-------------------
+       //
+       // client operations
+       //
+       //-------------------
 
 
-       if (timecount < 1000)
-               return;
+               if (cl_timer > 0 || cls.timedemo)
+               {
+                       if (cls.state == ca_dedicated)
+                       {
+                               // if there is no client, run client timing at 10fps
+                               cl_timer -= 0.1;
+                               if (host_speeds.integer)
+                                       time1 = time2 = Sys_DoubleTime();
+                       }
+                       else
+                       {
+                               double frametime;
+                               frametime = cl.realframetime = min(cl_timer, 1);
+
+                               // decide the simulation time
+                               if (!cls.timedemo)
+                               {
+                                       if (cls.capturevideo_active && !cls.capturevideo_soundfile)
+                                       {
+                                               frametime = 1.0 / cls.capturevideo_framerate;
+                                               cl.realframetime = max(cl.realframetime, frametime);
+                                       }
+                                       else if (vid_activewindow)
+                                               frametime = cl.realframetime = max(cl.realframetime, 1.0 / cl_maxfps.value);
+                                       else
+                                               frametime = cl.realframetime = 0.1;
+
+                                       // deduct the frame time from the accumulator
+                                       cl_timer -= cl.realframetime;
+
+                                       // apply slowmo scaling
+                                       frametime *= slowmo.value;
+
+                                       // host_framerate overrides all else
+                                       if (host_framerate.value)
+                                               frametime = host_framerate.value;
+                               }
+
+                               cl.oldtime = cl.time;
+                               cl.time += frametime;
+
+                               // Collect input into cmd
+                               CL_Move();
+
+                               NetConn_ClientFrame();
+
+                               if (cls.state == ca_connected)
+                               {
+                                       CL_ReadFromServer();
+                                       // if running the server remotely, send intentions now after
+                                       // the incoming messages have been read
+                                       //if (!cl.islocalgame)
+                                       //      CL_SendCmd();
+                               }
+
+                               // update video
+                               if (host_speeds.integer)
+                                       time1 = Sys_DoubleTime();
+
+                               //ui_update();
+
+                               CL_VideoFrame();
+
+                               CL_UpdateScreen();
+
+                               if (host_speeds.integer)
+                                       time2 = Sys_DoubleTime();
+
+                               // update audio
+                               if(csqc_usecsqclistener)
+                               {
+                                       S_Update(&csqc_listenermatrix);
+                                       csqc_usecsqclistener = false;
+                               }
+                               else
+                                       S_Update(&r_refdef.viewentitymatrix);
+
+                               CDAudio_Update();
+                       }
+
+                       if (host_speeds.integer)
+                       {
+                               int pass1, pass2, pass3;
+                               pass1 = (int)((time1 - time3)*1000000);
+                               time3 = Sys_DoubleTime();
+                               pass2 = (int)((time2 - time1)*1000000);
+                               pass3 = (int)((time3 - time2)*1000000);
+                               Con_Printf("%6ius total %6ius server %6ius gfx %6ius snd\n",
+                                                       pass1+pass2+pass3, pass1, pass2, pass3);
+                       }
+               }
 
 
-       m = (int)(timetotal*1000/timecount);
-       timecount = 0;
-       timetotal = 0;
-       c = 0;
-       for (i=0 ; i<svs.maxclients ; i++)
-       {
-               if (svs.clients[i].active)
-                       c++;
+               host_framecount++;
        }
        }
-
-       Con_Printf("serverprofile: %2i clients %2i msec\n",  c,  m);
 }
 
 //============================================================================
 }
 
 //============================================================================
@@ -881,7 +839,7 @@ extern qboolean host_stuffcmdsrun;
 Host_Init
 ====================
 */
 Host_Init
 ====================
 */
-void Host_Init (void)
+static void Host_Init (void)
 {
        int i;
        const char* os;
 {
        int i;
        const char* os;
index 6567d89c4163d9666ba23600bf66f4a949225a6b..b921a2f19b69fa9ff65d4427cea1e83b39bd581e 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -1555,7 +1555,7 @@ void NetConn_QueryQueueFrame(void)
                return;
 
        // each time querycounter reaches 1.0 issue a query
                return;
 
        // each time querycounter reaches 1.0 issue a query
-       querycounter += host_realframetime * net_slist_queriespersecond.value;
+       querycounter += cl.realframetime * net_slist_queriespersecond.value;
        maxqueries = (int)querycounter;
        maxqueries = bound(0, maxqueries, net_slist_queriesperframe.integer);
        querycounter -= maxqueries;
        maxqueries = (int)querycounter;
        maxqueries = bound(0, maxqueries, net_slist_queriesperframe.integer);
        querycounter -= maxqueries;
@@ -2207,7 +2207,6 @@ void NetConn_ServerFrame(void)
 {
        int i, length;
        lhnetaddress_t peeraddress;
 {
        int i, length;
        lhnetaddress_t peeraddress;
-       NetConn_UpdateSockets();
        for (i = 0;i < sv_numsockets;i++)
                while (sv_sockets[i] && (length = NetConn_Read(sv_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0)
                        NetConn_ServerParsePacket(sv_sockets[i], readbuffer, length, &peeraddress);
        for (i = 0;i < sv_numsockets;i++)
                while (sv_sockets[i] && (length = NetConn_Read(sv_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0)
                        NetConn_ServerParsePacket(sv_sockets[i], readbuffer, length, &peeraddress);
index 66991037842231389ca26aaa156c56a10d22b24d..b6faccba15392357ef35342c630053831f729e70 100644 (file)
@@ -228,20 +228,16 @@ extern qboolean noclip_anglehack;
 extern char engineversion[128];
 extern cvar_t developer;
 
 extern char engineversion[128];
 extern cvar_t developer;
 
-extern double host_frametime;
-// the real frametime, before slowmo and clamping are applied (used for console scrolling)
-extern double host_realframetime;
 // incremented every frame, never reset
 extern int host_framecount;
 // not bounded in any way, changed at start of every frame, never reset
 extern double realtime;
 
 void Host_InitCommands(void);
 // incremented every frame, never reset
 extern int host_framecount;
 // not bounded in any way, changed at start of every frame, never reset
 extern double realtime;
 
 void Host_InitCommands(void);
-void Host_Init(void);
+void Host_Main(void);
 void Host_Shutdown(void);
 void Host_StartVideo(void);
 void Host_Error(const char *error, ...);
 void Host_Shutdown(void);
 void Host_StartVideo(void);
 void Host_Error(const char *error, ...);
-void Host_Frame(float time);
 void Host_Quit_f(void);
 void Host_ClientCommands(const char *fmt, ...);
 void Host_ShutdownServer(void);
 void Host_Quit_f(void);
 void Host_ClientCommands(const char *fmt, ...);
 void Host_ShutdownServer(void);
index aab7353205f216b3cade969399034b38fb9fe04e..73ca5a6c5aab05533176d3a5985db266c6541434 100644 (file)
--- a/server.h
+++ b/server.h
@@ -52,9 +52,6 @@ typedef struct server_s
        // one of the PROTOCOL_ values
        protocolversion_t protocol;
 
        // one of the PROTOCOL_ values
        protocolversion_t protocol;
 
-       // used for running multiple steps in one frame, etc
-       double timer;
-
        double time;
 
        double frametime;
        double time;
 
        double frametime;
index c523807a56b897867814aa889bdcf7b2d655263e..ae11f0ca69e2a041ff66de6b67de3db929b50e01 100644 (file)
@@ -852,13 +852,13 @@ void S_UpdateAmbientSounds (void)
                // FIXME: this rounds off to an int each frame, meaning there is little to no fade at extremely high framerates!
                if (chan->master_vol < vol)
                {
                // FIXME: this rounds off to an int each frame, meaning there is little to no fade at extremely high framerates!
                if (chan->master_vol < vol)
                {
-                       chan->master_vol += (int)(host_realframetime * ambient_fade.value);
+                       chan->master_vol += (int)(cl.realframetime * ambient_fade.value);
                        if (chan->master_vol > vol)
                                chan->master_vol = vol;
                }
                else if (chan->master_vol > vol)
                {
                        if (chan->master_vol > vol)
                                chan->master_vol = vol;
                }
                else if (chan->master_vol > vol)
                {
-                       chan->master_vol -= (int)(host_realframetime * ambient_fade.value);
+                       chan->master_vol -= (int)(cl.realframetime * ambient_fade.value);
                        if (chan->master_vol < vol)
                                chan->master_vol = vol;
                }
                        if (chan->master_vol < vol)
                                chan->master_vol = vol;
                }
index 7e2c391ba18b94fd9ca4aa460bd76199b9e22740..d8c7f70c9ba08acdbeebbaad97e78d9825a7257d 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -1843,7 +1843,7 @@ void SV_SpawnServer (const char *server)
 // run two frames to allow everything to settle
        for (i = 0;i < 2;i++)
        {
 // run two frames to allow everything to settle
        for (i = 0;i < 2;i++)
        {
-               sv.frametime = host_frametime = 0.1;
+               sv.frametime = 0.1;
                SV_Physics ();
        }
 
                SV_Physics ();
        }
 
index 6264af67cdf3130feef0c559d2d62ea33700c5d6..637cf29e245ae2447641096ed976c2559b4bf379 100644 (file)
@@ -240,8 +240,6 @@ void Sys_Init_Commands (void)
 
 int main (int argc, char **argv)
 {
 
 int main (int argc, char **argv)
 {
-       double frameoldtime, framenewtime;
-
        signal(SIGFPE, SIG_IGN);
 
        com_argc = argc;
        signal(SIGFPE, SIG_IGN);
 
        com_argc = argc;
@@ -251,17 +249,7 @@ int main (int argc, char **argv)
        fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
 #endif
 
        fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
 #endif
 
-       Host_Init();
-
-       frameoldtime = Sys_DoubleTime () - 0.1;
-       while (1)
-       {
-               // find time spent rendering last frame
-               framenewtime = Sys_DoubleTime ();
+       Host_Main();
 
 
-               Host_Frame (framenewtime - frameoldtime);
-
-               frameoldtime = framenewtime;
-       }
        return 0;
 }
        return 0;
 }
index 6bbbe382aebd46dbc600d81d45571b6858134590..9be28cd40cf80723df973fb8762e98ec85aebec9 100644 (file)
--- a/sys_sdl.c
+++ b/sys_sdl.c
@@ -199,8 +199,6 @@ void Sys_Init_Commands (void)
 
 int main (int argc, char *argv[])
 {
 
 int main (int argc, char *argv[])
 {
-       double frameoldtime, framenewtime;
-
        signal(SIGFPE, SIG_IGN);
 
        com_argc = argc;
        signal(SIGFPE, SIG_IGN);
 
        com_argc = argc;
@@ -210,17 +208,7 @@ int main (int argc, char *argv[])
        fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
 #endif
 
        fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
 #endif
 
-       Host_Init();
-
-       frameoldtime = Sys_DoubleTime () - 0.1;
-       while (1)
-       {
-               // find time spent rendering last frame
-               framenewtime = Sys_DoubleTime ();
+       Host_Main();
 
 
-               Host_Frame (framenewtime - frameoldtime);
-
-               frameoldtime = framenewtime;
-       }
        return 0;
 }
        return 0;
 }
index 69387dccadfc6515d9c3b67d426cc222014a2f06..27041f6d6a5d712080557fa0a711df6ff789e8c6 100644 (file)
--- a/sys_win.c
+++ b/sys_win.c
@@ -371,7 +371,6 @@ char                program_name[MAX_OSPATH];
 
 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 {
 
 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 {
-       double frameoldtime, framenewtime;
        MEMORYSTATUS lpBuffer;
 
        /* previous instances do not exist in Win32 */
        MEMORYSTATUS lpBuffer;
 
        /* previous instances do not exist in Win32 */
@@ -424,17 +423,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
                }
        }
 
                }
        }
 
-       Host_Init ();
-
-       frameoldtime = Sys_DoubleTime ();
-
-       /* main window message loop */
-       while (1)
-       {
-               framenewtime = Sys_DoubleTime ();
-               Host_Frame (framenewtime - frameoldtime);
-               frameoldtime = framenewtime;
-       }
+       Host_Main();
 
        /* return success of application */
        return true;
 
        /* return success of application */
        return true;
index d5f9299675132e4a74ae4045fa471da5701c552c..5a66af884d46d6e93994035c4c8c7715c3b48987 100644 (file)
@@ -803,13 +803,13 @@ void VID_UpdateGamma(qboolean force, int rampsize)
 
                        for (x = 0;x < 3;x++)
                        {
 
                        for (x = 0;x < 3;x++)
                        {
-                               nt[x] -= host_realframetime;
+                               nt[x] -= cl.realframetime;
                                if (nt[x] < 0)
                                {
                                        nd[x] = -nd[x];
                                        nt[x] += lhrandom(1, 8.2);
                                }
                                if (nt[x] < 0)
                                {
                                        nd[x] = -nd[x];
                                        nt[x] += lhrandom(1, 8.2);
                                }
-                               n[x] += nd[x] * host_realframetime;
+                               n[x] += nd[x] * cl.realframetime;
                                n[x] -= floor(n[x]);
                        }
 
                                n[x] -= floor(n[x]);
                        }
 
index 1e5a738271e703cd4ccf773f200cc3445ad9048d..faf8ff606a5890e25b9dc9abb5694fb4ed5d0809 100644 (file)
--- a/vid_wgl.c
+++ b/vid_wgl.c
@@ -1625,7 +1625,7 @@ static void IN_JoyMove (void)
        else
                speed = 1;
        // LordHavoc: viewzoom affects sensitivity for sniping
        else
                speed = 1;
        // LordHavoc: viewzoom affects sensitivity for sniping
-       aspeed = speed * host_realframetime * cl.viewzoom;
+       aspeed = speed * cl.realframetime * cl.viewzoom;
 
        // loop through the axes
        for (i = 0; i < JOY_MAX_AXES; i++)
 
        // loop through the axes
        for (i = 0; i < JOY_MAX_AXES; i++)
diff --git a/view.c b/view.c
index 7d690e9a987b1ef58cfa268e4e6ddb0231c7e5d5..9c3512286b4c11dd4f65f9043b781a8c3defe88e 100644 (file)
--- a/view.c
+++ b/view.c
@@ -155,7 +155,7 @@ void V_DriftPitch (void)
                if ( fabs(cl.cmd.forwardmove) < cl_forwardspeed.value)
                        cl.driftmove = 0;
                else
                if ( fabs(cl.cmd.forwardmove) < cl_forwardspeed.value)
                        cl.driftmove = 0;
                else
-                       cl.driftmove += cl.frametime;
+                       cl.driftmove += cl.realframetime;
 
                if ( cl.driftmove > v_centermove.value)
                {
 
                if ( cl.driftmove > v_centermove.value)
                {
@@ -172,8 +172,8 @@ void V_DriftPitch (void)
                return;
        }
 
                return;
        }
 
-       move = cl.frametime * cl.pitchvel;
-       cl.pitchvel += cl.frametime * v_centerspeed.value;
+       move = cl.realframetime * cl.pitchvel;
+       cl.pitchvel += cl.realframetime * v_centerspeed.value;
 
        if (delta > 0)
        {
 
        if (delta > 0)
        {
@@ -421,7 +421,7 @@ void V_CalcRefdef (void)
                                {
                                        viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll;
                                        viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch;
                                {
                                        viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll;
                                        viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch;
-                                       v_dmg_time -= cl.frametime;
+                                       v_dmg_time -= cl.realframetime;
                                }
                                // origin
                                VectorAdd(vieworg, cl.punchvector, vieworg);
                                }
                                // origin
                                VectorAdd(vieworg, cl.punchvector, vieworg);