Skip to content

Commit 3bf9396

Browse files
committed
bugfix(fps): Decouple camera zoom and rotation time step from render update (#1451)
1 parent 579f189 commit 3bf9396

File tree

4 files changed

+50
-47
lines changed

4 files changed

+50
-47
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ class View : public Snapshot
7373

7474
public:
7575

76+
enum
77+
{
78+
ZoomHeightPerSecond = 10,
79+
};
80+
7681
/// Add an impulse force to shake the camera
7782
enum CameraShakeType
7883
{
@@ -184,8 +189,7 @@ class View : public Snapshot
184189
virtual void setZoom(Real z) { }
185190
virtual Real getHeightAboveGround() { return m_heightAboveGround; }
186191
virtual void setHeightAboveGround(Real z) { m_heightAboveGround = z; }
187-
virtual void zoomIn( void ); ///< Zoom in, closer to the ground, limit to min
188-
virtual void zoomOut( void ); ///< Zoom out, farther away from the ground, limit to max
192+
virtual void zoom( Real height ); ///< Zoom in/out, closer to the ground, limit to min, or farther away from the ground, limit to max
189193
virtual void setZoomToDefault( void ) { } ///< Set zoom to default value
190194
virtual Real getMaxZoom( void ) { return m_maxZoom; } ///< return max zoom value
191195
virtual void setOkToAdjustHeight( Bool val ) { m_okToAdjustHeight = val; } ///< Set this to adjust camera height

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

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
#include "Common/ThingTemplate.h"
4646
#include "Common/BuildAssistant.h"
4747
#include "Common/Recorder.h"
48-
#include "Common/BuildAssistant.h"
4948
#include "Common/SpecialPower.h"
5049

5150
#include "GameClient/Anim2D.h"
@@ -67,7 +66,6 @@
6766
#include "GameClient/GadgetStaticText.h"
6867
#include "GameClient/View.h"
6968
#include "GameClient/TerrainVisual.h"
70-
#include "GameClient/ControlBar.h"
7169
#include "GameClient/Display.h"
7270
#include "GameClient/WindowLayout.h"
7371
#include "GameClient/LookAtXlat.h"
@@ -1883,26 +1881,30 @@ void InGameUI::update( void )
18831881
layout->runUpdate();
18841882
}
18851883

1886-
//Handle keyboard camera rotations
1887-
if( m_cameraRotatingLeft && !m_cameraRotatingRight )
1884+
if (m_cameraRotatingLeft || m_cameraRotatingRight || m_cameraZoomingIn || m_cameraZoomingOut)
18881885
{
1889-
//Keyboard rotate left
1890-
TheTacticalView->setAngle( TheTacticalView->getAngle() - TheGlobalData->m_keyboardCameraRotateSpeed );
1891-
}
1892-
if( m_cameraRotatingRight && !m_cameraRotatingLeft )
1893-
{
1894-
//Keyboard rotate right
1895-
TheTacticalView->setAngle( TheTacticalView->getAngle() + TheGlobalData->m_keyboardCameraRotateSpeed );
1896-
}
1897-
if( m_cameraZoomingIn && !m_cameraZoomingOut )
1898-
{
1899-
//Keyboard zoom in
1900-
TheTacticalView->zoomIn();
1901-
}
1902-
if( m_cameraZoomingOut && !m_cameraZoomingIn )
1903-
{
1904-
//Keyboard zoom out
1905-
TheTacticalView->zoomOut();
1886+
// TheSuperHackers @tweak The camera rotation and zoom are now decoupled from the render update.
1887+
const Real fpsRatio = (Real)BaseFps / TheGameEngine->getUpdateFps();
1888+
const Real rotateAngle = TheGlobalData->m_keyboardCameraRotateSpeed * fpsRatio;
1889+
const Real zoomHeight = (Real)View::ZoomHeightPerSecond * fpsRatio;
1890+
1891+
if( m_cameraRotatingLeft && !m_cameraRotatingRight )
1892+
{
1893+
TheTacticalView->setAngle( TheTacticalView->getAngle() - rotateAngle );
1894+
}
1895+
else if( m_cameraRotatingRight && !m_cameraRotatingLeft )
1896+
{
1897+
TheTacticalView->setAngle( TheTacticalView->getAngle() + rotateAngle );
1898+
}
1899+
1900+
if( m_cameraZoomingIn && !m_cameraZoomingOut )
1901+
{
1902+
TheTacticalView->zoom( -zoomHeight );
1903+
}
1904+
else if( m_cameraZoomingOut && !m_cameraZoomingIn )
1905+
{
1906+
TheTacticalView->zoom( +zoomHeight );
1907+
}
19061908
}
19071909

19081910

GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
3030

3131
#include "Common/GameType.h"
32+
#include "Common/GameEngine.h"
3233
#include "Common/MessageStream.h"
3334
#include "Common/Player.h"
3435
#include "Common/PlayerList.h"
@@ -366,15 +367,19 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
366367

367368
Int spin = msg->getArgument( 1 )->integer;
368369

370+
// TheSuperHackers @tweak The camera zoom is now decoupled from the render update.
371+
const Real fpsRatio = (Real)BaseFps / TheGameEngine->getUpdateFps();
372+
const Real zoomHeight = (Real)View::ZoomHeightPerSecond * fpsRatio;
373+
369374
if (spin > 0)
370375
{
371376
for ( ; spin > 0; spin--)
372-
TheTacticalView->zoomIn();
377+
TheTacticalView->zoom( -zoomHeight );
373378
}
374379
else
375380
{
376381
for ( ;spin < 0; spin++ )
377-
TheTacticalView->zoomOut();
382+
TheTacticalView->zoom( +zoomHeight );
378383
}
379384
}
380385

