Merge remote-tracking branch 'github/master'

This commit is contained in:
Kamay Xutax 2024-09-13 02:58:11 +02:00
commit 30ad2cc5a0
12 changed files with 200 additions and 200 deletions

View file

@ -699,7 +699,7 @@ typedef enum _DXVA_SampleFormat {
DXVA_SampleSubStream = 7 DXVA_SampleSubStream = 7
} DXVA_SampleFormat; } DXVA_SampleFormat;
#define DXVA_ExtractSampleFormat(_sf) ((_sf) & (DXVA_SampleFormatMask)) #define DXVA_ExtraMovementSampleFormatMask))
#define DXVA_ExtractExtColorData(_sf, _Mask, _Shift) \ #define DXVA_ExtractExtColorData(_sf, _Mask, _Shift) \
(((_sf) >> (_Shift)) & (_Mask)) (((_sf) >> (_Shift)) & (_Mask))

View file

@ -10,6 +10,7 @@
#include "client.h" #include "client.h"
#include "client_pch.h" #include "client_pch.h"
#include "clockdriftmgr.h" #include "clockdriftmgr.h"
#include "host.h"
#include "sound.h" #include "sound.h"
#include <inetchannel.h> #include <inetchannel.h>
#include "checksum_engine.h" #include "checksum_engine.h"
@ -593,7 +594,7 @@ void CL_ReadPackets ( bool bFinalTick )
// While clock correction is off, we have the old behavior of matching the client and server clocks. // While clock correction is off, we have the old behavior of matching the client and server clocks.
if (CClockDriftMgr::IsClockCorrectionEnabled()) if (CClockDriftMgr::IsClockCorrectionEnabled())
{ {
cl.m_ClockDriftMgr.IncrementCachedTickCount(bFinalTick); cl.GetClockDriftMgr().IncrementCachedTickCount(bFinalTick);
g_ClientGlobalVariables.tickcount = cl.GetClientTickCount(); g_ClientGlobalVariables.tickcount = cl.GetClientTickCount();
g_ClientGlobalVariables.curtime = cl.GetTime(); g_ClientGlobalVariables.curtime = cl.GetTime();
} }
@ -2081,7 +2082,7 @@ void CL_DecayLights (void)
} }
void CL_ExtraMouseUpdate( float frametime ) void CL_ExtraMovementUpdate( float frametime )
{ {
// Not ready for commands yet. // Not ready for commands yet.
if ( !cl.IsActive() ) if ( !cl.IsActive() )
@ -2102,7 +2103,7 @@ void CL_ExtraMouseUpdate( float frametime )
int nextcommandnr = cl.lastoutgoingcommand + cl.chokedcommands + 1; int nextcommandnr = cl.lastoutgoingcommand + cl.chokedcommands + 1;
// Have client .dll create and store usercmd structure // Have client .dll create and store usercmd structure
g_ClientDLL->ExtraMouseSample( nextcommandnr, frametime, !cl.m_bPaused ); g_ClientDLL->ExtraMovementSample( cl.GetClockDriftMgr().m_nNumberOfTicks, nextcommandnr, frametime, !cl.m_bPaused );
} }
/* /*
@ -2159,7 +2160,7 @@ void CL_SendMove( void )
} }
} }
void CL_Move(float accumulated_extra_samples, bool bFinalTick ) void CL_Move(float frametime, bool bFinalTick )
{ {
if ( !cl.IsConnected() ) if ( !cl.IsConnected() )
return; return;
@ -2205,10 +2206,20 @@ void CL_Move(float accumulated_extra_samples, bool bFinalTick )
int nextcommandnr = cl.lastoutgoingcommand + cl.chokedcommands + 1; int nextcommandnr = cl.lastoutgoingcommand + cl.chokedcommands + 1;
// Have client .dll create and store usercmd structure // TODO_ENHANCED:
// Sooo why do we ignore interval per tick overlap here?
// Because the mouse accumulators even in low fps are always reset to zero anyway after the first tick.
// Movements will be instead calculate inside CL_ExtraMovementSample with the correct frametime.
// Doing host_state.interval_per_tick - frametime was just to calculate the previous frametime, but it has issues:
// Before even if you had low fps, the mouse will only be updated only once even if CreateMove is called multiple times.
// So basically, no matter the frametime you had, the mouse will never update its angles anyway with the correct amount (multiple interval per ticks.);
// Because GetRawMouseAccumulators will always be zero, except with old behavior with GetCursorPos.
// So, instead the frametime has been divided by the number ticks been ran, so we get the right amount to adjust everytime.
// Technically it's even safe to remove now the calculation for movements since they'll calculated inside CL_ExtraMovementSample now.
g_ClientDLL->CreateMove( g_ClientDLL->CreateMove(
nextcommandnr, nextcommandnr,
host_state.interval_per_tick - accumulated_extra_samples, frametime,
!cl.IsPaused() ); !cl.IsPaused() );
// Store new usercmd to dem file // Store new usercmd to dem file

View file

@ -158,7 +158,7 @@ void CL_RegisterResources ( void );
// cl_input // cl_input
// //
void CL_Move( float accumulated_extra_samples, bool bFinalTick ); void CL_Move( float accumulated_extra_samples, bool bFinalTick );
void CL_ExtraMouseUpdate( float remainder ); void CL_ExtraMovementUpdate( float remainder );
void CL_ClearState (void); void CL_ClearState (void);
void CL_ReadPackets ( bool framefinished ); // Read packets from server and other sources (ping requests, etc.) void CL_ReadPackets ( bool framefinished ); // Read packets from server and other sources (ping requests, etc.)

View file

@ -2623,7 +2623,7 @@ Runs all active servers
================== ==================
*/ */
void _Host_RunFrame_Input( float accumulated_extra_samples, bool bFinalTick ) void _Host_RunFrame_Input( float frametime, bool bFinalTick )
{ {
VPROF_BUDGET( "_Host_RunFrame_Input", _T("Input") ); VPROF_BUDGET( "_Host_RunFrame_Input", _T("Input") );
@ -2656,7 +2656,7 @@ void _Host_RunFrame_Input( float accumulated_extra_samples, bool bFinalTick )
g_HostTimes.EndFrameSegment( FRAME_SEGMENT_CMD_EXECUTE ); g_HostTimes.EndFrameSegment( FRAME_SEGMENT_CMD_EXECUTE );
// Send any current movement commands to server and flush reliable buffer even if not moving yet. // Send any current movement commands to server and flush reliable buffer even if not moving yet.
CL_Move( accumulated_extra_samples, bFinalTick ); CL_Move( frametime, bFinalTick );
#endif #endif
@ -3054,7 +3054,6 @@ void _Host_RunFrame (float time)
{ {
MDLCACHE_COARSE_LOCK_(g_pMDLCache); MDLCACHE_COARSE_LOCK_(g_pMDLCache);
static double host_remainder = 0.0f; static double host_remainder = 0.0f;
double prevremainder;
bool shouldrender; bool shouldrender;
#if defined( RAD_TELEMETRY_ENABLED ) #if defined( RAD_TELEMETRY_ENABLED )
@ -3104,11 +3103,6 @@ void _Host_RunFrame (float time)
shouldrender = !sv.IsDedicated(); shouldrender = !sv.IsDedicated();
// FIXME: Could track remainder as fractional ticks instead of msec
prevremainder = host_remainder;
if ( prevremainder < 0 )
prevremainder = 0;
#if !defined(SWDS) #if !defined(SWDS)
if ( !demoplayer->IsPlaybackPaused() ) if ( !demoplayer->IsPlaybackPaused() )
#endif #endif
@ -3136,7 +3130,7 @@ void _Host_RunFrame (float time)
host_remainder -= numticks * host_state.interval_per_tick; host_remainder -= numticks * host_state.interval_per_tick;
} }
cl.m_ClockDriftMgr.m_nNumberOfTicks = numticks; cl.GetClockDriftMgr().m_nNumberOfTicks = numticks;
host_nexttick = host_state.interval_per_tick - host_remainder; host_nexttick = host_state.interval_per_tick - host_remainder;
@ -3240,14 +3234,14 @@ void _Host_RunFrame (float time)
g_ClientGlobalVariables.next_interpolation_amount = cl.m_tickRemainder / host_state.interval_per_tick; g_ClientGlobalVariables.next_interpolation_amount = cl.m_tickRemainder / host_state.interval_per_tick;
// TODO_ENHANCED: // TODO_ENHANCED:
// Update the mouse as last so we can get the right viewangles while taking screenshot. // Update the mouse as first so we can get the right viewangles while rendering.
// The mouse is always simulated for the current frame's time // The mouse is always simulated for the current frame's time
// This makes updates smooth in every case // This makes updates smooth in every case
// continuous controllers affecting the view are also simulated this way // continuous controllers affecting the view are also simulated this way
// but they have a cap applied by IN_SetSampleTime() so they are not also // but they have a cap applied by IN_SetSampleTime() so they are not also
// simulated during input gathering // simulated during input gathering
g_ClientGlobalVariables.frametime = host_frametime; g_ClientGlobalVariables.frametime = host_frametime;
CL_ExtraMouseUpdate( host_frametime ); CL_ExtraMovementUpdate( host_frametime );
#endif #endif
for ( int tick = 0; tick < numticks; tick++ ) for ( int tick = 0; tick < numticks; tick++ )
{ {
@ -3300,8 +3294,7 @@ void _Host_RunFrame (float time)
//--------------------------------------------------------- //---------------------------------------------------------
// CL_RunPrediction( PREDICTION_NORMAL ); // CL_RunPrediction( PREDICTION_NORMAL );
_Host_RunFrame_Input( prevremainder, bFinalTick ); _Host_RunFrame_Input( host_frametime, bFinalTick );
prevremainder = 0;
//------------------- //-------------------
// //
@ -3436,14 +3429,14 @@ void _Host_RunFrame (float time)
g_ServerGlobalVariables.tickcount = sv.m_nTickCount; g_ServerGlobalVariables.tickcount = sv.m_nTickCount;
// TODO_ENHANCED: // TODO_ENHANCED:
// Update the mouse as last so we can get the right viewangles while taking screenshot. // Update the mouse as first so we can get the right viewangles while rendering.
// The mouse is always simulated for the current frame's time // The mouse is always simulated for the current frame's time
// This makes updates smooth in every case // This makes updates smooth in every case
// continuous controllers affecting the view are also simulated this way // continuous controllers affecting the view are also simulated this way
// but they have a cap applied by IN_SetSampleTime() so they are not also // but they have a cap applied by IN_SetSampleTime() so they are not also
// simulated during input gathering // simulated during input gathering
g_ClientGlobalVariables.frametime = host_frametime; g_ClientGlobalVariables.frametime = host_frametime;
CL_ExtraMouseUpdate( host_frametime ); CL_ExtraMovementUpdate( host_frametime );
// THREADED: Run Client // THREADED: Run Client
// ------------------- // -------------------
@ -3518,8 +3511,7 @@ void _Host_RunFrame (float time)
bool bFinalTick = tick==(serverticks-1) ? true : false; bool bFinalTick = tick==(serverticks-1) ? true : false;
// Run prediction before inputs if fps is lower than tickrate // Run prediction before inputs if fps is lower than tickrate
// CL_RunPrediction( PREDICTION_NORMAL ); // CL_RunPrediction( PREDICTION_NORMAL );
_Host_RunFrame_Input( prevremainder, bFinalTick ); _Host_RunFrame_Input( host_frametime, bFinalTick );
prevremainder = 0;
// process any asynchronous network traffic (TCP), set net_time // process any asynchronous network traffic (TCP), set net_time
NET_RunFrame( Plat_FloatTime() ); NET_RunFrame( Plat_FloatTime() );
} }

View file

@ -630,7 +630,7 @@ public:
virtual void IN_SetSampleTime( float frametime ); virtual void IN_SetSampleTime( float frametime );
// Create movement command // Create movement command
virtual void CreateMove ( int sequence_number, float input_sample_frametime, bool active ); virtual void CreateMove ( int sequence_number, float input_sample_frametime, bool active );
virtual void ExtraMouseSample( int sequence_number, float frametime, bool active ); virtual void ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active );
virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand ); virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand );
virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot ); virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot );
virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot ); virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot );
@ -1419,7 +1419,7 @@ int CHLClient::IN_KeyEvent( int eventcode, ButtonCode_t keynum, const char *pszC
return input->KeyEvent( eventcode, keynum, pszCurrentBinding ); return input->KeyEvent( eventcode, keynum, pszCurrentBinding );
} }
void CHLClient::ExtraMouseSample( int sequence_number, float frametime, bool active ) void CHLClient::ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active )
{ {
Assert( C_BaseEntity::IsAbsRecomputationsEnabled() ); Assert( C_BaseEntity::IsAbsRecomputationsEnabled() );
Assert( C_BaseEntity::IsAbsQueriesValid() ); Assert( C_BaseEntity::IsAbsQueriesValid() );
@ -1427,7 +1427,7 @@ void CHLClient::ExtraMouseSample( int sequence_number, float frametime, bool act
C_BaseAnimating::AutoAllowBoneAccess boneaccess( true, false ); C_BaseAnimating::AutoAllowBoneAccess boneaccess( true, false );
MDLCACHE_CRITICAL_SECTION(); MDLCACHE_CRITICAL_SECTION();
input->ExtraMouseSample( sequence_number, frametime, active ); input->ExtraMovementSample( number_of_ticks_this_frame, current_command, frametime, active );
} }
void CHLClient::IN_SetSampleTime( float frametime ) void CHLClient::IN_SetSampleTime( float frametime )

View file

@ -37,7 +37,7 @@ public:
virtual int GetButtonBits( int ) = 0; virtual int GetButtonBits( int ) = 0;
// Create movement command // Create movement command
virtual void CreateMove ( int sequence_number, float input_sample_frametime, bool active ) = 0; virtual void CreateMove ( int sequence_number, float input_sample_frametime, bool active ) = 0;
virtual void ExtraMouseSample( int sequence_number, float frametime, bool active ) = 0; virtual void ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active ) = 0;
virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand ) = 0; virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand ) = 0;
virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot ) = 0; virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot ) = 0;
virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot ) = 0; virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot ) = 0;

