diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt index 0a58dfc431..81ca007c37 100644 --- a/Core/GameEngine/CMakeLists.txt +++ b/Core/GameEngine/CMakeLists.txt @@ -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 @@ -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 diff --git a/Core/GameEngine/Include/Common/AddonCompat.h b/Core/GameEngine/Include/Common/AddonCompat.h new file mode 100644 index 0000000000..7b8bc2c9e9 --- /dev/null +++ b/Core/GameEngine/Include/Common/AddonCompat.h @@ -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 . +*/ + +#pragma once + +namespace addon +{ +extern Bool HasFullviewportDat(); + +} // namespace addon diff --git a/Core/GameEngine/Source/Common/AddonCompat.cpp b/Core/GameEngine/Source/Common/AddonCompat.cpp new file mode 100644 index 0000000000..6d88feb47d --- /dev/null +++ b/Core/GameEngine/Source/Common/AddonCompat.cpp @@ -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 . +*/ + +#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 diff --git a/Generals/Code/GameEngine/Include/GameClient/GlobalLanguage.h b/Generals/Code/GameEngine/Include/GameClient/GlobalLanguage.h index 531df38574..9ceb7abe0f 100644 --- a/Generals/Code/GameEngine/Include/GameClient/GlobalLanguage.h +++ b/Generals/Code/GameEngine/Include/GameClient/GlobalLanguage.h @@ -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(); @@ -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 StringList; // Used for our font file names that we want to load typedef StringList::iterator StringListIt; diff --git a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp index 7943cab329..e4a20be08c 100644 --- a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp @@ -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()) diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index 9030c358e6..4b72223877 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -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" @@ -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; } } diff --git a/Generals/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp b/Generals/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp index 68f47aacb1..d41cae4064 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp @@ -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[] = { @@ -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) }, @@ -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; @@ -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"; /// StringList; // Used for our font file names that we want to load typedef StringList::iterator StringListIt; diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp index 2b6bcad36d..7c7418a6a5 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp @@ -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);////////////////////////////////////////////////////////////////// diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index 41bb35cfe3..071c5debeb 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -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" @@ -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; } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp index 9ee55242c9..2b279e0c56 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp @@ -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[] = { @@ -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) }, @@ -119,6 +130,7 @@ GlobalLanguage::GlobalLanguage() m_militaryCaptionSpeed = 0; m_useHardWrap = FALSE; m_resolutionFontSizeAdjustment = 0.7f; + m_resolutionFontSizeMethod = ResolutionFontSizeMethod_Default; m_militaryCaptionDelayMS = 750; //End Add @@ -195,14 +207,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"; ///