Added smoothed interpolation amount & fixed fews issues with prediction
Added vprof too
This commit is contained in:
parent
139f81eb02
commit
860bd3e883
6 changed files with 113 additions and 91 deletions
130
engine/host.cpp
130
engine/host.cpp
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "dbg.h"
|
||||
#include "tier0/fasttimer.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -3139,7 +3140,68 @@ void _Host_RunFrame (float time)
|
|||
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
|
||||
VPROF( "_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)
|
||||
Host_SetClientInSimulation(false);
|
||||
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
}
|
||||
CalcInterpolationAmount();
|
||||
|
||||
#if defined(REPLAY_ENABLED)
|
||||
// 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)
|
||||
Host_SetClientInSimulation( false );
|
||||
|
||||
// Please check Notice_Enhanced.
|
||||
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
|
||||
}
|
||||
CalcInterpolationAmount();
|
||||
|
||||
//-------------------
|
||||
// Run prediction if it hasn't been run yet
|
||||
//-------------------
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
#if defined( CCSPlayer )
|
||||
#undef CCSPlayer
|
||||
#endif
|
||||
|
||||
#include "debugoverlay_shared.h"
|
||||
#include "materialsystem/imesh.h" //for materials->FindMaterial
|
||||
#include "iviewrender.h" //for view->
|
||||
|
||||
|
@ -2240,21 +2240,25 @@ void C_CSPlayer::Simulate( void )
|
|||
}
|
||||
|
||||
for (int i = 0; i < m_iBulletServerPositionCount; i++)
|
||||
{
|
||||
debugoverlay->AddSweptBoxOverlay(m_vecServerShootPosition[i],
|
||||
m_vecBulletServerPositions[i],
|
||||
Vector(-m_lastBulletDiameter,
|
||||
-m_lastBulletDiameter,
|
||||
-m_lastBulletDiameter)
|
||||
/ 2,
|
||||
Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter)
|
||||
/ 2,
|
||||
QAngle(0, 0, 0),
|
||||
0,
|
||||
0,
|
||||
255,
|
||||
127,
|
||||
60.f);
|
||||
{
|
||||
NDebugOverlay::SweptBox(m_vecServerShootPosition[i],
|
||||
m_vecBulletServerPositions[i],
|
||||
Vector(-m_lastBulletDiameter, -m_lastBulletDiameter, -m_lastBulletDiameter) / 2,
|
||||
Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter) / 2,
|
||||
QAngle(0, 0, 0),
|
||||
0,
|
||||
0,
|
||||
255,
|
||||
127,
|
||||
60.f);
|
||||
NDebugOverlay::Box(m_vecBulletServerPositions[i],
|
||||
Vector(-m_lastBulletDiameter, -m_lastBulletDiameter, -m_lastBulletDiameter) / 2,
|
||||
Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter) / 2,
|
||||
0,
|
||||
0,
|
||||
255,
|
||||
127,
|
||||
60.f);
|
||||
}
|
||||
|
||||
m_lastBulletDiameter = -1.0f;
|
||||
|
|
|
@ -890,6 +890,12 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper
|
|||
gpGlobals->frametime = m_bEnginePaused ? 0 : 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 );
|
||||
|
||||
// TODO
|
||||
|
@ -936,12 +942,6 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper
|
|||
// 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
|
||||
RunPreThink( player );
|
||||
|
||||
|
@ -1695,8 +1695,12 @@ void CPrediction::Update( int startframe, bool validframe,
|
|||
|
||||
_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.
|
||||
*gpGlobals = saveVars;
|
||||
*gpGlobals = saveVars;
|
||||
gpGlobals->client_taking_screenshot = is_taking_screenshot;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -590,7 +590,15 @@ void CCSPlayer::FireBullet(
|
|||
|
||||
if (cl_showimpacts.GetInt() == 1
|
||||
|| cl_showimpacts.GetInt() == 2)
|
||||
{
|
||||
{
|
||||
NDebugOverlay::Box(tr.endpos,
|
||||
vecBulletRadiusMins,
|
||||
vecBulletRadiusMaxs,
|
||||
255,
|
||||
0,
|
||||
0,
|
||||
127,
|
||||
60.f);
|
||||
player->DrawClientHitboxes(60.0f, true);
|
||||
}
|
||||
|
||||
|
@ -600,7 +608,7 @@ void CCSPlayer::FireBullet(
|
|||
#else
|
||||
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_vecServerShootPosition.Set(m_iBulletServerPositionCount.Get(), vecSrc);
|
||||
|
|
|
@ -13,12 +13,11 @@
|
|||
#include "ilagcompensationmanager.h"
|
||||
#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_noinaccuracy( "weapon_accuracy_noinaccuracy", "0", FCVAR_REPLICATED );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
|
||||
ConVar debug_screenshot_bullet_position("debug_screenshot_bullet_position", "0");
|
||||
#include "fx_impact.h"
|
||||
|
||||
// this is a cheap ripoff from CBaseCombatWeapon::WeaponSound():
|
||||
|
@ -299,7 +298,9 @@ void FX_FireBullets(
|
|||
{
|
||||
#ifdef CLIENT_DLL
|
||||
if (debug_screenshot_bullet_position.GetBool())
|
||||
{
|
||||
gpGlobals->client_taking_screenshot = true;
|
||||
}
|
||||
#endif
|
||||
pPlayer->FireBullet(
|
||||
iBullet,
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
#include "tier0/vprof_telemetry.h"
|
||||
|
||||
// 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)
|
||||
#include "tier0/pmc360.h"
|
||||
|
|
Loading…
Reference in a new issue