View file

@ -1016,124 +1016,155 @@ if active == 1 then we are 1) not playing back demos ( where our commands are ig
================ ================
*/ */
void CInput::ExtraMouseSample( int sequence_number, float frametime, bool active ) void CInput::ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active )
{ {
VPROF( "CInput::ExtraMouseSample" ); VPROF( "CInput::ExtraMovementSample" );
CUserCmd dummy; CUserCmd dummy;
CUserCmd* cmd; CUserCmd* cmd;
static int old_sequence_number = 0; auto UpdateMovements = [&]()
// Be sure to call this only once per tick.
if ( old_sequence_number != sequence_number )
{ {
cmd = &m_pCommands[sequence_number % MULTIPLAYER_BACKUP]; cmd->Reset();
old_sequence_number = sequence_number;
QAngle viewangles;
engine->GetViewAngles( viewangles );
QAngle originalViewangles = viewangles;
if ( active )
{
// Determine view angles
AdjustAngles ( frametime );
// Determine sideways movement
ComputeSideMove( cmd );
// Determine vertical movement
ComputeUpwardMove( cmd );
// Determine forward movement
ComputeForwardMove( cmd );
// Scale based on holding speed key or having too fast of a velocity based on client maximum
// speed.
ScaleMovements( cmd );
// Allow mice and other controllers to add their inputs
ControllerMove( frametime, cmd );
#ifdef SIXENSE
g_pSixenseInput->SixenseFrame( frametime, cmd );
if( g_pSixenseInput->IsEnabled() )
{
g_pSixenseInput->SetView( frametime, cmd );
}
#endif
}
else
{
// need to run and reset mouse input so that there is no view pop when unpausing
if ( !m_fCameraInterceptingMouse && m_fMouseActive )
{
float mx, my;
GetAccumulatedMouseDeltasAndResetAccumulators( &mx, &my );
ResetMouse();
}
}
// Retreive view angles from engine ( could have been set in IN_AdjustAngles above )
engine->GetViewAngles( viewangles );
// Set button and flag bits, don't blow away state
#ifdef SIXENSE
if( g_pSixenseInput->IsEnabled() )
{
// Some buttons were set in SixenseUpdateKeys, so or in any real keypresses
cmd->buttons |= GetButtonBits( 0 );
}
else
{
cmd->buttons = GetButtonBits( 0 );
}
#else
cmd->buttons = GetButtonBits( 0 );
#endif
// Use new view angles if alive, otherwise user last angles we stored off.
if ( g_iAlive )
{
VectorCopy( viewangles, cmd->viewangles );
VectorCopy( viewangles, m_angPreviousViewAngles );
}
else
{
VectorCopy( m_angPreviousViewAngles, cmd->viewangles );
}
// Let the move manager override anything it wants to.
if ( g_pClientMode->CreateMove( frametime, cmd ) )
{
// Get current view angles after the client mode tweaks with it
engine->SetViewAngles( cmd->viewangles );
prediction->SetLocalViewAngles( cmd->viewangles );
}
// Let the headtracker override the view at the very end of the process so
// that vehicles and other stuff in g_pClientMode->CreateMove can override
// first
if ( active && UseVR() )
{
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
if( pPlayer && !pPlayer->GetVehicle() )
{
QAngle curViewangles, newViewangles;
Vector curMotion, newMotion;
engine->GetViewAngles( curViewangles );
curMotion.Init (
cmd->forwardmove,
cmd->sidemove,
cmd->upmove );
g_ClientVirtualReality.OverridePlayerMotion ( frametime, originalViewangles, curViewangles, curMotion, &newViewangles, &newMotion );
engine->SetViewAngles( newViewangles );
cmd->forwardmove = newMotion[0];
cmd->sidemove = newMotion[1];
cmd->upmove = newMotion[2];
cmd->viewangles = newViewangles;
prediction->SetLocalViewAngles( cmd->viewangles );
}
}
};
// TODO_ENHANCED:
//
// Be sure to set the usercmd once
// because CreateMove won't be able to adjust angles anyway since accumulators will be reset to zero.
// How ever when fps is lower than tickrate, this function is actually never called into the engine
// In order to use interval per tick instead of frametime.
if ( number_of_ticks_this_frame > 0 )
{
// Sometimes, when fps is too low or framerate suddently dropped,
// We need to do this to prevent CreateMove using old commands.
// TODO_ENHANCED:
// We will need this eventually,
// but since accumulators gets reset to zero, its actually better to let it like this.
// Maybe if the accumulators aren't zeros per number_of_ticks_this_frame,
// we could get more accurate viewangles changes.
// frametime /= number_of_ticks_this_frame;
for (int i = 0; i < number_of_ticks_this_frame; i++)
{
cmd = &m_pCommands[(current_command + i) % MULTIPLAYER_BACKUP];
UpdateMovements();
}
} }
else else
{ {
cmd = &dummy; cmd = &dummy;
} UpdateMovements();
cmd->Reset();
QAngle viewangles;
engine->GetViewAngles( viewangles );
QAngle originalViewangles = viewangles;
if ( active )
{
// Determine view angles
AdjustAngles ( frametime );
// Determine sideways movement
ComputeSideMove( cmd );
// Determine vertical movement
ComputeUpwardMove( cmd );
// Determine forward movement
ComputeForwardMove( cmd );
// Scale based on holding speed key or having too fast of a velocity based on client maximum
// speed.
ScaleMovements( cmd );
// Allow mice and other controllers to add their inputs
ControllerMove( frametime, cmd );
#ifdef SIXENSE
g_pSixenseInput->SixenseFrame( frametime, cmd );
if( g_pSixenseInput->IsEnabled() )
{
g_pSixenseInput->SetView( frametime, cmd );
}
#endif
}
// Retreive view angles from engine ( could have been set in IN_AdjustAngles above )
engine->GetViewAngles( viewangles );
// Set button and flag bits, don't blow away state
#ifdef SIXENSE
if( g_pSixenseInput->IsEnabled() )
{
// Some buttons were set in SixenseUpdateKeys, so or in any real keypresses
cmd->buttons |= GetButtonBits( 0 );
}
else
{
cmd->buttons = GetButtonBits( 0 );
}
#else
cmd->buttons = GetButtonBits( 0 );
#endif
// Use new view angles if alive, otherwise user last angles we stored off.
if ( g_iAlive )
{
VectorCopy( viewangles, cmd->viewangles );
VectorCopy( viewangles, m_angPreviousViewAngles );
}
else
{
VectorCopy( m_angPreviousViewAngles, cmd->viewangles );
}
// Let the move manager override anything it wants to.
if ( g_pClientMode->CreateMove( frametime, cmd ) )
{
// Get current view angles after the client mode tweaks with it
engine->SetViewAngles( cmd->viewangles );
prediction->SetLocalViewAngles( cmd->viewangles );
}
// Let the headtracker override the view at the very end of the process so
// that vehicles and other stuff in g_pClientMode->CreateMove can override
// first
if ( active && UseVR() )
{
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
if( pPlayer && !pPlayer->GetVehicle() )
{
QAngle curViewangles, newViewangles;
Vector curMotion, newMotion;
engine->GetViewAngles( curViewangles );
curMotion.Init (
cmd->forwardmove,
cmd->sidemove,
cmd->upmove );
g_ClientVirtualReality.OverridePlayerMotion ( frametime, originalViewangles, curViewangles, curMotion, &newViewangles, &newMotion );
engine->SetViewAngles( newViewangles );
cmd->forwardmove = newMotion[0];
cmd->sidemove = newMotion[1];
cmd->upmove = newMotion[2];
cmd->viewangles = newViewangles;
prediction->SetLocalViewAngles( cmd->viewangles );
}
} }
} }
@ -1149,49 +1180,6 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
QAngle viewangles; QAngle viewangles;
engine->GetViewAngles( viewangles ); engine->GetViewAngles( viewangles );
QAngle originalViewangles = viewangles;
if ( active || sv_noclipduringpause.GetInt() )
{
// Determine view angles
AdjustAngles ( input_sample_frametime );
// Determine sideways movement
ComputeSideMove( cmd );
// Determine vertical movement
ComputeUpwardMove( cmd );
// Determine forward movement
ComputeForwardMove( cmd );
// Scale based on holding speed key or having too fast of a velocity based on client maximum
// speed.
ScaleMovements( cmd );
// Allow mice and other controllers to add their inputs
ControllerMove( input_sample_frametime, cmd );
#ifdef SIXENSE
g_pSixenseInput->SixenseFrame( input_sample_frametime, cmd );
if( g_pSixenseInput->IsEnabled() )
{
g_pSixenseInput->SetView( input_sample_frametime, cmd );
}
#endif
}
else
{
// need to run and reset mouse input so that there is no view pop when unpausing
if ( !m_fCameraInterceptingMouse && m_fMouseActive )
{
float mx, my;
GetAccumulatedMouseDeltasAndResetAccumulators( &mx, &my );
ResetMouse();
}
}
// Retreive view angles from engine ( could have been set in IN_AdjustAngles above )
engine->GetViewAngles( viewangles );
// Latch and clear impulse // Latch and clear impulse
cmd->impulse = in_impulse; cmd->impulse = in_impulse;
@ -1242,17 +1230,6 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
} }
} }
// Use new view angles if alive, otherwise user last angles we stored off.
if ( g_iAlive )
{
VectorCopy( viewangles, cmd->viewangles );
VectorCopy( viewangles, m_angPreviousViewAngles );
}
else
{
VectorCopy( m_angPreviousViewAngles, cmd->viewangles );
}
// Let the move manager override anything it wants to. // Let the move manager override anything it wants to.
if ( g_pClientMode->CreateMove( input_sample_frametime, cmd ) ) if ( g_pClientMode->CreateMove( input_sample_frametime, cmd ) )
{ {
@ -1280,7 +1257,7 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
cmd->forwardmove, cmd->forwardmove,
cmd->sidemove, cmd->sidemove,
cmd->upmove ); cmd->upmove );
g_ClientVirtualReality.OverridePlayerMotion ( input_sample_frametime, originalViewangles, curViewangles, curMotion, &newViewangles, &newMotion ); g_ClientVirtualReality.OverridePlayerMotion ( input_sample_frametime, viewangles, curViewangles, curMotion, &newViewangles, &newMotion );
engine->SetViewAngles( newViewangles ); engine->SetViewAngles( newViewangles );
cmd->forwardmove = newMotion[0]; cmd->forwardmove = newMotion[0];
cmd->sidemove = newMotion[1]; cmd->sidemove = newMotion[1];
@ -1296,6 +1273,17 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
} }
} }
// Use new view angles if alive, otherwise user last angles we stored off.
if ( g_iAlive )
{
VectorCopy( viewangles, cmd->viewangles );
VectorCopy( viewangles, m_angPreviousViewAngles );
}
else
{
VectorCopy( m_angPreviousViewAngles, cmd->viewangles );
}
m_flLastForwardMove = cmd->forwardmove; m_flLastForwardMove = cmd->forwardmove;
cmd->random_seed = MD5_PseudoRandom( sequence_number ) & 0x7fffffff; cmd->random_seed = MD5_PseudoRandom( sequence_number ) & 0x7fffffff;

