Skip to content

Conversation

@Mauller
Copy link

@Mauller Mauller commented Oct 18, 2025

Merge with Rebase

This PR adjusts the default max camera height to compensate for different screen aspect ratios.

Previous work fixed the vertical field of view to match retail and adjusted the horizontal fields of view.
But this resulted in significant distortion being observed in the periphery of the view and lower corners.
This distortion was also observed at the 16:9 aspect ratio and became significantly worse as the aspect ratio increased.

By maintaining the original 60 degrees horizontal field of view, while allowing the game to narrow the vertical field of view, increasing the camera height results in minimal to no distortion being observed.

This PR does not fix any other known camera issues and focuses on giving a playable default view.


TODO

  • Implement in generals

@Mauller Mauller self-assigned this Oct 18, 2025
@Mauller Mauller added Bug Something is not working right, typically is user facing GUI For graphical user interface Major Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour labels Oct 18, 2025
@Mauller Mauller added this to the Major bug fixes milestone Oct 18, 2025
@ElTioRata
Copy link

Comparison

@xezon
Copy link

xezon commented Oct 19, 2025

At 4:3 "This Change" gives identical view to "Original Game + GenTool" ✅

At 16:9 "This Change" gives a bit more view than "Original Game + GenTool" ❓

Is this correct? I do not recall if GenTool view is correct.

zoom16x9

@xezon xezon added Enhancement Is new feature or request and removed GUI For graphical user interface labels Oct 19, 2025
@Mauller
Copy link
Author

Mauller commented Oct 19, 2025

At 4:3 "This Change" gives identical view to "Original Game + GenTool" ✅

At 16:9 "This Change" gives a bit more view than "Original Game + GenTool" ❓

Is this correct? I do not recall if GenTool view is correct.

zoom16x9

My goal was to try match the vertical view as close as possible to retail, I think it's slightly less than compared to 4:3 but slightly more than 16:9 gentool + retail.

I think it has a reasonable tradeoff considering the extended horizontal view.

It also gives a reasonable view for aspect ratios between 4:3 and 1:1 as well. Giving a little more vertical view.

Under 1:1 things are still quite broken but a lot needs changing in the view handling to properly support portrait mode.

@xezon
Copy link

xezon commented Oct 19, 2025

Yes GenTool did take some vertical view away to compensate for the wider view, perhaps in an attempt to keep conditions fair. Additional camera height does give a competitive advantage. Are we ok with giving advantages to Wide Screen?

@Mauller
Copy link
Author

Mauller commented Oct 19, 2025

I wouldn't consider it an issue since most screens have been wide aspect For the past decade. If anything widescreen is the standard now.

Ultrawide is where it becomes more of an issue. But we could look at implementing a locked aspect mode for the tactical view in future.
This could give a standardised view to all players in a competition etc.

Or another option could be implementing tactical zoom to let people zoom out to view the entire map etc.

@Mauller Mauller force-pushed the fix-default-camera-height branch from 02a64e0 to 57fe78d Compare October 19, 2025 15:37
Copy link

@xezon xezon left a comment

Choose a reason for hiding this comment

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

Simple implementation, but man the EA code is confusing.

@Mauller Mauller force-pushed the fix-default-camera-height branch from 57fe78d to 271ca5b Compare October 19, 2025 19:09
@Mauller
Copy link
Author

Mauller commented Oct 19, 2025

Tweaked the code so setDefaultView is now setDefaultCameraHeight with a default argument of 1.0f for the heightScale.

Still need to look at the zoom default handling.

@Mauller Mauller force-pushed the fix-default-camera-height branch from 271ca5b to f6c96d8 Compare October 19, 2025 19:36
@Mauller
Copy link
Author

Mauller commented Oct 19, 2025

Updated with tweaked max and default zoom handling code.

@Mauller Mauller force-pushed the fix-default-camera-height branch from f6c96d8 to c3c7b85 Compare October 19, 2025 19:56
@Mauller
Copy link
Author

Mauller commented Oct 19, 2025

Small tweak to comments

@L3-M L3-M added this to the GenTool features replication milestone Oct 20, 2025
}

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.

@Mauller Mauller force-pushed the fix-default-camera-height branch from c3c7b85 to 7acc71b Compare October 23, 2025 18:30
@Mauller
Copy link
Author

Mauller commented Oct 23, 2025

I have updated based on feedback and extended the functionality of this PR to fix some other issues that crop up with the camera.

The camera extent limits have now been reduced by half at the edges of the map, allowing the camera to move closer to the edge of the map. This fixes the view at the bottom of the map experienced by quite a few maps.

It also extends the rendering distance from the camera of the terrain by 50% if a wide aspect ratio is in use. This works all the way up to 32:9 aspects. Originally i was going to scale based on aspect ratio but it always produced values higher than the fixed scale.

