Added enhanced cl_clock_correction & misc

- Added vprof
- Fixed few issues again with cl_showhitboxes
- Fixed some shader compilation
- Fixed few issues with bitbuf
This commit is contained in:
Kamay Xutax 2024-07-23 03:05:29 +02:00
parent a2e8d9e9d4
commit 6691968046
22 changed files with 158 additions and 242 deletions

View file

@ -1032,8 +1032,10 @@ const char *SVC_VoiceData::ToString(void) const
bool NET_Tick::WriteToBuffer( bf_write &buffer )
{
VPROF( "NET_Tick::WriteToBuffer" );
buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
buffer.WriteLong( m_nTick );
buffer.WriteLong( m_nLagTick );
#if PROTOCOL_VERSION > 10
buffer.WriteUBitLong( clamp( (int)( NET_TICK_SCALEUP * m_flHostFrameTime ), 0, 65535 ), 16 );
buffer.WriteUBitLong( clamp( (int)( NET_TICK_SCALEUP * m_flHostFrameTimeStdDeviation ), 0, 65535 ), 16 );
@ -1046,6 +1048,7 @@ bool NET_Tick::ReadFromBuffer( bf_read &buffer )
VPROF( "NET_Tick::ReadFromBuffer" );
m_nTick = buffer.ReadLong();
m_nLagTick = buffer.ReadLong();
#if PROTOCOL_VERSION > 10
m_flHostFrameTime = (float)buffer.ReadUBitLong( 16 ) / NET_TICK_SCALEUP;
m_flHostFrameTimeStdDeviation = (float)buffer.ReadUBitLong( 16 ) / NET_TICK_SCALEUP;
@ -1055,7 +1058,7 @@ bool NET_Tick::ReadFromBuffer( bf_read &buffer )
const char *NET_Tick::ToString(void) const
{
Q_snprintf(s_text, sizeof(s_text), "%s: tick %i", GetName(), m_nTick );
Q_snprintf(s_text, sizeof(s_text), "%s: tick %i, lagtick %i", GetName(), m_nTick, m_nLagTick );
return s_text;
}

View file

@ -144,18 +144,21 @@ class NET_Tick : public CNetMessage
DECLARE_NET_MESSAGE( Tick );
NET_Tick()
{
m_bReliable = false;
{
m_bReliable = false;
m_nTick = 0;
m_nLagTick = 0;
#if PROTOCOL_VERSION > 10
m_flHostFrameTime = 0;
m_flHostFrameTimeStdDeviation = 0;
#endif
};
NET_Tick( int tick, float hostFrametime, float hostFrametime_stddeviation )
NET_Tick( int tick, int lagTick, float hostFrametime, float hostFrametime_stddeviation )
{
m_bReliable = false;
m_nTick = tick;
m_bReliable = false;
m_nTick = tick;
m_nLagTick = lagTick;
#if PROTOCOL_VERSION > 10
m_flHostFrameTime = hostFrametime;
m_flHostFrameTimeStdDeviation = hostFrametime_stddeviation;
@ -166,7 +169,8 @@ class NET_Tick : public CNetMessage
};
public:
int m_nTick;
int m_nTick;
int m_nLagTick;
#if PROTOCOL_VERSION > 10
float m_flHostFrameTime;
float m_flHostFrameTimeStdDeviation;

View file

@ -529,7 +529,7 @@ void CBaseClient::SpawnPlayer( void )
}
// Set client clock to match server's
NET_Tick tick( m_Server->GetTick(), host_frametime_unbounded, host_frametime_stddeviation );
NET_Tick tick( m_Server->GetTick(), m_nClientTick, host_frametime_unbounded, host_frametime_stddeviation );
SendNetMsg( tick, true );
// Spawned into server, not fully active, though
@ -717,7 +717,7 @@ bool CBaseClient::SendServerInfo( void )
// send first tick
m_nSignonTick = m_Server->m_nTickCount;
NET_Tick signonTick( m_nSignonTick, 0, 0 );
NET_Tick signonTick( m_nSignonTick, m_nClientTick, 0, 0 );
signonTick.WriteToBuffer( msg );
// write stringtable baselines
@ -794,6 +794,7 @@ void CBaseClient::ConnectionStart(INetChannel *chan)
bool CBaseClient::ProcessTick( NET_Tick *msg )
{
m_NetChannel->SetRemoteFramerate( msg->m_flHostFrameTime, msg->m_flHostFrameTimeStdDeviation );
m_nClientTick = msg->m_nLagTick;
return UpdateAcknowledgedFramecount( msg->m_nTick );
}
@ -1179,7 +1180,7 @@ write_again:
}
// send tick time
NET_Tick tickmsg( pFrame->tick_count, host_frametime_unbounded, host_frametime_stddeviation );
NET_Tick tickmsg( pFrame->tick_count, m_nClientTick, host_frametime_unbounded, host_frametime_stddeviation );
StartTrace( msg );

