Added smoothed interpolation amount & fixed fews issues with prediction

Added vprof too
This commit is contained in:
Kamay Xutax 2024-07-19 03:39:47 +02:00
parent 139f81eb02
commit 860bd3e883
6 changed files with 113 additions and 91 deletions

View file

@ -4,6 +4,7 @@
// //
//===========================================================================// //===========================================================================//
#include "dbg.h"
#include "tier0/fasttimer.h" #include "tier0/fasttimer.h"
#ifdef _WIN32 #ifdef _WIN32
@ -3139,7 +3140,68 @@ void _Host_RunFrame (float time)
g_pMDLCache->MarkFrame(); g_pMDLCache->MarkFrame();
} }
{ const auto CalcInterpolationAmount = [&]()
{
// TODO_ENHANCED:
// Notice_Enhanced:
// This check permits to fix interpolation problems on the
// local player that valve has been (fucking finally)
// caring about on counter-strike 2.
//
// To recall the original issue, the
// problem that Valve cared about is that interpolation
// had some problems with interpolating the local
// player because the screen would never in the first
// place match the tick "screen", because interpolation
// amount could never reach 0.0 or 1.0
//
// Valve solution was to introduce bugs with lag
// compensating the local player and made the game worse,
// introducing a new way for cheaters to cheat even more
// on their games.
// I'm joking, but you can clearly see the outcome anyway.
//
// My solution is to simply set interpolation amount
// to 0.0 when a tick arrives.
//
// So when we shoot, we get the frame we shot with an
// interpolation amount at 0.0, perfectly aligned to user
// commands which is ideal for us.
//
// Now includes smoothing.
static float flLastInterpolationAmountOnTick = 0.0f;
float flInterpAmount = cl.m_tickRemainder / host_state.interval_per_tick;
if (numticks > 0)
{
#ifdef false
printf("interpolation amount was %f, corrected to "
"fix interpolation issues.\n",
flInterpAmount);
#endif
g_ClientGlobalVariables.interpolation_amount = 0.0f;
flLastInterpolationAmountOnTick = flInterpAmount;
}
else
{
// Just subtract the amount, so we can get a smooth interpolation being on a correct amount.
g_ClientGlobalVariables.interpolation_amount = flInterpAmount - flLastInterpolationAmountOnTick;
ErrorIfNot(g_ClientGlobalVariables.interpolation_amount >= 0.0f,
("Interpolation amount was bigger than 1 (%f)\n", g_ClientGlobalVariables.interpolation_amount));
#ifdef false
printf("current interp: %f, old amount: %f, time: %f, frametime: %f, last remainder not interpolated: %f\n",
g_ClientGlobalVariables.interpolation_amount,
flInterpAmount,
time,
host_frametime,
flLastInterpolationAmountOnTick);
#endif
}
};
{
// Profile scope, protect from setjmp() problems // Profile scope, protect from setjmp() problems
VPROF( "_Host_RunFrame" ); VPROF( "_Host_RunFrame" );
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "_Host_RunFrame" ); tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "_Host_RunFrame" );
@ -3311,52 +3373,7 @@ void _Host_RunFrame (float time)
// This causes cl.gettime() to return the true clock being used for rendering (tickcount * rate + remainder) // This causes cl.gettime() to return the true clock being used for rendering (tickcount * rate + remainder)
Host_SetClientInSimulation(false); Host_SetClientInSimulation(false);
// TODO_ENHANCED: CalcInterpolationAmount();
// Notice_Enhanced:
// This check permits to fix interpolation problems on the
// local player that valve has been (fucking finally)
// caring about on counter-strike 2.
//
// To recall the original issue, the
// problem that Valve cared about is that interpolation
// had some problems with interpolating the local
// player because the screen would never in the first
// place match the tick "screen", because interpolation
// amount could never reach 0.0 or 1.0
//
// Valve solution was to introduce bugs with lag
// compensating the local player and made the game worse,
// introducing a new way for cheaters to cheat even more
// on their games.
// I'm joking, but you can clearly see the outcome anyway.
//
// My solution is to simply set interpolation amount
// to 0.0 when a tick arrives.
//
// So when we shoot, we get the frame we shot with an
// interpolation amount at 0.0, perfectly aligned to user
// commands which is ideal for us.
//
// It might look a bit more unsmooth with lower fps
// but with high enough fps, the issue goes away anyway.
// It's not very noticeable which is very nice for us.
// No need to lag compensate the local player anymore !
if (numticks == 0)
{
g_ClientGlobalVariables.interpolation_amount = (cl.m_tickRemainder
/ host_state
.interval_per_tick);
}
else
{
g_ClientGlobalVariables.interpolation_amount = 0.0f;
#ifdef false
printf("interpolation amount was %f, corrected to "
"fix interpolation issues.\n",
cl.m_tickRemainder
/ host_state.interval_per_tick);
#endif
}
#if defined(REPLAY_ENABLED) #if defined(REPLAY_ENABLED)
// Update client-side replay history manager - called here // Update client-side replay history manager - called here
@ -3465,23 +3482,8 @@ void _Host_RunFrame (float time)
// This causes cl.gettime() to return the true clock being used for rendering (tickcount * rate + remainder) // This causes cl.gettime() to return the true clock being used for rendering (tickcount * rate + remainder)
Host_SetClientInSimulation( false ); Host_SetClientInSimulation( false );
// Please check Notice_Enhanced. CalcInterpolationAmount();
if (numticks == 0)
{
g_ClientGlobalVariables.interpolation_amount = (cl.m_tickRemainder
/ host_state
.interval_per_tick);
}
else
{
g_ClientGlobalVariables.interpolation_amount = 0.0f;
#ifdef false
printf("interpolation amount was %f, corrected to "
"fix interpolation issues.\n",
cl.m_tickRemainder
/ host_state.interval_per_tick);
#endif
}
//------------------- //-------------------
// Run prediction if it hasn't been run yet // Run prediction if it hasn't been run yet
//------------------- //-------------------