@Mauller Mauller changed the title fix(view): Adjust default camera height to compensate for screen aspect ratio fix(view): Adjust default camera height to compensate for screen aspect ratio, reduce camera map limits and increase terrain render distance. Oct 23, 2025
@Mauller Mauller force-pushed the fix-default-camera-height branch from 7acc71b to c5fbb86 Compare October 24, 2025 13:42
@Mauller
Copy link
Author

Mauller commented Oct 24, 2025

Last one was a quick rebase with main

@Mauller Mauller force-pushed the fix-default-camera-height branch from c5fbb86 to 52f7de7 Compare October 26, 2025 09:56
@Mauller
Copy link
Author

Mauller commented Oct 26, 2025

Tweaked naming, should be good now

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.

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

m_drawHeightY=m_height;
}
else {
//TheSuperHacker @bugfix Mauller 23/10/2025 Increase the terrain draw area for wide aspect ratios
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 offset = center.length();
// TheSuperHackers @bugfix Mauller 22/10/2025 Halve the camera offset to allow the camera to move closer to the map edges
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.

@Mauller Mauller force-pushed the fix-default-camera-height branch from 52f7de7 to ab0b316 Compare November 1, 2025 14:15
@Mauller Mauller changed the title fix(view): Adjust default camera height to compensate for screen aspect ratio, reduce camera map limits and increase terrain render distance. fix(view): Adjust default camera height to compensate for screen aspect ratio Nov 1, 2025
@Mauller
Copy link
Author

Mauller commented Nov 1, 2025

Reverted this to just have the camera height adjustments and nothing else.

@Mauller Mauller force-pushed the fix-default-camera-height branch 3 times, most recently from 968ad71 to e497ba8 Compare November 7, 2025 16:15
@xezon
Copy link

xezon commented Nov 15, 2025

Note for future:

When raising up the camera, the following things need to be scaled as well:

farZ in W3DView::setCameraTransform

m_x, m_y in HeightMapRenderObjClass

@Mauller Mauller force-pushed the fix-default-camera-height branch from e497ba8 to a0b7db7 Compare January 16, 2026 16:48
@greptile-apps
Copy link

greptile-apps bot commented Jan 16, 2026

Greptile Overview

Greptile Summary

This PR adjusts the default camera height to compensate for different screen aspect ratios by scaling the max and min camera heights based on the ratio between the current aspect ratio and the base 4:3 (800x600) aspect ratio. The implementation replaces the old setDefaultView() method with setCameraHeightAboveGroundLimitsToDefault() and introduces a new setZoomToMax() method to handle zoom separately from camera state resets.

Key changes:

  • Aspect ratio-based camera height scaling prevents visual distortion on widescreen displays
  • Separated zoom functionality into setZoomToMax() and setZoomToDefault() for better control
  • Camera limits now recalculated on resolution changes and game initialization
  • Script action doCameraSetDefault() refactored to set height limits, pitch, and angle separately

Issues found:

  • Critical logic bug in View::setZoomToMax() that adds max height to current height instead of setting to max
  • Syntax errors: typo heighScale instead of heightScale in ScriptActions
  • Unnecessary fabs() calls wrapping already-positive expressions in aspect ratio calculation

Confidence Score: 2/5

  • This PR has a critical logic bug that will cause incorrect camera behavior
  • Score reflects the critical bug in View::setZoomToMax() that incorrectly adds to current height rather than setting to max height, plus syntax errors in parameter naming that need correction before merge
  • Pay close attention to Core/GameEngine/Source/GameClient/View.cpp (logic bug), GeneralsMD/Code/GameEngine/Include/GameLogic/ScriptActions.h and GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp (typos)

Important Files Changed

Filename Overview
Core/GameEngine/Source/GameClient/View.cpp Added setZoomToMax() with incorrect implementation that adds max height to current height instead of setting height to max
Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp Implemented aspect ratio-based camera height adjustment with unnecessary fabs() calls and refactored zoom methods
GeneralsMD/Code/GameEngine/Include/GameLogic/ScriptActions.h Updated doCameraSetDefault() signature with typo: heighScale instead of heightScale
GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp Refactored doCameraSetDefault() to separately set height limits, pitch, and angle with typo in parameter name

Sequence Diagram

sequenceDiagram
    participant GameLogic
    participant InGameUI
    participant OptionsMenu
    participant TheTacticalView as W3DView
    participant GlobalData
    
    Note over GameLogic,W3DView: Game Initialization Flow
    GameLogic->>TheTacticalView: setCameraHeightAboveGroundLimitsToDefault()
    TheTacticalView->>GlobalData: Read m_maxCameraHeight & m_minCameraHeight
    TheTacticalView->>TheTacticalView: Calculate aspectRatioScale from viewport dimensions
    TheTacticalView->>TheTacticalView: Set m_maxHeightAboveGround = maxHeight * aspectRatioScale * heightScale
    TheTacticalView->>TheTacticalView: Set m_minHeightAboveGround = minHeight * aspectRatioScale
    GameLogic->>TheTacticalView: setAngleAndPitchToDefault()
    GameLogic->>TheTacticalView: setZoomToDefault()
    TheTacticalView->>TheTacticalView: setZoomToMax()
    TheTacticalView->>TheTacticalView: Calculate terrain height and desired zoom
    TheTacticalView->>TheTacticalView: Set m_zoom and m_heightAboveGround
    
    Note over InGameUI,TheTacticalView: UI Initialization/Reset Flow
    InGameUI->>TheTacticalView: setCameraHeightAboveGroundLimitsToDefault()
    TheTacticalView->>TheTacticalView: Recalculate height limits based on aspect ratio
    
    Note over OptionsMenu,TheTacticalView: Resolution Change Flow
    OptionsMenu->>TheTacticalView: setCameraHeightAboveGroundLimitsToDefault()
    TheTacticalView->>TheTacticalView: Recalculate height limits for new aspect ratio
    OptionsMenu->>TheTacticalView: setZoomToMax()
    TheTacticalView->>TheTacticalView: Adjust zoom for new height limits
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

10 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +129 to +132
void View::setZoomToMax()
{
setHeightAboveGround(getHeightAboveGround() + m_maxHeightAboveGround);
}
Copy link

Choose a reason for hiding this comment

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

logic: incorrectly adds m_maxHeightAboveGround to current height instead of setting height to max

Suggested change
void View::setZoomToMax()
{
setHeightAboveGround(getHeightAboveGround() + m_maxHeightAboveGround);
}
void View::setZoomToMax()
{
setHeightAboveGround(m_maxHeightAboveGround);
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: Core/GameEngine/Source/GameClient/View.cpp
Line: 129:132

Comment:
**logic:** incorrectly adds `m_maxHeightAboveGround` to current height instead of setting height to max

```suggestion
void View::setZoomToMax()
{
	setHeightAboveGround(m_maxHeightAboveGround);
}
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +1942 to +1949
if (currentAspectRatio > baseAspectRatio)
{
aspectRatioScale = fabs(( 1 + ( currentAspectRatio - baseAspectRatio) ));
}
else
{
aspectRatioScale = fabs(( 1 - ( baseAspectRatio - currentAspectRatio) ));
}
Copy link

Choose a reason for hiding this comment

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

style: unnecessary fabs() wraps expressions that are already positive by construction

Suggested change
if (currentAspectRatio > baseAspectRatio)
{
aspectRatioScale = fabs(( 1 + ( currentAspectRatio - baseAspectRatio) ));
}
else
{
aspectRatioScale = fabs(( 1 - ( baseAspectRatio - currentAspectRatio) ));
}
if (currentAspectRatio > baseAspectRatio)
{
aspectRatioScale = 1 + (currentAspectRatio - baseAspectRatio);
}
else
{
aspectRatioScale = 1 - (baseAspectRatio - currentAspectRatio);
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
Line: 1942:1949

Comment:
**style:** unnecessary `fabs()` wraps expressions that are already positive by construction

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

How can I resolve this? If you propose a fix, please make it concise.

/** doCameraSetDefault */
//-------------------------------------------------------------------------------------------------
void ScriptActions::doCameraSetDefault(Real pitch, Real angle, Real maxHeight)
void ScriptActions::doCameraSetDefault(Real pitch, Real angle, Real heighScale)
Copy link

Choose a reason for hiding this comment

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

syntax: typo: heighScale should be heightScale

Suggested change
void ScriptActions::doCameraSetDefault(Real pitch, Real angle, Real heighScale)
void ScriptActions::doCameraSetDefault(Real pitch, Real angle, Real heightScale)
Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp
Line: 4611:4611

Comment:
**syntax:** typo: `heighScale` should be `heightScale`

```suggestion
void ScriptActions::doCameraSetDefault(Real pitch, Real angle, Real heightScale)
```

How can I resolve this? If you propose a fix, please make it concise.

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);
Copy link

Choose a reason for hiding this comment

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

syntax: typo: heighScale should be heightScale

Suggested change
void doCameraSetDefault(Real pitch, Real angle, Real heighScale);
void doCameraSetDefault(Real pitch, Real angle, Real heightScale);
Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Include/GameLogic/ScriptActions.h
Line: 114:114

Comment:
**syntax:** typo: `heighScale` should be `heightScale`

```suggestion
	void doCameraSetDefault(Real pitch, Real angle, Real heightScale);
```

How can I resolve this? If you propose a fix, please make it concise.

@Mauller Mauller force-pushed the fix-default-camera-height branch from a0b7db7 to 22e6c6b Compare January 28, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Enhancement Is new feature or request Gen Relates to Generals Major Severity: Minor < Major < Critical < Blocker ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Camera height does not scale properly along with aspect ratio of game resolution

5 participants