Skip to content
Merged
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 @@ -554,6 +555,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
18 changes: 15 additions & 3 deletions Generals/Code/GameEngine/Include/GameClient/GlobalLanguage.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ 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_ClassicNoCeiling, // Uses the original scaling method, but without ceiling. Works ok for the original Game UI and with large resolutions. Scales poorly on very wide screens.
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.

ResolutionFontSizeMethod_Default = ResolutionFontSizeMethod_ClassicNoCeiling,
};

public:

GlobalLanguage();
Expand Down Expand Up @@ -95,15 +107,15 @@ class GlobalLanguage : public SubsystemInterface
FontDesc m_creditsTitleFont;
FontDesc m_creditsPositionFont;
FontDesc m_creditsNormalFont;

Real m_resolutionFontSizeAdjustment;
Real m_userResolutionFontSizeAdjustment;

//UnicodeString m_unicodeFontNameUStr;
ResolutionFontSizeMethod m_resolutionFontSizeMethod;

float getResolutionFontSizeAdjustment() const;
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 Generals/Code/GameEngine/Source/Common/GameEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ void GameEngine::init()
initSubsystem(TheTerrainTypes,"TheTerrainTypes", MSGNEW("GameEngineSubsystem") TerrainTypeCollection(), &xferCRC, "Data\\INI\\Default\\Terrain", "Data\\INI\\Terrain");
initSubsystem(TheTerrainRoads,"TheTerrainRoads", MSGNEW("GameEngineSubsystem") TerrainRoadCollection(), &xferCRC, "Data\\INI\\Default\\Roads", "Data\\INI\\Roads");
initSubsystem(TheGlobalLanguageData,"TheGlobalLanguageData",MSGNEW("GameEngineSubsystem") GlobalLanguage, NULL); // must be before the game text
TheGlobalLanguageData->parseCustomDefinition();
initSubsystem(TheCDManager,"TheCDManager", CreateCDManager(), NULL);
initSubsystem(TheAudio,"TheAudio", TheGlobalData->m_headless ? NEW AudioManagerDummy : createAudioManager(), NULL);
if (!TheAudio->isMusicAlreadyLoaded())
Expand Down
17 changes: 6 additions & 11 deletions Generals/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 @@ -1218,18 +1221,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
98 changes: 92 additions & 6 deletions Generals/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,28 @@
//-----------------------------------------------------------------------------
#include "PreRTS.h"

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

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

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

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

static const FieldParse TheGlobalLanguageDataFieldParseTable[] =
{
Expand All @@ -72,7 +83,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 @@ -118,6 +129,7 @@ GlobalLanguage::GlobalLanguage()
m_militaryCaptionSpeed = 0;
m_useHardWrap = FALSE;
m_resolutionFontSizeAdjustment = 0.7f;
m_resolutionFontSizeMethod = ResolutionFontSizeMethod_Default;
//End Add

m_userResolutionFontSizeAdjustment = -1.0f;
Expand Down Expand Up @@ -193,14 +205,88 @@ float GlobalLanguage::getResolutionFontSizeAdjustment( void ) const

Int GlobalLanguage::adjustFontSize(Int theFontSize)
{
Real adjustFactor = TheGlobalData->m_xResolution / (Real)DEFAULT_DISPLAY_WIDTH;
adjustFactor = 1.0f + (adjustFactor-1.0f) * getResolutionFontSizeAdjustment();
if (adjustFactor<1.0f) adjustFactor = 1.0f;
if (adjustFactor>2.0f) adjustFactor = 2.0f;
// TheSuperHackers @todo This function is called very often.
// Therefore cache the adjustFactor on resolution change to not recompute it on every call.
Real adjustFactor;

switch (m_resolutionFontSizeMethod)
{
default:
case ResolutionFontSizeMethod_Classic:
{
// TheSuperHackers @info The original font scaling for this game.
// Useful for not breaking legacy Addons and Mods. Scales poorly with large resolutions.
adjustFactor = TheDisplay->getWidth() / (Real)DEFAULT_DISPLAY_WIDTH;
adjustFactor = 1.0f + (adjustFactor - 1.0f) * getResolutionFontSizeAdjustment();
if (adjustFactor > 2.0f)
adjustFactor = 2.0f;
break;
}
case ResolutionFontSizeMethod_ClassicNoCeiling:
{
// TheSuperHackers @feature The original font scaling, but without ceiling.
// Useful for not changing the original look of the game. Scales alright with large resolutions.
adjustFactor = TheDisplay->getWidth() / (Real)DEFAULT_DISPLAY_WIDTH;
adjustFactor = 1.0f + (adjustFactor - 1.0f) * getResolutionFontSizeAdjustment();
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) * getResolutionFontSizeAdjustment();
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 to
// prevent oversizing.
constexpr const Real maxAspect = 1.8f;
constexpr const Real minAspect = 1.0f;
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 > maxAspect)
{
// Recompute width at max aspect
w = maxAspect * h;
wScale = w / (Real)DEFAULT_DISPLAY_WIDTH;
}
else if (aspect < minAspect)
{
// Recompute height at min aspect
h = minAspect * w;
hScale = h / (Real)DEFAULT_DISPLAY_HEIGHT;
}
adjustFactor = (wScale + hScale) * 0.5f;
adjustFactor = 1.0f + (adjustFactor - 1.0f) * getResolutionFontSizeAdjustment();
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
18 changes: 15 additions & 3 deletions GeneralsMD/Code/GameEngine/Include/GameClient/GlobalLanguage.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ 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_ClassicNoCeiling, // Uses the original scaling method, but without ceiling. Works ok for the original Game UI and with large resolutions. Scales poorly on very wide screens.
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.

ResolutionFontSizeMethod_Default = ResolutionFontSizeMethod_ClassicNoCeiling,
};

public:

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

Real m_resolutionFontSizeAdjustment;
Real m_userResolutionFontSizeAdjustment;

//UnicodeString m_unicodeFontNameUStr;
ResolutionFontSizeMethod m_resolutionFontSizeMethod;

float getResolutionFontSizeAdjustment() const;
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 @@ -520,6 +520,7 @@ void GameEngine::init()
initSubsystem(TheTerrainTypes,"TheTerrainTypes", MSGNEW("GameEngineSubsystem") TerrainTypeCollection(), &xferCRC, "Data\\INI\\Default\\Terrain", "Data\\INI\\Terrain");
initSubsystem(TheTerrainRoads,"TheTerrainRoads", MSGNEW("GameEngineSubsystem") TerrainRoadCollection(), &xferCRC, "Data\\INI\\Default\\Roads", "Data\\INI\\Roads");
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 @@ -1246,18 +1249,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
Loading
Loading