View file

@ -57,7 +57,7 @@
#if defined( CCSPlayer ) #if defined( CCSPlayer )
#undef CCSPlayer #undef CCSPlayer
#endif #endif
#include "debugoverlay_shared.h"
#include "materialsystem/imesh.h" //for materials->FindMaterial #include "materialsystem/imesh.h" //for materials->FindMaterial
#include "iviewrender.h" //for view-> #include "iviewrender.h" //for view->
@ -2240,21 +2240,25 @@ void C_CSPlayer::Simulate( void )
} }
for (int i = 0; i < m_iBulletServerPositionCount; i++) for (int i = 0; i < m_iBulletServerPositionCount; i++)
{ {
debugoverlay->AddSweptBoxOverlay(m_vecServerShootPosition[i], NDebugOverlay::SweptBox(m_vecServerShootPosition[i],
m_vecBulletServerPositions[i], m_vecBulletServerPositions[i],
Vector(-m_lastBulletDiameter, Vector(-m_lastBulletDiameter, -m_lastBulletDiameter, -m_lastBulletDiameter) / 2,
-m_lastBulletDiameter, Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter) / 2,
-m_lastBulletDiameter) QAngle(0, 0, 0),
/ 2, 0,
Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter) 0,
/ 2, 255,
QAngle(0, 0, 0), 127,
0, 60.f);
0, NDebugOverlay::Box(m_vecBulletServerPositions[i],
255, Vector(-m_lastBulletDiameter, -m_lastBulletDiameter, -m_lastBulletDiameter) / 2,
127, Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter) / 2,
60.f); 0,
0,
255,
127,
60.f);
} }
m_lastBulletDiameter = -1.0f; m_lastBulletDiameter = -1.0f;

View file

@ -890,6 +890,12 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper
gpGlobals->frametime = m_bEnginePaused ? 0 : TICK_INTERVAL; gpGlobals->frametime = m_bEnginePaused ? 0 : TICK_INTERVAL;
gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL; gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL;
// Copy from command to player unless game .dll has set angle using fixangle
// if ( !player->pl.fixangle )
{
player->SetLocalViewAngles( ucmd->viewangles );
}
RunPostThink( player ); RunPostThink( player );
// TODO // TODO
@ -936,12 +942,6 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper
// player->pl.v_angle = ucmd->viewangles + player->pl.anglechange; // player->pl.v_angle = ucmd->viewangles + player->pl.anglechange;
// } // }
// Copy from command to player unless game .dll has set angle using fixangle
// if ( !player->pl.fixangle )
{
player->SetLocalViewAngles( ucmd->viewangles );
}
// Call standard client pre-think // Call standard client pre-think
RunPreThink( player ); RunPreThink( player );
@ -1695,8 +1695,12 @@ void CPrediction::Update( int startframe, bool validframe,
_Update( received_new_world_update, validframe, incoming_acknowledged, outgoing_command ); _Update( received_new_world_update, validframe, incoming_acknowledged, outgoing_command );
// TODO_ENHANCED: This, exactly, have made me debugging for 2h...
// the value isn't saved.
bool is_taking_screenshot = gpGlobals->client_taking_screenshot;
// Restore current timer values, etc. // Restore current timer values, etc.
*gpGlobals = saveVars; *gpGlobals = saveVars;
gpGlobals->client_taking_screenshot = is_taking_screenshot;
#endif #endif
} }