View file

@ -230,6 +230,7 @@ public:
int m_nSignonState; // connection state
int m_nDeltaTick; // -1 = no compression. This is where the server is creating the
// compressed info from.
int m_nClientTick;
int m_nStringTableAckTick; // Highest tick acked for string tables (usually m_nDeltaTick, except when it's -1)
int m_nSignonTick; // tick the client got his signon data
CSmartPtr<CFrameSnapshot,CRefCountAccessorLongName> m_pLastSnapshot; // last send snapshot

View file

@ -1010,8 +1010,9 @@ bool CBaseClientState::ProcessTick( NET_Tick *msg )
// Note: CClientState separates the client and server clock states and drifts
// the client's clock to match the server's, but right here, we keep the two clocks in sync.
SetClientTickCount( msg->m_nTick );
SetServerTickCount( msg->m_nTick );
SetClientTickCount( msg->m_nTick );
SetServerTickCount( msg->m_nTick );
m_ClockDriftMgr.m_nLaggedClientTick = msg->m_nLagTick;
if ( m_StringTableContainer )
{

View file

@ -518,19 +518,6 @@ void CL_ReadPackets ( bool bFinalTick )
// update client times/tick
cl.oldtickcount = cl.GetServerTickCount();
if ( !cl.IsPaused() )
{
cl.SetClientTickCount( cl.GetClientTickCount() + 1 );
// While clock correction is off, we have the old behavior of matching the client and server clocks.
if ( !CClockDriftMgr::IsClockCorrectionEnabled() )
cl.SetServerTickCount( cl.GetClientTickCount() );
g_ClientGlobalVariables.tickcount = cl.GetClientTickCount();
g_ClientGlobalVariables.curtime = cl.GetTime();
}
// 0 or tick_rate if simulating
g_ClientGlobalVariables.frametime = cl.GetFrameTime();
// read packets, if any in queue
if ( demoplayer->IsPlayingBack() && cl.m_NetChannel )
@ -574,6 +561,26 @@ void CL_ReadPackets ( bool bFinalTick )
}
#endif
// Moved after process socket so we can receive the lastest updates.
if ( !cl.IsPaused() )
{
// While clock correction is off, we have the old behavior of matching the client and server clocks.
if (!CClockDriftMgr::IsClockCorrectionEnabled())
{
cl.SetClientTickCount(cl.GetClientTickCount() + 1);
cl.SetServerTickCount(cl.GetClientTickCount());
}
else
{
cl.m_ClockDriftMgr.ApplyClockCorrection(bFinalTick);
}
g_ClientGlobalVariables.tickcount = cl.GetClientTickCount();
g_ClientGlobalVariables.curtime = cl.GetTime();
}
// 0 or tick_rate if simulating
g_ClientGlobalVariables.frametime = cl.GetFrameTime();
}
//-----------------------------------------------------------------------------
@ -2128,8 +2135,6 @@ void CL_SendMove( void )
void CL_Move(float accumulated_extra_samples, bool bFinalTick )
{
CL_ReadPackets(bFinalTick);
if ( !cl.IsConnected() )
return;
@ -2228,10 +2233,10 @@ void CL_Move(float accumulated_extra_samples, bool bFinalTick )
}
if ( cl.IsActive() )
{
NET_Tick mymsg( cl.m_nDeltaTick, host_frametime_unbounded, host_frametime_stddeviation );
{
NET_Tick mymsg( cl.m_nDeltaTick, cl.m_ClockDriftMgr.m_nCachedRealClientTick, host_frametime_unbounded, host_frametime_stddeviation );
cl.m_NetChannel->SendNetMsg( mymsg );
}
}
//COM_Log( "cl.log", "Sending command number %i(%i) to server\n", cl.m_NetChan->m_nOutSequenceNr, cl.m_NetChan->m_nOutSequenceNr & CL_UPDATE_MASK );

