From 641037c8c7798a893c51a76022d10afefce9a752 Mon Sep 17 00:00:00 2001 From: Mauller <26652186+Mauller@users.noreply.github.com> Date: Sat, 21 Jun 2025 23:06:38 +0100 Subject: [PATCH 1/2] [ZH] Implement system time and simulation timer within InGameUI --- .../GameEngine/Include/Common/GlobalData.h | 4 + .../Include/Common/UserPreferences.h | 3 + .../GameEngine/Include/GameClient/InGameUI.h | 27 ++++ .../GameEngine/Source/Common/GlobalData.cpp | 5 + .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 51 +++++++ .../GameEngine/Source/GameClient/InGameUI.cpp | 139 ++++++++++++++++++ .../W3DDevice/GameClient/W3DInGameUI.cpp | 2 + 7 files changed, 231 insertions(+) diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index d986d77495..55d89c99f8 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -409,6 +409,10 @@ class GlobalData : public SubsystemInterface Bool m_saveCameraInReplay; Bool m_useCameraInReplay; + // TheSuperHackers @feature Mauller 21/06/2025 allow the system time and game time font size to be set, a size of zero disables them + Int m_systemTimeFontSize; + Int m_gameTimeFontSize; + Real m_shakeSubtleIntensity; ///< Intensity for shaking a camera with SHAKE_SUBTLE Real m_shakeNormalIntensity; ///< Intensity for shaking a camera with SHAKE_NORMAL Real m_shakeStrongIntensity; ///< Intensity for shaking a camera with SHAKE_STRONG diff --git a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h index dfcec0df8c..1748f6ae6f 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h @@ -129,6 +129,9 @@ class OptionPreferences : public UserPreferences Int getCampaignDifficulty(void); void setCampaignDifficulty( Int diff ); + + Int getSystemTimeFontSize(void); + Int getGameTimeFontSize(void); }; //----------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h b/GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h index d6bc351a9a..2e4dcc6d8f 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h @@ -382,6 +382,7 @@ friend class Drawable; // for selection/deselection transactions virtual void toggleMessages( void ) { m_messagesOn = 1 - m_messagesOn; } ///< toggle messages on/off virtual Bool isMessagesOn( void ) { return m_messagesOn; } ///< are the display messages on void freeMessageResources( void ); ///< free resources for the ui messages + void freeCustomUiResources( void ); ///< free resources for custom ui elements Color getMessageColor(Bool altColor) { return (altColor)?m_messageColor2:m_messageColor1; } // interface for military style messages @@ -466,6 +467,7 @@ friend class Drawable; // for selection/deselection transactions virtual void preDraw( void ); ///< Logic which needs to occur before the UI renders virtual void draw( void ) = 0; ///< Render the in-game user interface virtual void postDraw( void ); ///< Logic which needs to occur after the UI renders + virtual void postWindowDraw( void ); ///< Logic which needs to occur after the WindowManager has repainted the menus /// Ingame video playback virtual void playMovie( const AsciiString& movieName ); @@ -559,6 +561,9 @@ friend class Drawable; // for selection/deselection transactions virtual void selectNextIdleWorker( void ); virtual void recreateControlBar( void ); + virtual void refreshCustomUiResources( void ); + virtual void refreshSystemTimeResources( void ); + virtual void refreshGameTimeResources( void ); virtual void disableTooltipsUntil(UnsignedInt frameNum); virtual void clearTooltipsDisabled(); @@ -578,6 +583,9 @@ friend class Drawable; // for selection/deselection transactions virtual void updateIdleWorker( void ); virtual void resetIdleWorker( void ); + void drawSystemTime(); + void drawGameTime(); + public: void registerWindowLayout(WindowLayout *layout); // register a layout for updates void unregisterWindowLayout(WindowLayout *layout); // stop updates for this layout @@ -741,6 +749,25 @@ friend class Drawable; // for selection/deselection transactions VideoBuffer* m_cameoVideoBuffer;///< video playback buffer VideoStreamInterface* m_cameoVideoStream;///< Video stream; + // System Time + DisplayString * m_systemTimeString; + AsciiString m_systemTimeFont; + Int m_systemTimePointSize; + Bool m_systemTimeBold; + Coord2D m_systemTimePosition; + Color m_systemTimeColor; + Color m_systemTimeDropColor; + + // Game Time + DisplayString * m_gameTimeString; + DisplayString * m_gameTimeFrameString; + AsciiString m_gameTimeFont; + Int m_gameTimePointSize; + Bool m_gameTimeBold; + Coord2D m_gameTimePosition; + Color m_gameTimeColor; + Color m_gameTimeDropColor; + // message data UIMessage m_uiMessages[ MAX_UI_MESSAGES ];/**< messages to display to the user, the array is organized with newer messages at diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index 7e4469e0ae..b0431c566a 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -928,6 +928,8 @@ GlobalData::GlobalData() m_saveCameraInReplay = FALSE; m_useCameraInReplay = FALSE; + m_systemTimeFontSize = 8; + m_gameTimeFontSize = 8; m_debugShowGraphicalFramerate = FALSE; @@ -1196,6 +1198,9 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_saveCameraInReplay = optionPref.saveCameraInReplays(); TheWritableGlobalData->m_useCameraInReplay = optionPref.useCameraInReplays(); + + TheWritableGlobalData->m_systemTimeFontSize = optionPref.getSystemTimeFontSize(); + TheWritableGlobalData->m_gameTimeFontSize = optionPref.getGameTimeFontSize(); Int val=optionPref.getGammaValue(); //generate a value between 0.6 and 2.0. diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp index 92a54431f7..bef0859bd8 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -767,6 +767,34 @@ Real OptionPreferences::getMusicVolume(void) return volume; } +Int OptionPreferences::getSystemTimeFontSize(void) +{ + OptionPreferences::const_iterator it = find("SystemTimeFontSize"); + if (it == end()) + return 8; + + Int fontSize = atoi(it->second.str()); + if (fontSize < 0) + { + fontSize = 0; + } + return fontSize; +} + +Int OptionPreferences::getGameTimeFontSize(void) +{ + OptionPreferences::const_iterator it = find("GameTimeFontSize"); + if (it == end()) + return 8; + + Int fontSize = atoi(it->second.str()); + if (fontSize < 0) + { + fontSize = 0; + } + return fontSize; +} + static OptionPreferences *pref = NULL; static void setDefaults( void ) @@ -1257,6 +1285,28 @@ static void saveOptions( void ) } } + //------------------------------------------------------------------------------------------------- + // Set System Time Font Size + val = TheWritableGlobalData->m_systemTimeFontSize; // TheSuperHackers @todo replace with options input when applicable + if (val) + { + AsciiString prefString; + prefString.format("%d", val); + (*pref)["SystemTimeFontSize"] = prefString; + TheInGameUI->refreshSystemTimeResources(); + } + + //------------------------------------------------------------------------------------------------- + // Set Game Time Font Size + val = TheWritableGlobalData->m_gameTimeFontSize; // TheSuperHackers @todo replace with options input when applicable + if (val) + { + AsciiString prefString; + prefString.format("%d", val); + (*pref)["GameTimeFontSize"] = prefString; + TheInGameUI->refreshGameTimeResources(); + } + //------------------------------------------------------------------------------------------------- // Resolution // @@ -1299,6 +1349,7 @@ static void saveOptions( void ) TheShell->recreateWindowLayouts(); TheInGameUI->recreateControlBar(); + TheInGameUI->refreshCustomUiResources(); } } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index 19662d0d8c..89c9e80ff3 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -871,6 +871,19 @@ const FieldParse InGameUI::s_fieldParseTable[] = { "ClearMinesRadiusCursor", RadiusDecalTemplate::parseRadiusDecalTemplate, NULL, offsetof( InGameUI, m_radiusCursors[ RADIUSCURSOR_CLEARMINES] ) }, { "AmbulanceRadiusCursor", RadiusDecalTemplate::parseRadiusDecalTemplate, NULL, offsetof( InGameUI, m_radiusCursors[ RADIUSCURSOR_AMBULANCE] ) }, + // TheSuperHackers @info ui enhancement configuration + { "SystemTimeFont", INI::parseAsciiString, NULL, offsetof( InGameUI, m_systemTimeFont ) }, + { "SystemTimeBold", INI::parseBool, NULL, offsetof( InGameUI, m_systemTimeBold ) }, + { "SystemTimePosition", INI::parseCoord2D, NULL, offsetof( InGameUI, m_systemTimePosition ) }, + { "SystemTimeColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_systemTimeColor ) }, + { "SystemTimeDropColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_systemTimeDropColor ) }, + + { "GameTimeFont", INI::parseAsciiString, NULL, offsetof( InGameUI, m_gameTimeFont ) }, + { "GameTimeBold", INI::parseBool, NULL, offsetof( InGameUI, m_gameTimeBold ) }, + { "GameTimePosition", INI::parseCoord2D, NULL, offsetof( InGameUI, m_gameTimePosition ) }, + { "GameTimeColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_gameTimeColor ) }, + { "GameTimeDropColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_gameTimeDropColor ) }, + { NULL, NULL, NULL, 0 } // keep this last }; @@ -996,6 +1009,26 @@ InGameUI::InGameUI() m_replayWindow = NULL; m_messagesOn = TRUE; + // TheSuperHackers @info the default font, size and positions of the system and game times were chosen based on GenTools implementation + m_systemTimeString = NULL; + m_systemTimeFont = "Tahoma"; + m_systemTimePointSize = TheGlobalData->m_systemTimeFontSize; + m_systemTimeBold = TRUE; + m_systemTimePosition.x = 3; // TheSuperHackers @info relative to the left of the screen + m_systemTimePosition.y = -1; + m_systemTimeColor = GameMakeColor( 255, 255, 255, 255 ); + m_systemTimeDropColor = GameMakeColor( 0, 0, 0, 255 ); + + m_gameTimeString = NULL; + m_gameTimeFrameString = NULL; + m_gameTimeFont = "Tahoma"; + m_gameTimePointSize = TheGlobalData->m_gameTimeFontSize; + m_gameTimeBold = TRUE; + m_gameTimePosition.x = 3; // TheSuperHackers @info relative to the right of the screen + m_gameTimePosition.y = -1; + m_gameTimeColor = GameMakeColor( 255, 255, 255, 255 ); + m_gameTimeDropColor = GameMakeColor( 0, 0, 0, 255 ); + m_superweaponPosition.x = 0.7f; m_superweaponPosition.y = 0.7f; m_superweaponFlashDuration = 1.0f; @@ -1077,6 +1110,9 @@ InGameUI::~InGameUI() // delete the message resources freeMessageResources(); + // free custom ui strings + freeCustomUiResources(); + // delete the array for the drawbles delete [] m_placeIcon; m_placeIcon = NULL; @@ -1919,6 +1955,9 @@ void InGameUI::reset( void ) // free any message resources allocated freeMessageResources(); + // refresh custom ui strings - this will create the strings if required and update the fonts + refreshCustomUiResources(); + Int i; for (i=0; ifreeDisplayString(m_systemTimeString); + m_systemTimeString = NULL; + TheDisplayStringManager->freeDisplayString(m_gameTimeString); + m_gameTimeString = NULL; + TheDisplayStringManager->freeDisplayString(m_gameTimeFrameString); + m_gameTimeFrameString = NULL; +} + //------------------------------------------------------------------------------------------------- /** Same as the unicode message method, but this takes an ascii string which is assumed * to me a string manager label */ @@ -3454,6 +3503,22 @@ void InGameUI::disregardDrawable( Drawable *draw ) } +//------------------------------------------------------------------------------------------------- +/** This is called after the WindowManager has drawn the menus. */ +//------------------------------------------------------------------------------------------------- +void InGameUI::postWindowDraw( void ) +{ + if (m_systemTimePointSize > 0) + { + drawSystemTime(); + } + + if ( (m_gameTimePointSize > 0) && !TheGameLogic->isInShellGame() && TheGameLogic->isInGame() ) + { + drawGameTime(); + } +} + //------------------------------------------------------------------------------------------------- /** This is called after the UI has been drawn. */ //------------------------------------------------------------------------------------------------- @@ -5659,6 +5724,44 @@ void InGameUI::recreateControlBar( void ) } +void InGameUI::refreshCustomUiResources(void) +{ + refreshSystemTimeResources(); + refreshGameTimeResources(); +} + +void InGameUI::refreshSystemTimeResources(void) +{ + if (!m_systemTimeString) + { + m_systemTimeString = TheDisplayStringManager->newDisplayString(); + } + + m_systemTimePointSize = TheGlobalData->m_systemTimeFontSize; + Int adjustedSystemTimeFontSize = TheGlobalLanguageData->adjustFontSize(m_systemTimePointSize); + GameFont* systemTimeFont = TheWindowManager->winFindFont(m_systemTimeFont, adjustedSystemTimeFontSize, m_systemTimeBold); + m_systemTimeString->setFont(systemTimeFont); +} + +void InGameUI::refreshGameTimeResources(void) +{ + if (!m_gameTimeString) + { + m_gameTimeString = TheDisplayStringManager->newDisplayString(); + } + + if (!m_gameTimeFrameString) + { + m_gameTimeFrameString = TheDisplayStringManager->newDisplayString(); + } + + m_gameTimePointSize = TheGlobalData->m_gameTimeFontSize; + Int adjustedGameTimeFontSize = TheGlobalLanguageData->adjustFontSize(m_gameTimePointSize); + GameFont* gameTimeFont = TheWindowManager->winFindFont(m_gameTimeFont, adjustedGameTimeFontSize, m_gameTimeBold); + m_gameTimeString->setFont(gameTimeFont); + m_gameTimeFrameString->setFont(gameTimeFont); +} + void InGameUI::disableTooltipsUntil(UnsignedInt frameNum) { if (frameNum > m_tooltipsDisabledUntil) @@ -5713,4 +5816,40 @@ WindowMsgHandledType IdleWorkerSystem( GameWindow *window, UnsignedInt msg, } +void InGameUI::drawSystemTime() +{ + // current system time + SYSTEMTIME systemTime; + GetLocalTime( &systemTime ); + + UnicodeString TimeString; + TimeString.format(L"%2.2d:%2.2d:%2.2d", systemTime.wHour, systemTime.wMinute, systemTime.wSecond); + m_systemTimeString->setText(TimeString); + m_systemTimeString->draw(m_systemTimePosition.x, m_systemTimePosition.y, m_systemTimeColor, m_systemTimeDropColor); +} + +void InGameUI::drawGameTime() +{ + Int currentFrame = TheGameLogic->getFrame(); + Int gameSeconds = (Int) (SECONDS_PER_LOGICFRAME_REAL * currentFrame ); + Int hours = gameSeconds / 60 / 60; + Int minutes = (gameSeconds / 60) % 60; + Int seconds = gameSeconds % 60; + Int frame = currentFrame % 30; + + UnicodeString gameTimeString; + gameTimeString.format(L"%2.2d:%2.2d:%2.2d", hours, minutes, seconds); + m_gameTimeString->setText(gameTimeString); + + UnicodeString gameTimeFrameString; + gameTimeFrameString.format(L".%2.2d", frame); + m_gameTimeFrameString->setText(gameTimeFrameString); + + // TheSuperHackers @info this implicitly offsets the game timer from the right instead of left of the screen + int horizontalTimerOffset = TheDisplay->getWidth() - (Int)m_gameTimePosition.x - m_gameTimeString->getWidth() - m_gameTimeFrameString->getWidth(); + int horizontalFrameOffset = TheDisplay->getWidth() - (Int)m_gameTimePosition.x - m_gameTimeFrameString->getWidth(); + + m_gameTimeString->draw(horizontalTimerOffset, m_gameTimePosition.y, m_gameTimeColor, m_gameTimeDropColor); + m_gameTimeFrameString->draw(horizontalFrameOffset, m_gameTimePosition.y, GameMakeColor(180,180,180,255), m_gameTimeDropColor); +} diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp index 006b43e343..b7ed33a180 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp @@ -432,6 +432,8 @@ void W3DInGameUI::draw( void ) postDraw(); TheWindowManager->winRepaint(); + + postWindowDraw(); #ifdef EXTENDED_STATS } From 9fed2249e006f026e0ca2f6fce34102e72bef28b Mon Sep 17 00:00:00 2001 From: Mauller <26652186+Mauller@users.noreply.github.com> Date: Sun, 13 Jul 2025 10:13:03 +0100 Subject: [PATCH 2/2] [GEN] Replicate in generals --- .../GameEngine/Include/Common/GlobalData.h | 4 + .../Include/Common/UserPreferences.h | 3 + .../GameEngine/Include/GameClient/InGameUI.h | 27 ++++ .../GameEngine/Source/Common/GlobalData.cpp | 5 + .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 51 +++++++ .../GameEngine/Source/GameClient/InGameUI.cpp | 139 ++++++++++++++++++ .../W3DDevice/GameClient/W3DInGameUI.cpp | 2 + 7 files changed, 231 insertions(+) diff --git a/Generals/Code/GameEngine/Include/Common/GlobalData.h b/Generals/Code/GameEngine/Include/Common/GlobalData.h index 19cb080c38..181b7bb9e8 100644 --- a/Generals/Code/GameEngine/Include/Common/GlobalData.h +++ b/Generals/Code/GameEngine/Include/Common/GlobalData.h @@ -400,6 +400,10 @@ class GlobalData : public SubsystemInterface Bool m_saveCameraInReplay; Bool m_useCameraInReplay; + // TheSuperHackers @feature Mauller 21/06/2025 allow the system time and game time font size to be set, a size of zero disables them + Int m_systemTimeFontSize; + Int m_gameTimeFontSize; + Real m_shakeSubtleIntensity; ///< Intensity for shaking a camera with SHAKE_SUBTLE Real m_shakeNormalIntensity; ///< Intensity for shaking a camera with SHAKE_NORMAL Real m_shakeStrongIntensity; ///< Intensity for shaking a camera with SHAKE_STRONG diff --git a/Generals/Code/GameEngine/Include/Common/UserPreferences.h b/Generals/Code/GameEngine/Include/Common/UserPreferences.h index 7a47480a37..0597e15cbb 100644 --- a/Generals/Code/GameEngine/Include/Common/UserPreferences.h +++ b/Generals/Code/GameEngine/Include/Common/UserPreferences.h @@ -124,6 +124,9 @@ class OptionPreferences : public UserPreferences Int getCampaignDifficulty(void); void setCampaignDifficulty( Int diff ); + + Int getSystemTimeFontSize(void); + Int getGameTimeFontSize(void); }; //----------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Include/GameClient/InGameUI.h b/Generals/Code/GameEngine/Include/GameClient/InGameUI.h index c20803a84c..6be88c3906 100644 --- a/Generals/Code/GameEngine/Include/GameClient/InGameUI.h +++ b/Generals/Code/GameEngine/Include/GameClient/InGameUI.h @@ -367,6 +367,7 @@ friend class Drawable; // for selection/deselection transactions virtual void toggleMessages( void ) { m_messagesOn = 1 - m_messagesOn; } ///< toggle messages on/off virtual Bool isMessagesOn( void ) { return m_messagesOn; } ///< are the display messages on void freeMessageResources( void ); ///< free resources for the ui messages + void freeCustomUiResources( void ); ///< free resources for custom ui elements Color getMessageColor(Bool altColor) { return (altColor)?m_messageColor2:m_messageColor1; } // interface for military style messages @@ -451,6 +452,7 @@ friend class Drawable; // for selection/deselection transactions virtual void preDraw( void ); ///< Logic which needs to occur before the UI renders virtual void draw( void ) = 0; ///< Render the in-game user interface virtual void postDraw( void ); ///< Logic which needs to occur after the UI renders + virtual void postWindowDraw( void ); ///< Logic which needs to occur after the WindowManager has repainted the menus /// Ingame video playback virtual void playMovie( const AsciiString& movieName ); @@ -542,6 +544,9 @@ friend class Drawable; // for selection/deselection transactions virtual void selectNextIdleWorker( void ); virtual void recreateControlBar( void ); + virtual void refreshCustomUiResources( void ); + virtual void refreshSystemTimeResources( void ); + virtual void refreshGameTimeResources( void ); virtual void disableTooltipsUntil(UnsignedInt frameNum); virtual void clearTooltipsDisabled(); @@ -561,6 +566,9 @@ friend class Drawable; // for selection/deselection transactions virtual void updateIdleWorker( void ); virtual void resetIdleWorker( void ); + void drawSystemTime(); + void drawGameTime(); + public: void registerWindowLayout(WindowLayout *layout); // register a layout for updates void unregisterWindowLayout(WindowLayout *layout); // stop updates for this layout @@ -719,6 +727,25 @@ friend class Drawable; // for selection/deselection transactions VideoBuffer* m_cameoVideoBuffer;///< video playback buffer VideoStreamInterface* m_cameoVideoStream;///< Video stream; + // System Time + DisplayString * m_systemTimeString; + AsciiString m_systemTimeFont; + Int m_systemTimePointSize; + Bool m_systemTimeBold; + Coord2D m_systemTimePosition; + Color m_systemTimeColor; + Color m_systemTimeDropColor; + + // Game Time + DisplayString * m_gameTimeString; + DisplayString * m_gameTimeFrameString; + AsciiString m_gameTimeFont; + Int m_gameTimePointSize; + Bool m_gameTimeBold; + Coord2D m_gameTimePosition; + Color m_gameTimeColor; + Color m_gameTimeDropColor; + // message data UIMessage m_uiMessages[ MAX_UI_MESSAGES ];/**< messages to display to the user, the array is organized with newer messages at diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index 220d0c5aa0..0d21ee85fc 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -919,6 +919,8 @@ GlobalData::GlobalData() m_saveCameraInReplay = FALSE; m_useCameraInReplay = FALSE; + m_systemTimeFontSize = 8; + m_gameTimeFontSize = 8; m_debugShowGraphicalFramerate = FALSE; @@ -1168,6 +1170,9 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_saveCameraInReplay = optionPref.saveCameraInReplays(); TheWritableGlobalData->m_useCameraInReplay = optionPref.useCameraInReplays(); + + TheWritableGlobalData->m_systemTimeFontSize = optionPref.getSystemTimeFontSize(); + TheWritableGlobalData->m_gameTimeFontSize = optionPref.getGameTimeFontSize(); Int val=optionPref.getGammaValue(); //generate a value between 0.6 and 2.0. diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp index 1273b71e5e..dbc67b29ac 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -723,6 +723,34 @@ Real OptionPreferences::getMusicVolume(void) return volume; } +Int OptionPreferences::getSystemTimeFontSize(void) +{ + OptionPreferences::const_iterator it = find("SystemTimeFontSize"); + if (it == end()) + return 8; + + Int fontSize = atoi(it->second.str()); + if (fontSize < 0) + { + fontSize = 0; + } + return fontSize; +} + +Int OptionPreferences::getGameTimeFontSize(void) +{ + OptionPreferences::const_iterator it = find("GameTimeFontSize"); + if (it == end()) + return 8; + + Int fontSize = atoi(it->second.str()); + if (fontSize < 0) + { + fontSize = 0; + } + return fontSize; +} + static OptionPreferences *pref = NULL; static void setDefaults( void ) @@ -1197,6 +1225,28 @@ static void saveOptions( void ) } } + //------------------------------------------------------------------------------------------------- + // Set System Time Font Size + val = TheWritableGlobalData->m_systemTimeFontSize; // TheSuperHackers @todo replace with options input when applicable + if (val) + { + AsciiString prefString; + prefString.format("%d", val); + (*pref)["SystemTimeFontSize"] = prefString; + TheInGameUI->refreshSystemTimeResources(); + } + + //------------------------------------------------------------------------------------------------- + // Set Game Time Font Size + val = TheWritableGlobalData->m_gameTimeFontSize; // TheSuperHackers @todo replace with options input when applicable + if (val) + { + AsciiString prefString; + prefString.format("%d", val); + (*pref)["GameTimeFontSize"] = prefString; + TheInGameUI->refreshGameTimeResources(); + } + //------------------------------------------------------------------------------------------------- // Resolution // @@ -1239,6 +1289,7 @@ static void saveOptions( void ) TheShell->recreateWindowLayouts(); TheInGameUI->recreateControlBar(); + TheInGameUI->refreshCustomUiResources(); } } } diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index 99fb712174..d51d423628 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -842,6 +842,19 @@ const FieldParse InGameUI::s_fieldParseTable[] = { "RadarRadiusCursor", RadiusDecalTemplate::parseRadiusDecalTemplate, NULL, offsetof( InGameUI, m_radiusCursors[ RADIUSCURSOR_RADAR] ) }, { "SpyDroneRadiusCursor", RadiusDecalTemplate::parseRadiusDecalTemplate, NULL, offsetof( InGameUI, m_radiusCursors[ RADIUSCURSOR_SPYDRONE] ) }, + // TheSuperHackers @info ui enhancement configuration + { "SystemTimeFont", INI::parseAsciiString, NULL, offsetof( InGameUI, m_systemTimeFont ) }, + { "SystemTimeBold", INI::parseBool, NULL, offsetof( InGameUI, m_systemTimeBold ) }, + { "SystemTimePosition", INI::parseCoord2D, NULL, offsetof( InGameUI, m_systemTimePosition ) }, + { "SystemTimeColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_systemTimeColor ) }, + { "SystemTimeDropColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_systemTimeDropColor ) }, + + { "GameTimeFont", INI::parseAsciiString, NULL, offsetof( InGameUI, m_gameTimeFont ) }, + { "GameTimeBold", INI::parseBool, NULL, offsetof( InGameUI, m_gameTimeBold ) }, + { "GameTimePosition", INI::parseCoord2D, NULL, offsetof( InGameUI, m_gameTimePosition ) }, + { "GameTimeColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_gameTimeColor ) }, + { "GameTimeDropColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_gameTimeDropColor ) }, + { NULL, NULL, NULL, 0 } // keep this last }; @@ -966,6 +979,26 @@ InGameUI::InGameUI() m_replayWindow = NULL; m_messagesOn = TRUE; + // TheSuperHackers @info the default font, size and positions of the system and game times were chosen based on GenTools implementation + m_systemTimeString = NULL; + m_systemTimeFont = "Tahoma"; + m_systemTimePointSize = TheGlobalData->m_systemTimeFontSize; + m_systemTimeBold = TRUE; + m_systemTimePosition.x = 3; // TheSuperHackers @info relative to the left of the screen + m_systemTimePosition.y = -1; + m_systemTimeColor = GameMakeColor( 255, 255, 255, 255 ); + m_systemTimeDropColor = GameMakeColor( 0, 0, 0, 255 ); + + m_gameTimeString = NULL; + m_gameTimeFrameString = NULL; + m_gameTimeFont = "Tahoma"; + m_gameTimePointSize = TheGlobalData->m_gameTimeFontSize; + m_gameTimeBold = TRUE; + m_gameTimePosition.x = 3; // TheSuperHackers @info relative to the right of the screen + m_gameTimePosition.y = -1; + m_gameTimeColor = GameMakeColor( 255, 255, 255, 255 ); + m_gameTimeDropColor = GameMakeColor( 0, 0, 0, 255 ); + m_superweaponPosition.x = 0.7f; m_superweaponPosition.y = 0.7f; m_superweaponFlashDuration = 1.0f; @@ -1047,6 +1080,9 @@ InGameUI::~InGameUI() // delete the message resources freeMessageResources(); + // free custom ui strings + freeCustomUiResources(); + // delete the array for the drawbles delete [] m_placeIcon; m_placeIcon = NULL; @@ -1863,6 +1899,9 @@ void InGameUI::reset( void ) // free any message resources allocated freeMessageResources(); + // refresh custom ui strings - this will create the strings if required and update the fonts + refreshCustomUiResources(); + Int i; for (i=0; ifreeDisplayString(m_systemTimeString); + m_systemTimeString = NULL; + TheDisplayStringManager->freeDisplayString(m_gameTimeString); + m_gameTimeString = NULL; + TheDisplayStringManager->freeDisplayString(m_gameTimeFrameString); + m_gameTimeFrameString = NULL; +} + //------------------------------------------------------------------------------------------------- /** Same as the unicode message method, but this takes an ascii string which is assumed * to me a string manager label */ @@ -3364,6 +3413,22 @@ void InGameUI::disregardDrawable( Drawable *draw ) } +//------------------------------------------------------------------------------------------------- +/** This is called after the WindowManager has drawn the menus. */ +//------------------------------------------------------------------------------------------------- +void InGameUI::postWindowDraw( void ) +{ + if (m_systemTimePointSize > 0) + { + drawSystemTime(); + } + + if ( (m_gameTimePointSize > 0) && !TheGameLogic->isInShellGame() && TheGameLogic->isInGame() ) + { + drawGameTime(); + } +} + //------------------------------------------------------------------------------------------------- /** This is called after the UI has been drawn. */ //------------------------------------------------------------------------------------------------- @@ -5487,6 +5552,44 @@ void InGameUI::recreateControlBar( void ) } +void InGameUI::refreshCustomUiResources(void) +{ + refreshSystemTimeResources(); + refreshGameTimeResources(); +} + +void InGameUI::refreshSystemTimeResources(void) +{ + if (!m_systemTimeString) + { + m_systemTimeString = TheDisplayStringManager->newDisplayString(); + } + + m_systemTimePointSize = TheGlobalData->m_systemTimeFontSize; + Int adjustedSystemTimeFontSize = TheGlobalLanguageData->adjustFontSize(m_systemTimePointSize); + GameFont* systemTimeFont = TheWindowManager->winFindFont(m_systemTimeFont, adjustedSystemTimeFontSize, m_systemTimeBold); + m_systemTimeString->setFont(systemTimeFont); +} + +void InGameUI::refreshGameTimeResources(void) +{ + if (!m_gameTimeString) + { + m_gameTimeString = TheDisplayStringManager->newDisplayString(); + } + + if (!m_gameTimeFrameString) + { + m_gameTimeFrameString = TheDisplayStringManager->newDisplayString(); + } + + m_gameTimePointSize = TheGlobalData->m_gameTimeFontSize; + Int adjustedGameTimeFontSize = TheGlobalLanguageData->adjustFontSize(m_gameTimePointSize); + GameFont* gameTimeFont = TheWindowManager->winFindFont(m_gameTimeFont, adjustedGameTimeFontSize, m_gameTimeBold); + m_gameTimeString->setFont(gameTimeFont); + m_gameTimeFrameString->setFont(gameTimeFont); +} + void InGameUI::disableTooltipsUntil(UnsignedInt frameNum) { if (frameNum > m_tooltipsDisabledUntil) @@ -5541,4 +5644,40 @@ WindowMsgHandledType IdleWorkerSystem( GameWindow *window, UnsignedInt msg, } +void InGameUI::drawSystemTime() +{ + // current system time + SYSTEMTIME systemTime; + GetLocalTime( &systemTime ); + + UnicodeString TimeString; + TimeString.format(L"%2.2d:%2.2d:%2.2d", systemTime.wHour, systemTime.wMinute, systemTime.wSecond); + m_systemTimeString->setText(TimeString); + m_systemTimeString->draw(m_systemTimePosition.x, m_systemTimePosition.y, m_systemTimeColor, m_systemTimeDropColor); +} + +void InGameUI::drawGameTime() +{ + Int currentFrame = TheGameLogic->getFrame(); + Int gameSeconds = (Int) (SECONDS_PER_LOGICFRAME_REAL * currentFrame ); + Int hours = gameSeconds / 60 / 60; + Int minutes = (gameSeconds / 60) % 60; + Int seconds = gameSeconds % 60; + Int frame = currentFrame % 30; + + UnicodeString gameTimeString; + gameTimeString.format(L"%2.2d:%2.2d:%2.2d", hours, minutes, seconds); + m_gameTimeString->setText(gameTimeString); + + UnicodeString gameTimeFrameString; + gameTimeFrameString.format(L".%2.2d", frame); + m_gameTimeFrameString->setText(gameTimeFrameString); + + // TheSuperHackers @info this implicitly offsets the game timer from the right instead of left of the screen + int horizontalTimerOffset = TheDisplay->getWidth() - (Int)m_gameTimePosition.x - m_gameTimeString->getWidth() - m_gameTimeFrameString->getWidth(); + int horizontalFrameOffset = TheDisplay->getWidth() - (Int)m_gameTimePosition.x - m_gameTimeFrameString->getWidth(); + + m_gameTimeString->draw(horizontalTimerOffset, m_gameTimePosition.y, m_gameTimeColor, m_gameTimeDropColor); + m_gameTimeFrameString->draw(horizontalFrameOffset, m_gameTimePosition.y, GameMakeColor(180,180,180,255), m_gameTimeDropColor); +} diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp index fb06ee3c18..9e2166d6b7 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp @@ -432,6 +432,8 @@ void W3DInGameUI::draw( void ) postDraw(); TheWindowManager->winRepaint(); + + postWindowDraw(); #ifdef EXTENDED_STATS }