From 354208009f5868b5eb706c718f8bb066b77c37de Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Sat, 11 Nov 2023 20:47:50 +1000 Subject: [PATCH] cl_maxfps*: various adjustments Ensures minimum FPS of 10 even while idle to prevent weird issues (networking assumes at least 10). If you want to save more resources, hide the game window (disables rendering entirely) such as by using vid_minimize_on_focus_loss 1. Disables cl_maxfps_alwayssleep by default, on modern systems with accurate timers and higher FPS this has a significant impact. Allows cl_maxfps_alwayssleep to be used with cl_maxfps 0, this was requested some time ago. Switches from cl_maxidlefps to cl_maxfps when querying servers to give pings representative of what can be expected when playing on them. Cleans up the cl_maxfps* code. Signed-off-by: bones_was_here --- cl_main.c | 34 ++++++++++++++++++---------------- cl_screen.c | 4 ++-- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/cl_main.c b/cl_main.c index d1887cb1..6e385c81 100644 --- a/cl_main.c +++ b/cl_main.c @@ -104,7 +104,7 @@ cvar_t cl_minfps_qualityhysteresis = {CF_CLIENT | CF_ARCHIVE, "cl_minfps_quality cvar_t cl_minfps_qualitystepmax = {CF_CLIENT | CF_ARCHIVE, "cl_minfps_qualitystepmax", "0.1", "maximum quality change in a single frame"}; cvar_t cl_minfps_force = {CF_CLIENT, "cl_minfps_force", "0", "also apply quality reductions in timedemo/capturevideo"}; cvar_t cl_maxfps = {CF_CLIENT | CF_ARCHIVE, "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 = {CF_CLIENT | CF_ARCHIVE, "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_maxfps_alwayssleep = {CF_CLIENT | CF_ARCHIVE, "cl_maxfps_alwayssleep", "0", "gives up some processing time to other applications each frame, value in milliseconds, disabled if a timedemo is running"}; cvar_t cl_maxidlefps = {CF_CLIENT | CF_ARCHIVE, "cl_maxidlefps", "20", "maximum fps cap when the game is not the active window (makes cpu time available to other programs"}; cvar_t cl_areagrid_link_SOLID_NOT = {CF_CLIENT, "cl_areagrid_link_SOLID_NOT", "1", "set to 0 to prevent SOLID_NOT entities from being linked to the area grid, and unlink any that are already linked (in the code paths that would otherwise link them), for better performance"}; @@ -2802,13 +2802,14 @@ void CL_StartVideo(void) extern cvar_t host_framerate; extern cvar_t host_speeds; - +extern qbool serverlist_querystage; double CL_Frame (double time) { static double clframetime; static double cl_timer = 0; static double time1 = 0, time2 = 0, time3 = 0; int pass1, pass2, pass3; + float maxfps; CL_VM_PreventInformationLeaks(); @@ -2824,7 +2825,11 @@ double CL_Frame (double time) if (cl_timer > 0.1) cl_timer = 0.1; - if (cls.state != ca_dedicated && (cl_timer > 0 || cls.timedemo || ((vid_activewindow ? cl_maxfps : cl_maxidlefps).value < 1))) + // Run at full speed when querying servers, compared to waking up early to parse + // this is simpler and gives pings more representative of what can be expected when playing. + maxfps = (vid_activewindow || serverlist_querystage ? cl_maxfps : cl_maxidlefps).value; + + if (cls.state != ca_dedicated && (cl_timer > 0 || cls.timedemo || maxfps <= 0)) { R_TimeReport("---"); Collision_Cache_NewFrame(); @@ -2833,7 +2838,6 @@ double CL_Frame (double time) // decide the simulation time if (cls.capturevideo.active) { - //*** if (cls.capturevideo.realtime) clframetime = cl.realframetime = max(time, 1.0 / cls.capturevideo.framerate); else @@ -2842,21 +2846,19 @@ double CL_Frame (double time) cl.realframetime = max(time, clframetime); } } - else if (vid_activewindow && cl_maxfps.value >= 1 && !cls.timedemo) - -#else - if (vid_activewindow && cl_maxfps.value >= 1 && !cls.timedemo) + else #endif { - clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxfps.value); - // when running slow, we need to sleep to keep input responsive - if (cl_maxfps_alwayssleep.value > 0) - Sys_Sleep((int)bound(0, cl_maxfps_alwayssleep.value * 1000, 100000)); + if (maxfps <= 0 || cls.timedemo) + clframetime = cl.realframetime = cl_timer; + else + // networking assumes at least 10fps + clframetime = cl.realframetime = bound(cl_timer, 1 / maxfps, 0.1); + + // on some legacy systems, we need to sleep to keep input responsive + if (cl_maxfps_alwayssleep.value > 0 && !cls.timedemo) + Sys_Sleep((int)bound(1, cl_maxfps_alwayssleep.value * 1000, 50000)); } - 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; diff --git a/cl_screen.c b/cl_screen.c index 6435b576..6e9fbeb6 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -2231,11 +2231,11 @@ void CL_UpdateScreen(void) { if(!loadingscreenstack && !cls.connect_trying && (cls.state != ca_connected || cls.signon == SIGNONS)) SCR_EndLoadingPlaque(); - else if (scr_loadingscreen_maxfps.value) + else if (scr_loadingscreen_maxfps.value > 0) { static float lastupdate; float now = Sys_DirtyTime(); - if (now - lastupdate < 1.0f / scr_loadingscreen_maxfps.value) + if (now - lastupdate < min(1.0f / scr_loadingscreen_maxfps.value, 0.1)) return; lastupdate = now; } -- 2.39.2