diff --git a/engine/cl_main.cpp b/engine/cl_main.cpp index 52a5a5811a..e0e403cb6c 100644 --- a/engine/cl_main.cpp +++ b/engine/cl_main.cpp @@ -15,6 +15,7 @@ #include "r_local.h" #include "gl_lightmap.h" #include "console.h" +#include "sv_main.h" #include "traceinit.h" #include "cl_demo.h" #include "cdll_engine_int.h" @@ -1393,10 +1394,18 @@ void CL_TakeSnapshotAndSwap() if ( bReadPixelsFromFrontBuffer ) { Shader_SwapBuffers(); + } + + if (g_ClientGlobalVariables.client_taking_screenshot + || g_ServerGlobalVariables.client_taking_screenshot) + { + CL_TakeScreenshot(NULL); + g_ClientGlobalVariables.client_taking_screenshot = false; + g_ServerGlobalVariables.client_taking_screenshot = false; } - + if (cl_takesnapshot) - { + { // Disable threading for the duration of the screenshots, because we need to get pointers to the (complete) // back buffer right now. bool bEnabled = materials->AllowThreading( false, g_nMaterialSystemThread ); @@ -1505,7 +1514,7 @@ void CL_TakeSnapshotAndSwap() // Restore threading if it was previously enabled (if it wasn't this will do nothing). materials->AllowThreading( bEnabled, g_nMaterialSystemThread ); - } + } // If recording movie and the console is totally up, then write out this frame to movie file. if ( cl_movieinfo.IsRecording() && !Con_IsVisible() && !scr_drawloading ) diff --git a/engine/host.cpp b/engine/host.cpp index 02b0752bf8..79ac7610a2 100644 --- a/engine/host.cpp +++ b/engine/host.cpp @@ -3061,8 +3061,7 @@ void _Host_RunFrame (float time) Cbuf_AddText( "quit\n" ); } #endif - - int numticks; + int numticks; { // Profile scope specific to the top of this function, protect from setjmp() problems VPROF( "_Host_RunFrame_Upto_MarkFrame" ); @@ -3236,7 +3235,7 @@ void _Host_RunFrame (float time) //--------------------------------------------------------- // Run prediction, useful when fps is lower than tickrate. //--------------------------------------------------------- - CL_RunPrediction( PREDICTION_NORMAL ); + // CL_RunPrediction( PREDICTION_NORMAL ); _Host_RunFrame_Input( prevremainder, bFinalTick ); prevremainder = 0; @@ -3310,24 +3309,72 @@ void _Host_RunFrame (float time) tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "Host_SetClientInSimulation" ); // This causes cl.gettime() to return the true clock being used for rendering (tickcount * rate + remainder) - Host_SetClientInSimulation( false ); - // Now allow for interpolation on client - g_ClientGlobalVariables.interpolation_amount = ( cl.m_tickRemainder / host_state.interval_per_tick ); + Host_SetClientInSimulation(false); -#if defined( REPLAY_ENABLED ) - // Update client-side replay history manager - called here since interpolation_amount is set - if ( g_pClientReplayContext && g_pClientReplayContext->IsInitialized() ) + // 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 _DEBUG + printf("interpolation amount was %f, corrected to " + "fix interpolation issues.\n", + cl.m_tickRemainder + / host_state.interval_per_tick); + #endif + } + + #if defined(REPLAY_ENABLED) + // Update client-side replay history manager - called here + // since interpolation_amount is set + if ( g_pClientReplayContext && g_pClientReplayContext->IsInitialized() ) { g_pClientReplayContext->Think(); } -#endif + #endif - //------------------- - // Run prediction if it hasn't been run yet - //------------------- - // If we haven't predicted/simulated the player (multiplayer with prediction enabled and - // not a listen server with zero frame lag, then go ahead and predict now - CL_RunPrediction( PREDICTION_NORMAL ); + //------------------- + // Run prediction if it hasn't been run yet + //------------------- + // If we haven't predicted/simulated the player + // (multiplayer with prediction enabled and + // not a listen server with zero frame lag, then go ahead + // and predict now + CL_RunPrediction( PREDICTION_NORMAL ); CL_ApplyAddAngle(); @@ -3417,9 +3464,24 @@ void _Host_RunFrame (float time) // This causes cl.gettime() to return the true clock being used for rendering (tickcount * rate + remainder) Host_SetClientInSimulation( false ); - // Now allow for interpolation on client - g_ClientGlobalVariables.interpolation_amount = ( cl.m_tickRemainder / host_state.interval_per_tick ); + // 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 _DEBUG + 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 //------------------- @@ -3443,7 +3505,7 @@ void _Host_RunFrame (float time) g_ClientGlobalVariables.tickcount = host_tickcount; bool bFinalTick = tick==(serverticks-1) ? true : false; // Run prediction before inputs if fps is lower than tickrate - CL_RunPrediction( PREDICTION_NORMAL ); + // CL_RunPrediction( PREDICTION_NORMAL ); _Host_RunFrame_Input( prevremainder, bFinalTick ); prevremainder = 0; // process any asynchronous network traffic (TCP), set net_time @@ -3592,7 +3654,7 @@ void _Host_RunFrame (float time) GetTestScriptMgr()->CheckPoint( "frame_end" ); } // Profile scope, protect from setjmp() problems - Host_ShowIPCCallCount(); + Host_ShowIPCCallCount(); } /* ============================== diff --git a/game/client/prediction.cpp b/game/client/prediction.cpp index 0bb34533df..edb7b5cbde 100644 --- a/game/client/prediction.cpp +++ b/game/client/prediction.cpp @@ -922,7 +922,7 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper // Get button states player->UpdateButtonState( ucmd->buttons ); - // CheckMovingGround( player, gpGlobals->frametime ); + CheckMovingGround( player, gpGlobals->frametime ); g_pMoveData->m_vecOldAngles = player->pl.v_angle; diff --git a/game/shared/cstrike/fx_cs_shared.cpp b/game/shared/cstrike/fx_cs_shared.cpp index f4a04504c2..3191592f1c 100644 --- a/game/shared/cstrike/fx_cs_shared.cpp +++ b/game/shared/cstrike/fx_cs_shared.cpp @@ -6,6 +6,7 @@ #include "cbase.h" #include "fx_cs_shared.h" +#include "convar.h" #include "weapon_csbase.h" #ifndef CLIENT_DLL @@ -284,8 +285,12 @@ void FX_FireBullets( y1[iBullet] = fRadius1 * sinf(fTheta1); } + static ConVar debug_screenshot_bullet_position("debug_screenshot_bullet_position", "0"); for ( int iBullet=0; iBullet < pWeaponInfo->m_iBullets; iBullet++ ) - { + { + if (debug_screenshot_bullet_position.GetBool()) + gpGlobals->client_taking_screenshot = true; + pPlayer->FireBullet( vOrigin, vAngles, diff --git a/public/globalvars_base.h b/public/globalvars_base.h index 7ba96cb2e8..b9dc8fca8b 100644 --- a/public/globalvars_base.h +++ b/public/globalvars_base.h @@ -74,6 +74,7 @@ public: // current saverestore data CSaveRestoreData *pSaveData; + bool client_taking_screenshot; private: // Set to true in client code. @@ -99,6 +100,7 @@ inline CGlobalVarsBase::CGlobalVarsBase( bool bIsClient ) : nTimestampNetworkingBase( 100 ), nTimestampRandomizeWindow( 32 ) { + client_taking_screenshot = false; } inline bool CGlobalVarsBase::IsClient() const