Qcommon_Frame(): Try to get closer to desired packet framerate

.. by running a packet frame if the current renderframe is closer to
the time the packet frame *should* be run than the next renderframe
(presumably) will be.

This should also help when using cl_maxfps -1 on a slow system that
can't reach the desired rfps (vid_maxfps or display refresh rate).
Without this change, we might run int the problem described in the
following example:
Imagine having cl_async 1, cl_maxfps 100, no vsync and a system that
mostly only reaches about 60fps. So rfps is 100 and pfps is 50.
But then (without this change) running at 60fps means that only every
second renderframe is a packetframe, so the packetframerate
*effectively* is 30, which can cause movement/clipping/physics bugs
(for example when hugging some non-perpendicular walls, like the right
 wall with the window that leads to the last room in base1).
With this change the packet framerate would effectively be 60 (every
renderframe is also a packetframe), which is less buggy and also closer
to 50 than 30 is.
This commit is contained in:
Daniel Gibson 2022-05-09 20:27:41 +02:00
parent f95b5e7725
commit 413b44b4cd

View file

@ -602,7 +602,6 @@ Qcommon_Frame(int usec)
- 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;
}
@ -618,22 +617,23 @@ Qcommon_Frame(int usec)
{
if (cl_async->value)
{
// Network frames.
if (packetdelta < (1000000.0f / pfps))
{
packetframe = false;
}
// Render frames.
if (renderdelta < (1000000.0f / rfps))
{
renderframe = false;
}
if (!renderframe)
// Network frames.
float packettargetdelta = 1000000.0f / pfps;
// "packetdelta + renderdelta/2 >= packettargetdelta" if now we're
// closer to when we want to run the next packetframe than we'd
// (probably) be after the next render frame
// also, we only run packetframes together with renderframes,
// because we must have at least one render frame between two packet frames
// TODO: does it make sense to use the average renderdelta of the last X frames
// instead of just the last renderdelta?
if (!renderframe || packetdelta + renderdelta/2 < packettargetdelta)
{
// we must have at least one render frame between two packet frames
// => no packet frame without render frame
packetframe = false;
}
}