Skip to content

Commit 63f64e4

Browse files
committed
Backport graceful exit logic from GeneralsMD
1 parent 4fda496 commit 63f64e4

File tree

7 files changed

+114
-37
lines changed

7 files changed

+114
-37
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ class GameClient : public SubsystemInterface,
150150
UnsignedInt getRenderedObjectCount() const { return m_renderedObjectCount; }
151151
void incrementRenderedObjectCount() { m_renderedObjectCount++; }
152152

153+
virtual Bool isMovieAbortRequested( void );
154+
153155
protected:
154156

155157
// snapshot methods

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class GameLogic : public SubsystemInterface, public Snapshot
131131
Bool isInGameLogicUpdate( void ) const { return m_isInUpdate; }
132132
Bool hasUpdated() const { return m_hasUpdated; } ///< Returns true if the logic frame has advanced in the current client/render update
133133
UnsignedInt getFrame( void ); ///< Returns the current simulation frame number
134+
void quit(Bool toDesktop);
134135
UnsignedInt getCRC( Int mode = CRC_CACHED, AsciiString deepCRCFileName = AsciiString::TheEmptyString ); ///< Returns the CRC
135136

136137
void setObjectIDCounter( ObjectID nextObjID ) { m_nextObjID = nextObjID; }
@@ -243,6 +244,8 @@ class GameLogic : public SubsystemInterface, public Snapshot
243244
// this should be called only by UpdateModule, thanks.
244245
void friend_awakenUpdateModule(Object* obj, UpdateModulePtr update, UnsignedInt whenToWakeUp);
245246

247+
Bool m_quitToDesktopAfterMatch;
248+
246249
protected:
247250

248251
// snapshot methods

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

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -139,21 +139,7 @@ static void exitQuitMenu()
139139
{
140140
// destroy the quit menu
141141
destroyQuitMenu();
142-
143-
// clear out all the game data
144-
if ( TheGameLogic->isInMultiplayerGame() && !TheGameLogic->isInSkirmishGame() && !TheGameInfo->isSandbox() )
145-
{
146-
GameMessage *msg = TheMessageStream->appendMessage(GameMessage::MSG_SELF_DESTRUCT);
147-
msg->appendBooleanArgument(TRUE);
148-
}
149-
TheGameLogic->exitGame();
150-
// TheGameLogic->clearGameData();
151-
// display the menu on top of the shell stack
152-
// TheShell->showShell();
153-
154-
// this will trigger an exit
155-
// TheGameEngine->setQuitting( TRUE );
156-
TheInGameUI->setClientQuiet( TRUE );
142+
TheGameLogic->quit(FALSE);
157143
}
158144
static void noExitQuitMenu()
159145
{
@@ -164,18 +150,7 @@ static void quitToDesktopQuitMenu()
164150
{
165151
// destroy the quit menu
166152
destroyQuitMenu();
167-
168-
if (TheGameLogic->isInGame())
169-
{
170-
if (TheRecorder->getMode() == RECORDERMODETYPE_RECORD)
171-
{
172-
TheRecorder->stopRecording();
173-
}
174-
TheGameLogic->clearGameData();
175-
}
176-
TheGameEngine->setQuitting(TRUE);
177-
TheInGameUI->setClientQuiet( TRUE );
178-
153+
TheGameLogic->quit(TRUE);
179154
}
180155

181156
static void surrenderQuitMenu()

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,11 @@ void GameClient::update( void )
535535
Int beginTime = timeGetTime();
536536
while(beginTime + 4000 > timeGetTime() )
537537
{
538+
if (TheGameClient->isMovieAbortRequested())
539+
{
540+
break;
541+
}
542+
538543
TheWindowManager->update();
539544
// redraw all views, update the GUI
540545
TheDisplay->draw();
@@ -755,6 +760,33 @@ void GameClient::updateHeadless()
755760
TheParticleSystemManager->reset();
756761
}
757762

763+
// TheSuperHackers Check if the user has requested to abort movie
764+
Bool GameClient::isMovieAbortRequested( void )
765+
{
766+
// User can skip video by pressing ESC
767+
if (TheKeyboard)
768+
{
769+
TheKeyboard->UPDATE();
770+
KeyboardIO *io = TheKeyboard->findKey(KEY_ESC, KeyboardIO::STATUS_UNUSED);
771+
if (io && BitIsSet(io->state, KEY_STATE_DOWN))
772+
{
773+
io->setUsed();
774+
return TRUE;
775+
}
776+
}
777+
778+
// Service OS for Window Close / Alt-F4 events
779+
TheGameEngine->serviceWindowsOS();
780+
TheMessageStream->propagateMessages();
781+
782+
if (TheGameEngine->getQuitting() || (TheGameLogic && TheGameLogic->m_quitToDesktopAfterMatch))
783+
{
784+
return TRUE;
785+
}
786+
787+
return FALSE;
788+
}
789+
758790
/** -----------------------------------------------------------------------------------------------
759791
* Call the given callback function for each object contained within the given region.
760792
*/

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3706,15 +3706,8 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage
37063706
//------------------------------------------------------------------------------- DEMO MESSAGES
37073707
//-----------------------------------------------------------------------------------------
37083708
case GameMessage::MSG_META_DEMO_INSTANT_QUIT:
3709-
if (TheGameLogic->isInGame())
37103709
{
3711-
if (TheRecorder->getMode() == RECORDERMODETYPE_RECORD)
3712-
{
3713-
TheRecorder->stopRecording();
3714-
}
3715-
TheGameLogic->clearGameData();
3716-
}
3717-
TheGameEngine->setQuitting(TRUE);
3710+
TheGameLogic->quit(TRUE);
37183711
disp = DESTROY_MESSAGE;
37193712
break;
37203713

@@ -5053,6 +5046,7 @@ static Bool isSystemMessage( const GameMessage *msg )
50535046
case GameMessage::MSG_LOGIC_CRC:
50545047
case GameMessage::MSG_SET_REPLAY_CAMERA:
50555048
case GameMessage::MSG_FRAME_TICK:
5049+
case GameMessage::MSG_META_DEMO_INSTANT_QUIT:
50565050
return TRUE;
50575051
}
50585052
return FALSE;

Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ enum { OBJ_HASH_SIZE = 8192 };
130130
/// The GameLogic singleton instance
131131
GameLogic *TheGameLogic = nullptr;
132132

