Introduce cl_maxfps -1 for "use optimal value based on render framerate"

(this is the default value of that cvar now)

In Qcommon_Frame(), if cl_async is 1, the packet framerate should
ideally be a fraction of the render framerate, and to avoid movement
glitches and such it should be between 45 and 90, ideally around 60.
With cl_maxfps set to -1, pfps now is set to such a value automatically.
This commit is contained in:
Daniel Gibson 2022-05-09 01:48:29 +02:00
parent 7cf1392765
commit 502ff345c3

View file

@ -342,7 +342,7 @@ Qcommon_Init(int argc, char **argv)
// cvars
cl_maxfps = Cvar_Get("cl_maxfps", "60", CVAR_ARCHIVE);
cl_maxfps = Cvar_Get("cl_maxfps", "-1", CVAR_ARCHIVE);
developer = Cvar_Get("developer", "0", 0);
fixedtime = Cvar_Get("fixedtime", "0", 0);
@ -542,10 +542,6 @@ Qcommon_Frame(int usec)
{
Cvar_SetValue("cl_maxfps", 250);
}
else if (cl_maxfps->value < 1)
{
Cvar_SetValue("cl_maxfps", 60);
}
// Calculate target and renderframerate.
if (R_IsVSyncActive())
@ -563,13 +559,13 @@ Qcommon_Frame(int usec)
}
else // target refresh rate, not vid_maxfps
{
// if vsync is active, we increase the target framerate a bit for two reasons
// 1. On Windows, GLimp_GetFrefreshRate() (or the SDL counterpart, or even
// the underlying WinAPI function) often returns a too small value,
// like 58 or 59 when it's really 59.95 and thus (as integer) should be 60
// 2. vsync will throttle us to refreshrate anyway, so there is no harm
// in starting the frame *a bit* earlier, instead of risking starting
// it too late
/* if vsync is active, we increase the target framerate a bit for two reasons
1. On Windows, GLimp_GetFrefreshRate() (or the SDL counterpart, or even
the underlying WinAPI function) often returns a too small value,
like 58 or 59 when it's really 59.95 and thus (as integer) should be 60
2. vsync will throttle us to refreshrate anyway, so there is no harm
in starting the frame *a bit* earlier, instead of risking starting
it too late */
rfps = refreshrate * 1.2f;
// we can't have more packet frames than render frames, so limit pfps to rfps
// but in this case use tolerance for comparison and assign rfps with tolerance
@ -583,6 +579,35 @@ Qcommon_Frame(int usec)
pfps = (cl_maxfps->value > rfps) ? rfps : cl_maxfps->value;
}
// cl_maxfps <= 0 means: automatically choose a packet framerate that should work
// well with the render framerate, which is the case if rfps is a multiple of pfps
if (cl_maxfps->value <= 0.0f && cl_async->value != 0.0f)
{
// packet framerates between about 45 and 90 should be ok,
// with other values the game (esp. movement/clipping) can become glitchy
// as pfps must be <= rfps, for rfps < 90 just use that as pfps
if (rfps < 90)
{
pfps = rfps;
}
else
{
/* we want an integer divider, so every div-th renderframe is a packetframe.
this formula gives nice dividers that keep pfps as close as possible
to 60 (which seems to be ideal):
- for < 150 rfps div will be 2, so pfps will be between 45 and ~75
=> exactly every second renderframe we also run a packetframe
- for < 210 rfps div will be 3, so pfps will be between 50 and ~70
=> exactly every third renderframe we also run a packetframe
- etc, the higher the rfps, the closer the pfps-range will be to 60
(and you probably get the very best results by running at a
render framerate that's a multiple of 60) */
// TODO: what happens if we can't reach rfps? probably a suboptimal pfps?
float div = round(rfps/60);
pfps = rfps/div;
}
}
// Calculate timings.
packetdelta += usec;
renderdelta += usec;