Skip to content

Commit 27f7063

Browse files
authored
[GEN][ZH] Implement System Time and Game Time display (#1170)
1 parent 1b1f576 commit 27f7063

File tree

14 files changed

+462
-0
lines changed

14 files changed

+462
-0
lines changed

Generals/Code/GameEngine/Include/Common/GlobalData.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ class GlobalData : public SubsystemInterface
400400
Bool m_saveCameraInReplay;
401401
Bool m_useCameraInReplay;
402402

403+
// TheSuperHackers @feature Mauller 21/06/2025 allow the system time and game time font size to be set, a size of zero disables them
404+
Int m_systemTimeFontSize;
405+
Int m_gameTimeFontSize;
406+
403407
Real m_shakeSubtleIntensity; ///< Intensity for shaking a camera with SHAKE_SUBTLE
404408
Real m_shakeNormalIntensity; ///< Intensity for shaking a camera with SHAKE_NORMAL
405409
Real m_shakeStrongIntensity; ///< Intensity for shaking a camera with SHAKE_STRONG

Generals/Code/GameEngine/Include/Common/UserPreferences.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ class OptionPreferences : public UserPreferences
124124

125125
Int getCampaignDifficulty(void);
126126
void setCampaignDifficulty( Int diff );
127+
128+
Int getSystemTimeFontSize(void);
129+
Int getGameTimeFontSize(void);
127130
};
128131

129132
//-----------------------------------------------------------------------------

Generals/Code/GameEngine/Include/GameClient/InGameUI.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ friend class Drawable; // for selection/deselection transactions
367367
virtual void toggleMessages( void ) { m_messagesOn = 1 - m_messagesOn; } ///< toggle messages on/off
368368
virtual Bool isMessagesOn( void ) { return m_messagesOn; } ///< are the display messages on
369369
void freeMessageResources( void ); ///< free resources for the ui messages
370+
void freeCustomUiResources( void ); ///< free resources for custom ui elements
370371
Color getMessageColor(Bool altColor) { return (altColor)?m_messageColor2:m_messageColor1; }
371372

372373
// interface for military style messages
@@ -451,6 +452,7 @@ friend class Drawable; // for selection/deselection transactions
451452
virtual void preDraw( void ); ///< Logic which needs to occur before the UI renders
452453
virtual void draw( void ) = 0; ///< Render the in-game user interface
453454
virtual void postDraw( void ); ///< Logic which needs to occur after the UI renders
455+
virtual void postWindowDraw( void ); ///< Logic which needs to occur after the WindowManager has repainted the menus
454456

455457
/// Ingame video playback
456458
virtual void playMovie( const AsciiString& movieName );
@@ -542,6 +544,9 @@ friend class Drawable; // for selection/deselection transactions
542544
virtual void selectNextIdleWorker( void );
543545

544546
virtual void recreateControlBar( void );
547+
virtual void refreshCustomUiResources( void );
548+
virtual void refreshSystemTimeResources( void );
549+
virtual void refreshGameTimeResources( void );
545550

546551
virtual void disableTooltipsUntil(UnsignedInt frameNum);
547552
virtual void clearTooltipsDisabled();
@@ -561,6 +566,9 @@ friend class Drawable; // for selection/deselection transactions
561566
virtual void updateIdleWorker( void );
562567
virtual void resetIdleWorker( void );
563568

569+
void drawSystemTime();
570+
void drawGameTime();
571+
564572
public:
565573
void registerWindowLayout(WindowLayout *layout); // register a layout for updates
566574
void unregisterWindowLayout(WindowLayout *layout); // stop updates for this layout
@@ -719,6 +727,25 @@ friend class Drawable; // for selection/deselection transactions
719727
VideoBuffer* m_cameoVideoBuffer;///< video playback buffer
720728
VideoStreamInterface* m_cameoVideoStream;///< Video stream;
721729

