Skip to content

Commit 44ee55a

Browse files
committed
[ZH] Implement system time and simulation timer within InGameUI
1 parent 222a7bf commit 44ee55a

File tree

6 files changed

+180
-0
lines changed

6 files changed

+180
-0
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ class GlobalData : public SubsystemInterface
284284
Bool m_constantDebugUpdate; ///< should we update the debug stats constantly, vs every 2 seconds?
285285
Bool m_showTeamDot; ///< Shows the little colored team dot representing which team you are controlling.
286286

287+
287288
#ifdef DUMP_PERF_STATS
288289
Bool m_dumpPerformanceStatistics;
289290
Bool m_dumpStatsAtInterval;///< should I automatically dum stats every in N frames
@@ -409,6 +410,10 @@ class GlobalData : public SubsystemInterface
409410
Bool m_saveCameraInReplay;
410411
Bool m_useCameraInReplay;
411412

413+
// TheSuperHackers @feature Mauller 21/06/2025 allow the system time and game timer to be toggleable
414+
Bool m_showSystemTime;
415+
Bool m_showGameTime;
416+
412417
Real m_shakeSubtleIntensity; ///< Intensity for shaking a camera with SHAKE_SUBTLE
413418
Real m_shakeNormalIntensity; ///< Intensity for shaking a camera with SHAKE_NORMAL
414419
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+
Bool getSystemTimeEnabled(void);
134+
Bool getGameTimeEnabled(void);
132135
};
133136

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

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ friend class Drawable; // for selection/deselection transactions
382382
virtual void toggleMessages( void ) { m_messagesOn = 1 - m_messagesOn; } ///< toggle messages on/off
383383
virtual Bool isMessagesOn( void ) { return m_messagesOn; } ///< are the display messages on
384384
void freeMessageResources( void ); ///< free resources for the ui messages
385+
void freeCustomUiResources( void ); ///< free resources for custom ui elements
385386
Color getMessageColor(Bool altColor) { return (altColor)?m_messageColor2:m_messageColor1; }
386387

387388
// interface for military style messages
@@ -741,6 +742,25 @@ friend class Drawable; // for selection/deselection transactions
741742
VideoBuffer* m_cameoVideoBuffer;///< video playback buffer
742743
VideoStreamInterface* m_cameoVideoStream;///< Video stream;
743744