View file

@ -19,33 +19,6 @@ ConVar cl_clockdrift_max_ms_threadmode( "cl_clockdrift_max_ms_threadmode", "0",
ConVar cl_clock_showdebuginfo( "cl_clock_showdebuginfo", "0", FCVAR_CHEAT, "Show debugging info about the clock drift. ");
ConVar cl_clock_correction_force_server_tick( "cl_clock_correction_force_server_tick", "999", FCVAR_CHEAT, "Force clock correction to match the server tick + this offset (-999 disables it)." );
ConVar cl_clock_correction_adjustment_max_amount( "cl_clock_correction_adjustment_max_amount", "200", FCVAR_CHEAT,
"Sets the maximum number of milliseconds per second it is allowed to correct the client clock. "
"It will only correct this amount if the difference between the client and server clock is equal to or larger than cl_clock_correction_adjustment_max_offset." );
ConVar cl_clock_correction_adjustment_min_offset( "cl_clock_correction_adjustment_min_offset", "10", FCVAR_CHEAT,
"If the clock offset is less than this amount (in milliseconds), then no clock correction is applied." );
ConVar cl_clock_correction_adjustment_max_offset( "cl_clock_correction_adjustment_max_offset", "90", FCVAR_CHEAT,
"As the clock offset goes from cl_clock_correction_adjustment_min_offset to this value (in milliseconds), "
"it moves towards applying cl_clock_correction_adjustment_max_amount of adjustment. That way, the response "
"is small when the offset is small." );
// Given the offset (in milliseconds) of the client clock from the server clock,
// returns how much correction we'd like to apply per second (in seconds).
static float GetClockAdjustmentAmount( float flCurDiffInMS )
{
flCurDiffInMS = clamp( flCurDiffInMS, cl_clock_correction_adjustment_min_offset.GetFloat(), cl_clock_correction_adjustment_max_offset.GetFloat() );
float flReturnValue = RemapVal( flCurDiffInMS,
cl_clock_correction_adjustment_min_offset.GetFloat(), cl_clock_correction_adjustment_max_offset.GetFloat(),
0, cl_clock_correction_adjustment_max_amount.GetFloat() / 1000.0f );
return flReturnValue;
}
// -------------------------------------------------------------------------------------------------- /
@ -60,10 +33,12 @@ CClockDriftMgr::CClockDriftMgr()
void CClockDriftMgr::Clear()
{
m_nClientTick = 0;
m_nClientTick = 0;
m_nServerTick = 0;
m_iCurClockOffset = 0;
memset( m_ClockOffsets, 0, sizeof( m_ClockOffsets ) );
m_nOldServerTick = 0;
m_nLaggedClientTick = 0;
m_flServerHostFrametime = 0.0f;
m_flServerHostFrametimeStdDeviation = 0.0f;
}
@ -76,137 +51,76 @@ void CClockDriftMgr::Clear()
// NOTE: or decrementing the client tick after receiving pause
// NOTE: This is due to the fact that currently pause is applied at frame start on the server
// NOTE: and frame end on the client
void CClockDriftMgr::SetServerTick( int nTick )
void CClockDriftMgr::SetServerTick( int nTick, int nLaggedTick, float flServerHostFrametime, float flServerHostFrametimeStdDeviation )
{
#if !defined( SWDS )
m_nServerTick = nTick;
m_nServerTick = nTick;
m_nLaggedClientTick = nLaggedTick;
m_flServerHostFrametime = flServerHostFrametime;
m_flServerHostFrametimeStdDeviation = flServerHostFrametimeStdDeviation;
int nMaxDriftTicks = IsEngineThreaded() ?
TIME_TO_TICKS( (cl_clockdrift_max_ms_threadmode.GetFloat() / 1000.0) ) :
TIME_TO_TICKS( (cl_clockdrift_max_ms.GetFloat() / 1000.0) );
int clientTick = m_nClientTick + g_ClientGlobalVariables.simTicksThisFrame - 1;
int nMaxDriftTicks = IsEngineThreaded() ? TIME_TO_TICKS((cl_clockdrift_max_ms_threadmode.GetFloat() / 1000.0)) :
TIME_TO_TICKS((cl_clockdrift_max_ms.GetFloat() / 1000.0));
int clientTick = cl.GetClientTickCount() + g_ClientGlobalVariables.simTicksThisFrame - 1;
if ( cl_clock_correction_force_server_tick.GetInt() == 999 )
if (cl_clock_correction_force_server_tick.GetInt() == 999)
{
// If this is the first tick from the server, or if we get further than cl_clockdrift_max_ticks off, then
if (IsClockCorrectionEnabled())
{
// Take the difference between last sent client tick and server tick
// This will give how much we are shifted from the server perfectly
// If server fps is higher than tickrate.
m_nLagDiff = m_nServerTick - m_nLaggedClientTick;
}
// If this is the first tick from the server, or if we get further than cl_clockdrift_max_ticks off, then
// use the old behavior and slam the server's tick into the client tick.
if ( !IsClockCorrectionEnabled() ||
clientTick == 0 ||
abs(nTick - clientTick) > nMaxDriftTicks
)
{
cl.SetClientTickCount( nTick - (g_ClientGlobalVariables.simTicksThisFrame - 1) );
if ( cl.GetClientTickCount() < cl.oldtickcount )
{
cl.oldtickcount = cl.GetClientTickCount();
}
memset( m_ClockOffsets, 0, sizeof( m_ClockOffsets ) );
}
}
else if (!IsClockCorrectionEnabled() || clientTick == 0 || abs(nTick - clientTick) > nMaxDriftTicks)
{
m_nClientTick = (nTick - (g_ClientGlobalVariables.simTicksThisFrame - 1));
if (m_nClientTick < cl.oldtickcount)
{
cl.oldtickcount = m_nClientTick;
}
}
}
else
{
// Used for testing..
cl.SetClientTickCount( nTick + cl_clock_correction_force_server_tick.GetInt() );
m_nClientTick = (nTick + cl_clock_correction_force_server_tick.GetInt());
}
// adjust the clock offset by the clock with thread mode compensation
m_ClockOffsets[m_iCurClockOffset] = clientTick - m_nServerTick;
m_iCurClockOffset = (m_iCurClockOffset + 1) % NUM_CLOCKDRIFT_SAMPLES;
ShowDebugInfo();
m_nOldServerTick = m_nServerTick;
#endif // SWDS
}
float CClockDriftMgr::AdjustFrameTime( float inputFrameTime )
void CClockDriftMgr::ApplyClockCorrection(bool bFinalTick)
{
float flAdjustmentThisFrame = 0;
float flAdjustmentPerSec = 0;
if ( IsClockCorrectionEnabled()
#if !defined( _XBOX ) && !defined( SWDS )
&& !demoplayer->IsPlayingBack()
#endif
)
{
// Get the clock difference in seconds.
float flCurDiffInSeconds = GetCurrentClockDifference() * host_state.interval_per_tick;
float flCurDiffInMS = flCurDiffInSeconds * 1000.0f;
// Is the server ahead or behind us?
if ( flCurDiffInMS > cl_clock_correction_adjustment_min_offset.GetFloat() )
{
flAdjustmentPerSec = -GetClockAdjustmentAmount( flCurDiffInMS );
flAdjustmentThisFrame = inputFrameTime * flAdjustmentPerSec;
flAdjustmentThisFrame = max( flAdjustmentThisFrame, -flCurDiffInSeconds );
}
else if ( flCurDiffInMS < -cl_clock_correction_adjustment_min_offset.GetFloat() )
{
flAdjustmentPerSec = GetClockAdjustmentAmount( -flCurDiffInMS );
flAdjustmentThisFrame = inputFrameTime * flAdjustmentPerSec;
flAdjustmentThisFrame = min( flAdjustmentThisFrame, -flCurDiffInSeconds );
}
if ( IsEngineThreaded() )
{
flAdjustmentThisFrame = -flCurDiffInSeconds;
}
AdjustAverageDifferenceBy( flAdjustmentThisFrame );
}
ShowDebugInfo( flAdjustmentPerSec );
return inputFrameTime + flAdjustmentThisFrame;
if (bFinalTick)
{
m_nCachedRealClientTick++;
}
m_nClientTick = m_nCachedRealClientTick + m_nLagDiff + g_ClientGlobalVariables.simTicksThisFrame - 1;
}
float CClockDriftMgr::GetCurrentClockDifference() const
{
// Note: this could be optimized a little by updating it each time we add
// a sample (subtract the old value from the total and add the new one in).
float total = 0;
for ( int i=0; i < NUM_CLOCKDRIFT_SAMPLES; i++ )
total += m_ClockOffsets[i];
return total / NUM_CLOCKDRIFT_SAMPLES;
}
void CClockDriftMgr::ShowDebugInfo( float flAdjustment )
void CClockDriftMgr::ShowDebugInfo()
{
#if !defined( SWDS )
if ( !cl_clock_showdebuginfo.GetInt() )
return;
if ( IsClockCorrectionEnabled() )
{
int high=-999, low=999;
int exactDiff = cl.GetClientTickCount() - m_nServerTick;
for ( int i=0; i < NUM_CLOCKDRIFT_SAMPLES; i++ )
{
high = max( (float)high, m_ClockOffsets[i] );
low = min( (float)low, m_ClockOffsets[i] );
}
{
int clientTick = m_nClientTick + g_ClientGlobalVariables.simTicksThisFrame - 1;
Msg( "Clock drift: adjustment (per sec): %.2fms, avg: %.3f, lo: %d, hi: %d, ex: %d\n", flAdjustment*1000.0f, GetCurrentClockDifference(), low, high, exactDiff );
ConMsg( "Clock drift: client sim tick: %i, client tick: %i, server tick: %i, lagged tick: %i, cached server tick: %i\n", clientTick, m_nClientTick, m_nServerTick, m_nLaggedClientTick, m_nCachedRealClientTick);
}
else
{
Msg( "Clock drift disabled.\n" );
}
}
void CClockDriftMgr::AdjustAverageDifferenceBy( float flAmountInSeconds )
{
// Don't adjust the average if it's already tiny.
float c = GetCurrentClockDifference();
if ( c < 0.05f )
return;
float flAmountInTicks = flAmountInSeconds / host_state.interval_per_tick;
float factor = 1 + flAmountInTicks / c;
for ( int i=0; i < NUM_CLOCKDRIFT_SAMPLES; i++ )
m_ClockOffsets[i] *= factor;
Assert( fabs( GetCurrentClockDifference() - (c + flAmountInTicks) ) < 0.001f );
ConMsg( "Clock drift disabled.\n" );
}
#endif
}
extern float NET_GetFakeLag();

