Skip to content

Commit 01dc8cb

Browse files
committed
Implement multiple resolution font size methods
1 parent d3784a4 commit 01dc8cb

File tree

7 files changed

+154
-38
lines changed

7 files changed

+154
-38
lines changed

Core/GameEngine/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(GAMEENGINE_SRC
22
# Include/Common/AcademyStats.h
33
# Include/Common/ActionManager.h
4+
Include/Common/AddonCompat.h
45
Include/Common/ArchiveFile.h
56
Include/Common/ArchiveFileSystem.h
67
Include/Common/AsciiString.h
@@ -552,6 +553,7 @@ set(GAMEENGINE_SRC
552553
# Include/GameNetwork/WOLBrowser/FEBDispatch.h
553554
# Include/GameNetwork/WOLBrowser/WebBrowser.h
554555
# Include/Precompiled/PreRTS.h
556+
Source/Common/AddonCompat.cpp
555557
Source/Common/Audio/AudioEventRTS.cpp
556558
Source/Common/Audio/AudioRequest.cpp
557559
Source/Common/Audio/DynamicAudioEventInfo.cpp
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
** Command & Conquer Generals Zero Hour(tm)
3+
** Copyright 2025 TheSuperHackers
4+
**
5+
** This program is free software: you can redistribute it and/or modify
6+
** it under the terms of the GNU General Public License as published by
7+
** the Free Software Foundation, either version 3 of the License, or
8+
** (at your option) any later version.
9+
**
10+
** This program is distributed in the hope that it will be useful,
11+
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
** GNU General Public License for more details.
14+
**
15+
** You should have received a copy of the GNU General Public License
16+
** along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#pragma once
20+
21+
namespace addon
22+
{
23+
extern Bool HasFullviewportDat();
24+
25+
} // namespace addon
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
** Command & Conquer Generals Zero Hour(tm)
3+
** Copyright 2025 TheSuperHackers
4+
**
5+
** This program is free software: you can redistribute it and/or modify
6+
** it under the terms of the GNU General Public License as published by
7+
** the Free Software Foundation, either version 3 of the License, or
8+
** (at your option) any later version.
9+
**
10+
** This program is distributed in the hope that it will be useful,
11+
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
** GNU General Public License for more details.
14+
**
15+
** You should have received a copy of the GNU General Public License
16+
** along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include "PreRTS.h"
20+
21+
#include "Common/AddonCompat.h"
22+
#include "Common/FileSystem.h"
23+
24+
namespace addon
25+
{
26+
Bool HasFullviewportDat()
27+
{
28+
Char value = '0';
29+
if (File* file = TheFileSystem->openFile("GenTool/fullviewport.dat", File::READ | File::BINARY))
30+
{
31+
file->read(&value, 1);
32+
}
33+
return value != '0';
34+
}
35+
36+
} // namespace addon

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ class AsciiString;
6868
//-----------------------------------------------------------------------------
6969
class GlobalLanguage : public SubsystemInterface
7070
{
71+
public:
72+
73+
enum ResolutionFontSizeMethod
74+
{
75+
ResolutionFontSizeMethod_Classic, // Uses the original scaling method. Scales poorly on wide screens and large resolutions.
76+
ResolutionFontSizeMethod_Strict, // Uses a strict scaling method. Width and height are strictly bounded on upscales. Works well for accurate UI layouts and with large resolutions.
77+
ResolutionFontSizeMethod_Balanced, // Uses a balanced scaling method. Width and height are evenly weighted for upscales. Works well for the original Game UI and with large resolutions.
78+
};
79+
7180
public:
7281

7382
GlobalLanguage();
@@ -99,13 +108,13 @@ class GlobalLanguage : public SubsystemInterface
99108
FontDesc m_creditsTitleFont;
100109
FontDesc m_creditsPositionFont;
101110
FontDesc m_creditsNormalFont;
102-
103111
Real m_resolutionFontSizeAdjustment;
104-
105-
//UnicodeString m_unicodeFontNameUStr;
112+
ResolutionFontSizeMethod m_resolutionFontSizeMethod;
106113

107114
Int adjustFontSize(Int theFontSize); // Adjusts font size for resolution. jba.
108115

116+
void parseCustomDefinition();
117+
109118
typedef std::list<AsciiString> StringList; // Used for our font file names that we want to load
110119
typedef StringList::iterator StringListIt;
111120

GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ void GameEngine::init()
495495
initSubsystem(TheTerrainTypes,"TheTerrainTypes", MSGNEW("GameEngineSubsystem") TerrainTypeCollection(), &xferCRC, "Data\\INI\\Default\\Terrain.ini", "Data\\INI\\Terrain.ini");
496496
initSubsystem(TheTerrainRoads,"TheTerrainRoads", MSGNEW("GameEngineSubsystem") TerrainRoadCollection(), &xferCRC, "Data\\INI\\Default\\Roads.ini", "Data\\INI\\Roads.ini");
497497
initSubsystem(TheGlobalLanguageData,"TheGlobalLanguageData",MSGNEW("GameEngineSubsystem") GlobalLanguage, NULL); // must be before the game text
498+
TheGlobalLanguageData->parseCustomDefinition();
498499
initSubsystem(TheCDManager,"TheCDManager", CreateCDManager(), NULL);
499500
#ifdef DUMP_PERF_STATS///////////////////////////////////////////////////////////////////////////
500501
GetPrecisionTimer(&endTime64);//////////////////////////////////////////////////////////////////

GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@
3232
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
3333
#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
3434

35+
#include "Common/GlobalData.h"
36+
3537
#define DEFINE_TERRAIN_LOD_NAMES
3638
#define DEFINE_TIME_OF_DAY_NAMES
3739
#define DEFINE_WEATHER_NAMES
3840
#define DEFINE_BODYDAMAGETYPE_NAMES
3941
#define DEFINE_PANNING_NAMES
4042

43+
#include "Common/AddonCompat.h"
4144
#include "Common/crc.h"
4245
#include "Common/file.h"
4346
#include "Common/FileSystem.h"
@@ -1226,18 +1229,10 @@ void GlobalData::parseGameDataDefinition( INI* ini )
12261229

12271230
void GlobalData::parseCustomDefinition()
12281231
{
1232+
if (addon::HasFullviewportDat())
12291233
{
1230-
// TheSuperHackers @feature xezon 03/08/2025 Force full viewport for 'Control Bar Pro' Addons like GenTool did it.
1231-
File* file = TheFileSystem->openFile("GenTool/fullviewport.dat", File::READ | File::BINARY);
1232-
if (file != NULL)
1233-
{
1234-
Char value = '0';
1235-
file->read(&value, 1);
1236-
if (value != '0')
1237-
{
1238-
m_viewportHeightScale = 1.0f;
1239-
}
1240-
}
1234+
// TheSuperHackers @tweak xezon 03/08/2025 Force full viewport for 'Control Bar Pro' Addons like GenTool did it.
1235+
m_viewportHeightScale = 1.0f;
12411236
}
12421237
}
12431238

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

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
//-----------------------------------------------------------------------------
5353
#include "PreRTS.h"
5454

55+
#include "Common/AddonCompat.h"
5556
#include "Common/FileSystem.h"
5657
#include "Common/INI.h"
5758
#include "Common/Registry.h"
@@ -64,6 +65,14 @@
6465
//-----------------------------------------------------------------------------
6566
GlobalLanguage *TheGlobalLanguageData = NULL; ///< The global language singalton
6667

68+
static const LookupListRec ResolutionFontSizeMethodNames[] =
69+
{
70+
{ "CLASSIC", GlobalLanguage::ResolutionFontSizeMethod_Classic },
71+
{ "STRICT", GlobalLanguage::ResolutionFontSizeMethod_Strict },
72+
{ "BALANCED", GlobalLanguage::ResolutionFontSizeMethod_Balanced },
73+
{ NULL, 0 }
74+
};
75+
6776
static const FieldParse TheGlobalLanguageDataFieldParseTable[] =
6877
{
6978
{ "UnicodeFontName", INI::parseAsciiString,NULL, offsetof( GlobalLanguage, m_unicodeFontName ) },
@@ -72,7 +81,7 @@ static const FieldParse TheGlobalLanguageDataFieldParseTable[] =
7281
{ "MilitaryCaptionSpeed", INI::parseInt, NULL, offsetof( GlobalLanguage, m_militaryCaptionSpeed ) },
7382
{ "UseHardWordWrap", INI::parseBool, NULL, offsetof( GlobalLanguage, m_useHardWrap) },
7483
{ "ResolutionFontAdjustment", INI::parseReal, NULL, offsetof( GlobalLanguage, m_resolutionFontSizeAdjustment) },
75-
84+
{ "ResolutionFontSizeMethod", INI::parseLookupList, ResolutionFontSizeMethodNames, offsetof( GlobalLanguage, m_resolutionFontSizeMethod) },
7685
{ "CopyrightFont", GlobalLanguage::parseFontDesc, NULL, offsetof( GlobalLanguage, m_copyrightFont ) },
7786
{ "MessageFont", GlobalLanguage::parseFontDesc, NULL, offsetof( GlobalLanguage, m_messageFont) },
7887
{ "MilitaryCaptionTitleFont", GlobalLanguage::parseFontDesc, NULL, offsetof( GlobalLanguage, m_militaryCaptionTitleFont) },
@@ -119,6 +128,7 @@ GlobalLanguage::GlobalLanguage()
119128
m_militaryCaptionSpeed = 0;
120129
m_useHardWrap = FALSE;
121130
m_resolutionFontSizeAdjustment = 0.7f;
131+
m_resolutionFontSizeMethod = ResolutionFontSizeMethod_Balanced;
122132
m_militaryCaptionDelayMS = 750;
123133
//End Add
124134
}
@@ -193,38 +203,76 @@ void GlobalLanguage::parseFontFileName( INI *ini, void * instance, void *store,
193203

194204
Int GlobalLanguage::adjustFontSize(Int theFontSize)
195205
{
196-
// TheSuperHackers @tweak xezon 16/08/2025 The size adjustment now also weighs in
197-
// the display height for a balanced rescale on non 4:3 resolutions.
198-
// The aspect ratio scaling is clamped between 1 and 2 to avoid oversizing.
199-
// The scaler no longer clamps at max 2, which makes it work properly for
200-
// 4k Resolutions and beyond.
201-
202-
Real w = TheDisplay->getWidth();
203-
Real h = TheDisplay->getHeight();
204-
const Real aspect = w / h;
205-
Real wScale = w / (Real)DEFAULT_DISPLAY_WIDTH;
206-
Real hScale = h / (Real)DEFAULT_DISPLAY_HEIGHT;
207-
208-
if (aspect > 2.0f)
206+
Real adjustFactor;
207+
208+
switch (m_resolutionFontSizeMethod)
209209
{
210-
// Recompute width at aspect=2
211-
w = 2.0f * h;
212-
wScale = w / (Real)DEFAULT_DISPLAY_WIDTH;
210+
default:
211+
case ResolutionFontSizeMethod_Classic:
212+
{
213+
// TheSuperHackers @info The original font scaling for this game.
214+
// Can be useful for not breaking legacy Addons and Mods but scales poorly.
215+
adjustFactor = TheDisplay->getWidth() / (Real)DEFAULT_DISPLAY_WIDTH;
216+
adjustFactor = 1.0f + (adjustFactor - 1.0f) * m_resolutionFontSizeAdjustment;
217+
if (adjustFactor > 2.0f)
218+
adjustFactor = 2.0f;
219+
break;
213220
}
214-
else if (aspect < 1.0f)
221+
case ResolutionFontSizeMethod_Strict:
215222
{
216-
// Recompute height at aspect=1
217-
h = 1.0f * w;
218-
hScale = h / (Real)DEFAULT_DISPLAY_HEIGHT;
223+
// TheSuperHackers @feature The strict method scales fonts based on the smallest screen
224+
// dimension so they scale independent of aspect ratio.
225+
const Real wScale = TheDisplay->getWidth() / (Real)DEFAULT_DISPLAY_WIDTH;
226+
const Real hScale = TheDisplay->getHeight() / (Real)DEFAULT_DISPLAY_HEIGHT;
227+
adjustFactor = min(wScale, hScale);
228+
adjustFactor = 1.0f + (adjustFactor - 1.0f) * m_resolutionFontSizeAdjustment;
229+
break;
219230
}
231+
case ResolutionFontSizeMethod_Balanced:
232+
{
233+
// TheSuperHackers @feature The balanced method evenly weighs the display width and height
234+
// for a balanced rescale on non 4:3 resolutions. The aspect ratio scaling is clamped
235+
// between 1 and 2 to avoid oversizing.
236+
Real w = TheDisplay->getWidth();
237+
Real h = TheDisplay->getHeight();
238+
const Real aspect = w / h;
239+
Real wScale = w / (Real)DEFAULT_DISPLAY_WIDTH;
240+
Real hScale = h / (Real)DEFAULT_DISPLAY_HEIGHT;
220241

221-
Real adjustFactor = (wScale + hScale) * 0.5f;
222-
adjustFactor = 1.0f + (adjustFactor-1.0f) * m_resolutionFontSizeAdjustment;
223-
if (adjustFactor < 1.0f) adjustFactor = 1.0f;
242+
if (aspect > 2.0f)
243+
{
244+
// Recompute width at aspect=2
245+
w = 2.0f * h;
246+
wScale = w / (Real)DEFAULT_DISPLAY_WIDTH;
247+
}
248+
else if (aspect < 1.0f)
249+
{
250+
// Recompute height at aspect=1
251+
h = 1.0f * w;
252+
hScale = h / (Real)DEFAULT_DISPLAY_HEIGHT;
253+
}
254+
adjustFactor = (wScale + hScale) * 0.5f;
255+
adjustFactor = 1.0f + (adjustFactor - 1.0f) * m_resolutionFontSizeAdjustment;
256+
break;
257+
}
258+
}
259+
260+
if (adjustFactor < 1.0f)
261+
adjustFactor = 1.0f;
224262
Int pointSize = REAL_TO_INT_FLOOR(theFontSize*adjustFactor);
225263
return pointSize;
226264
}
227265

266+
void GlobalLanguage::parseCustomDefinition()
267+
{
268+
if (addon::HasFullviewportDat())
269+
{
270+
// TheSuperHackers @tweak xezon 19/08/2025 Force the classic font size adjustment for the old
271+
// 'Control Bar Pro' Addons because they use manual font upscaling in higher resolution packages.
272+
m_resolutionFontSizeMethod = ResolutionFontSizeMethod_Classic;
273+
}
274+
}
275+
228276
FontDesc::FontDesc(void)
229277
{
230278
name = "Arial Unicode MS"; ///<name of font

0 commit comments

Comments
 (0)