Skip to content

Commit 113babd

Browse files
authored
bugfix(view): Prevent moving the camera with most user inputs during camera playback in Replay playback (#1599)
1 parent 1a78051 commit 113babd

File tree

8 files changed

+36
-0
lines changed

8 files changed

+36
-0
lines changed

Generals/Code/GameEngine/Include/GameClient/View.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class View : public Snapshot
131131
virtual void setOrigin( Int x, Int y) { m_originX=x; m_originY=y;} ///< Sets location of top-left view corner on display
132132
virtual void getOrigin( Int *x, Int *y) { *x=m_originX; *y=m_originY;} ///< Return location of top-left view corner on display
133133

134+
virtual void lockViewUntilFrame(UnsignedInt frame); ///< Locks the current view until the given frame is reached.
134135
virtual void forceRedraw() = 0;
135136

136137
virtual void lookAt( const Coord3D *o ); ///< Center the view on the given coordinate
@@ -255,6 +256,8 @@ class View : public Snapshot
255256
UnsignedInt m_id; ///< Rhe ID of this view
256257
static UnsignedInt m_idNext; ///< Used for allocating view ID's for all views
257258

259+
UnsignedInt m_viewLockedUntilFrame;
260+
258261
Coord3D m_pos; ///< Position of this view, in world coordinates
259262
Int m_width, m_height; ///< Dimensions of the view
260263
Int m_originX, m_originY; ///< Location of top/left view corner

Generals/Code/GameEngine/Source/GameClient/View.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ View::View( void )
4343
{
4444
//Added By Sadullah Nader
4545
//Initialization(s) inserted
46+
m_viewLockedUntilFrame = 0u;
4647
m_currentHeightAboveGround = 0.0f;
4748
m_defaultAngle = 0.0f;
4849
m_defaultPitchAngle = 0.0f;
@@ -110,6 +111,8 @@ void View::reset( void )
110111
{
111112
// Only fixing the reported bug. Who knows what side effects resetting the rest could have.
112113
m_zoomLimited = TRUE;
114+
115+
m_viewLockedUntilFrame = 0u;
113116
}
114117

115118
/**
@@ -126,6 +129,11 @@ void View::zoom( Real height )
126129
setHeightAboveGround(getHeightAboveGround() + height);
127130
}
128131

132+
void View::lockViewUntilFrame(UnsignedInt frame)
133+
{
134+
m_viewLockedUntilFrame = frame;
135+
}
136+
129137
/**
130138
* Center the view on the given coordinate.
131139
*/

Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,9 @@ void GameLogic::logicMessageDispatcher( GameMessage *msg, void *userData )
18731873
loc.init(pos.x, pos.y, pos.z, angle, pitch, zoom);
18741874
TheTacticalView->setLocation( &loc );
18751875

1876+
// TheSuperHackers @fix xezon 18/09/2025 Lock the new location to avoid user input from changing the camera in this frame.
1877+
TheTacticalView->lockViewUntilFrame( getFrame() + 1 );
1878+
18761879
if (!TheLookAtTranslator->hasMouseMovedRecently())
18771880
{
18781881
TheMouse->setCursor( (Mouse::MouseCursor)(msg->getArgument( 4 )->integer) );

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,10 @@ void W3DView::setCameraTransform( void )
413413
{
414414
if (TheGlobalData->m_headless)
415415
return;
416+
417+
if (m_viewLockedUntilFrame > TheGameClient->getFrame())
418+
return;
419+
416420
m_cameraHasMovedSinceRequest = true;
417421
Matrix3D cameraTransform( 1 );
418422

GeneralsMD/Code/GameEngine/Include/GameClient/View.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class View : public Snapshot
131131
virtual void setOrigin( Int x, Int y) { m_originX=x; m_originY=y;} ///< Sets location of top-left view corner on display
132132
virtual void getOrigin( Int *x, Int *y) { *x=m_originX; *y=m_originY;} ///< Return location of top-left view corner on display
133133

134+
virtual void lockViewUntilFrame(UnsignedInt frame); ///< Locks the current view until the given frame is reached.
134135
virtual void forceRedraw() = 0;
135136

136137
virtual void lookAt( const Coord3D *o ); ///< Center the view on the given coordinate
@@ -259,6 +260,8 @@ class View : public Snapshot
259260
UnsignedInt m_id; ///< Rhe ID of this view
260261
static UnsignedInt m_idNext; ///< Used for allocating view ID's for all views
261262

263+
UnsignedInt m_viewLockedUntilFrame;
264+
262265
Coord3D m_pos; ///< Position of this view, in world coordinates
263266
Int m_width, m_height; ///< Dimensions of the view
264267
Int m_originX, m_originY; ///< Location of top/left view corner

GeneralsMD/Code/GameEngine/Source/GameClient/View.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ View::View( void )
4343
{
4444
//Added By Sadullah Nader
4545
//Initialization(s) inserted
46+
m_viewLockedUntilFrame = 0u;
4647
m_currentHeightAboveGround = 0.0f;
4748
m_defaultAngle = 0.0f;
4849
m_defaultPitchAngle = 0.0f;
@@ -110,6 +111,8 @@ void View::reset( void )
110111
{
111112
// Only fixing the reported bug. Who knows what side effects resetting the rest could have.
112113
m_zoomLimited = TRUE;
114+
115+
m_viewLockedUntilFrame = 0u;
113116
}
114117

115118
/**
@@ -126,6 +129,11 @@ void View::zoom( Real height )
126129
setHeightAboveGround(getHeightAboveGround() + height);
127130
}
128131

132+
void View::lockViewUntilFrame(UnsignedInt frame)
133+
{
134+
m_viewLockedUntilFrame = frame;
135+
}
136+
129137
/**
130138
* Center the view on the given coordinate.
131139
*/

GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,9 @@ void GameLogic::logicMessageDispatcher( GameMessage *msg, void *userData )
19011901
loc.init(pos.x, pos.y, pos.z, angle, pitch, zoom);
19021902
TheTacticalView->setLocation( &loc );
19031903

1904+
// TheSuperHackers @fix xezon 18/09/2025 Lock the new location to avoid user input from changing the camera in this frame.
1905+
TheTacticalView->lockViewUntilFrame( getFrame() + 1 );
1906+
19041907
if (!TheLookAtTranslator->hasMouseMovedRecently())
19051908
{
19061909
TheMouse->setCursor( (Mouse::MouseCursor)(msg->getArgument( 4 )->integer) );

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,10 @@ void W3DView::setCameraTransform( void )
544544
{
545545
if (TheGlobalData->m_headless)
546546
return;
547+
548+
if (m_viewLockedUntilFrame > TheGameClient->getFrame())
549+
return;
550+
547551
m_cameraHasMovedSinceRequest = true;
548552
Matrix3D cameraTransform( 1 );
549553

0 commit comments

Comments
 (0)