ioquake / ioq3

The ioquake3 community effort to continue supporting/developing id's Quake III Arena
https://ioquake3.org/
GNU General Public License v2.0
2.39k stars 529 forks source link

Input sampled on wrong side of frame limiter #177

Closed wareya closed 7 years ago

wareya commented 8 years ago

Test:

Expected behavior:

Gotten behavior:

The actual issue, from what I can tell, is that the framerate limiter is part of the thinking code itself, and the input is outside of that. Either IN_Frame would have to be shoved inside of Com_Frame, out of logical scope, or Com_Frame would have to be split up to different functions between framerate limiting and "thinking".

Why is this an issue? Some mods, like CPMA, forcibly limit framerate online. CPMA limits framerate to 125. This forces the total average input latency from the game to always be 12ms. On a machine with infinite processing power, with input sampled on the right side of the framerate limiter, the added input latency from 125fps should be 4ms, or half of the frame time, for continuous inputs. The difference is the 8ms added by basically delaying inputs for up to 1/125th of a second due to sampling them on the wrong side of the frame limiter. The added lag decreases as the FPS cap approaches the com_maxfps 0 framerate, but it's always there.

input -> limiter -> think -> repeat

The limiter sleeps between taking inputs and using them.

limiter -> input -> think -> repeat

The limiter correctly extends the thinking time on the end instead of the beginning.

ensiform commented 8 years ago

I believe in frame is called in main() after the com frame function so it happens after com frame takes place all together.

wareya commented 8 years ago

Yes, it goes like thus:

while( 1 )
{
    IN_Frame( );
    Com_Frame( );
}

And Com_Frame runs the framelimiter before thinking, which puts things in the wrong order.

ensiform commented 8 years ago

That's really no different from how quake3.exe does it though.

wareya commented 8 years ago

That's right, vanilla quake 3 also has this problem.

ensiform commented 8 years ago

Is there any sort of fixes in cnq3 ?

wareya commented 8 years ago

cnq3 somehow fixes mouse button inputs without fixing mouse movement or keyboard press inputs.

youurayy commented 8 years ago

Blunt test code here: https://github.com/youurayy/ioq3/commit/6908038ff5d01c791f37160718aaa965883bf6f6

It's just IN_Frame() called again within Com_Frame() right after the limiter code, with a flag added to prevent it from triggering a second vid_restart or possibly a vid_restart in the wrong place. Only tested with bots so far.

Also tested at com_maxfps=1 and the lag is not there anymore, well played sir @wareya, well played.

I'm gaming at 60Hz with GTX 980, and to me the improvement is incredible, there's just no way back. To me, the mouse movement now seems "glued" to the mouse, it's like a different game.

I'm gaming with:

seta com_maxfps "60"
seta r_finish "1"
seta in_mouse "1"
seta cl_mouseAccel "2"
seta sensitivity "1.500000"
seta cl_mouseAccelOffset "5"
seta cl_mouseAccelStyle "1"
seta m_filter "0"
seta r_mode "-1"
seta r_fullscreen "1"
seta r_customwidth "1920"
seta r_customheight "1080"
seta com_hunkMegs "1024"
youurayy commented 8 years ago

Alternate name for this issue: "Halving input latency after 17 years of Quake 3."

zturtleman commented 7 years ago

Fixed in https://github.com/ioquake/ioq3/commit/ead54782d05b67e33ba5338fae081ea3c4af45af. Thanks.