745+
// System Time
746+
DisplayString * m_systemTimeString;
747+
AsciiString m_systemTimeFont;
748+
Int m_systemTimePointSize;
749+
Bool m_systemTimeBold;
750+
Coord2D m_systemTimePosition;
751+
Color m_systemTimeColor;
752+
Color m_systemTimeDropColor;
753+
754+
// Simulation Timer
755+
DisplayString * m_gameTimeString;
756+
DisplayString * m_gameTimeFrameString;
757+
AsciiString m_gameTimeFont;
758+
Int m_gameTimePointSize;
759+
Bool m_gameTimeBold;
760+
Coord2D m_gameTimePosition;
761+
Color m_gameTimeColor;
762+
Color m_gameTimeDropColor;
763+
744764
// message data
745765
UIMessage m_uiMessages[ MAX_UI_MESSAGES ];/**< messages to display to the user, the
746766
array is organized with newer messages at

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,8 @@ GlobalData::GlobalData()
928928
m_saveCameraInReplay = FALSE;
929929
m_useCameraInReplay = FALSE;
930930

931+
m_showSystemTime = TRUE;
932+
m_showGameTime = TRUE;
931933

932934
m_debugShowGraphicalFramerate = FALSE;
933935

@@ -1263,6 +1265,9 @@ void GlobalData::parseGameDataDefinition( INI* ini )
12631265

12641266
TheWritableGlobalData->m_saveCameraInReplay = optionPref.saveCameraInReplays();
12651267
TheWritableGlobalData->m_useCameraInReplay = optionPref.useCameraInReplays();
1268+
1269+
TheWritableGlobalData->m_showSystemTime = optionPref.getSystemTimeEnabled();
1270+
TheWritableGlobalData->m_showGameTime = optionPref.getGameTimeEnabled();
12661271

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

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,32 @@ Real OptionPreferences::getMusicVolume(void)
772772
return volume;
773773
}
774774

775+
// TheSuperHackers @info Here for ini parsing and future use when the options menu is reworked to add new options
776+
Bool OptionPreferences::getSystemTimeEnabled(void)
777+
{
778+
OptionPreferences::const_iterator it = find("SystemTimeEnabled");
779+
if (it == end())
780+
return TRUE;
781+
782+
if (stricmp(it->second.str(), "yes") == 0) {
783+
return TRUE;
784+
}
785+
return FALSE;
786+
}
787+
788+
// TheSuperHackers @info Here for ini parsing and future use when the options menu is reworked to add new options
789+
Bool OptionPreferences::getGameTimeEnabled(void)
790+
{
791+
OptionPreferences::const_iterator it = find("GameTimerEnabled");
792+
if (it == end())
793+
return TRUE;
794+
795+
if (stricmp(it->second.str(), "yes") == 0) {
796+
return TRUE;
797+
}
798+
return FALSE;
799+
}
800+
775801
static OptionPreferences *pref = NULL;
776802

777803
static void setDefaults( void )
@@ -1262,6 +1288,16 @@ static void saveOptions( void )
12621288
}
12631289
}
12641290

1291+
//-------------------------------------------------------------------------------------------------
1292+
// Show System Time
1293+
1294+
(*pref)["ShowSystemTime"] = TheWritableGlobalData->m_showSystemTime ? "yes" : "no";
1295+
1296+
//-------------------------------------------------------------------------------------------------
1297+
// Show Game Time
1298+
1299+
(*pref)["ShowGameTime"] = TheWritableGlobalData->m_showGameTime ? "yes" : "no";
1300+
12651301
//-------------------------------------------------------------------------------------------------
12661302
// Resolution
12671303
//

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

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,21 @@ const FieldParse InGameUI::s_fieldParseTable[] =
876876
{ "ClearMinesRadiusCursor", RadiusDecalTemplate::parseRadiusDecalTemplate, NULL, offsetof( InGameUI, m_radiusCursors[ RADIUSCURSOR_CLEARMINES] ) },
877877
{ "AmbulanceRadiusCursor", RadiusDecalTemplate::parseRadiusDecalTemplate, NULL, offsetof( InGameUI, m_radiusCursors[ RADIUSCURSOR_AMBULANCE] ) },
878878

879+
// TheSuperHackers @info ui enhancement configuration
880+
{ "SystemTimeFont", INI::parseAsciiString, NULL, offsetof( InGameUI, m_systemTimeFont ) },
881+
{ "SystemTimePointSize", INI::parseInt, NULL, offsetof( InGameUI, m_systemTimePointSize ) },
882+
{ "SystemTimeBold", INI::parseBool, NULL, offsetof( InGameUI, m_systemTimeBold ) },
883+
{ "SystemTimePosition", INI::parseCoord2D, NULL, offsetof( InGameUI, m_systemTimePosition ) },
884+
{ "SystemTimeColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_systemTimeColor ) },
885+
{ "SystemTimeDropColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_systemTimeDropColor ) },
886+
887+
{ "GameTimeFont", INI::parseAsciiString, NULL, offsetof( InGameUI, m_gameTimeFont ) },
888+
{ "GameTimePointSize", INI::parseInt, NULL, offsetof( InGameUI, m_gameTimePointSize ) },
889+
{ "GameTimeBold", INI::parseBool, NULL, offsetof( InGameUI, m_gameTimeBold ) },
890+
{ "GameTimePosition", INI::parseCoord2D, NULL, offsetof( InGameUI, m_gameTimePosition ) },
891+
{ "GameTimeColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_gameTimeColor ) },
892+
{ "GameTimeDropColor", INI::parseColorInt, NULL, offsetof( InGameUI, m_gameTimeDropColor ) },
893+
879894
{ NULL, NULL, NULL, 0 } // keep this last
880895
};
881896

@@ -1001,6 +1016,25 @@ InGameUI::InGameUI()
10011016
m_replayWindow = NULL;
10021017
m_messagesOn = TRUE;
10031018

1019+
m_systemTimeString = NULL;
1020+
m_systemTimeFont = "Tahoma";
1021+
m_systemTimePointSize = 8;
1022+
m_systemTimeBold = TRUE;
1023+
m_systemTimePosition.x = 3; // TheSuperHackers @info relative to the left of the screen
1024+
m_systemTimePosition.y = -1;
1025+
m_systemTimeColor = GameMakeColor( 255, 255, 255, 255 );
1026+
m_systemTimeDropColor = GameMakeColor( 0, 0, 0, 255 );
1027+
1028+
m_gameTimeString = NULL;
1029+
m_gameTimeFrameString = NULL;
1030+
m_gameTimeFont = "Tahoma";
1031+
m_gameTimePointSize = 8;
1032+
m_gameTimeBold = TRUE;
1033+
m_gameTimePosition.x = 3; // TheSuperHackers @info relative to the right of the screen
1034+
m_gameTimePosition.y = -1;
1035+
m_gameTimeColor = GameMakeColor( 255, 255, 255, 255 );
1036+
m_gameTimeDropColor = GameMakeColor( 0, 0, 0, 255 );
1037+
10041038
m_superweaponPosition.x = 0.7f;
10051039
m_superweaponPosition.y = 0.7f;
10061040
m_superweaponFlashDuration = 1.0f;
@@ -1082,6 +1116,9 @@ InGameUI::~InGameUI()
10821116
// delete the message resources
10831117
freeMessageResources();
10841118

1119+
// free custom ui strings
1120+
freeCustomUiResources();
1121+
10851122
// delete the array for the drawbles
10861123
delete [] m_placeIcon;
10871124
m_placeIcon = NULL;
@@ -1924,6 +1961,9 @@ void InGameUI::reset( void )
19241961
// free any message resources allocated
19251962
freeMessageResources();
19261963

1964+
// free custom ui strings
1965+
freeCustomUiResources();
1966+
19271967
Int i;
19281968
for (i=0; i<MAX_PLAYER_COUNT; ++i)
19291969
{
@@ -2009,6 +2049,19 @@ void InGameUI::freeMessageResources( void )
20092049

20102050
} // end freeMessageResources
20112051

2052+
void InGameUI::freeCustomUiResources( void )
2053+
{
2054+
2055+
// release system time and game timer strings then set them to empty
2056+
TheDisplayStringManager->freeDisplayString(m_systemTimeString);
2057+
m_systemTimeString = NULL;
2058+
TheDisplayStringManager->freeDisplayString(m_gameTimeString);
2059+
m_gameTimeString = NULL;
2060+
TheDisplayStringManager->freeDisplayString(m_gameTimeFrameString);
2061+
m_gameTimeFrameString = NULL;
2062+
2063+
} // end freeCustomUiResources
2064+
20122065
//-------------------------------------------------------------------------------------------------
20132066
/** Same as the unicode message method, but this takes an ascii string which is assumed
20142067
* to me a string manager label */
@@ -3465,6 +3518,64 @@ void InGameUI::disregardDrawable( Drawable *draw )
34653518
void InGameUI::postDraw( void )
34663519
{
34673520

3521+
// TheSuperHackers @info render the system time and game timer first, this way other text will render over them if they overlap
3522+
if (TheGlobalData->m_showSystemTime)
3523+
{
3524+
if (!m_systemTimeString) {
3525+
m_systemTimeString = TheDisplayStringManager->newDisplayString();
3526+
}
3527+
3528+
// current system time
3529+
SYSTEMTIME systemTime;
3530+
GetLocalTime( &systemTime );
3531+
3532+
UnicodeString TimeString;
3533+
TimeString.format(L"%2.2d:%2.2d:%2.2d", systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
3534+
Int adjustedSystemTimeFontSize = TheGlobalLanguageData->adjustFontSize(m_systemTimePointSize);
3535+
GameFont* systemTimeFont = TheWindowManager->winFindFont(m_systemTimeFont, adjustedSystemTimeFontSize, m_systemTimeBold);
3536+
m_systemTimeString->setFont(systemTimeFont);
3537+
m_systemTimeString->setText(TimeString);
3538+
3539+
m_systemTimeString->draw(m_systemTimePosition.x, m_systemTimePosition.y, m_systemTimeColor, m_systemTimeDropColor);
3540+
}
3541+
3542+
if (TheGlobalData->m_showGameTime && !TheGameLogic->isInShellGame())
3543+
{
3544+
if (!m_gameTimeString) {
3545+
m_gameTimeString = TheDisplayStringManager->newDisplayString();
3546+
}
3547+
3548+
if (!m_gameTimeFrameString) {
3549+
m_gameTimeFrameString = TheDisplayStringManager->newDisplayString();
3550+
}
3551+
3552+
Int currentFrame = TheGameLogic->getFrame();
3553+
Int gameSeconds = (Int) (SECONDS_PER_LOGICFRAME_REAL * currentFrame );
3554+
Int hours = gameSeconds / 60 / 60;
3555+
Int minutes = (gameSeconds / 60) % 60;
3556+
Int seconds = gameSeconds % 60;
3557+
Int frame = currentFrame % 30;
3558+
3559+
UnicodeString gameTimeString;
3560+
gameTimeString.format(L"%2.2d:%2.2d:%2.2d", hours, minutes, seconds);
3561+
Int adjustedGameTimeFontSize = TheGlobalLanguageData->adjustFontSize(m_gameTimePointSize);
3562+
GameFont* gameTimeFont = TheWindowManager->winFindFont(m_gameTimeFont, adjustedGameTimeFontSize, m_gameTimeBold);
3563+
m_gameTimeString->setFont(gameTimeFont);
3564+
m_gameTimeString->setText(gameTimeString);
3565+
3566+
UnicodeString gameTimeFrameString;
3567+
gameTimeFrameString.format(L".%2.2d", frame);
3568+
m_gameTimeFrameString->setFont(gameTimeFont);
3569+
m_gameTimeFrameString->setText(gameTimeFrameString);
3570+
3571+
// TheSuperHackers @info this implicitly offsets the game timer from the right instead of left of the screen
3572+
int horizontalTimerOffset = TheDisplay->getWidth() - (Int)m_gameTimePosition.x - m_gameTimeString->getWidth() - m_gameTimeFrameString->getWidth();
3573+
int horizontalFrameOffset = TheDisplay->getWidth() - (Int)m_gameTimePosition.x - m_gameTimeFrameString->getWidth();
3574+
3575+
m_gameTimeString->draw(horizontalTimerOffset, m_gameTimePosition.y, m_gameTimeColor, m_gameTimeDropColor);
3576+
m_gameTimeFrameString->draw(horizontalFrameOffset, m_gameTimePosition.y, GameMakeColor(180,180,180,255), m_gameTimeDropColor);
3577+
}
3578+
34683579
// render our display strings for the messages if on
34693580
if( m_messagesOn )
34703581
{

0 commit comments

Comments
 (0)