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
2 changes: 2 additions & 0 deletions Core/GameEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(GAMEENGINE_SRC
# Include/Common/AcademyStats.h
# Include/Common/ActionManager.h
Include/Common/AddonCompat.h
Include/Common/ArchiveFile.h
Include/Common/ArchiveFileSystem.h
Include/Common/AsciiString.h
Expand Down Expand Up @@ -552,6 +553,7 @@ set(GAMEENGINE_SRC
# Include/GameNetwork/WOLBrowser/FEBDispatch.h
# Include/GameNetwork/WOLBrowser/WebBrowser.h
# Include/Precompiled/PreRTS.h
Source/Common/AddonCompat.cpp
Source/Common/Audio/AudioEventRTS.cpp
Source/Common/Audio/AudioRequest.cpp
Source/Common/Audio/DynamicAudioEventInfo.cpp
Expand Down
25 changes: 25 additions & 0 deletions Core/GameEngine/Include/Common/AddonCompat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 TheSuperHackers
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

namespace addon
{
extern Bool HasFullviewportDat();

} // namespace addon
36 changes: 36 additions & 0 deletions Core/GameEngine/Source/Common/AddonCompat.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 TheSuperHackers
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "PreRTS.h"

#include "Common/AddonCompat.h"
#include "Common/FileSystem.h"

namespace addon
{
Bool HasFullviewportDat()
{
Char value = '0';
if (File* file = TheFileSystem->openFile("GenTool/fullviewport.dat", File::READ | File::BINARY))
{
file->read(&value, 1);
}
return value != '0';
}

} // namespace addon
15 changes: 12 additions & 3 deletions GeneralsMD/Code/GameEngine/Include/GameClient/GlobalLanguage.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ class AsciiString;
//-----------------------------------------------------------------------------
class GlobalLanguage : public SubsystemInterface
{
public:

enum ResolutionFontSizeMethod
{
ResolutionFontSizeMethod_Classic, // Uses the original scaling method. Scales poorly on wide screens and large resolutions.
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.
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.
};

public:

GlobalLanguage();
Expand Down Expand Up @@ -99,13 +108,13 @@ class GlobalLanguage : public SubsystemInterface
FontDesc m_creditsTitleFont;
FontDesc m_creditsPositionFont;
FontDesc m_creditsNormalFont;

Real m_resolutionFontSizeAdjustment;

//UnicodeString m_unicodeFontNameUStr;
ResolutionFontSizeMethod m_resolutionFontSizeMethod;

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

void parseCustomDefinition();

typedef std::list<AsciiString> StringList; // Used for our font file names that we want to load
typedef StringList::iterator StringListIt;

Expand Down
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ void GameEngine::init()
initSubsystem(TheTerrainTypes,"TheTerrainTypes", MSGNEW("GameEngineSubsystem") TerrainTypeCollection(), &xferCRC, "Data\\INI\\Default\\Terrain.ini", "Data\\INI\\Terrain.ini");
initSubsystem(TheTerrainRoads,"TheTerrainRoads", MSGNEW("GameEngineSubsystem") TerrainRoadCollection(), &xferCRC, "Data\\INI\\Default\\Roads.ini", "Data\\INI\\Roads.ini");
initSubsystem(TheGlobalLanguageData,"TheGlobalLanguageData",MSGNEW("GameEngineSubsystem") GlobalLanguage, NULL); // must be before the game text
TheGlobalLanguageData->parseCustomDefinition();
initSubsystem(TheCDManager,"TheCDManager", CreateCDManager(), NULL);
#ifdef DUMP_PERF_STATS///////////////////////////////////////////////////////////////////////////
GetPrecisionTimer(&endTime64);//////////////////////////////////////////////////////////////////
Expand Down
17 changes: 6 additions & 11 deletions GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine

#include "Common/GlobalData.h"

#define DEFINE_TERRAIN_LOD_NAMES
#define DEFINE_TIME_OF_DAY_NAMES
#define DEFINE_WEATHER_NAMES
#define DEFINE_BODYDAMAGETYPE_NAMES
#define DEFINE_PANNING_NAMES

#include "Common/AddonCompat.h"
#include "Common/crc.h"
#include "Common/file.h"
#include "Common/FileSystem.h"
Expand Down Expand Up @@ -1226,18 +1229,10 @@ void GlobalData::parseGameDataDefinition( INI* ini )

void GlobalData::parseCustomDefinition()
{
if (addon::HasFullviewportDat())
{
// TheSuperHackers @feature xezon 03/08/2025 Force full viewport for 'Control Bar Pro' Addons like GenTool did it.
File* file = TheFileSystem->openFile("GenTool/fullviewport.dat", File::READ | File::BINARY);
if (file != NULL)
{
Char value = '0';
file->read(&value, 1);
if (value != '0')
{
m_viewportHeightScale = 1.0f;
}
}
// TheSuperHackers @tweak xezon 03/08/2025 Force full viewport for 'Control Bar Pro' Addons like GenTool did it.
m_viewportHeightScale = 1.0f;
}
}

Expand Down
86 changes: 80 additions & 6 deletions GeneralsMD/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,27 @@
//-----------------------------------------------------------------------------
#include "PreRTS.h"

#include "Common/AddonCompat.h"
#include "Common/FileSystem.h"
#include "Common/INI.h"
#include "Common/Registry.h"

#include "GameClient/Display.h"
#include "GameClient/GlobalLanguage.h"
#include "Common/FileSystem.h"

//-----------------------------------------------------------------------------
// DEFINES ////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
GlobalLanguage *TheGlobalLanguageData = NULL; ///< The global language singalton

static const LookupListRec ResolutionFontSizeMethodNames[] =
{
{ "CLASSIC", GlobalLanguage::ResolutionFontSizeMethod_Classic },
{ "STRICT", GlobalLanguage::ResolutionFontSizeMethod_Strict },
{ "BALANCED", GlobalLanguage::ResolutionFontSizeMethod_Balanced },
{ NULL, 0 }
};

static const FieldParse TheGlobalLanguageDataFieldParseTable[] =
{
{ "UnicodeFontName", INI::parseAsciiString,NULL, offsetof( GlobalLanguage, m_unicodeFontName ) },
Expand All @@ -70,7 +81,7 @@ static const FieldParse TheGlobalLanguageDataFieldParseTable[] =
{ "MilitaryCaptionSpeed", INI::parseInt, NULL, offsetof( GlobalLanguage, m_militaryCaptionSpeed ) },
{ "UseHardWordWrap", INI::parseBool, NULL, offsetof( GlobalLanguage, m_useHardWrap) },
{ "ResolutionFontAdjustment", INI::parseReal, NULL, offsetof( GlobalLanguage, m_resolutionFontSizeAdjustment) },

{ "ResolutionFontSizeMethod", INI::parseLookupList, ResolutionFontSizeMethodNames, offsetof( GlobalLanguage, m_resolutionFontSizeMethod) },
{ "CopyrightFont", GlobalLanguage::parseFontDesc, NULL, offsetof( GlobalLanguage, m_copyrightFont ) },
{ "MessageFont", GlobalLanguage::parseFontDesc, NULL, offsetof( GlobalLanguage, m_messageFont) },
{ "MilitaryCaptionTitleFont", GlobalLanguage::parseFontDesc, NULL, offsetof( GlobalLanguage, m_militaryCaptionTitleFont) },
Expand Down Expand Up @@ -117,6 +128,7 @@ GlobalLanguage::GlobalLanguage()
m_militaryCaptionSpeed = 0;
m_useHardWrap = FALSE;
m_resolutionFontSizeAdjustment = 0.7f;
m_resolutionFontSizeMethod = ResolutionFontSizeMethod_Balanced;
m_militaryCaptionDelayMS = 750;
//End Add
}
Expand Down Expand Up @@ -191,14 +203,76 @@ void GlobalLanguage::parseFontFileName( INI *ini, void * instance, void *store,

Int GlobalLanguage::adjustFontSize(Int theFontSize)
{
Real adjustFactor = TheGlobalData->m_xResolution / (Real)DEFAULT_DISPLAY_WIDTH;
adjustFactor = 1.0f + (adjustFactor-1.0f) * m_resolutionFontSizeAdjustment;
if (adjustFactor<1.0f) adjustFactor = 1.0f;
if (adjustFactor>2.0f) adjustFactor = 2.0f;
Copy link

Choose a reason for hiding this comment

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

On a different note, this also breaks the current implementation of control bar pro at higher than 2k.

I made this tweak in the past for my test builds.

It would require control bar pro to be updated with a parralel SH compatible version that removes the new fonts for 2k+ resolutions

Copy link
Author

Choose a reason for hiding this comment

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

Fixed.

Real adjustFactor;

switch (m_resolutionFontSizeMethod)
{
default:
case ResolutionFontSizeMethod_Classic:
{
// TheSuperHackers @info The original font scaling for this game.
// Can be useful for not breaking legacy Addons and Mods but scales poorly.
adjustFactor = TheDisplay->getWidth() / (Real)DEFAULT_DISPLAY_WIDTH;
adjustFactor = 1.0f + (adjustFactor - 1.0f) * m_resolutionFontSizeAdjustment;
if (adjustFactor > 2.0f)
adjustFactor = 2.0f;
break;
}
case ResolutionFontSizeMethod_Strict:
{
// TheSuperHackers @feature The strict method scales fonts based on the smallest screen
// dimension so they scale independent of aspect ratio.
const Real wScale = TheDisplay->getWidth() / (Real)DEFAULT_DISPLAY_WIDTH;
const Real hScale = TheDisplay->getHeight() / (Real)DEFAULT_DISPLAY_HEIGHT;
adjustFactor = min(wScale, hScale);
adjustFactor = 1.0f + (adjustFactor - 1.0f) * m_resolutionFontSizeAdjustment;
break;
}
case ResolutionFontSizeMethod_Balanced:
{
// TheSuperHackers @feature The balanced method evenly weighs the display width and height
// for a balanced rescale on non 4:3 resolutions. The aspect ratio scaling is clamped
// between 1 and 2 to avoid oversizing.
Real w = TheDisplay->getWidth();
Real h = TheDisplay->getHeight();
const Real aspect = w / h;
Real wScale = w / (Real)DEFAULT_DISPLAY_WIDTH;
Real hScale = h / (Real)DEFAULT_DISPLAY_HEIGHT;

if (aspect > 2.0f)
{
// Recompute width at aspect=2
w = 2.0f * h;
wScale = w / (Real)DEFAULT_DISPLAY_WIDTH;
}
else if (aspect < 1.0f)
{
// Recompute height at aspect=1
h = 1.0f * w;
hScale = h / (Real)DEFAULT_DISPLAY_HEIGHT;
}
adjustFactor = (wScale + hScale) * 0.5f;
adjustFactor = 1.0f + (adjustFactor - 1.0f) * m_resolutionFontSizeAdjustment;
break;
}
}

if (adjustFactor < 1.0f)
adjustFactor = 1.0f;
Int pointSize = REAL_TO_INT_FLOOR(theFontSize*adjustFactor);
return pointSize;
}

void GlobalLanguage::parseCustomDefinition()
{
if (addon::HasFullviewportDat())
{
// TheSuperHackers @tweak xezon 19/08/2025 Force the classic font size adjustment for the old
// 'Control Bar Pro' Addons because they use manual font upscaling in higher resolution packages.
m_resolutionFontSizeMethod = ResolutionFontSizeMethod_Classic;
}
}

FontDesc::FontDesc(void)
{
name = "Arial Unicode MS"; ///<name of font
Expand Down
Loading