@@ -404,11 +409,8 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
404409
if (m_isScrolling)
405410
{
406411

407-
// TheSuperHackers @bugfix Mauller 07/06/2025 Adjust the viewport scrolling so it is independent of GameClient FPS
408-
// The scaling is based on the current logic rate, this provides a consistent scroll speed at all GameClient FPS
409-
// This also fixes scrolling within replays when fast forwarding due to the uncapped FPS
410-
// When the FPS is in excess of the expected frame rate, the ratio will reduce the offset of the cameras movement
411-
const Real logicToFpsRatio = TheGlobalData->m_framesPerSecondLimit / TheDisplay->getCurrentFPS();
412+
// TheSuperHackers @bugfix Mauller 07/06/2025 The camera scrolling is now decoupled from the render update.
413+
const Real fpsRatio = (Real)BaseFps / TheGameEngine->getUpdateFps();
412414

413415
switch (m_scrollType)
414416
{
@@ -437,27 +439,27 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
437439
// TheSuperHackers @info calculate the length of the vector to obtain the movement speed before the vector is normalized
438440
float vecLength = vec.length();
439441
vec.normalize();
440-
offset.x = TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * vecLength * vec.x * SCROLL_MULTIPLIER * TheGlobalData->m_keyboardScrollFactor;
441-
offset.y = TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * vecLength * vec.y * SCROLL_MULTIPLIER * TheGlobalData->m_keyboardScrollFactor;
442+
offset.x = TheGlobalData->m_horizontalScrollSpeedFactor * fpsRatio * vecLength * vec.x * SCROLL_MULTIPLIER * TheGlobalData->m_keyboardScrollFactor;
443+
offset.y = TheGlobalData->m_verticalScrollSpeedFactor * fpsRatio * vecLength * vec.y * SCROLL_MULTIPLIER * TheGlobalData->m_keyboardScrollFactor;
442444
}
443445
break;
444446
case SCROLL_KEY:
445447
{
446448
if (scrollDir[DIR_UP])
447449
{
448-
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
450+
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * fpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
449451
}
450452
if (scrollDir[DIR_DOWN])
451453
{
452-
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
454+
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * fpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
453455
}
454456
if (scrollDir[DIR_LEFT])
455457
{
456-
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
458+
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * fpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
457459
}
458460
if (scrollDir[DIR_RIGHT])
459461
{
460-
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
462+
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * fpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
461463
}
462464
}
463465
break;
@@ -467,19 +469,19 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
467469
UnsignedInt width = TheDisplay->getWidth();
468470
if (m_currentPos.y < edgeScrollSize)
469471
{
470-
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
472+
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * fpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
471473
}
472474
if (m_currentPos.y >= height-edgeScrollSize)
473475
{
474-
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
476+
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * fpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
475477
}
476478
if (m_currentPos.x < edgeScrollSize)
477479
{
478-
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
480+
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * fpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
479481
}
480482
if (m_currentPos.x >= width-edgeScrollSize)
481483
{
482-
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
484+
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * fpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
483485
}
484486
}
485487
break;

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,9 @@ View *View::prependViewToList( View *list )
125125
return this;
126126
}
127127

128-
void View::zoomIn( void )
128+
void View::zoom( Real height )
129129
{
130-
setHeightAboveGround(getHeightAboveGround() - 10.0f);
131-
}
132-
133-
void View::zoomOut( void )
134-
{
135-
setHeightAboveGround(getHeightAboveGround() + 10.0f);
130+
setHeightAboveGround(getHeightAboveGround() + height);
136131
}
137132

138133
/**

0 commit comments

Comments
 (0)