diff --git a/code/client/cl_cgame.c b/code/client/cl_cgame.c index ccbe3c079a..0e5f3b6b1b 100644 --- a/code/client/cl_cgame.c +++ b/code/client/cl_cgame.c @@ -1162,7 +1162,37 @@ void CL_SetCGameTime( void ) { // cl_timeNudge is a user adjustable cvar that allows more // or less latency to be added in the interest of better // smoothness or better responsiveness. - cl.serverTime = cls.realtime + cl.serverTimeDelta - CL_TimeNudge(); + + if ( cl_localTime->integer && !clc.demoplaying ) { + // PLL: advance serverTime at constant local rate instead of + // jumping to network-derived value each frame. Eliminates + // rendering jitter from snapshot arrival variance. + static int lastRealtime = 0; + int frameDelta, targetTime, error; + + if ( lastRealtime == 0 || lastRealtime > cls.realtime ) + lastRealtime = cls.realtime; + + frameDelta = cls.realtime - lastRealtime; + lastRealtime = cls.realtime; + + targetTime = cls.realtime + cl.serverTimeDelta - CL_TimeNudge(); + error = targetTime - cl.serverTime; + + // soft rate adjustment: speed up/slow down max 2% to track server + if ( error > 2 ) + cl.serverTime += (int)( frameDelta * 1.02f ); + else if ( error < -2 ) + cl.serverTime += (int)( frameDelta * 0.98f ); + else + cl.serverTime += frameDelta; + + // hard clamp: never diverge more than 100ms from server + if ( error > 100 || error < -100 ) + cl.serverTime = targetTime; + } else { + cl.serverTime = cls.realtime + cl.serverTimeDelta - CL_TimeNudge(); + } // guarantee that time will never flow backwards, even if // serverTimeDelta made an adjustment or cl_timeNudge was changed diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 7ca80f2cf4..e5a87a6d7f 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -39,6 +39,7 @@ cvar_t *cl_timeout; cvar_t *cl_autoNudge; cvar_t *cl_timeNudge; cvar_t *cl_showTimeDelta; +cvar_t *cl_localTime; cvar_t *cl_shownet; cvar_t *cl_autoRecordDemo; @@ -3908,6 +3909,10 @@ void CL_Init( void ) { Cvar_CheckRange( cl_timeNudge, "-250", "250", CV_INTEGER ); Cvar_SetDescription( cl_timeNudge, "Allows more or less latency to be added in the interest of better smoothness or better responsiveness." ); + cl_localTime = Cvar_Get( "cl_localTime", "0", CVAR_ARCHIVE_ND ); + Cvar_CheckRange( cl_localTime, "0", "1", CV_INTEGER ); + Cvar_SetDescription( cl_localTime, "Local time mode: cl.serverTime advances at constant local rate instead of jumping to network-derived values.\n 0 - standard network-synced time (default)\n 1 - smooth local clock, eliminates rendering jitter from network\n" ); + cl_shownet = Cvar_Get ("cl_shownet", "0", CVAR_TEMP ); Cvar_SetDescription( cl_shownet, "Toggle the display of current network status." ); cl_showTimeDelta = Cvar_Get ("cl_showTimeDelta", "0", CVAR_TEMP ); diff --git a/code/client/client.h b/code/client/client.h index 48e980c9c2..c3fe86dad5 100644 --- a/code/client/client.h +++ b/code/client/client.h @@ -392,6 +392,7 @@ extern cvar_t *cl_shownet; extern cvar_t *cl_autoNudge; extern cvar_t *cl_timeNudge; extern cvar_t *cl_showTimeDelta; +extern cvar_t *cl_localTime; extern cvar_t *com_timedemo; extern cvar_t *cl_aviFrameRate;