View file

@ -26,42 +26,24 @@ public:
// This is called each time a server packet comes in. It is used to correlate
// where the server is in time compared to us.
void SetServerTick( int iServerTick );
// Pass in the frametime you would use, and it will drift it towards the server clock.
float AdjustFrameTime( float inputFrameTime );
// Returns how many ticks ahead of the server the client is.
float GetCurrentClockDifference() const;
void SetServerTick( int iServerTick, int nLaggedTick, float flServerHostFrametime, float flServerHostFrametimeStdDeviation);
void ApplyClockCorrection(bool bFinalTick);
private:
void ShowDebugInfo( float flAdjustment );
// This scales the offsets so the average produced is equal to the
// current average + flAmount. This way, as we add corrections,
// we lower the average accordingly so we don't keep responding
// as much as we need to after we'd adjusted it a couple times.
void AdjustAverageDifferenceBy( float flAmountInSeconds );
void ShowDebugInfo();
private:
enum
{
// This controls how much it smoothes out the samples from the server.
NUM_CLOCKDRIFT_SAMPLES=16
};
// This holds how many ticks the client is ahead each time we get a server tick.
// We average these together to get our estimate of how far ahead we are.
float m_ClockOffsets[NUM_CLOCKDRIFT_SAMPLES];
int m_iCurClockOffset;
public:
int m_nLagDiff;
int m_nOldServerTick;
int m_nServerTick; // Last-received tick from the server.
int m_nClientTick; // The client's own tick counter (specifically, for interpolation during rendering).
// The server may be on a slightly different tick and the client will drift towards it.
int m_nClientTick;
int m_nCachedRealClientTick; // The client's own tick counter (specifically, for interpolation during rendering).
// The server may be on a slightly different tick and the client will drift towards it.
int m_nLaggedClientTick;
float m_flServerHostFrametime;
float m_flServerHostFrametimeStdDeviation;
};

