diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/View.h b/GeneralsMD/Code/GameEngine/Include/GameClient/View.h index 415726609e..28345bfd57 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/View.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/View.h @@ -234,6 +234,8 @@ class View : public Snapshot virtual void forceCameraConstraintRecalc(void) {} virtual void setGuardBandBias( const Coord2D *gb ) = 0; + virtual void adjustFovToAspectRatio(const Int width, const Int height) { }; + protected: friend class Display; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp index 7eeb18b5d2..5b66b4755b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp @@ -161,6 +161,10 @@ Bool Display::setDisplayMode( UnsignedInt xres, UnsignedInt yres, UnsignedInt bi TheTacticalView->setHeight((Real)oldViewHeight/(Real)oldDisplayHeight*(Real)yres); TheTacticalView->setOrigin((Real)oldViewOriginX/(Real)oldDisplayWidth*(Real)xres, (Real)oldViewOriginY/(Real)oldDisplayHeight*(Real)yres); + + // TheSuperHackers @tweak valeronm 25/03/2025 Adjust camera FOV according to display resolution + TheTacticalView->adjustFovToAspectRatio(xres, yres); + return TRUE; } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index e540c5ab11..4fe5d50e03 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -1165,10 +1165,15 @@ void InGameUI::init( void ) TheTacticalView->init(); TheDisplay->attachView( TheTacticalView ); + Int displayWidth = TheDisplay->getWidth(); + Int displayHeight = TheDisplay->getHeight(); // make the tactical display the full screen width for now - TheTacticalView->setWidth( TheDisplay->getWidth()); + TheTacticalView->setWidth(displayWidth); // make the tactical display 0.76 of full screen so no drawing under GUI. - TheTacticalView->setHeight( TheDisplay->getHeight() * 0.77f); + TheTacticalView->setHeight(displayHeight * 0.77f); + + // TheSuperHackers @tweak valeronm 25/03/2025 Adjust camera FOV according to display resolution + TheTacticalView->adjustFovToAspectRatio(displayWidth, displayHeight); } TheTacticalView->setDefaultView(0.0f, 0.0f, 1.0f); diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h index 3bb8218743..446b72e710 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h +++ b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h @@ -232,7 +232,7 @@ class W3DView : public View, public SubsystemInterface virtual void setGuardBandBias( const Coord2D *gb ) { m_guardBandBias.x = gb->x; m_guardBandBias.y = gb->y; } - + virtual void adjustFovToAspectRatio(const Int width, const Int height); private: CameraClass *m_3DCamera; ///< camera representation for 3D scene diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp index 26b369fac0..e9906ae3a1 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp @@ -226,10 +226,48 @@ void W3DView::setWidth(Int width) m_3DCamera->Get_Viewport(vMin,vMax); vMax.X=(Real)(m_originX+width)/(Real)TheDisplay->getWidth(); m_3DCamera->Set_Viewport(vMin,vMax); +} + +// TheSuperHackers @tweak valeronm 25/03/2025 Adjusting FOV to look similar to what we have in in 4:3 (hFOV: 50, vFOV 38.55) +void W3DView::adjustFovToAspectRatio(const Int width, const Int height) +{ + static const Real fixedHFOV = 50.00f; + static const Real fixedVFOV = 38.55f; - //we want to maintain the same scale, so we'll need to adjust the fov. - //default W3D fov for full-screen is 50 degrees. - m_3DCamera->Set_View_Plane((Real)width/(Real)TheDisplay->getWidth()*DEG_TO_RADF(50.0f),-1); + const Real aspectRatio = static_cast(width)/ static_cast(height); + Real vFOVRad, hFOVRad; + Bool drawEntireTerrain = false; + if (aspectRatio >= 4.0f / 3.0f) + { + // Wider than 4:3 resolutions get fixed vFOV 38.55 + vFOVRad = DEG_TO_RADF(fixedVFOV); + hFOVRad = 2.0f * atan(tan(vFOVRad / 2.0f) * aspectRatio); + drawEntireTerrain = true; + } + else if (aspectRatio >= 1.0) + { + // Narrower than 4:3 but not yet portrait resolutions get fixed hFOV 50.0 + hFOVRad = DEG_TO_RADF(fixedHFOV); + vFOVRad = 2.0f * atan(tan(hFOVRad / 2.0f) / aspectRatio); + } + else + { + // Portrait resolutions get fixed vFOV adjusted to aspect ratio + // vFOV increases from 50.0 for 1:1 to 60.0 for 9:21 and then fixed 60.0 + static const Real adjMinRatio = 9.0f / 21.0f; + static const Real adjValue = 10.0f; + + Real adjustment; + if (aspectRatio < adjMinRatio) + adjustment = adjValue; + else + adjustment = (1 - aspectRatio) * adjValue / (1 - adjMinRatio); + vFOVRad = DEG_TO_RADF(50 + adjustment); + hFOVRad = 2.0f * atan(tan(vFOVRad / 2.0f) * aspectRatio); + drawEntireTerrain = true; + } + TheWritableGlobalData->m_drawEntireTerrain = drawEntireTerrain; + m_3DCamera->Set_View_Plane(hFOVRad, vFOVRad); } //-------------------------------------------------------------------------------------------------