Skip to content

Commit 4a723fd

Browse files
authored
[GEN][ZH] Implement feature to Pause and Step Frames in Replay playback (#969)
Press P to Pause and O to Step 1 Frame in Replay playback
1 parent 13a19a9 commit 4a723fd

File tree

18 files changed

+421
-68
lines changed

18 files changed

+421
-68
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,9 @@ class GameMessage : public MemoryPoolObject
267267
MSG_META_BEGIN_CAMERA_ZOOM_OUT,
268268
MSG_META_END_CAMERA_ZOOM_OUT,
269269
MSG_META_CAMERA_RESET,
270-
MSG_META_TOGGLE_FAST_FORWARD_REPLAY, ///< Toggle the fast forward feature
270+
MSG_META_TOGGLE_FAST_FORWARD_REPLAY, ///< Toggle the fast forward feature
271+
MSG_META_TOGGLE_PAUSE, ///< TheSuperHackers @feature Toggle game pause (in replay playbacks)
272+
MSG_META_STEP_FRAME, ///< TheSuperHackers @feature Step one frame (in replay playbacks)
271273

272274

273275
// META items that are really for debug/demo/development use only...

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,11 @@ class MetaMap : public SubsystemInterface
371371
void update() { }
372372

373373
static void parseMetaMap(INI* ini);
374+
375+
// TheSuperHackers @info Function to generate default key mappings
376+
// for actions that were not found in a CommandMap.ini
377+
static void generateMetaMap();
378+
374379
const MetaMapRec *getFirstMetaMapRec() const { return m_metaMaps; }
375380
};
376381

Generals/Code/GameEngine/Include/GameLogic/GameLogic.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ class GameLogic : public SubsystemInterface, public Snapshot
111111
virtual void reset( void ); ///< Reset the logic system
112112
virtual void update( void ); ///< update the world
113113

114+
void preUpdate();
115+
114116
void processCommandList( CommandList *list ); ///< process the command list
115117

116118
void prepareNewGame( Int gameMode, GameDifficulty diff, Int rankPoints ); ///< prepare for new game
@@ -198,9 +200,11 @@ class GameLogic : public SubsystemInterface, public Snapshot
198200

199201
void bindObjectAndDrawable(Object* obj, Drawable* draw);
200202

201-
void setGamePaused( Bool paused, Bool pauseMusic = TRUE );
203+
void setGamePausedInFrame( UnsignedInt frame );
204+
UnsignedInt getGamePauseFrame() const { return m_pauseFrame; }
205+
void setGamePaused( Bool paused, Bool pauseMusic = TRUE, Bool pauseInput = TRUE );
202206
Bool isGamePaused( void );
203-
Bool getInputEnabledMemory( void ) { return m_inputEnabledMemory; }
207+
Bool getInputEnabledMemory( void ) const { return m_inputEnabledMemory; }
204208

205209
void processProgress(Int playerId, Int percentage);
206210
void processProgressComplete(Int playerId);
@@ -244,6 +248,11 @@ class GameLogic : public SubsystemInterface, public Snapshot
244248

245249
private:
246250

251+
void pauseGameLogic(Bool paused);
252+
void pauseGameSound(Bool paused);
253+
void pauseGameMusic(Bool paused);
254+
void pauseGameInput(Bool paused);
255+
247256
void pushSleepyUpdate(UpdateModulePtr u);
248257
UpdateModulePtr peekSleepyUpdate() const;
249258
void popSleepyUpdate();
@@ -330,7 +339,12 @@ class GameLogic : public SubsystemInterface, public Snapshot
330339

331340
LoadScreen *getLoadScreen( Bool saveGame );
332341
LoadScreen *m_loadScreen;
342+
343+
UnsignedInt m_pauseFrame;
333344
Bool m_gamePaused;
345+
Bool m_pauseSound;
346+
Bool m_pauseMusic;
347+
Bool m_pauseInput;
334348
Bool m_inputEnabledMemory;// Latches used to remember what to restore to after we unpause
335349
Bool m_mouseVisibleMemory;
336350

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ void GameEngine::init( int argc, char *argv[] )
382382
fname.format("Data\\%s\\CommandMap.ini", GetRegistryLanguage().str());
383383
initSubsystem(TheMetaMap,"TheMetaMap", MSGNEW("GameEngineSubsystem") MetaMap(), NULL, fname.str(), "Data\\INI\\CommandMap.ini");
384384

385+
TheMetaMap->generateMetaMap();
386+
385387
#if defined(RTS_DEBUG) || defined(RTS_INTERNAL)
386388
ini.load("Data\\INI\\CommandMapDebug.ini", INI_LOAD_MULTIFILE, NULL);
387389
#endif
@@ -575,6 +577,7 @@ void GameEngine::update( void )
575577
TheCDManager->UPDATE();
576578
}
577579

580+
TheGameLogic->preUpdate();
578581

579582
if ((TheNetwork == NULL && !TheGameLogic->isGamePaused()) || (TheNetwork && TheNetwork->isFrameDataReady()))
580583
{

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,9 @@ AsciiString GameMessage::getCommandTypeAsAsciiString(GameMessage::Type t)
377377

378378

379379
CHECK_IF(MSG_META_TOGGLE_FAST_FORWARD_REPLAY)
380-
381-
380+
CHECK_IF(MSG_META_TOGGLE_PAUSE)
381+
CHECK_IF(MSG_META_STEP_FRAME)
382+
382383
#if defined(RTS_DEBUG) || defined(RTS_INTERNAL)
383384
CHECK_IF(MSG_META_DEMO_TOGGLE_BEHIND_BUILDINGS)
384385
CHECK_IF(MSG_META_DEMO_TOGGLE_LETTERBOX)

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,10 @@ void RecorderClass::handleCRCMessage(UnsignedInt newCRC, Int playerIndex, Bool f
10431043
playbackCRC, newCRC, TheGameLogic->getFrame()-m_crcInfo->GetQueueSize()-1));
10441044