View file

@ -47,7 +47,7 @@ public:
virtual void Shutdown_All( void ); virtual void Shutdown_All( void );
virtual int GetButtonBits( int ); virtual int GetButtonBits( int );
virtual void CreateMove ( int sequence_number, float input_sample_frametime, bool active ); virtual void CreateMove ( int sequence_number, float input_sample_frametime, bool active );
virtual void ExtraMouseSample( int sequence_number, float frametime, bool active ); virtual void ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active );
virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand ); virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand );
virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot ); virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot );
virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot ); virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot );

View file

@ -6,6 +6,8 @@
#include "cbase.h" #include "cbase.h"
#include "view.h" #include "view.h"
#include "cdll_client_int.h"
#include "gamerules.h"
#include "iviewrender.h" #include "iviewrender.h"
#include "iviewrender_beams.h" #include "iviewrender_beams.h"
#include "view_shared.h" #include "view_shared.h"
@ -150,7 +152,14 @@ static void CalcDemoViewOverride( Vector &origin, QAngle &angles )
{ {
engine->SetViewAngles( s_DemoAngle ); engine->SetViewAngles( s_DemoAngle );
input->ExtraMouseSample( 0, gpGlobals->absoluteframetime, true ); input->ExtraMovementSample( gpGlobals->tickcount, 0, gpGlobals->absoluteframetime, true );
static int iOldTickCount = 0;
if (iOldTickCount != gpGlobals->tickcount)
{
iOldTickCount = gpGlobals->tickcount;
}
engine->GetViewAngles( s_DemoAngle ); engine->GetViewAngles( s_DemoAngle );

View file

@ -653,7 +653,7 @@ public:
// If the game is running faster than the tick_interval framerate, then we do extra mouse sampling to avoid jittery input // If the game is running faster than the tick_interval framerate, then we do extra mouse sampling to avoid jittery input
// This code path is much like the normal move creation code, except no move is created // This code path is much like the normal move creation code, except no move is created
virtual void ExtraMouseSample( int sequence_number, float frametime, bool active ) = 0; virtual void ExtraMovementSample( int number_of_ticks_this_frame, int current_command, float frametime, bool active ) = 0;
// Encode the delta (changes) between the CUserCmd in slot from vs the one in slot to. The game code will have // Encode the delta (changes) between the CUserCmd in slot from vs the one in slot to. The game code will have
// matching logic to read the delta. // matching logic to read the delta.

View file

@ -10633,7 +10633,7 @@ enum DISPID_SpeechWaveFormatEx
DISPID_SWFEAvgBytesPerSec = DISPID_SWFESamplesPerSec + 1, DISPID_SWFEAvgBytesPerSec = DISPID_SWFESamplesPerSec + 1,
DISPID_SWFEBlockAlign = DISPID_SWFEAvgBytesPerSec + 1, DISPID_SWFEBlockAlign = DISPID_SWFEAvgBytesPerSec + 1,
DISPID_SWFEBitsPerSample = DISPID_SWFEBlockAlign + 1, DISPID_SWFEBitsPerSample = DISPID_SWFEBlockAlign + 1,
DISPID_SWFEExtraData = DISPID_SWFEBitsPerSample + 1 DISPID_SWFEExtraMovementSample + 1
} DISPID_SpeechWaveFormatEx; } DISPID_SpeechWaveFormatEx;
typedef /* [hidden] */ typedef /* [hidden] */