730+
// System Time
731+
DisplayString * m_systemTimeString;
732+
AsciiString m_systemTimeFont;
733+
Int m_systemTimePointSize;
734+
Bool m_systemTimeBold;
735+
Coord2D m_systemTimePosition;
736+
Color m_systemTimeColor;
737+
Color m_systemTimeDropColor;
738+
739+
// Game Time
740+
DisplayString * m_gameTimeString;
741+
DisplayString * m_gameTimeFrameString;
742+
AsciiString m_gameTimeFont;
743+
Int m_gameTimePointSize;
744+
Bool m_gameTimeBold;
745+
Coord2D m_gameTimePosition;
746+
Color m_gameTimeColor;
747+
Color m_gameTimeDropColor;
748+
722749
// message data
723750
UIMessage m_uiMessages[ MAX_UI_MESSAGES ];/**< messages to display to the user, the
724751
array is organized with newer messages at

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,8 @@ GlobalData::GlobalData()
922922
m_saveCameraInReplay = FALSE;
923923
m_useCameraInReplay = FALSE;
924924

925+
m_systemTimeFontSize = 8;
926+
m_gameTimeFontSize = 8;
925927

926928
m_debugShowGraphicalFramerate = FALSE;
927929

@@ -1171,6 +1173,9 @@ void GlobalData::parseGameDataDefinition( INI* ini )
11711173

11721174
TheWritableGlobalData->m_saveCameraInReplay = optionPref.saveCameraInReplays();
11731175
TheWritableGlobalData->m_useCameraInReplay = optionPref.useCameraInReplays();
1176+
1177+
TheWritableGlobalData->m_systemTimeFontSize = optionPref.getSystemTimeFontSize();
1178+
TheWritableGlobalData->m_gameTimeFontSize = optionPref.getGameTimeFontSize();
11741179

11751180
Int val=optionPref.getGammaValue();
11761181
//generate a value between 0.6 and 2.0.

Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,34 @@ Real OptionPreferences::getMusicVolume(void)
723723
return volume;
724724
}
725725

726+
Int OptionPreferences::getSystemTimeFontSize(void)
727+
{
728+
OptionPreferences::const_iterator it = find("SystemTimeFontSize");
729+
if (it == end())
730+
return 8;
731+
732+
Int fontSize = atoi(it->second.str());
733+
if (fontSize < 0)
734+
{
735+
fontSize = 0;
736+
}
737+
return fontSize;
738+
}
739+
740+
Int OptionPreferences::getGameTimeFontSize(void)
741+
{
742+
OptionPreferences::const_iterator it = find("GameTimeFontSize");
743+
if (it == end())
744+
return 8;
745+
746+
Int fontSize = atoi(it->second.str());
747+
if (fontSize < 0)
748+
{
749+
fontSize = 0;
750+
}
751+
return fontSize;
752+
}
753+
726754
static OptionPreferences *pref = NULL;
727755

728756
static void setDefaults( void )
@@ -1197,6 +1225,28 @@ static void saveOptions( void )
11971225
}
11981226
}
11991227

1228+
//-------------------------------------------------------------------------------------------------
1229+
// Set System Time Font Size
1230+
val = TheWritableGlobalData->m_systemTimeFontSize; // TheSuperHackers @todo replace with options input when applicable
1231+
if (val)
1232+
{
1233+
AsciiString prefString;
1234+
prefString.format("%d", val);
1235+
(*pref)["SystemTimeFontSize"] = prefString;
1236+
TheInGameUI->refreshSystemTimeResources();
1237+
}
1238+
1239+
//-------------------------------------------------------------------------------------------------
1240+
// Set Game Time Font Size
1241+
val = TheWritableGlobalData->m_gameTimeFontSize; // TheSuperHackers @todo replace with options input when applicable
1242+
if (val)
1243+
{
1244+
AsciiString prefString;
1245+
prefString.format("%d", val);
1246+
(*pref)["GameTimeFontSize"] = prefString;
1247+
TheInGameUI->refreshGameTimeResources();
1248+
}
1249+
12001250
//-------------------------------------------------------------------------------------------------
12011251
// Resolution
12021252
//
@@ -1239,6 +1289,7 @@ static void saveOptions( void )
12391289
TheShell->recreateWindowLayouts();
12401290

12411291
TheInGameUI->recreateControlBar();
1292+
TheInGameUI->refreshCustomUiResources();
12421293
}
12431294
}
12441295
}

Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,19 @@ const FieldParse InGameUI::s_fieldParseTable[] =
842842
{ "RadarRadiusCursor", RadiusDecalTemplate::parseRadiusDecalTemplate, NULL, offsetof( InGameUI, m_radiusCursors[ RADIUSCURSOR_RADAR] ) },
843843
{ "SpyDroneRadiusCursor", RadiusDecalTemplate::parseRadiusDecalTemplate, NULL, offsetof( InGameUI, m_radiusCursors[ RADIUSCURSOR_SPYDRONE] ) },
844844

845+
// TheSuperHackers @info ui enhancement configuration
846+
{ "SystemTimeFont", INI::parseAsciiString, NULL, offsetof( InGameUI, m_systemTimeFont ) },
847+
{ "SystemTimeBold", INI::parseBool, NULL, offsetof( InGameUI, m_systemTimeBold ) },
848+
{ "SystemTimePosition", INI::parseCoord2D, NULL, offsetof( InGameUI, m_systemTimePosition ) },
849+
{ "SystemTimeColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_systemTimeColor ) },
850+
{ "SystemTimeDropColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_systemTimeDropColor ) },
851+
852+
{ "GameTimeFont", INI::parseAsciiString, NULL, offsetof( InGameUI, m_gameTimeFont ) },
853+
{ "GameTimeBold", INI::parseBool, NULL, offsetof( InGameUI, m_gameTimeBold ) },
854+
{ "GameTimePosition", INI::parseCoord2D, NULL, offsetof( InGameUI, m_gameTimePosition ) },
855+
{ "GameTimeColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_gameTimeColor ) },
856+
{ "GameTimeDropColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_gameTimeDropColor ) },
857+
845858
{ NULL, NULL, NULL, 0 } // keep this last
846859
};
847860

@@ -966,6 +979,26 @@ InGameUI::InGameUI()
966979
m_replayWindow = NULL;
967980
m_messagesOn = TRUE;
968981

982+
// TheSuperHackers @info the default font, size and positions of the system and game times were chosen based on GenTools implementation
983+
m_systemTimeString = NULL;
984+
m_systemTimeFont = "Tahoma";
985+
m_systemTimePointSize = TheGlobalData->m_systemTimeFontSize;
986+
m_systemTimeBold = TRUE;
987+
m_systemTimePosition.x = 3; // TheSuperHackers @info relative to the left of the screen
988+
m_systemTimePosition.y = -1;
989+
m_systemTimeColor = GameMakeColor( 255, 255, 255, 255 );
990+
m_systemTimeDropColor = GameMakeColor( 0, 0, 0, 255 );
991+
992+
m_gameTimeString = NULL;
993+
m_gameTimeFrameString = NULL;
994+
m_gameTimeFont = "Tahoma";
995+
m_gameTimePointSize = TheGlobalData->m_gameTimeFontSize;
996+
m_gameTimeBold = TRUE;
997+
m_gameTimePosition.x = 3; // TheSuperHackers @info relative to the right of the screen
998+
m_gameTimePosition.y = -1;
999+
m_gameTimeColor = GameMakeColor( 255, 255, 255, 255 );
1000+
m_gameTimeDropColor = GameMakeColor( 0, 0, 0, 255 );
1001+
9691002
m_superweaponPosition.x = 0.7f;
9701003
m_superweaponPosition.y = 0.7f;
9711004
m_superweaponFlashDuration = 1.0f;
@@ -1047,6 +1080,9 @@ InGameUI::~InGameUI()
10471080
// delete the message resources
10481081
freeMessageResources();
10491082

1083+
// free custom ui strings
1084+
freeCustomUiResources();
1085+
10501086
// delete the array for the drawbles
10511087
delete [] m_placeIcon;
10521088
m_placeIcon = NULL;
@@ -1863,6 +1899,9 @@ void InGameUI::reset( void )
18631899
// free any message resources allocated
18641900
freeMessageResources();
18651901

1902+
// refresh custom ui strings - this will create the strings if required and update the fonts
1903+
refreshCustomUiResources();
1904+
18661905
Int i;
18671906
for (i=0; i<MAX_PLAYER_COUNT; ++i)
18681907
{
@@ -1948,6 +1987,16 @@ void InGameUI::freeMessageResources( void )
19481987

19491988
} // end freeMessageResources
19501989

1990+
void InGameUI::freeCustomUiResources( void )
1991+
{
1992+
TheDisplayStringManager->freeDisplayString(m_systemTimeString);
1993+
m_systemTimeString = NULL;
1994+
TheDisplayStringManager->freeDisplayString(m_gameTimeString);
1995+
m_gameTimeString = NULL;
1996+
TheDisplayStringManager->freeDisplayString(m_gameTimeFrameString);
1997+
m_gameTimeFrameString = NULL;
1998+
}
1999+
19512000
//-------------------------------------------------------------------------------------------------
19522001
/** Same as the unicode message method, but this takes an ascii string which is assumed
19532002
* to me a string manager label */
@@ -3364,6 +3413,22 @@ void InGameUI::disregardDrawable( Drawable *draw )
33643413

