From 8a9043aac80429deac2bbbe5a3727b6b14bad3c4 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Thu, 18 Sep 2025 19:48:19 +0200 Subject: [PATCH 1/4] bugfix(view): Fix camera terrain height adjustment during camera playback in Replay playback --- GeneralsMD/Code/GameEngine/Include/GameClient/View.h | 5 +---- .../Code/GameEngine/Source/GameClient/InGameUI.cpp | 3 ++- .../Code/GameEngine/Source/GameClient/View.cpp | 6 +----- .../Source/W3DDevice/GameClient/W3DView.cpp | 12 +++++------- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/View.h b/GeneralsMD/Code/GameEngine/Include/GameClient/View.h index 127eb0fc1f..b204b908e1 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/View.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/View.h @@ -184,12 +184,11 @@ class View : public Snapshot virtual const Coord3D& get3DCameraPosition() const = 0; ///< Returns the actual camera position virtual Real getZoom() { return m_zoom; } - virtual void setZoom(Real z) { } + virtual void setZoom(Real z) { m_zoom = z; } virtual Real getHeightAboveGround() { return m_heightAboveGround; } virtual void setHeightAboveGround(Real z); virtual void zoom( Real height ); ///< Zoom in/out, closer to the ground, limit to min, or farther away from the ground, limit to max virtual void setZoomToDefault( void ) { m_zoom = 1.0f; } ///< Set zoom to default value - virtual Real getMaxZoom( void ) { return m_maxZoom; } ///< return max zoom value virtual void setOkToAdjustHeight( Bool val ) { m_okToAdjustHeight = val; } ///< Set this to adjust camera height // for debugging @@ -267,8 +266,6 @@ class View : public Snapshot Real m_angle; ///< Angle at which view has been rotated about the Z axis Real m_pitchAngle; ///< Rotation of view direction around horizontal (X) axis - Real m_maxZoom; ///< Largest zoom value (minimum actual zoom) - Real m_minZoom; ///< Smallest zoom value (maximum actual zoom) Real m_maxHeightAboveGround; ///< Highest camera above ground value Real m_minHeightAboveGround; ///< Lowest camera above ground value Real m_zoom; ///< Current zoom value diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index 6a4164d916..9f3071c90a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5517,7 +5517,8 @@ void InGameUI::updateAndDrawWorldAnimations( void ) UnsignedInt height = wad->m_anim->getCurrentFrameHeight(); // scale the width and height given the camera zoom level - Real zoomScale = TheTacticalView->getMaxZoom() / TheTacticalView->getZoom(); + constexpr Real scaler = 1.3f; + Real zoomScale = scaler / TheTacticalView->getZoom(); width *= zoomScale; height *= zoomScale; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/View.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/View.cpp index c2481779ec..7d49cb9a7f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/View.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/View.cpp @@ -49,9 +49,7 @@ View::View( void ) m_heightAboveGround = 0.0f; m_lockDist = 0.0f; m_maxHeightAboveGround = 0.0f; - m_maxZoom = 0.0f; m_minHeightAboveGround = 0.0f; - m_minZoom = 0.0f; m_next = NULL; m_okToAdjustHeight = TRUE; m_originX = 0; @@ -99,9 +97,7 @@ void View::init( void ) m_cameraLockDrawable = NULL; m_zoomLimited = TRUE; - m_maxZoom = 1.3f; - m_minZoom = 0.2f; - m_zoom = m_maxZoom; + m_zoom = 1.0f; m_maxHeightAboveGround = TheGlobalData->m_maxCameraHeight; m_minHeightAboveGround = TheGlobalData->m_minCameraHeight; m_okToAdjustHeight = FALSE; diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp index 7231705257..23df35b329 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp @@ -1940,15 +1940,13 @@ void W3DView::setHeightAboveGround(Real z) //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- +// TheSuperHackers @bugfix xezon 18/09/2025 setZoom is no longer clamped by a min and max zoom. +// Instead the min and max camera height will be clamped elsewhere. Clamping the zoom would cause +// issues with camera playback in replay playback where changes in terrain elevation would not raise +// the camera height. void W3DView::setZoom(Real z) { - m_zoom = z; - - if (m_zoom < m_minZoom) - m_zoom = m_minZoom; - - if (m_zoom > m_maxZoom) - m_zoom = m_maxZoom; + View::setZoom(z); m_doingMoveCameraOnWaypointPath = false; m_CameraArrivedAtWaypointOnPathFlag = false; From ca186dc5c71d8e84747e6f6b82e5f97c0007da45 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Fri, 19 Sep 2025 09:10:47 +0200 Subject: [PATCH 2/4] Add todo comment --- GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index 9f3071c90a..b9b634db3b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5517,6 +5517,7 @@ void InGameUI::updateAndDrawWorldAnimations( void ) UnsignedInt height = wad->m_anim->getCurrentFrameHeight(); // scale the width and height given the camera zoom level + // TheSuperHackers @todo Reword this with sane values. scaler=1.3 originally came from TheTacticalView::getMaxZoom() constexpr Real scaler = 1.3f; Real zoomScale = scaler / TheTacticalView->getZoom(); width *= zoomScale; From 8032ff70f2a85998e6286253a023d6b4a81a0a33 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 20 Sep 2025 12:26:17 +0200 Subject: [PATCH 3/4] Rework --- GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index b9b634db3b..1696a7a00e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5517,7 +5517,7 @@ void InGameUI::updateAndDrawWorldAnimations( void ) UnsignedInt height = wad->m_anim->getCurrentFrameHeight(); // scale the width and height given the camera zoom level - // TheSuperHackers @todo Reword this with sane values. scaler=1.3 originally came from TheTacticalView::getMaxZoom() + // TheSuperHackers @todo Rework this with sane values. scaler=1.3 originally came from TheTacticalView::getMaxZoom() constexpr Real scaler = 1.3f; Real zoomScale = scaler / TheTacticalView->getZoom(); width *= zoomScale; From 7bfca02242edd87ea7291227288c2c9b1ccf8641 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 20 Sep 2025 12:29:18 +0200 Subject: [PATCH 4/4] Replicate in Generals --- Generals/Code/GameEngine/Include/GameClient/View.h | 5 +---- .../Code/GameEngine/Source/GameClient/InGameUI.cpp | 4 +++- Generals/Code/GameEngine/Source/GameClient/View.cpp | 6 +----- .../Source/W3DDevice/GameClient/W3DView.cpp | 12 +++++------- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/View.h b/Generals/Code/GameEngine/Include/GameClient/View.h index 88ebe6138a..ae60609b1e 100644 --- a/Generals/Code/GameEngine/Include/GameClient/View.h +++ b/Generals/Code/GameEngine/Include/GameClient/View.h @@ -180,12 +180,11 @@ class View : public Snapshot virtual const Coord3D& get3DCameraPosition() const = 0; ///< Returns the actual camera position virtual Real getZoom() { return m_zoom; } - virtual void setZoom(Real z) { } + virtual void setZoom(Real z) { m_zoom = z; } virtual Real getHeightAboveGround() { return m_heightAboveGround; } virtual void setHeightAboveGround(Real z); virtual void zoom( Real height ); ///< Zoom in/out, closer to the ground, limit to min, or farther away from the ground, limit to max virtual void setZoomToDefault( void ) { m_zoom = 1.0f; } ///< Set zoom to default value - virtual Real getMaxZoom( void ) { return m_maxZoom; } ///< return max zoom value virtual void setOkToAdjustHeight( Bool val ) { m_okToAdjustHeight = val; } ///< Set this to adjust camera height // for debugging @@ -263,8 +262,6 @@ class View : public Snapshot Real m_angle; ///< Angle at which view has been rotated about the Z axis Real m_pitchAngle; ///< Rotation of view direction around horizontal (X) axis - Real m_maxZoom; ///< Largest zoom value (minimum actual zoom) - Real m_minZoom; ///< Smallest zoom value (maximum actual zoom) Real m_maxHeightAboveGround; ///< Highest camera above ground value Real m_minHeightAboveGround; ///< Lowest camera above ground value Real m_zoom; ///< Current zoom value diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index 68ddc81b73..616d2fca86 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5345,7 +5345,9 @@ void InGameUI::updateAndDrawWorldAnimations( void ) UnsignedInt height = wad->m_anim->getCurrentFrameHeight(); // scale the width and height given the camera zoom level - Real zoomScale = TheTacticalView->getMaxZoom() / TheTacticalView->getZoom(); + // TheSuperHackers @todo Rework this with sane values. scaler=1.3 originally came from TheTacticalView::getMaxZoom() + constexpr Real scaler = 1.3f; + Real zoomScale = scaler / TheTacticalView->getZoom(); width *= zoomScale; height *= zoomScale; diff --git a/Generals/Code/GameEngine/Source/GameClient/View.cpp b/Generals/Code/GameEngine/Source/GameClient/View.cpp index c864b2feef..c7c16c651a 100644 --- a/Generals/Code/GameEngine/Source/GameClient/View.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/View.cpp @@ -49,9 +49,7 @@ View::View( void ) m_heightAboveGround = 0.0f; m_lockDist = 0.0f; m_maxHeightAboveGround = 0.0f; - m_maxZoom = 0.0f; m_minHeightAboveGround = 0.0f; - m_minZoom = 0.0f; m_next = NULL; m_okToAdjustHeight = TRUE; m_originX = 0; @@ -99,9 +97,7 @@ void View::init( void ) m_cameraLockDrawable = NULL; m_zoomLimited = TRUE; - m_maxZoom = 1.3f; - m_minZoom = 0.2f; - m_zoom = m_maxZoom; + m_zoom = 1.0f; m_maxHeightAboveGround = TheGlobalData->m_maxCameraHeight; m_minHeightAboveGround = TheGlobalData->m_minCameraHeight; m_okToAdjustHeight = FALSE; diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp index 0d887707f6..6cb2ee8fad 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp @@ -1777,15 +1777,13 @@ void W3DView::setHeightAboveGround(Real z) //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- +// TheSuperHackers @bugfix xezon 18/09/2025 setZoom is no longer clamped by a min and max zoom. +// Instead the min and max camera height will be clamped elsewhere. Clamping the zoom would cause +// issues with camera playback in replay playback where changes in terrain elevation would not raise +// the camera height. void W3DView::setZoom(Real z) { - m_zoom = z; - - if (m_zoom < m_minZoom) - m_zoom = m_minZoom; - - if (m_zoom > m_maxZoom) - m_zoom = m_maxZoom; + View::setZoom(z); m_doingMoveCameraOnWaypointPath = false; m_doingRotateCamera = false;