133+
extern GameInfo *TheGameInfo;
134+
133135
static void findAndSelectCommandCenter(Object *obj, void* alreadyFound);
134136

135137

@@ -244,6 +246,7 @@ GameLogic::GameLogic( void )
244246
m_logicTimeScaleEnabledMemory = FALSE;
245247
m_loadScreen = nullptr;
246248
m_forceGameStartByTimeOut = FALSE;
249+
m_quitToDesktopAfterMatch = FALSE;
247250
#ifdef DUMP_PERF_STATS
248251
m_overallFailedPathfinds = 0;
249252
#endif
@@ -911,6 +914,8 @@ static void populateRandomStartPosition( GameInfo *game )
911914
}
912915
}
913916

917+
struct QuitGameException {};
918+
914919
// ------------------------------------------------------------------------------------------------
915920
/** Update the load screen progress */
916921
// ------------------------------------------------------------------------------------------------
@@ -920,6 +925,10 @@ void GameLogic::updateLoadProgress( Int progress )
920925
if( m_loadScreen )
921926
m_loadScreen->update( progress );
922927

928+
if (TheGameEngine->getQuitting() || m_quitToDesktopAfterMatch)
929+
{
930+
throw QuitGameException();
931+
}
923932
}
924933

925934
// ------------------------------------------------------------------------------------------------
@@ -966,6 +975,8 @@ void GameLogic::setGameMode( GameMode mode )
966975
// ------------------------------------------------------------------------------------------------
967976
void GameLogic::startNewGame( Bool saveGame )
968977
{
978+
try
979+
{
969980

970981
#ifdef DUMP_PERF_STATS
971982
__int64 startTime64;
@@ -2067,7 +2078,11 @@ void GameLogic::startNewGame( Bool saveGame )
20672078
TheInGameUI->messageNoFormat( TheGameText->FETCH_OR_SUBSTITUTE( "GUI:FastForwardInstructions", L"Press F to toggle Fast Forward" ) );
20682079
}
20692080

2070-
2081+
}
2082+
catch (QuitGameException&)
2083+
{
2084+
// TheSuperHackers: The application is cleanly aborting the loading process.
2085+
}
20712086
}
20722087

20732088
//-----------------------------------------------------------------------------------------
@@ -3619,6 +3634,61 @@ void GameLogic::exitGame()
36193634
TheMessageStream->appendMessage(GameMessage::MSG_CLEAR_GAME_DATA);
36203635
}
36213636

3637+
// ------------------------------------------------------------------------------------------------
3638+
void GameLogic::quit(Bool toDesktop)
3639+
{
3640+
if (isInGame())
3641+
{
3642+
if (isInMultiplayerGame() && !isInSkirmishGame() && TheGameInfo && !TheGameInfo->isSandbox())
3643+
{
3644+
GameMessage *msg = TheMessageStream->appendMessage(GameMessage::MSG_SELF_DESTRUCT);
3645+
msg->appendBooleanArgument(TRUE);
3646+
}
3647+
3648+
if (TheRecorder && TheRecorder->getMode() == RECORDERMODETYPE_RECORD)
3649+
{
3650+
TheRecorder->stopRecording();
3651+
}
3652+
3653+
setGamePaused(FALSE);
3654+
if (TheScriptEngine)
3655+
{
3656+
TheScriptEngine->forceUnfreezeTime();
3657+
TheScriptEngine->doUnfreezeTime();
3658+
}
3659+
3660+
if (toDesktop)
3661+
{
3662+
if (isInMultiplayerGame())
3663+
{
3664+
m_quitToDesktopAfterMatch = TRUE;
3665+
exitGame();
3666+
}
3667+
else
3668+
{
3669+
clearGameData();
3670+
}
3671+
}
3672+
else
3673+
{
3674+
exitGame();
3675+
}
3676+
}
3677+
3678+
if (toDesktop)
3679+
{
3680+
if (!isInMultiplayerGame())
3681+
{
3682+
TheGameEngine->setQuitting(TRUE);
3683+
}
3684+
}
3685+
3686+
if (TheInGameUI)
3687+
{
3688+
TheInGameUI->setClientQuiet(TRUE);
3689+
}
3690+
}
3691+
36223692
// ------------------------------------------------------------------------------------------------
36233693
/** A new GameLogic object has been constructed, therefore create
36243694
* a corresponding drawable and bind them together. */

Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,10 @@ void GameLogic::clearGameData( Bool showScoreScreen )
275275
// if(shellGame)
276276

277277

278-
if (TheGlobalData->m_initialFile.isEmpty() == FALSE)
278+
if (TheGlobalData->m_initialFile.isEmpty() == FALSE || m_quitToDesktopAfterMatch)
279279
{
280280
TheGameEngine->setQuitting(TRUE);
281+
m_quitToDesktopAfterMatch = FALSE;
281282
}
282283

283284
HideControlBar();

0 commit comments

Comments
 (0)