33653414
}
33663415

3416+
//-------------------------------------------------------------------------------------------------
3417+
/** This is called after the WindowManager has drawn the menus. */
3418+
//-------------------------------------------------------------------------------------------------
3419+
void InGameUI::postWindowDraw( void )
3420+
{
3421+
if (m_systemTimePointSize > 0)
3422+
{
3423+
drawSystemTime();
3424+
}
3425+
3426+
if ( (m_gameTimePointSize > 0) && !TheGameLogic->isInShellGame() && TheGameLogic->isInGame() )
3427+
{
3428+
drawGameTime();
3429+
}
3430+
}
3431+
33673432
//-------------------------------------------------------------------------------------------------
33683433
/** This is called after the UI has been drawn. */
33693434
//-------------------------------------------------------------------------------------------------
@@ -5487,6 +5552,44 @@ void InGameUI::recreateControlBar( void )
54875552

54885553
}
54895554

5555+
void InGameUI::refreshCustomUiResources(void)
5556+
{
5557+
refreshSystemTimeResources();
5558+
refreshGameTimeResources();
5559+
}
5560+
5561+
void InGameUI::refreshSystemTimeResources(void)
5562+
{
5563+
if (!m_systemTimeString)
5564+
{
5565+
m_systemTimeString = TheDisplayStringManager->newDisplayString();
5566+
}
5567+
5568+
m_systemTimePointSize = TheGlobalData->m_systemTimeFontSize;
5569+
Int adjustedSystemTimeFontSize = TheGlobalLanguageData->adjustFontSize(m_systemTimePointSize);
5570+
GameFont* systemTimeFont = TheWindowManager->winFindFont(m_systemTimeFont, adjustedSystemTimeFontSize, m_systemTimeBold);
5571+
m_systemTimeString->setFont(systemTimeFont);
5572+
}
5573+
5574+
void InGameUI::refreshGameTimeResources(void)
5575+
{
5576+
if (!m_gameTimeString)
5577+
{
5578+
m_gameTimeString = TheDisplayStringManager->newDisplayString();
5579+
}
5580+
5581+
if (!m_gameTimeFrameString)
5582+
{
5583+
m_gameTimeFrameString = TheDisplayStringManager->newDisplayString();
5584+
}
5585+
5586+
m_gameTimePointSize = TheGlobalData->m_gameTimeFontSize;
5587+
Int adjustedGameTimeFontSize = TheGlobalLanguageData->adjustFontSize(m_gameTimePointSize);
5588+
GameFont* gameTimeFont = TheWindowManager->winFindFont(m_gameTimeFont, adjustedGameTimeFontSize, m_gameTimeBold);
5589+
m_gameTimeString->setFont(gameTimeFont);
5590+
m_gameTimeFrameString->setFont(gameTimeFont);
5591+
}
5592+
54905593
void InGameUI::disableTooltipsUntil(UnsignedInt frameNum)
54915594
{
54925595
if (frameNum > m_tooltipsDisabledUntil)
@@ -5541,4 +5644,40 @@ WindowMsgHandledType IdleWorkerSystem( GameWindow *window, UnsignedInt msg,
55415644

55425645
}
55435646

5647+
void InGameUI::drawSystemTime()
5648+
{
5649+
// current system time
5650+
SYSTEMTIME systemTime;
5651+
GetLocalTime( &systemTime );
5652+
5653+
UnicodeString TimeString;
5654+
TimeString.format(L"%2.2d:%2.2d:%2.2d", systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
5655+
m_systemTimeString->setText(TimeString);
55445656

5657+
m_systemTimeString->draw(m_systemTimePosition.x, m_systemTimePosition.y, m_systemTimeColor, m_systemTimeDropColor);
5658+
}
5659+
5660+
void InGameUI::drawGameTime()
5661+
{
5662+
Int currentFrame = TheGameLogic->getFrame();
5663+
Int gameSeconds = (Int) (SECONDS_PER_LOGICFRAME_REAL * currentFrame );
5664+
Int hours = gameSeconds / 60 / 60;
5665+
Int minutes = (gameSeconds / 60) % 60;
5666+
Int seconds = gameSeconds % 60;
5667+
Int frame = currentFrame % 30;
5668+
5669+
UnicodeString gameTimeString;
5670+
gameTimeString.format(L"%2.2d:%2.2d:%2.2d", hours, minutes, seconds);
5671+
m_gameTimeString->setText(gameTimeString);
5672+
5673+
UnicodeString gameTimeFrameString;
5674+
gameTimeFrameString.format(L".%2.2d", frame);
5675+
m_gameTimeFrameString->setText(gameTimeFrameString);
5676+
5677+
// TheSuperHackers @info this implicitly offsets the game timer from the right instead of left of the screen
5678+
int horizontalTimerOffset = TheDisplay->getWidth() - (Int)m_gameTimePosition.x - m_gameTimeString->getWidth() - m_gameTimeFrameString->getWidth();
5679+
int horizontalFrameOffset = TheDisplay->getWidth() - (Int)m_gameTimePosition.x - m_gameTimeFrameString->getWidth();
5680+
5681+
m_gameTimeString->draw(horizontalTimerOffset, m_gameTimePosition.y, m_gameTimeColor, m_gameTimeDropColor);
5682+
m_gameTimeFrameString->draw(horizontalFrameOffset, m_gameTimePosition.y, GameMakeColor(180,180,180,255), m_gameTimeDropColor);
5683+
}

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ void W3DInGameUI::draw( void )
432432
postDraw();
433433

434434
TheWindowManager->winRepaint();
435+
436+
postWindowDraw();
435437

436438
#ifdef EXTENDED_STATS
437439
}

GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,10 @@ class GlobalData : public SubsystemInterface
408408
Bool m_saveCameraInReplay;
409409
Bool m_useCameraInReplay;
410410

411+
// TheSuperHackers @feature Mauller 21/06/2025 allow the system time and game time font size to be set, a size of zero disables them
412+
Int m_systemTimeFontSize;
413+
Int m_gameTimeFontSize;
414+
411415
Real m_shakeSubtleIntensity; ///< Intensity for shaking a camera with SHAKE_SUBTLE
412416
Real m_shakeNormalIntensity; ///< Intensity for shaking a camera with SHAKE_NORMAL
413417
Real m_shakeStrongIntensity; ///< Intensity for shaking a camera with SHAKE_STRONG

GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ class OptionPreferences : public UserPreferences
129129

130130
Int getCampaignDifficulty(void);
131131
void setCampaignDifficulty( Int diff );
132+
133+
Int getSystemTimeFontSize(void);
134+
Int getGameTimeFontSize(void);
132135
};
133136

134137
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)