Smooth unpause: reset client time delta and entity interpolation
On unpause, toggle SNAPFLAG_SERVERCOUNT and set SNAPFLAG_RESET_ENTITIES. In CL_ParseSnapshot, detect SERVERCOUNT toggle and hard-reset cl.serverTimeDelta instead of letting CL_AdjustTimeDelta slowly drift. During pause, the delta drifted because snapshots had frozen serverTime while cls.realtime advanced. Without the hard reset, it took 1-2 seconds of choppy interpolation to re-sync. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6e13c747ba
commit
490fcd9bde
2 changed files with 29 additions and 9 deletions
|
|
@ -288,17 +288,29 @@ void CL_ParseSnapshot( msg_t *msg ) {
|
||||||
cl.snapshots[oldMessageNum & PACKET_MASK].valid = qfalse;
|
cl.snapshots[oldMessageNum & PACKET_MASK].valid = qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy to the current good spot
|
{
|
||||||
cl.snap = newSnap;
|
int oldSnapFlags = cl.snap.snapFlags;
|
||||||
cl.snap.ping = 999;
|
|
||||||
// calculate ping time
|
// copy to the current good spot
|
||||||
for ( i = 0 ; i < PACKET_BACKUP ; i++ ) {
|
cl.snap = newSnap;
|
||||||
packetNum = ( clc.netchan.outgoingSequence - 1 - i ) & PACKET_MASK;
|
cl.snap.ping = 999;
|
||||||
if ( cl.snap.ps.commandTime >= cl.outPackets[ packetNum ].p_serverTime ) {
|
// calculate ping time
|
||||||
cl.snap.ping = cls.realtime - cl.outPackets[ packetNum ].p_realtime;
|
for ( i = 0 ; i < PACKET_BACKUP ; i++ ) {
|
||||||
break;
|
packetNum = ( clc.netchan.outgoingSequence - 1 - i ) & PACKET_MASK;
|
||||||
|
if ( cl.snap.ps.commandTime >= cl.outPackets[ packetNum ].p_serverTime ) {
|
||||||
|
cl.snap.ping = cls.realtime - cl.outPackets[ packetNum ].p_realtime;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if server count changed (map_restart or demo unpause), force-reset
|
||||||
|
// the time delta so the client doesn't slowly drift back to sync
|
||||||
|
if ( ( oldSnapFlags ^ newSnap.snapFlags ) & SNAPFLAG_SERVERCOUNT ) {
|
||||||
|
cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
|
||||||
|
cl.oldServerTime = cl.snap.serverTime;
|
||||||
|
cl.serverTime = cl.snap.serverTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the frame off in the backup array for later delta comparisons
|
// save the frame off in the backup array for later delta comparisons
|
||||||
cl.snapshots[cl.snap.messageNum & PACKET_MASK] = cl.snap;
|
cl.snapshots[cl.snap.messageNum & PACKET_MASK] = cl.snap;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -994,6 +994,14 @@ void SVD_Pause_f( void ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
demo.paused = !demo.paused;
|
demo.paused = !demo.paused;
|
||||||
|
if ( !demo.paused ) {
|
||||||
|
// resuming — reset entities so client doesn't interpolate
|
||||||
|
// from frozen positions to post-pause positions.
|
||||||
|
// also toggle SERVERCOUNT to reset client snapshot timing
|
||||||
|
// (drifted during pause from identical serverTimes).
|
||||||
|
svs.snapFlagServerBit |= SNAPFLAG_RESET_ENTITIES;
|
||||||
|
svs.snapFlagServerBit ^= SNAPFLAG_SERVERCOUNT;
|
||||||
|
}
|
||||||
Com_Printf( "Demo playback %s.\n", demo.paused ? "paused" : "resumed" );
|
Com_Printf( "Demo playback %s.\n", demo.paused ? "paused" : "resumed" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue