Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,11 @@ class GlobalData : public SubsystemInterface
Real m_cameraPitch;
Real m_cameraYaw;
Real m_cameraHeight;

// TheSuperHackers @info Max and Min camera height for the original 4:3 view, these are then scaled for other aspect ratios.
Real m_maxCameraHeight;
Real m_minCameraHeight;

Real m_terrainHeightAtEdgeOfMap;
Real m_unitDamagedThresh;
Real m_unitReallyDamagedThresh;
Expand Down
5 changes: 3 additions & 2 deletions GeneralsMD/Code/GameEngine/Include/GameClient/View.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class View : public Snapshot
virtual Bool isTimeFrozen(void){ return false;} ///< Freezes time during the next camera movement.
virtual Int getTimeMultiplier(void) {return 1;}; ///< Get the time multiplier.
virtual void setTimeMultiplier(Int multiple) {}; ///< Set the time multiplier.
virtual void setDefaultView(Real pitch, Real angle, Real maxHeight) {};
virtual void setCameraHeightAboveGroundLimitsToDefault(Real heightScale = 1.0f) {};
virtual void zoomCamera( Real finalZoom, Int milliseconds, Real easeIn, Real easeOut ) {};
virtual void pitchCamera( Real finalPitch, Int milliseconds, Real easeIn, Real easeOut ) {};

Expand All @@ -189,7 +189,8 @@ class View : public Snapshot
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 void setZoomToMax();
virtual void setZoomToDefault() { m_zoom = 1.0f; } ///< Set zoom to default value
virtual void setOkToAdjustHeight( Bool val ) { m_okToAdjustHeight = val; } ///< Set this to adjust camera height

// for debugging
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class ScriptActions : public ScriptActionsInterface

void doCameraTetherNamed(const AsciiString& unit, Bool snapToUnit, Real play);
void doCameraStopTetherNamed(void);
void doCameraSetDefault(Real pitch, Real angle, Real maxHeight);
void doCameraSetDefault(Real pitch, Real angle, Real heighScale);

void doOversizeTheTerrain(Int amount);
void doMoveCameraAlongWaypointPath(const AsciiString& waypoint, Real sec, Real cameraStutterSec, Real easeIn, Real easeOut);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,11 @@ static void saveOptions( void )

TheInGameUI->recreateControlBar();
TheInGameUI->refreshCustomUiResources();

// TheSuperHackers @info Only update the camera limits and set the zoom to max to not interfere with the scripted camera on the shellmap
// The tactical view gets reset at game start, this is here so the shell map looks correct once the resolution is adjusted
TheTacticalView->setCameraHeightAboveGroundLimitsToDefault();
TheTacticalView->setZoomToMax();
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1250,7 +1250,7 @@ void InGameUI::init( void )
TheTacticalView->setWidth( TheDisplay->getWidth() );
TheTacticalView->setHeight( TheDisplay->getHeight() );
}
TheTacticalView->setDefaultView(0.0f, 0.0f, 1.0f);
TheTacticalView->setCameraHeightAboveGroundLimitsToDefault();

/** @todo this may be the wrong place to create the sidebar, but for now
this is where it lives */
Expand Down Expand Up @@ -1995,7 +1995,7 @@ void InGameUI::reset( void )
// reset the command bar
TheControlBar->reset();

TheTacticalView->setDefaultView(0.0f, 0.0f, 1.0f);
TheTacticalView->setCameraHeightAboveGroundLimitsToDefault();

ResetInGameChat();

Expand Down
5 changes: 5 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/GameClient/View.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ void View::zoom( Real height )
setHeightAboveGround(getHeightAboveGround() + height);
}

void View::setZoomToMax()
{
setHeightAboveGround(getHeightAboveGround() + m_maxHeightAboveGround);
}

void View::lockViewUntilFrame(UnsignedInt frame)
{
m_viewLockedUntilFrame = frame;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4609,9 +4609,11 @@ void ScriptActions::doCameraStopTetherNamed(void)
//-------------------------------------------------------------------------------------------------
/** doCameraSetDefault */
//-------------------------------------------------------------------------------------------------
void ScriptActions::doCameraSetDefault(Real pitch, Real angle, Real maxHeight)
void ScriptActions::doCameraSetDefault(Real pitch, Real angle, Real heighScale)
{
TheTacticalView->setDefaultView(pitch, angle, maxHeight);
TheTacticalView->setCameraHeightAboveGroundLimitsToDefault(heighScale);
TheTacticalView->setPitch(pitch);
TheTacticalView->setAngle(angle);
}

//-------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2077,6 +2077,8 @@ void GameLogic::startNewGame( Bool loadingSaveGame )
// update the loadscreen
updateLoadProgress(LOAD_PROGRESS_POST_PRELOAD_ASSETS);

// TheSuperHackers @info Initialize the camera height limits to default if the resolution was changed
TheTacticalView->setCameraHeightAboveGroundLimitsToDefault();
TheTacticalView->setAngleAndPitchToDefault();
TheTacticalView->setZoomToDefault();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,14 @@ class W3DView : public View, public SubsystemInterface
virtual void Add_Camera_Shake(const Coord3D & position,float radius, float duration, float power); //WST 10.18.2002
virtual Int getTimeMultiplier(void) {return m_timeMultiplier;};///< Get the time multiplier.
virtual void setTimeMultiplier(Int multiple) {m_timeMultiplier = multiple;}; ///< Set the time multiplier.
virtual void setDefaultView(Real pitch, Real angle, Real maxHeight);
virtual void setCameraHeightAboveGroundLimitsToDefault(Real heightScale = 1.0f);
virtual void zoomCamera( Real finalZoom, Int milliseconds, Real easeIn, Real easeOut );
virtual void pitchCamera( Real finalPitch, Int milliseconds, Real easeIn, Real easeOut );

virtual void setHeightAboveGround(Real z);
virtual void setZoom(Real z);
virtual void setZoomToDefault( void ); ///< Set zoom to default value
virtual void setZoomToMax();
virtual void setZoomToDefault(); ///< Set zoom to default value - TheSuperHackers @info This function resets the camera so will cause scripted cameras to halt

virtual void setFieldOfView( Real angle ); ///< Set the horizontal field of view angle

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,8 @@ void W3DView::calcCameraConstraints()
center.x -= bottom.x;
center.y -= bottom.y;

Real offset = center.length();
// TheSuperHackers @bugfix Mauller 22/10/2025 Halve the camera offset to allow the camera to move closer to the map edges
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tweak

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing this for now till after this and your camera extents PR's are done

Real offset = center.length() * 0.5f;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this behavior and I suspect this was done to address #1270. However, the black area that this creates is quite substantial. I have created new change #1752 to address #1270 without extending the constraints area into blackness.

There still is merit to experiment with a greater viewable area, for example center.length() * 0.9f, but I suggest to do that after #1752.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will revert the offset change for now and we can look at that after this and #1752 are merged.


if (TheGlobalData->m_debugAI) {
offset = -1000; // push out the constraints so we can look at staging areas.
Expand Down Expand Up @@ -1923,12 +1924,25 @@ void W3DView::setAngleAndPitchToDefault( void )

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
void W3DView::setDefaultView(Real pitch, Real angle, Real maxHeight)
void W3DView::setCameraHeightAboveGroundLimitsToDefault(Real heightScale)
{
// MDC - we no longer want to rotate maps (design made all of them right to begin with)
// m_defaultAngle = angle * M_PI/180.0f;
m_defaultPitchAngle = pitch;
m_maxHeightAboveGround = TheGlobalData->m_maxCameraHeight*maxHeight;
// TheSuperHackers @fix Mauller Adjust the camera height to compensate for the screen aspect ratio
Real baseAspectRatio = (Real)DEFAULT_DISPLAY_WIDTH / (Real)DEFAULT_DISPLAY_HEIGHT;
Real currentAspectRatio = (Real)TheTacticalView->getWidth() / (Real)TheTacticalView->getHeight();
Real aspectRatioScale = 0.0f;

if (currentAspectRatio > baseAspectRatio)
{
aspectRatioScale = fabs(( 1 + ( currentAspectRatio - baseAspectRatio) ));
}
else
{
aspectRatioScale = fabs(( 1 - ( baseAspectRatio - currentAspectRatio) ));
}

m_maxHeightAboveGround = TheGlobalData->m_maxCameraHeight * aspectRatioScale * heightScale;
m_minHeightAboveGround = TheGlobalData->m_minCameraHeight * aspectRatioScale;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On map Defcon6 with 16:9 resolution, I can see black top edges when scrolling quickly. These are the edges of the rendered height map (a rectangle). Can you also look into scaling the terrain draw area? I do not yet know how this code works exactly but you can start looking around m_drawEntireTerrain, class WorldHeightMap. When zooming out more, it becomes more obvious (there is a Debug Command to zoom out).

If you do not want to do it in this change, then a follow up is also ok.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be possible, i think i have seen it in the camera code elsewhere.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So i have implemented a 1.5x scaling factor to the world height map draw area when a wide aspect ratio is used.
This works all the way up to 32:9 aspect ratios with the camera height scaling code.

I used a fixed scaling factor since when using an aspect ratio based scale it would often increase the draw area well beyond the size of the map itself.


if (m_minHeightAboveGround > m_maxHeightAboveGround)
m_maxHeightAboveGround = m_minHeightAboveGround;
}
Expand Down Expand Up @@ -1971,10 +1985,8 @@ void W3DView::setZoom(Real z)

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
void W3DView::setZoomToDefault( void )
void W3DView::setZoomToMax()
{
// default zoom has to be max, otherwise players will just zoom to max always

// terrain height + desired height offset == cameraOffset * actual zoom
// find best approximation of max terrain height we can see
Real terrainHeightMax = getHeightAroundPos(m_pos.x, m_pos.y);
Expand All @@ -1987,14 +1999,22 @@ void W3DView::setZoomToDefault( void )
m_zoom = desiredZoom;
m_heightAboveGround = m_maxHeightAboveGround;

m_cameraConstraintValid = false; // recalc it.
setCameraTransform();
}

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
void W3DView::setZoomToDefault()
{
// default zoom has to be max, otherwise players will just zoom to max always
m_doingMoveCameraOnWaypointPath = false;
m_CameraArrivedAtWaypointOnPathFlag = false;
m_doingRotateCamera = false;
m_doingPitchCamera = false;
m_doingZoomCamera = false;
m_doingScriptedCameraLock = false;
m_cameraConstraintValid = false; // recalc it.
setCameraTransform();
setZoomToMax();
}

//-------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
#include "W3DDevice/GameClient/TerrainTex.h"
#include "W3DDevice/GameClient/W3DShadow.h"

#include "GameClient/view.h"

#include "Common/file.h"


Expand Down Expand Up @@ -534,6 +536,19 @@ WorldHeightMap::WorldHeightMap(ChunkInputStream *pStrm, Bool logicalDataOnly):
m_drawWidthX=m_width;
m_drawHeightY=m_height;
}
else {
//TheSuperHacker @bugfix Mauller 23/10/2025 Increase the terrain draw area for wide aspect ratios
Copy link

@xezon xezon Oct 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tweak or @fix, because in original game this is not a bug, because the widescreen camera can not see that far.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this does not work correctly in Shell Map. When changing aspect ratio from 4:3 to wide, then this code is not called. Can we run this after the WorldHeightMap was created?

Copy link
Author

@Mauller Mauller Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah i am just looking a bit more into this and it's not very straightforwards, the heightmap is nested inside BaseHeightMap inside TheTerrainVisual within TheTerrainLogic.

Just muddling through a way to cleanly get at the height map inside it all from the terrain logic which has a singleton.

Real baseAspectRatio = (Real)DEFAULT_DISPLAY_WIDTH / (Real)DEFAULT_DISPLAY_HEIGHT;
Real currentAspectRatio = (Real)TheTacticalView->getWidth() / (Real)TheTacticalView->getHeight();
constexpr Real drawAreaScaleFactor = 1.5f;

if (currentAspectRatio > baseAspectRatio)
{
m_drawWidthX *= drawAreaScaleFactor;
m_drawHeightY *= drawAreaScaleFactor;
}
}

if (m_drawWidthX > m_width) {
m_drawWidthX = m_width;
}
Expand Down
Loading