From 44eac81079b734dfc633c6d91f3e57ab72e3b85c Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Fri, 17 Oct 2025 02:02:31 +1100 Subject: [PATCH 01/10] feat: Add replay archive feature --- .../GameEngine/Include/Common/GlobalData.h | 1 + .../Code/GameEngine/Include/Common/Recorder.h | 2 + .../Include/Common/UserPreferences.h | 1 + .../GameEngine/Source/Common/GlobalData.cpp | 2 + .../GameEngine/Source/Common/Recorder.cpp | 42 +++++++++++++++++++ .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 12 ++++++ .../GameEngine/Include/Common/GlobalData.h | 1 + .../Code/GameEngine/Include/Common/Recorder.h | 2 + .../Include/Common/UserPreferences.h | 1 + .../GameEngine/Source/Common/GlobalData.cpp | 2 + .../GameEngine/Source/Common/Recorder.cpp | 42 +++++++++++++++++++ .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 12 ++++++ 12 files changed, 120 insertions(+) diff --git a/Generals/Code/GameEngine/Include/Common/GlobalData.h b/Generals/Code/GameEngine/Include/Common/GlobalData.h index 30d3cf663b..be08d28531 100644 --- a/Generals/Code/GameEngine/Include/Common/GlobalData.h +++ b/Generals/Code/GameEngine/Include/Common/GlobalData.h @@ -392,6 +392,7 @@ class GlobalData : public SubsystemInterface smaller area within the rectangle to order the gather. */ Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu + Bool m_archiveReplays; ///< if true, each replay is archived to the replay archive folder after recording Bool m_languageFilterPref; ///< Bool if user wants to filter language Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie Bool m_disableRender; ///< if true, no rendering! diff --git a/Generals/Code/GameEngine/Include/Common/Recorder.h b/Generals/Code/GameEngine/Include/Common/Recorder.h index bbaa17a3f2..9e61ab7234 100644 --- a/Generals/Code/GameEngine/Include/Common/Recorder.h +++ b/Generals/Code/GameEngine/Include/Common/Recorder.h @@ -119,6 +119,7 @@ class RecorderClass : public SubsystemInterface { void initControls(); ///< Show or Hide the Replay controls AsciiString getReplayDir(); ///< Returns the directory that holds the replay files. + AsciiString getReplayArchiveDir(); ///< Returns the directory that holds the archived replay files. static AsciiString getReplayExtention(); ///< Returns the file extention for replay files. AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay. @@ -137,6 +138,7 @@ class RecorderClass : public SubsystemInterface { protected: void startRecording(GameDifficulty diff, Int originalGameMode, Int rankPoints, Int maxFPS); ///< Start recording to m_file. void writeToFile(GameMessage *msg); ///< Write this GameMessage to m_file. + void archiveReplay(AsciiString fileName); ///< Move the specified replay file to the archive directory. void logGameStart(AsciiString options); void logGameEnd( void ); diff --git a/Generals/Code/GameEngine/Include/Common/UserPreferences.h b/Generals/Code/GameEngine/Include/Common/UserPreferences.h index abe79797fb..1d141b0f17 100644 --- a/Generals/Code/GameEngine/Include/Common/UserPreferences.h +++ b/Generals/Code/GameEngine/Include/Common/UserPreferences.h @@ -91,6 +91,7 @@ class OptionPreferences : public UserPreferences void setOnlineIPAddress(AsciiString IP); // convenience function void setLANIPAddress(UnsignedInt IP); // convenience function void setOnlineIPAddress(UnsignedInt IP); // convenience function + Bool getArchiveReplaysEnabled(); // convenience function Bool getAlternateMouseModeEnabled(void); // convenience function Real getScrollFactor(void); // convenience function Bool getDrawScrollAnchor(void); diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index 8ad763222e..61e9e51f2d 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -920,6 +920,7 @@ GlobalData::GlobalData() m_standardPublicBones.clear(); m_antiAliasBoxValue = 0; + m_archiveReplays = false; // m_languageFilterPref = false; m_languageFilterPref = true; @@ -1174,6 +1175,7 @@ void GlobalData::parseGameDataDefinition( INI* ini ) // override INI values with user preferences OptionPreferences optionPref; + TheWritableGlobalData->m_archiveReplays = optionPref.getArchiveReplaysEnabled(); TheWritableGlobalData->m_useAlternateMouse = optionPref.getAlternateMouseModeEnabled(); TheWritableGlobalData->m_keyboardScrollFactor = optionPref.getScrollFactor(); TheWritableGlobalData->m_drawScrollAnchor = optionPref.getDrawScrollAnchor(); diff --git a/Generals/Code/GameEngine/Source/Common/Recorder.cpp b/Generals/Code/GameEngine/Source/Common/Recorder.cpp index b7a6df6e41..70d4f8477e 100644 --- a/Generals/Code/GameEngine/Source/Common/Recorder.cpp +++ b/Generals/Code/GameEngine/Source/Common/Recorder.cpp @@ -726,10 +726,40 @@ void RecorderClass::stopRecording() { if (m_file != NULL) { m_file->close(); m_file = NULL; + + if (TheGlobalData->m_archiveReplays) + archiveReplay(m_fileName); } m_fileName.clear(); } +/** + * Copy the replay file to the archive directory and rename it using the current timestamp. + */ +void RecorderClass::archiveReplay(AsciiString fileName) +{ + SYSTEMTIME st; + GetLocalTime(&st); + + AsciiString archiveFileName; + // Use a standard YYYYMMDD_HHMMSS format for simplicity and to avoid conflicts. + archiveFileName.format("%04d%02d%02d_%02d%02d%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + + AsciiString sourcePath = getReplayDir(); + sourcePath.concat(fileName); + + if (!sourcePath.endsWith(getReplayExtention())) + sourcePath.concat(getReplayExtention()); + + AsciiString destPath = getReplayArchiveDir(); + destPath.concat(archiveFileName); + destPath.concat(getReplayExtention()); + + TheFileSystem->createDirectory(getReplayArchiveDir().str()); + if (!CopyFile(sourcePath.str(), destPath.str(), FALSE)) + DEBUG_LOG(("RecorderClass::archiveReplay: Failed to copy %s to %s", sourcePath.str(), destPath.str())); +} + /** * Write this game message to the record file. This also writes the game message's execution frame. */ @@ -1602,6 +1632,18 @@ AsciiString RecorderClass::getReplayDir() return tmp; } +/** + * returns the directory that holds the archived replay files. + */ +AsciiString RecorderClass::getReplayArchiveDir() +{ + const char* replayDir = "ArchivedReplays\\"; + + AsciiString tmp = TheGlobalData->getPath_UserData(); + tmp.concat(replayDir); + return tmp; +} + /** * returns the file extention for the replay files. */ 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 d884d867e0..9f1d3aadff 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -310,6 +310,18 @@ void OptionPreferences::setOnlineIPAddress( UnsignedInt IP ) (*this)["GameSpyIPAddress"] = tmp; } +Bool OptionPreferences::getArchiveReplaysEnabled() +{ + OptionPreferences::const_iterator it = find("ArchiveReplays"); + if (it == end()) + return TheGlobalData->m_archiveReplays; + + if (stricmp(it->second.str(), "yes") == 0) { + return TRUE; + } + return FALSE; +} + Bool OptionPreferences::getAlternateMouseModeEnabled(void) { OptionPreferences::const_iterator it = find("UseAlternateMouse"); diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index 60573a5ab9..440327d207 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -400,6 +400,7 @@ class GlobalData : public SubsystemInterface smaller area within the rectangle to order the gather. */ Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu + Bool m_archiveReplays; ///< if true, each replay is archived to the replay archive folder after recording Bool m_languageFilterPref; ///< Bool if user wants to filter language Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie Bool m_disableRender; ///< if true, no rendering! diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h index 461b38cd87..78eda87d84 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h @@ -119,6 +119,7 @@ class RecorderClass : public SubsystemInterface { void initControls(); ///< Show or Hide the Replay controls AsciiString getReplayDir(); ///< Returns the directory that holds the replay files. + AsciiString getReplayArchiveDir(); ///< Returns the directory that holds the archived replay files. static AsciiString getReplayExtention(); ///< Returns the file extention for replay files. AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay. @@ -137,6 +138,7 @@ class RecorderClass : public SubsystemInterface { protected: void startRecording(GameDifficulty diff, Int originalGameMode, Int rankPoints, Int maxFPS); ///< Start recording to m_file. void writeToFile(GameMessage *msg); ///< Write this GameMessage to m_file. + void archiveReplay(AsciiString fileName); ///< Move the specified replay file to the archive directory. void logGameStart(AsciiString options); void logGameEnd( void ); diff --git a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h index b62a0afbe2..6ccbf8f35a 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h @@ -92,6 +92,7 @@ class OptionPreferences : public UserPreferences void setOnlineIPAddress(AsciiString IP); // convenience function void setLANIPAddress(UnsignedInt IP); // convenience function void setOnlineIPAddress(UnsignedInt IP); // convenience function + Bool getArchiveReplaysEnabled(); // convenience function Bool getAlternateMouseModeEnabled(void); // convenience function Bool getRetaliationModeEnabled(); // convenience function Bool getDoubleClickAttackMoveEnabled(void); // convenience function diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index 264a0ddab8..3431ceec38 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -929,6 +929,7 @@ GlobalData::GlobalData() m_standardPublicBones.clear(); m_antiAliasBoxValue = 0; + m_archiveReplays = false; // m_languageFilterPref = false; m_languageFilterPref = true; @@ -1200,6 +1201,7 @@ void GlobalData::parseGameDataDefinition( INI* ini ) // override INI values with user preferences OptionPreferences optionPref; + TheWritableGlobalData->m_archiveReplays = optionPref.getArchiveReplaysEnabled(); TheWritableGlobalData->m_useAlternateMouse = optionPref.getAlternateMouseModeEnabled(); TheWritableGlobalData->m_clientRetaliationModeEnabled = optionPref.getRetaliationModeEnabled(); TheWritableGlobalData->m_doubleClickAttackMove = optionPref.getDoubleClickAttackMoveEnabled(); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp index b59813da06..c5d21ec51e 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp @@ -728,10 +728,40 @@ void RecorderClass::stopRecording() { if (m_file != NULL) { m_file->close(); m_file = NULL; + + if (TheGlobalData->m_archiveReplays) + archiveReplay(m_fileName); } m_fileName.clear(); } +/** + * Copy the replay file to the archive directory and rename it using the current timestamp. + */ +void RecorderClass::archiveReplay(AsciiString fileName) +{ + SYSTEMTIME st; + GetLocalTime(&st); + + AsciiString archiveFileName; + // Use a standard YYYYMMDD_HHMMSS format for simplicity and to avoid conflicts. + archiveFileName.format("%04d%02d%02d_%02d%02d%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + + AsciiString sourcePath = getReplayDir(); + sourcePath.concat(fileName); + + if (!sourcePath.endsWith(getReplayExtention())) + sourcePath.concat(getReplayExtention()); + + AsciiString destPath = getReplayArchiveDir(); + destPath.concat(archiveFileName); + destPath.concat(getReplayExtention()); + + TheFileSystem->createDirectory(getReplayArchiveDir().str()); + if (!CopyFile(sourcePath.str(), destPath.str(), FALSE)) + DEBUG_LOG(("RecorderClass::archiveReplay: Failed to copy %s to %s", sourcePath.str(), destPath.str())); +} + /** * Write this game message to the record file. This also writes the game message's execution frame. */ @@ -1605,6 +1635,18 @@ AsciiString RecorderClass::getReplayDir() return tmp; } +/** + * returns the directory that holds the archived replay files. + */ +AsciiString RecorderClass::getReplayArchiveDir() +{ + const char* replayDir = "ArchivedReplays\\"; + + AsciiString tmp = TheGlobalData->getPath_UserData(); + tmp.concat(replayDir); + return tmp; +} + /** * returns the file extention for the replay files. */ 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 1e0498ea1c..f88e3abab1 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -319,6 +319,18 @@ void OptionPreferences::setOnlineIPAddress( UnsignedInt IP ) (*this)["GameSpyIPAddress"] = tmp; } +Bool OptionPreferences::getArchiveReplaysEnabled() +{ + OptionPreferences::const_iterator it = find("ArchiveReplays"); + if (it == end()) + return TheGlobalData->m_archiveReplays; + + if (stricmp(it->second.str(), "yes") == 0) { + return TRUE; + } + return FALSE; +} + Bool OptionPreferences::getAlternateMouseModeEnabled(void) { OptionPreferences::const_iterator it = find("UseAlternateMouse"); From 553c58687b1c3984cc23fe24efc8b6b36f6b501c Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 20 Oct 2025 18:20:39 +1100 Subject: [PATCH 02/10] refactor: Simplify replay directory concatenation --- Generals/Code/GameEngine/Source/Common/Recorder.cpp | 8 ++------ GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/Generals/Code/GameEngine/Source/Common/Recorder.cpp b/Generals/Code/GameEngine/Source/Common/Recorder.cpp index 70d4f8477e..c8c5e81c23 100644 --- a/Generals/Code/GameEngine/Source/Common/Recorder.cpp +++ b/Generals/Code/GameEngine/Source/Common/Recorder.cpp @@ -1625,10 +1625,8 @@ RecorderClass::CullBadCommandsResult RecorderClass::cullBadCommands() { */ AsciiString RecorderClass::getReplayDir() { - const char* replayDir = "Replays\\"; - AsciiString tmp = TheGlobalData->getPath_UserData(); - tmp.concat(replayDir); + tmp.concat("Replays\\"); return tmp; } @@ -1637,10 +1635,8 @@ AsciiString RecorderClass::getReplayDir() */ AsciiString RecorderClass::getReplayArchiveDir() { - const char* replayDir = "ArchivedReplays\\"; - AsciiString tmp = TheGlobalData->getPath_UserData(); - tmp.concat(replayDir); + tmp.concat("ArchivedReplays\\"); return tmp; } diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp index c5d21ec51e..5356481074 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp @@ -1628,10 +1628,8 @@ RecorderClass::CullBadCommandsResult RecorderClass::cullBadCommands() { */ AsciiString RecorderClass::getReplayDir() { - const char* replayDir = "Replays\\"; - AsciiString tmp = TheGlobalData->getPath_UserData(); - tmp.concat(replayDir); + tmp.concat("Replays\\"); return tmp; } @@ -1640,10 +1638,8 @@ AsciiString RecorderClass::getReplayDir() */ AsciiString RecorderClass::getReplayArchiveDir() { - const char* replayDir = "ArchivedReplays\\"; - AsciiString tmp = TheGlobalData->getPath_UserData(); - tmp.concat(replayDir); + tmp.concat("ArchivedReplays\\"); return tmp; } From c374b523648ca25715a0af0f36e9191129dac20b Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 20 Oct 2025 18:23:01 +1100 Subject: [PATCH 03/10] refactor: Simplify replay archive directory creation --- Generals/Code/GameEngine/Source/Common/Recorder.cpp | 3 ++- GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Generals/Code/GameEngine/Source/Common/Recorder.cpp b/Generals/Code/GameEngine/Source/Common/Recorder.cpp index c8c5e81c23..16aa731cd1 100644 --- a/Generals/Code/GameEngine/Source/Common/Recorder.cpp +++ b/Generals/Code/GameEngine/Source/Common/Recorder.cpp @@ -752,10 +752,11 @@ void RecorderClass::archiveReplay(AsciiString fileName) sourcePath.concat(getReplayExtention()); AsciiString destPath = getReplayArchiveDir(); + TheFileSystem->createDirectory(destPath.str()); + destPath.concat(archiveFileName); destPath.concat(getReplayExtention()); - TheFileSystem->createDirectory(getReplayArchiveDir().str()); if (!CopyFile(sourcePath.str(), destPath.str(), FALSE)) DEBUG_LOG(("RecorderClass::archiveReplay: Failed to copy %s to %s", sourcePath.str(), destPath.str())); } diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp index 5356481074..e764841282 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp @@ -754,10 +754,11 @@ void RecorderClass::archiveReplay(AsciiString fileName) sourcePath.concat(getReplayExtention()); AsciiString destPath = getReplayArchiveDir(); + TheFileSystem->createDirectory(destPath.str()); + destPath.concat(archiveFileName); destPath.concat(getReplayExtention()); - TheFileSystem->createDirectory(getReplayArchiveDir().str()); if (!CopyFile(sourcePath.str(), destPath.str(), FALSE)) DEBUG_LOG(("RecorderClass::archiveReplay: Failed to copy %s to %s", sourcePath.str(), destPath.str())); } From 1a0c7988835564911630e65768cbeb4166264670 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 20 Oct 2025 18:26:37 +1100 Subject: [PATCH 04/10] refactor: Make directory and extension functions static --- Generals/Code/GameEngine/Include/Common/Recorder.h | 8 ++++---- GeneralsMD/Code/GameEngine/Include/Common/Recorder.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Generals/Code/GameEngine/Include/Common/Recorder.h b/Generals/Code/GameEngine/Include/Common/Recorder.h index 9e61ab7234..fbac0ae40b 100644 --- a/Generals/Code/GameEngine/Include/Common/Recorder.h +++ b/Generals/Code/GameEngine/Include/Common/Recorder.h @@ -118,10 +118,10 @@ class RecorderClass : public SubsystemInterface { Bool isPlaybackMode() const { return m_mode == RECORDERMODETYPE_PLAYBACK || m_mode == RECORDERMODETYPE_SIMULATION_PLAYBACK; } void initControls(); ///< Show or Hide the Replay controls - AsciiString getReplayDir(); ///< Returns the directory that holds the replay files. - AsciiString getReplayArchiveDir(); ///< Returns the directory that holds the archived replay files. - static AsciiString getReplayExtention(); ///< Returns the file extention for replay files. - AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay. + static AsciiString getReplayDir(); ///< Returns the directory that holds the replay files. + static AsciiString getReplayArchiveDir(); ///< Returns the directory that holds the archived replay files. + static AsciiString getReplayExtention(); ///< Returns the file extention for replay files. + static AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay. GameInfo *getGameInfo( void ) { return &m_gameInfo; } ///< Returns the slot list for playback game start diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h index 78eda87d84..f00efa23f9 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h @@ -118,10 +118,10 @@ class RecorderClass : public SubsystemInterface { Bool isPlaybackMode() const { return m_mode == RECORDERMODETYPE_PLAYBACK || m_mode == RECORDERMODETYPE_SIMULATION_PLAYBACK; } void initControls(); ///< Show or Hide the Replay controls - AsciiString getReplayDir(); ///< Returns the directory that holds the replay files. - AsciiString getReplayArchiveDir(); ///< Returns the directory that holds the archived replay files. - static AsciiString getReplayExtention(); ///< Returns the file extention for replay files. - AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay. + static AsciiString getReplayDir(); ///< Returns the directory that holds the replay files. + static AsciiString getReplayArchiveDir(); ///< Returns the directory that holds the archived replay files. + static AsciiString getReplayExtention(); ///< Returns the file extention for replay files. + static AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay. GameInfo *getGameInfo( void ) { return &m_gameInfo; } ///< Returns the slot list for playback game start From 6c1adcdca88ee5234d53dfceb240437f7d5b6a0f Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 20 Oct 2025 18:29:26 +1100 Subject: [PATCH 05/10] refactor: Make archive option constant --- Generals/Code/GameEngine/Include/Common/UserPreferences.h | 2 +- .../Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | 2 +- GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h | 2 +- .../Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Include/Common/UserPreferences.h b/Generals/Code/GameEngine/Include/Common/UserPreferences.h index 1d141b0f17..b26417956d 100644 --- a/Generals/Code/GameEngine/Include/Common/UserPreferences.h +++ b/Generals/Code/GameEngine/Include/Common/UserPreferences.h @@ -91,7 +91,7 @@ class OptionPreferences : public UserPreferences void setOnlineIPAddress(AsciiString IP); // convenience function void setLANIPAddress(UnsignedInt IP); // convenience function void setOnlineIPAddress(UnsignedInt IP); // convenience function - Bool getArchiveReplaysEnabled(); // convenience function + const Bool getArchiveReplaysEnabled(); // convenience function Bool getAlternateMouseModeEnabled(void); // convenience function Real getScrollFactor(void); // convenience function Bool getDrawScrollAnchor(void); 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 9f1d3aadff..c9db0ec3ba 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -310,7 +310,7 @@ void OptionPreferences::setOnlineIPAddress( UnsignedInt IP ) (*this)["GameSpyIPAddress"] = tmp; } -Bool OptionPreferences::getArchiveReplaysEnabled() +const Bool OptionPreferences::getArchiveReplaysEnabled() { OptionPreferences::const_iterator it = find("ArchiveReplays"); if (it == end()) diff --git a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h index 6ccbf8f35a..caa575a040 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h @@ -92,7 +92,7 @@ class OptionPreferences : public UserPreferences void setOnlineIPAddress(AsciiString IP); // convenience function void setLANIPAddress(UnsignedInt IP); // convenience function void setOnlineIPAddress(UnsignedInt IP); // convenience function - Bool getArchiveReplaysEnabled(); // convenience function + const Bool getArchiveReplaysEnabled(); // convenience function Bool getAlternateMouseModeEnabled(void); // convenience function Bool getRetaliationModeEnabled(); // convenience function Bool getDoubleClickAttackMoveEnabled(void); // convenience function 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 f88e3abab1..26a72105eb 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -319,7 +319,7 @@ void OptionPreferences::setOnlineIPAddress( UnsignedInt IP ) (*this)["GameSpyIPAddress"] = tmp; } -Bool OptionPreferences::getArchiveReplaysEnabled() +const Bool OptionPreferences::getArchiveReplaysEnabled() { OptionPreferences::const_iterator it = find("ArchiveReplays"); if (it == end()) From e76633723ce80921e41f82747c6cbad90edd1fe7 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 20 Oct 2025 18:29:40 +1100 Subject: [PATCH 06/10] refactor: Reduce extension allocations --- Generals/Code/GameEngine/Source/Common/Recorder.cpp | 7 ++++--- GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Generals/Code/GameEngine/Source/Common/Recorder.cpp b/Generals/Code/GameEngine/Source/Common/Recorder.cpp index 16aa731cd1..e599afa531 100644 --- a/Generals/Code/GameEngine/Source/Common/Recorder.cpp +++ b/Generals/Code/GameEngine/Source/Common/Recorder.cpp @@ -745,17 +745,18 @@ void RecorderClass::archiveReplay(AsciiString fileName) // Use a standard YYYYMMDD_HHMMSS format for simplicity and to avoid conflicts. archiveFileName.format("%04d%02d%02d_%02d%02d%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + AsciiString extension = getReplayExtention(); AsciiString sourcePath = getReplayDir(); sourcePath.concat(fileName); - if (!sourcePath.endsWith(getReplayExtention())) - sourcePath.concat(getReplayExtention()); + if (!sourcePath.endsWith(extension)) + sourcePath.concat(extension); AsciiString destPath = getReplayArchiveDir(); TheFileSystem->createDirectory(destPath.str()); destPath.concat(archiveFileName); - destPath.concat(getReplayExtention()); + destPath.concat(extension); if (!CopyFile(sourcePath.str(), destPath.str(), FALSE)) DEBUG_LOG(("RecorderClass::archiveReplay: Failed to copy %s to %s", sourcePath.str(), destPath.str())); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp index e764841282..ad097d090c 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp @@ -747,17 +747,18 @@ void RecorderClass::archiveReplay(AsciiString fileName) // Use a standard YYYYMMDD_HHMMSS format for simplicity and to avoid conflicts. archiveFileName.format("%04d%02d%02d_%02d%02d%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + AsciiString extension = getReplayExtention(); AsciiString sourcePath = getReplayDir(); sourcePath.concat(fileName); - if (!sourcePath.endsWith(getReplayExtention())) - sourcePath.concat(getReplayExtention()); + if (!sourcePath.endsWith(extension)) + sourcePath.concat(extension); AsciiString destPath = getReplayArchiveDir(); TheFileSystem->createDirectory(destPath.str()); destPath.concat(archiveFileName); - destPath.concat(getReplayExtention()); + destPath.concat(extension); if (!CopyFile(sourcePath.str(), destPath.str(), FALSE)) DEBUG_LOG(("RecorderClass::archiveReplay: Failed to copy %s to %s", sourcePath.str(), destPath.str())); From edf1f218ed442db7c235eac6ce6d0289a2084fd6 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Thu, 23 Oct 2025 12:20:57 +1100 Subject: [PATCH 07/10] refactor: Proper const format --- Generals/Code/GameEngine/Include/Common/UserPreferences.h | 2 +- .../Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | 2 +- GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h | 2 +- .../Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Include/Common/UserPreferences.h b/Generals/Code/GameEngine/Include/Common/UserPreferences.h index b26417956d..279a15f91b 100644 --- a/Generals/Code/GameEngine/Include/Common/UserPreferences.h +++ b/Generals/Code/GameEngine/Include/Common/UserPreferences.h @@ -91,7 +91,7 @@ class OptionPreferences : public UserPreferences void setOnlineIPAddress(AsciiString IP); // convenience function void setLANIPAddress(UnsignedInt IP); // convenience function void setOnlineIPAddress(UnsignedInt IP); // convenience function - const Bool getArchiveReplaysEnabled(); // convenience function + Bool getArchiveReplaysEnabled() const; // convenience function Bool getAlternateMouseModeEnabled(void); // convenience function Real getScrollFactor(void); // convenience function Bool getDrawScrollAnchor(void); 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 c9db0ec3ba..2d67bf3584 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -310,7 +310,7 @@ void OptionPreferences::setOnlineIPAddress( UnsignedInt IP ) (*this)["GameSpyIPAddress"] = tmp; } -const Bool OptionPreferences::getArchiveReplaysEnabled() +Bool OptionPreferences::getArchiveReplaysEnabled() const { OptionPreferences::const_iterator it = find("ArchiveReplays"); if (it == end()) diff --git a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h index caa575a040..dbe3e77b2a 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h @@ -92,7 +92,7 @@ class OptionPreferences : public UserPreferences void setOnlineIPAddress(AsciiString IP); // convenience function void setLANIPAddress(UnsignedInt IP); // convenience function void setOnlineIPAddress(UnsignedInt IP); // convenience function - const Bool getArchiveReplaysEnabled(); // convenience function + Bool getArchiveReplaysEnabled() const; // convenience function Bool getAlternateMouseModeEnabled(void); // convenience function Bool getRetaliationModeEnabled(); // convenience function Bool getDoubleClickAttackMoveEnabled(void); // convenience function 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 26a72105eb..386c848d9f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -319,7 +319,7 @@ void OptionPreferences::setOnlineIPAddress( UnsignedInt IP ) (*this)["GameSpyIPAddress"] = tmp; } -const Bool OptionPreferences::getArchiveReplaysEnabled() +Bool OptionPreferences::getArchiveReplaysEnabled() const { OptionPreferences::const_iterator it = find("ArchiveReplays"); if (it == end()) From a57348d53c1b9489476fc2e8de7c3131cfce7562 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Thu, 23 Oct 2025 18:16:58 +1100 Subject: [PATCH 08/10] refactor: Move archive setting to the recorder class --- Generals/Code/GameEngine/Include/Common/GlobalData.h | 1 - Generals/Code/GameEngine/Include/Common/Recorder.h | 1 + Generals/Code/GameEngine/Source/Common/GlobalData.cpp | 2 -- Generals/Code/GameEngine/Source/Common/Recorder.cpp | 7 ++++++- .../GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | 2 +- GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h | 1 - GeneralsMD/Code/GameEngine/Include/Common/Recorder.h | 1 + GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp | 2 -- GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp | 7 ++++++- .../GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | 2 +- 10 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Generals/Code/GameEngine/Include/Common/GlobalData.h b/Generals/Code/GameEngine/Include/Common/GlobalData.h index be08d28531..30d3cf663b 100644 --- a/Generals/Code/GameEngine/Include/Common/GlobalData.h +++ b/Generals/Code/GameEngine/Include/Common/GlobalData.h @@ -392,7 +392,6 @@ class GlobalData : public SubsystemInterface smaller area within the rectangle to order the gather. */ Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu - Bool m_archiveReplays; ///< if true, each replay is archived to the replay archive folder after recording Bool m_languageFilterPref; ///< Bool if user wants to filter language Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie Bool m_disableRender; ///< if true, no rendering! diff --git a/Generals/Code/GameEngine/Include/Common/Recorder.h b/Generals/Code/GameEngine/Include/Common/Recorder.h index fbac0ae40b..5c5576fde8 100644 --- a/Generals/Code/GameEngine/Include/Common/Recorder.h +++ b/Generals/Code/GameEngine/Include/Common/Recorder.h @@ -169,6 +169,7 @@ class RecorderClass : public SubsystemInterface { Bool m_wasDesync; Bool m_doingAnalysis; + Bool m_archiveReplays; ///< if true, each replay is archived to the replay archive folder after recording Int m_originalGameMode; // valid in replays diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index 61e9e51f2d..8ad763222e 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -920,7 +920,6 @@ GlobalData::GlobalData() m_standardPublicBones.clear(); m_antiAliasBoxValue = 0; - m_archiveReplays = false; // m_languageFilterPref = false; m_languageFilterPref = true; @@ -1175,7 +1174,6 @@ void GlobalData::parseGameDataDefinition( INI* ini ) // override INI values with user preferences OptionPreferences optionPref; - TheWritableGlobalData->m_archiveReplays = optionPref.getArchiveReplaysEnabled(); TheWritableGlobalData->m_useAlternateMouse = optionPref.getAlternateMouseModeEnabled(); TheWritableGlobalData->m_keyboardScrollFactor = optionPref.getScrollFactor(); TheWritableGlobalData->m_drawScrollAnchor = optionPref.getDrawScrollAnchor(); diff --git a/Generals/Code/GameEngine/Source/Common/Recorder.cpp b/Generals/Code/GameEngine/Source/Common/Recorder.cpp index e599afa531..254accee05 100644 --- a/Generals/Code/GameEngine/Source/Common/Recorder.cpp +++ b/Generals/Code/GameEngine/Source/Common/Recorder.cpp @@ -45,6 +45,7 @@ #include "GameLogic/GameLogic.h" #include "Common/RandomValue.h" #include "Common/CRCDebug.h" +#include "Common/UserPreferences.h" #include "Common/version.h" constexpr const char s_genrep[] = "GENREP"; @@ -370,6 +371,7 @@ RecorderClass::RecorderClass() //Added By Sadullah Nader //Initializtion(s) inserted m_doingAnalysis = FALSE; + m_archiveReplays = FALSE; m_nextFrame = 0; m_wasDesync = FALSE; // @@ -406,6 +408,9 @@ void RecorderClass::init() { m_wasDesync = FALSE; m_doingAnalysis = FALSE; m_playbackFrameCount = 0; + + OptionPreferences optionPref; + m_archiveReplays = optionPref.getArchiveReplaysEnabled(); } /** @@ -727,7 +732,7 @@ void RecorderClass::stopRecording() { m_file->close(); m_file = NULL; - if (TheGlobalData->m_archiveReplays) + if (m_archiveReplays) archiveReplay(m_fileName); } m_fileName.clear(); 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 2d67bf3584..907685c974 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -314,7 +314,7 @@ Bool OptionPreferences::getArchiveReplaysEnabled() const { OptionPreferences::const_iterator it = find("ArchiveReplays"); if (it == end()) - return TheGlobalData->m_archiveReplays; + return FALSE; if (stricmp(it->second.str(), "yes") == 0) { return TRUE; diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index 440327d207..60573a5ab9 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -400,7 +400,6 @@ class GlobalData : public SubsystemInterface smaller area within the rectangle to order the gather. */ Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu - Bool m_archiveReplays; ///< if true, each replay is archived to the replay archive folder after recording Bool m_languageFilterPref; ///< Bool if user wants to filter language Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie Bool m_disableRender; ///< if true, no rendering! diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h index f00efa23f9..1c25ca339e 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h @@ -169,6 +169,7 @@ class RecorderClass : public SubsystemInterface { Bool m_wasDesync; Bool m_doingAnalysis; + Bool m_archiveReplays; ///< if true, each replay is archived to the replay archive folder after recording Int m_originalGameMode; // valid in replays diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index 3431ceec38..264a0ddab8 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -929,7 +929,6 @@ GlobalData::GlobalData() m_standardPublicBones.clear(); m_antiAliasBoxValue = 0; - m_archiveReplays = false; // m_languageFilterPref = false; m_languageFilterPref = true; @@ -1201,7 +1200,6 @@ void GlobalData::parseGameDataDefinition( INI* ini ) // override INI values with user preferences OptionPreferences optionPref; - TheWritableGlobalData->m_archiveReplays = optionPref.getArchiveReplaysEnabled(); TheWritableGlobalData->m_useAlternateMouse = optionPref.getAlternateMouseModeEnabled(); TheWritableGlobalData->m_clientRetaliationModeEnabled = optionPref.getRetaliationModeEnabled(); TheWritableGlobalData->m_doubleClickAttackMove = optionPref.getDoubleClickAttackMoveEnabled(); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp index ad097d090c..5137fe2fdc 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp @@ -45,6 +45,7 @@ #include "GameLogic/GameLogic.h" #include "Common/RandomValue.h" #include "Common/CRCDebug.h" +#include "Common/UserPreferences.h" #include "Common/version.h" constexpr const char s_genrep[] = "GENREP"; @@ -370,6 +371,7 @@ RecorderClass::RecorderClass() //Added By Sadullah Nader //Initializtion(s) inserted m_doingAnalysis = FALSE; + m_archiveReplays = FALSE; m_nextFrame = 0; m_wasDesync = FALSE; // @@ -406,6 +408,9 @@ void RecorderClass::init() { m_wasDesync = FALSE; m_doingAnalysis = FALSE; m_playbackFrameCount = 0; + + OptionPreferences optionPref; + m_archiveReplays = optionPref.getArchiveReplaysEnabled(); } /** @@ -729,7 +734,7 @@ void RecorderClass::stopRecording() { m_file->close(); m_file = NULL; - if (TheGlobalData->m_archiveReplays) + if (m_archiveReplays) archiveReplay(m_fileName); } m_fileName.clear(); 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 386c848d9f..3c2a963398 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -323,7 +323,7 @@ Bool OptionPreferences::getArchiveReplaysEnabled() const { OptionPreferences::const_iterator it = find("ArchiveReplays"); if (it == end()) - return TheGlobalData->m_archiveReplays; + return FALSE; if (stricmp(it->second.str(), "yes") == 0) { return TRUE; From 9fff13d1e40e2abd3dfea21e3b8bd445fc1b067b Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Fri, 24 Oct 2025 10:45:45 +1100 Subject: [PATCH 09/10] tweak: Add placeholder option setting --- Generals/Code/GameEngine/Include/Common/Recorder.h | 1 + .../GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | 8 ++++++++ GeneralsMD/Code/GameEngine/Include/Common/Recorder.h | 1 + .../GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | 8 ++++++++ 4 files changed, 18 insertions(+) diff --git a/Generals/Code/GameEngine/Include/Common/Recorder.h b/Generals/Code/GameEngine/Include/Common/Recorder.h index 5c5576fde8..6466ca26c3 100644 --- a/Generals/Code/GameEngine/Include/Common/Recorder.h +++ b/Generals/Code/GameEngine/Include/Common/Recorder.h @@ -134,6 +134,7 @@ class RecorderClass : public SubsystemInterface { Bool sawCRCMismatch() const; void cleanUpReplayFile( void ); ///< after a crash, send replay/debug info to a central repository + void setArchiveEnabled(Bool enable) { m_archiveReplays = enable; } ///< Enable or disable replay archiving. void stopRecording(); ///< Stop recording and close m_file. protected: void startRecording(GameDifficulty diff, Int originalGameMode, Int rankPoints, Int maxFPS); ///< Start recording to m_file. 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 907685c974..1e62b66325 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -38,6 +38,7 @@ #include "Common/GameEngine.h" #include "Common/UserPreferences.h" #include "Common/GameLOD.h" +#include "Common/Recorder.h" #include "Common/Registry.h" #include "Common/version.h" @@ -1308,6 +1309,13 @@ static void saveOptions( void ) TheWritableGlobalData->m_enablePlayerObserver = enabled; } + // TheSuperHackers @todo Add checkbox ? + { + Bool enabled = pref->getArchiveReplaysEnabled(); + (*pref)["ArchiveReplays"] = enabled ? "yes" : "no"; + TheRecorder->setArchiveEnabled(enabled); + } + //------------------------------------------------------------------------------------------------- // scroll speed val val = GadgetSliderGetPosition(sliderScrollSpeed); diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h index 1c25ca339e..a2a4a93b80 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/Recorder.h @@ -134,6 +134,7 @@ class RecorderClass : public SubsystemInterface { Bool sawCRCMismatch() const; void cleanUpReplayFile( void ); ///< after a crash, send replay/debug info to a central repository + void setArchiveEnabled(Bool enable) { m_archiveReplays = enable; } ///< Enable or disable replay archiving. void stopRecording(); ///< Stop recording and close m_file. protected: void startRecording(GameDifficulty diff, Int originalGameMode, Int rankPoints, Int maxFPS); ///< Start recording to m_file. 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 3c2a963398..0385a3a695 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -38,6 +38,7 @@ #include "Common/GameEngine.h" #include "Common/UserPreferences.h" #include "Common/GameLOD.h" +#include "Common/Recorder.h" #include "Common/Registry.h" #include "Common/version.h" @@ -1368,6 +1369,13 @@ static void saveOptions( void ) TheWritableGlobalData->m_enablePlayerObserver = enabled; } + // TheSuperHackers @todo Add checkbox ? + { + Bool enabled = pref->getArchiveReplaysEnabled(); + (*pref)["ArchiveReplays"] = enabled ? "yes" : "no"; + TheRecorder->setArchiveEnabled(enabled); + } + //------------------------------------------------------------------------------------------------- // scroll speed val val = GadgetSliderGetPosition(sliderScrollSpeed); From 18e94e3552659e07b1bb0cef35925e3ec5d8ea81 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Fri, 24 Oct 2025 22:41:11 +1100 Subject: [PATCH 10/10] docs: Update comments --- Generals/Code/GameEngine/Source/Common/Recorder.cpp | 2 +- GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Generals/Code/GameEngine/Source/Common/Recorder.cpp b/Generals/Code/GameEngine/Source/Common/Recorder.cpp index 254accee05..78b34abc42 100644 --- a/Generals/Code/GameEngine/Source/Common/Recorder.cpp +++ b/Generals/Code/GameEngine/Source/Common/Recorder.cpp @@ -739,7 +739,7 @@ void RecorderClass::stopRecording() { } /** - * Copy the replay file to the archive directory and rename it using the current timestamp. + * TheSuperHackers @feature Stubbjax 17/10/2025 Copy the replay file to the archive directory and rename it using the current timestamp. */ void RecorderClass::archiveReplay(AsciiString fileName) { diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp index 5137fe2fdc..00271e4472 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp @@ -741,7 +741,7 @@ void RecorderClass::stopRecording() { } /** - * Copy the replay file to the archive directory and rename it using the current timestamp. + * TheSuperHackers @feature Stubbjax 17/10/2025 Copy the replay file to the archive directory and rename it using the current timestamp. */ void RecorderClass::archiveReplay(AsciiString fileName) {