10451045
// TheSuperHackers @tweak Pause the game on mismatch.
1046-
TheGameLogic->setGamePaused(true);
1046+
Bool pause = TRUE;
1047+
Bool pauseMusic = FALSE;
1048+
Bool pauseInput = FALSE;
1049+
TheGameLogic->setGamePaused(pause, pauseMusic, pauseInput);
10471050
}
10481051
return;
10491052
}

Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3095,9 +3095,9 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage
30953095
{
30963096
if( TheGlobalData )
30973097
{
3098-
#if !defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)//may be defined in GameCommon.h
3098+
#if !defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)//may be defined in GameCommon.h
30993099
if (TheGameLogic->isInReplayGame())
3100-
#endif
3100+
#endif
31013101
{
31023102
TheWritableGlobalData->m_TiVOFastMode = 1 - TheGlobalData->m_TiVOFastMode;
31033103
TheInGameUI->message( UnicodeString( L"m_TiVOFastMode: %s" ),
@@ -3108,7 +3108,38 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage
31083108
disp = DESTROY_MESSAGE;
31093109
break;
31103110

3111-
} // end toggle special power delays
3111+
}
3112+
case GameMessage::MSG_META_TOGGLE_PAUSE:
3113+
{
3114+
#if !defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)//may be defined in GameCommon.h
3115+
if (TheGameLogic->isInReplayGame())
3116+
#endif
3117+
{
3118+
if (TheGameLogic->isGamePaused())
3119+
{
3120+
TheGameLogic->setGamePaused(FALSE);
3121+
}
3122+
else
3123+
{
3124+
Bool pause = TRUE;
3125+
Bool pauseMusic = FALSE;
3126+
Bool pauseInput = FALSE;
3127+
TheGameLogic->setGamePaused(pause, pauseMusic, pauseInput);
3128+
}
3129+
}
3130+
break;
3131+
}
3132+
case GameMessage::MSG_META_STEP_FRAME:
3133+
{
3134+
#if !defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)//may be defined in GameCommon.h
3135+
if (TheGameLogic->isInReplayGame())
3136+
#endif
3137+
{
3138+
TheGameLogic->setGamePaused(FALSE);
3139+
TheGameLogic->setGamePausedInFrame(TheGameLogic->getFrame() + 1);
3140+
}
3141+
break;
3142+
}
31123143
//-----------------------------------------------------------------------------------------
31133144
case GameMessage::MSG_META_BEGIN_FORCEMOVE:
31143145
DEBUG_ASSERTCRASH(!TheInGameUI->isInForceMoveToMode(), ("forceMoveToMode mismatch"));

Generals/Code/GameEngine/Source/GameClient/MessageStream/MetaEvent.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,9 @@ static const LookupListRec GameMessageMetaTypeNames[] =
172172
{ "BEGIN_CAMERA_ZOOM_OUT", GameMessage::MSG_META_BEGIN_CAMERA_ZOOM_OUT },
173173
{ "END_CAMERA_ZOOM_OUT", GameMessage::MSG_META_END_CAMERA_ZOOM_OUT },
174174
{ "CAMERA_RESET", GameMessage::MSG_META_CAMERA_RESET },
175-
{ "TOGGLE_FAST_FORWARD_REPLAY", GameMessage::MSG_META_TOGGLE_FAST_FORWARD_REPLAY },
175+
{ "TOGGLE_FAST_FORWARD_REPLAY", GameMessage::MSG_META_TOGGLE_FAST_FORWARD_REPLAY },
176+
{ "TOGGLE_PAUSE", GameMessage::MSG_META_TOGGLE_PAUSE },
177+
{ "STEP_FRAME", GameMessage::MSG_META_STEP_FRAME },
176178

177179
#if defined(RTS_DEBUG) || defined(RTS_INTERNAL)
178180
{ "HELP", GameMessage::MSG_META_HELP },
@@ -656,6 +658,31 @@ MetaMapRec *MetaMap::getMetaMapRec(GameMessage::Type t)
656658
ini->initFromINI(map, TheMetaMapFieldParseTable);
657659
}
658660

661+
//-------------------------------------------------------------------------------------------------
662+
/*static */ void MetaMap::generateMetaMap()
663+
{
664+
{
665+
MetaMapRec *map = TheMetaMap->getMetaMapRec(GameMessage::MSG_META_TOGGLE_PAUSE);
666+
if (map->m_key == MK_NONE)
667+
{
668+
map->m_key = MK_P;
669+
map->m_transition = DOWN;
670+
map->m_modState = NONE;
671+
map->m_usableIn = COMMANDUSABLE_GAME;
672+
}
673+
}
674+
{
675+
MetaMapRec *map = TheMetaMap->getMetaMapRec(GameMessage::MSG_META_STEP_FRAME);
676+
if (map->m_key == MK_NONE)
677+
{
678+
map->m_key = MK_O;
679+
map->m_transition = DOWN;
680+
map->m_modState = NONE;
681+
map->m_usableIn = COMMANDUSABLE_GAME;
682+
}
683+
}
684+
}
685+
659686
//-------------------------------------------------------------------------------------------------
660687
/*static*/ void INI::parseMetaMapDefinition( INI* ini )
661688
{

0 commit comments

Comments
 (0)