View file

@ -590,7 +590,15 @@ void CCSPlayer::FireBullet(
if (cl_showimpacts.GetInt() == 1 if (cl_showimpacts.GetInt() == 1
|| cl_showimpacts.GetInt() == 2) || cl_showimpacts.GetInt() == 2)
{ {
NDebugOverlay::Box(tr.endpos,
vecBulletRadiusMins,
vecBulletRadiusMaxs,
255,
0,
0,
127,
60.f);
player->DrawClientHitboxes(60.0f, true); player->DrawClientHitboxes(60.0f, true);
} }
@ -600,7 +608,7 @@ void CCSPlayer::FireBullet(
#else #else
if ( m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ON_HIT || m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ALWAYS_ON ) if ( m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ON_HIT || m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ALWAYS_ON )
{ {
if (iBullet < MAX_PLAYER_BULLET_SERVER_POSITIONS) if (m_iBulletServerPositionCount.Get() < MAX_PLAYER_BULLET_SERVER_POSITIONS)
{ {
m_vecBulletServerPositions.Set(m_iBulletServerPositionCount.Get(), tr.endpos); m_vecBulletServerPositions.Set(m_iBulletServerPositionCount.Get(), tr.endpos);
m_vecServerShootPosition.Set(m_iBulletServerPositionCount.Get(), vecSrc); m_vecServerShootPosition.Set(m_iBulletServerPositionCount.Get(), vecSrc);

View file

@ -13,12 +13,11 @@
#include "ilagcompensationmanager.h" #include "ilagcompensationmanager.h"
#endif #endif
ConVar debug_screenshot_bullet_position("debug_screenshot_bullet_position", "0");
ConVar weapon_accuracy_logging( "weapon_accuracy_logging", "0", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY | FCVAR_ARCHIVE ); ConVar weapon_accuracy_logging( "weapon_accuracy_logging", "0", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY | FCVAR_ARCHIVE );
ConVar weapon_accuracy_noinaccuracy( "weapon_accuracy_noinaccuracy", "0", FCVAR_REPLICATED ); ConVar weapon_accuracy_noinaccuracy( "weapon_accuracy_noinaccuracy", "0", FCVAR_REPLICATED );
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
ConVar debug_screenshot_bullet_position("debug_screenshot_bullet_position", "0");
#include "fx_impact.h" #include "fx_impact.h"
// this is a cheap ripoff from CBaseCombatWeapon::WeaponSound(): // this is a cheap ripoff from CBaseCombatWeapon::WeaponSound():
@ -299,7 +298,9 @@ void FX_FireBullets(
{ {
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
if (debug_screenshot_bullet_position.GetBool()) if (debug_screenshot_bullet_position.GetBool())
{
gpGlobals->client_taking_screenshot = true; gpGlobals->client_taking_screenshot = true;
}
#endif #endif
pPlayer->FireBullet( pPlayer->FireBullet(
iBullet, iBullet,

View file

@ -15,6 +15,9 @@
#include "tier0/vprof_telemetry.h" #include "tier0/vprof_telemetry.h"
// VProf is enabled by default in all configurations -except- X360 Retail. // VProf is enabled by default in all configurations -except- X360 Retail.
#if !( defined( _GAMECONSOLE ) && defined( _CERT ) )
#define VPROF_ENABLED
#endif
#if defined(_X360) && defined(VPROF_ENABLED) #if defined(_X360) && defined(VPROF_ENABLED)
#include "tier0/pmc360.h" #include "tier0/pmc360.h"