View file

@ -473,7 +473,7 @@ void CHLTVClient::SendSnapshot( CClientFrame * pFrame )
// now create client snapshot packet
// send tick time
NET_Tick tickmsg( pFrame->tick_count, host_frametime_unbounded, host_frametime_stddeviation );
NET_Tick tickmsg( pFrame->tick_count, m_nClientTick, host_frametime_unbounded, host_frametime_stddeviation );
tickmsg.WriteToBuffer( msg );
// Update shared client/server string tables. Must be done before sending entities

View file

@ -292,7 +292,7 @@ void CHLTVClientState::SendPacket()
if ( IsActive() )
{
NET_Tick tick( m_nDeltaTick, host_frametime_unbounded, host_frametime_stddeviation );
NET_Tick tick( m_nDeltaTick, host_tickcount, host_frametime_unbounded, host_frametime_stddeviation );
m_NetChannel->SendNetMsg( tick );
}

View file

@ -96,7 +96,8 @@ void CHLTVDemoRecorder::StartRecording( const char *filename, bool bContinuously
m_nFrameCount = 0;
m_nStartTick = host_tickcount;
m_nStartTick = host_tickcount;
m_nClientTick = host_tickcount;
// Demo playback should read this as an incoming message.
// Write the client's realtime value out so we can synchronize the reads.
@ -173,7 +174,7 @@ void CHLTVDemoRecorder::WriteServerInfo()
serverinfo.WriteToBuffer( msg );
// send first tick
NET_Tick signonTick( m_nSignonTick, 0, 0 );
NET_Tick signonTick( m_nSignonTick, m_nClientTick, 0, 0 );
signonTick.WriteToBuffer( msg );
// write stringtable baselines
@ -345,7 +346,7 @@ void CHLTVDemoRecorder::WriteFrame( CHLTVFrame *pFrame )
//now send snapshot data
// send tick time
NET_Tick tickmsg( pFrame->tick_count, host_frametime_unbounded, host_frametime_stddeviation );
NET_Tick tickmsg( pFrame->tick_count, m_nClientTick, host_frametime_unbounded, host_frametime_stddeviation );
tickmsg.WriteToBuffer( msg );
@ -380,7 +381,8 @@ void CHLTVDemoRecorder::WriteFrame( CHLTVFrame *pFrame )
msg.WriteBits( data->GetBasePointer(), data->GetNumBitsWritten() );
// update delta tick just like fakeclients do
m_nDeltaTick = pFrame->tick_count;
m_nDeltaTick = pFrame->tick_count;
m_nClientTick = pFrame->tick_count;
// write packet to demo file
WriteMessages( dem_packet, msg );

View file

@ -60,7 +60,8 @@ public:
int m_nFrameCount;
float m_nStartTick;
int m_SequenceInfo;
int m_nDeltaTick;
int m_nDeltaTick;
int m_nClientTick;
int m_nSignonTick;
bf_write m_MessageData; // temp buffer for all network messages
};

