X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=host.c;h=aedb1f7fa84a30e166311c92832adfe1411a2f6f;hb=70ec04cceecaa9db01621adb7fc12ff9ec9cb422;hp=2f8fcfd3bb8fbb50d460fe41a29959c27c50d7b3;hpb=be135a8eb4c9f12f7f561671b7c7684b4fba5587;p=xonotic%2Fdarkplaces.git diff --git a/host.c b/host.c index 2f8fcfd3..aedb1f7f 100644 --- a/host.c +++ b/host.c @@ -52,17 +52,6 @@ cvar_t cl_maxphysicsframesperserverframe = {CVAR_CLIENT, "cl_maxphysicsframesper // shows time used by certain subsystems cvar_t host_speeds = {CVAR_CLIENT | CVAR_SERVER, "host_speeds","0", "reports how much time is used in server/graphics/sound"}; cvar_t host_maxwait = {CVAR_CLIENT | CVAR_SERVER, "host_maxwait","1000", "maximum sleep time requested from the operating system in millisecond. Larger sleeps will be done using multiple host_maxwait length sleeps. Lowering this value will increase CPU load, but may help working around problems with accuracy of sleep times."}; -cvar_t cl_minfps = {CVAR_CLIENT | CVAR_SAVE, "cl_minfps", "40", "minimum fps target - while the rendering performance is below this, it will drift toward lower quality"}; -cvar_t cl_minfps_fade = {CVAR_CLIENT | CVAR_SAVE, "cl_minfps_fade", "1", "how fast the quality adapts to varying framerate"}; -cvar_t cl_minfps_qualitymax = {CVAR_CLIENT | CVAR_SAVE, "cl_minfps_qualitymax", "1", "highest allowed drawdistance multiplier"}; -cvar_t cl_minfps_qualitymin = {CVAR_CLIENT | CVAR_SAVE, "cl_minfps_qualitymin", "0.25", "lowest allowed drawdistance multiplier"}; -cvar_t cl_minfps_qualitymultiply = {CVAR_CLIENT | CVAR_SAVE, "cl_minfps_qualitymultiply", "0.2", "multiplier for quality changes in quality change per second render time (1 assumes linearity of quality and render time)"}; -cvar_t cl_minfps_qualityhysteresis = {CVAR_CLIENT | CVAR_SAVE, "cl_minfps_qualityhysteresis", "0.05", "reduce all quality increments by this to reduce flickering"}; -cvar_t cl_minfps_qualitystepmax = {CVAR_CLIENT | CVAR_SAVE, "cl_minfps_qualitystepmax", "0.1", "maximum quality change in a single frame"}; -cvar_t cl_minfps_force = {CVAR_CLIENT, "cl_minfps_force", "0", "also apply quality reductions in timedemo/capturevideo"}; -cvar_t cl_maxfps = {CVAR_CLIENT | CVAR_SAVE, "cl_maxfps", "0", "maximum fps cap, 0 = unlimited, if game is running faster than this it will wait before running another frame (useful to make cpu time available to other programs)"}; -cvar_t cl_maxfps_alwayssleep = {CVAR_CLIENT, "cl_maxfps_alwayssleep","1", "gives up some processing time to other applications each frame, value in milliseconds, disabled if cl_maxfps is 0"}; -cvar_t cl_maxidlefps = {CVAR_CLIENT | CVAR_SAVE, "cl_maxidlefps", "20", "maximum fps cap when the game is not the active window (makes cpu time available to other programs"}; cvar_t developer = {CVAR_CLIENT | CVAR_SERVER | CVAR_SAVE, "developer","0", "shows debugging messages and information (recommended for all developers and level designers); the value -1 also suppresses buffering and logging these messages"}; cvar_t developer_extra = {CVAR_CLIENT | CVAR_SERVER, "developer_extra", "0", "prints additional debugging messages, often very verbose!"}; @@ -247,17 +236,6 @@ static void Host_InitLocal (void) Cvar_RegisterVariable (&host_framerate); Cvar_RegisterVariable (&host_speeds); Cvar_RegisterVariable (&host_maxwait); - Cvar_RegisterVariable (&cl_minfps); - Cvar_RegisterVariable (&cl_minfps_fade); - Cvar_RegisterVariable (&cl_minfps_qualitymax); - Cvar_RegisterVariable (&cl_minfps_qualitymin); - Cvar_RegisterVariable (&cl_minfps_qualitystepmax); - Cvar_RegisterVariable (&cl_minfps_qualityhysteresis); - Cvar_RegisterVariable (&cl_minfps_qualitymultiply); - Cvar_RegisterVariable (&cl_minfps_force); - Cvar_RegisterVariable (&cl_maxfps); - Cvar_RegisterVariable (&cl_maxfps_alwayssleep); - Cvar_RegisterVariable (&cl_maxidlefps); Cvar_RegisterVariable (&developer); Cvar_RegisterVariable (&developer_extra); @@ -397,13 +375,10 @@ Runs all active servers static void Host_Init(void); void Host_Main(void) { - double time1 = 0; - double time2 = 0; - double time3 = 0; double cl_timer = 0, sv_timer = 0; - double clframetime, time, oldtime, newtime; + double time, oldtime, newtime; double wait; - int pass1, pass2, pass3, i; + int i; char vabuf[1024]; qboolean playing; @@ -452,11 +427,6 @@ void Host_Main(void) Log_DestBuffer_Flush(); - // receive packets on each main loop iteration, as the main loop may - // be undersleeping due to select() detecting a new packet - if (sv.active && !svs.threaded) - NetConn_ServerFrame(); - Curl_Run(); // check for commands typed to the host @@ -475,42 +445,6 @@ void Host_Main(void) //Con_Printf("%6.0f %6.0f\n", cl_timer * 1000000.0, sv_timer * 1000000.0); - // if the accumulators haven't become positive yet, wait a while - if (cls.state == ca_dedicated) - wait = sv_timer * -1000000.0; - else if (!sv.active || svs.threaded) - wait = cl_timer * -1000000.0; - else - wait = max(cl_timer, sv_timer) * -1000000.0; - - if (!host.restless && wait >= 1) - { - double time0, delta; - - if(host_maxwait.value <= 0) - wait = min(wait, 1000000.0); - else - wait = min(wait, host_maxwait.value * 1000.0); - if(wait < 1) - wait = 1; // because we cast to int - - time0 = Sys_DirtyTime(); - if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded) { - NetConn_SleepMicroseconds((int)wait); - if (cls.state != ca_dedicated) - NetConn_ClientFrame(); // helps server browser get good ping values - // TODO can we do the same for ServerFrame? Probably not. - } - else - Sys_Sleep((int)wait); - delta = Sys_DirtyTime() - time0; - if (delta < 0 || delta >= 1800) - delta = 0; - host.sleeptime += delta; -// R_TimeReport("sleep"); - continue; - } - R_TimeReport("---"); //------------------- @@ -560,7 +494,7 @@ void Host_Main(void) svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = host.sleeptime = 0; } - if (sv.active && sv_timer > 0 && !svs.threaded) + if (sv.active && sv_timer > 0) { // 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 @@ -570,18 +504,16 @@ void Host_Main(void) double advancetime, aborttime = 0; float offset; prvm_prog_t *prog = SVVM_prog; - + // receive packets on each main loop iteration, as the main loop may + // be undersleeping due to select() detecting a new packet + if (sv.active && !svs.threaded) + NetConn_ServerFrame(); // 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) advancetime = sv_timer; - else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer) - { - // synchronize to the client frametime, but no less than 10ms and no more than 100ms - advancetime = bound(0.01, cl_timer, 0.1); - } else { advancetime = sys_ticrate.value; @@ -663,153 +595,46 @@ void Host_Main(void) // //------------------- - // limit the frametime steps to no more than 100ms each - if (cl_timer > 0.1) - cl_timer = 0.1; - - // get new key events - Key_EventQueue_Unblock(); - SndSys_SendKeyEvents(); - Sys_SendKeyEvents(); - - if (cls.state != ca_dedicated && (cl_timer > 0 || cls.timedemo || ((vid_activewindow ? cl_maxfps : cl_maxidlefps).value < 1))) - { - R_TimeReport("---"); - Collision_Cache_NewFrame(); - R_TimeReport("photoncache"); -#ifdef CONFIG_VIDEO_CAPTURE - // decide the simulation time - if (cls.capturevideo.active) - { - //*** - if (cls.capturevideo.realtime) - clframetime = cl.realframetime = max(cl_timer, 1.0 / cls.capturevideo.framerate); - else - { - clframetime = 1.0 / cls.capturevideo.framerate; - cl.realframetime = max(cl_timer, clframetime); - } - } - else if (vid_activewindow && cl_maxfps.value >= 1 && !cls.timedemo) + cl_timer = CL_Frame(cl_timer); + cl_timer += time; +#if MEMPARANOIA + Mem_CheckSentinelsGlobal(); #else - if (vid_activewindow && cl_maxfps.value >= 1 && !cls.timedemo) + if (developer_memorydebug.integer) + Mem_CheckSentinelsGlobal(); #endif - { - clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxfps.value); - // when running slow, we need to sleep to keep input responsive - wait = bound(0, cl_maxfps_alwayssleep.value * 1000, 100000); - if (wait > 0) - Sys_Sleep((int)wait); - } - else if (!vid_activewindow && cl_maxidlefps.value >= 1 && !cls.timedemo) - clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxidlefps.value); - else - clframetime = cl.realframetime = cl_timer; - // apply slowmo scaling - clframetime *= cl.movevars_timescale; - // scale playback speed of demos by slowmo cvar - if (cls.demoplayback) - { - clframetime *= host_timescale.value; - // if demo playback is paused, don't advance time at all - if (cls.demopaused) - clframetime = 0; - } - else - { - // host_framerate overrides all else - if (host_framerate.value) - clframetime = host_framerate.value; - - if (cl.paused || host.paused) - clframetime = 0; - } - - if (cls.timedemo) - clframetime = cl.realframetime = cl_timer; - - // deduct the frame time from the accumulator - cl_timer -= cl.realframetime; - - cl.oldtime = cl.time; - cl.time += clframetime; - - // update video - if (host_speeds.integer) - time1 = Sys_DirtyTime(); - R_TimeReport("pre-input"); - - // Collect input into cmd - CL_Input(); - - R_TimeReport("input"); - - // check for new packets - NetConn_ClientFrame(); - - // read a new frame from a demo if needed - CL_ReadDemoMessage(); - R_TimeReport("clientnetwork"); - - // now that packets have been read, send input to server - CL_SendMove(); - R_TimeReport("sendmove"); - - // update client world (interpolate entities, create trails, etc) - CL_UpdateWorld(); - R_TimeReport("lerpworld"); - - CL_Video_Frame(); - - R_TimeReport("client"); - - CL_UpdateScreen(); - R_TimeReport("render"); + // if the accumulators haven't become positive yet, wait a while + wait = max(cl_timer, sv_timer) * -1000000.0; - if (host_speeds.integer) - time2 = Sys_DirtyTime(); + if (!host.restless && wait >= 1) + { + double time0, delta; - // update audio - if(cl.csqc_usecsqclistener) - { - S_Update(&cl.csqc_listenermatrix); - cl.csqc_usecsqclistener = false; - } + if(host_maxwait.value <= 0) + wait = min(wait, 1000000.0); else - S_Update(&r_refdef.view.matrix); - - CDAudio_Update(); - R_TimeReport("audio"); - - // reset gathering of mouse input - in_mouse_x = in_mouse_y = 0; + wait = min(wait, host_maxwait.value * 1000.0); + if(wait < 1) + wait = 1; // because we cast to int - if (host_speeds.integer) - { - pass1 = (int)((time1 - time3)*1000000); - time3 = Sys_DirtyTime(); - 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); + time0 = Sys_DirtyTime(); + if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded) { + NetConn_SleepMicroseconds((int)wait); + if (cls.state != ca_dedicated) + NetConn_ClientFrame(); // helps server browser get good ping values + // TODO can we do the same for ServerFrame? Probably not. } + else + Sys_Sleep((int)wait); + delta = Sys_DirtyTime() - time0; + if (delta < 0 || delta >= 1800) + delta = 0; + host.sleeptime += delta; +// R_TimeReport("sleep"); } - // if there is some time remaining from this frame, reset the timer - if (cl_timer >= 0) - cl_timer = 0; - - cl_timer += time; - -#if MEMPARANOIA - Mem_CheckSentinelsGlobal(); -#else - if (developer_memorydebug.integer) - Mem_CheckSentinelsGlobal(); -#endif - host.framecount++; oldtime = newtime; } @@ -1121,58 +946,36 @@ void Host_Shutdown(void) } isdown = true; - // be quiet while shutting down - S_StopAllSounds(); + if(cls.state != ca_dedicated) + CL_Shutdown(); // end the server thread if (svs.threaded) SV_StopThread(); - // disconnect client from server if active - CL_Disconnect(); - // shut down local server if active SV_LockThreadMutex(); SV_Shutdown (); SV_UnlockThreadMutex(); -#ifdef CONFIG_MENU - // Shutdown menu - if(MR_Shutdown) - MR_Shutdown(); -#endif - // AK shutdown PRVM // AK hmm, no PRVM_Shutdown(); yet - CL_Video_Shutdown(); - Host_SaveConfig(); - CDAudio_Shutdown (); - S_Terminate (); Curl_Shutdown (); NetConn_Shutdown (); - if (cls.state != ca_dedicated) - { - R_Modules_Shutdown(); - VID_Shutdown(); - } - SV_StopThread(); TaskQueue_Shutdown(); Thread_Shutdown(); Cmd_Shutdown(); - Key_Shutdown(); - CL_Shutdown(); Sys_Shutdown(); Log_Close(); Crypto_Shutdown(); Host_UnlockSession(); - S_Shutdown(); Con_Shutdown(); Memory_Shutdown(); }