View file

@ -50,7 +50,7 @@ inline float DecimateSamplePair(float input0, float input1, const float pCoeffic
return (input0 + input1); return (input0 + input1);
} }
static void ExtractFloatSamples( float *pOut, const short *pInputBuffer, int sampleCount, int stride ) static void ExtraMovementSamples( float *pOut, const short *pInputBuffer, int sampleCount, int stride )
{ {
for ( int i = 0; i < sampleCount; i++ ) for ( int i = 0; i < sampleCount; i++ )
{ {
@ -59,7 +59,7 @@ static void ExtractFloatSamples( float *pOut, const short *pInputBuffer, int sam
} }
} }
static void ExtractShortSamples( short *pOut, const float *pInputBuffer, float scale, int sampleCount, int stride ) static void ExtraMovementSamples( short *pOut, const float *pInputBuffer, float scale, int sampleCount, int stride )
{ {
for ( int i = 0; i < sampleCount; i++ ) for ( int i = 0; i < sampleCount; i++ )
{ {
@ -96,9 +96,9 @@ void DecimateSampleRateBy2_16( const short *pInputBuffer, short *pOutputBuffer,
float *pTmpBuf = new float[sampleCount]; float *pTmpBuf = new float[sampleCount];
for ( int i = 0; i < channelCount; i++ ) for ( int i = 0; i < channelCount; i++ )
{ {
ExtractFloatSamples( pTmpBuf, pInputBuffer+i, sampleCount, channelCount ); ExtraMovementSamples( pTmpBuf, pInputBuffer+i, sampleCount, channelCount );
DecimateSampleBlock( pTmpBuf, sampleCount ); DecimateSampleBlock( pTmpBuf, sampleCount );
ExtractShortSamples( pOutputBuffer+i, pTmpBuf, 0.5f * 32768.0f, sampleCount>>1, channelCount ); ExtraMovementSamples( pOutputBuffer+i, pTmpBuf, 0.5f * 32768.0f, sampleCount>>1, channelCount );
} }
delete [] pTmpBuf; delete [] pTmpBuf;
} }