View file

@ -1943,11 +1943,6 @@ void Host_AccumulateTime( float dt )
}
#endif
// Adjust the client clock very slightly to keep it in line with the server clock.
float adj = cl.GetClockDriftMgr().AdjustFrameTime( host_frametime ) - host_frametime;
host_frametime += adj;
host_frametime_unbounded += adj;
if ( g_pSoundServices ) // not present on linux server
g_pSoundServices->SetSoundFrametime(dt, host_frametime);
@ -3289,7 +3284,7 @@ void _Host_RunFrame (float time)
++host_tickcount;
++host_currentframetick;
#ifndef SWDS
g_ClientGlobalVariables.tickcount = cl.GetClientTickCount();
g_ClientGlobalVariables.tickcount = cl.GetClientTickCount();
// Make sure state is correct
CL_CheckClientState();
@ -3447,7 +3442,7 @@ void _Host_RunFrame (float time)
// initialize networking for dedicated server after commandline & autoexec.cfg have been parsed
if ( NET_IsDedicated() && !NET_IsMultiplayer() )
NET_SetMutiplayer( true );
g_ClientGlobalVariables.tickcount = cl.GetClientTickCount();
g_ClientGlobalVariables.tickcount = cl.GetClientTickCount();
// Make sure state is correct
CL_CheckClientState();

View file

@ -287,16 +287,16 @@ void CClientState::Disconnect( const char *pszReason, bool bShowMainMenu )
bool CClientState::ProcessTick( NET_Tick *msg )
{
int tick = msg->m_nTick;
int tick = msg->m_nTick;
m_NetChannel->SetRemoteFramerate( msg->m_flHostFrameTime, msg->m_flHostFrameTimeStdDeviation );
m_NetChannel->SetRemoteFramerate(msg->m_flHostFrameTime, msg->m_flHostFrameTimeStdDeviation);
m_ClockDriftMgr.SetServerTick( tick );
m_ClockDriftMgr.SetServerTick(tick, msg->m_nLagTick, msg->m_flHostFrameTime, msg->m_flHostFrameTimeStdDeviation);
// Remember this for GetLastTimeStamp().
m_flLastServerTickTime = tick * host_state.interval_per_tick;
// Remember this for GetLastTimeStamp().
m_flLastServerTickTime = tick * host_state.interval_per_tick;
// Use the server tick while reading network data (used for interpolation samples, etc).
// Use the server tick while reading network data (used for interpolation samples, etc).
g_ClientGlobalVariables.tickcount = tick;
g_ClientGlobalVariables.curtime = tick * host_state.interval_per_tick;
g_ClientGlobalVariables.frametime = (tick - oldtickcount) * host_state.interval_per_tick; // We used to call GetFrameTime() here, but 'insimulation' is always

View file

@ -567,6 +567,16 @@ DEFERRED_CON_COMMAND(vprof_reset_peaks, "Reset just the peak time in VProf profi
g_VProfCurrentProfile.ResetPeaks();
}
DEFERRED_CON_COMMAND(vprof_generate_report_full, "Generate a report to the console.")
{
g_VProfCurrentProfile.Pause();
ConsoleLogger consoleLog;
// This used to generate six different reports, which is expensive and hard to read. Default to
// two to save time and space.
g_VProfCurrentProfile.OutputReport( VPRT_FULL );
g_VProfCurrentProfile.Resume();
}
DEFERRED_CON_COMMAND(vprof_generate_report, "Generate a report to the console.")
{
g_VProfCurrentProfile.Pause();

View file

@ -2179,7 +2179,7 @@ void C_BasePlayer::Simulate()
{
auto player = UTIL_PlayerByIndex(i);
if (player && player != GetLocalPlayer())
if (player)
{
player->DrawServerHitboxes(60.0f, true);
}
@ -2191,7 +2191,7 @@ void C_BasePlayer::Simulate()
{
auto player = UTIL_PlayerByIndex(entityIndex);
if (player && player != GetLocalPlayer())
if (player)
{
player->DrawServerHitboxes(60.0f, true);
}

View file

@ -607,10 +607,11 @@ void CCSPlayer::PlayerRunCommand( CUserCmd *ucmd, IMoveHelper *moveHelper )
return;
// don't run commands in the future
if ( !IsEngineThreaded() &&
( ucmd->tick_count > (gpGlobals->tickcount + sv_max_usercmd_future_ticks.GetInt()) ) )
if (!IsEngineThreaded()
&& ((ucmd->tick_count > (gpGlobals->tickcount + sv_max_usercmd_future_ticks.GetInt()))
|| ( ucmd->tick_count < (gpGlobals->tickcount - sv_max_usercmd_future_ticks.GetInt()) )))
{
DevMsg( "Client cmd out of sync (delta %i).\n", ucmd->tick_count - gpGlobals->tickcount );
DevMsg( "Client cmd out of sync (delta: %i, client: %i != server: %i).\n", ucmd->tick_count - gpGlobals->tickcount, ucmd->tick_count, gpGlobals->tickcount);
return;
}

View file

@ -113,7 +113,7 @@ BEGIN_VS_SHADER( Cable_DX8,
}
// This is the light direction [0,1,0,0] * A * 0.5
float lightDir[4] = {0, A*0.5, 0, 0};
float lightDir[4] = {0, A*0.5f, 0, 0};
if( g_pHardwareConfig->GetDXSupportLevel() >= 90)
{
SetVertexShaderConstantGammaToLinear( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lightDir );

View file

@ -161,7 +161,7 @@ BEGIN_VS_SHADER( VortWarp_dx8,
pShaderAPI->SetPixelShaderConstant( 5, c5, 1 );
float curTime = pShaderAPI->CurrentTime();
float selfIllumScroll[4] = { .11f * curTime, .124 * curTime, 0.0f, 0.0f };
float selfIllumScroll[4] = { .11f * curTime, .124f * curTime, 0.0f, 0.0f };
pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, selfIllumScroll, 1 );
vortwarp_vs11_Dynamic_Index vshIndex;

View file

@ -61,6 +61,10 @@
#ifdef VPROF_ENABLED
#ifndef VPROF_LEVEL
#define VPROF_LEVEL 0
#endif
#define VPROF_VTUNE_GROUP
#define VPROF( name ) VPROF_(name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0)
@ -68,7 +72,7 @@
#define VPROF_( name, detail, group, bAssertAccounted, budgetFlags ) VPROF_##detail(name,group, bAssertAccounted, budgetFlags)
#define VPROF_BUDGET( name, group ) VPROF_BUDGET_FLAGS(name, group, BUDGETFLAG_OTHER)
#define VPROF_BUDGET_FLAGS( name, group, flags ) VPROF_(name, 0, group, false, flags)
#define VPROF_BUDGET_FLAGS( name, group, flags ) VPROF_(name, 1, group, false, flags)
#define VPROF_SCOPE_BEGIN( tag ) do { VPROF( tag )
#define VPROF_SCOPE_END() } while (0)
@ -152,10 +156,6 @@
//-------------------------------------
#ifndef VPROF_LEVEL
#define VPROF_LEVEL 0
#endif
//these macros exist to create VProf_<line number> variables. This is important because it avoids /analyze warnings about variable aliasing when VPROF's are nested within each other, and allows
//for multiple VPROF's to exist within the same scope. Three macros must be used to force the __LINE__ to be resolved prior to the token concatenation, but just ignore the _INTERNAL macros and use
//the VPROF_VAR_NAME

View file

@ -407,7 +407,7 @@ BITBUF_INLINE void bf_write::WriteUBitLong( unsigned int curData, int numbits, b
SetOverflowFlag();
CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() );
return;
}
}
int iCurBitMasked = m_iCurBit & 31;
int iDWord = m_iCurBit >> 5;
@ -417,16 +417,17 @@ BITBUF_INLINE void bf_write::WriteUBitLong( unsigned int curData, int numbits, b
Assert( (iDWord*4 + sizeof(int32)) <= (unsigned int)m_nDataBytes );
uint32 * RESTRICT pOut = &m_pData[iDWord];
// Rotate data into dword alignment
curData = (curData << iCurBitMasked) | (curData >> (32 - iCurBitMasked));
// Rotate data into dword alignment
uint32 dwordCurData = LoadLittleDWord(&curData, 0);
curData = (dwordCurData << iCurBitMasked) | (dwordCurData >> (32 - iCurBitMasked));
// Calculate bitmasks for first and second word
unsigned int temp = 1 << (numbits-1);
unsigned int mask1 = (temp*2-1) << iCurBitMasked;
unsigned int mask2 = (temp-1) >> (31 - iCurBitMasked);
unsigned int bitmask = numbits == 32 ? 0xFFFFFFFF : (1 << numbits) - 1;
unsigned int mask1 = bitmask << iCurBitMasked;
unsigned int mask2 = ((1 << (numbits - 1))-1) >> (31 - iCurBitMasked);
// Only look beyond current word if necessary (avoid access violation)
int i = mask2 & 1;
unsigned int i = mask2 & 1;
uint32 dword1 = LoadLittleDWord( pOut, 0 );
uint32 dword2 = LoadLittleDWord( pOut, i );
@ -784,12 +785,7 @@ BITBUF_INLINE unsigned int bf_read::ReadUBitLong( int numbits ) RESTRICT
unsigned int iWordOffset2 = iLastBit >> 5;
m_iCurBit += numbits;
#if __i386__
unsigned int bitmask = (2 << (numbits-1)) - 1;
#else
extern uint32 g_ExtraMasks[33];
unsigned int bitmask = g_ExtraMasks[numbits];
#endif
unsigned int bitmask = numbits == 32 ? 0xFFFFFFFF : (1 << numbits) - 1;
unsigned int dw1 = LoadLittleDWord( (uint32* RESTRICT)m_pData, iWordOffset1 ) >> iStartBit;
unsigned int dw2 = LoadLittleDWord( (uint32* RESTRICT)m_pData, iWordOffset2 ) << (32 - iStartBit);

View file

@ -280,7 +280,7 @@ def define_platform(conf):
])
conf.define('GIT_COMMIT_HASH', conf.env.GIT_VERSION)
conf.define('VPROF_LEVEL', 1)
def options(opt):
grp = opt.add_option_group('Common options')