Skip to content

Commit f7cea8f

Browse files
committed
Implement graceful exit for Alt+F4 and window close events
1 parent 5d9aa65 commit f7cea8f

5 files changed

Lines changed: 69 additions & 48 deletions

File tree

GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ class GameLogic : public SubsystemInterface, public Snapshot
136136
Bool isInGameLogicUpdate( void ) const { return m_isInUpdate; }
137137
Bool hasUpdated() const { return m_hasUpdated; } ///< Returns true if the logic frame has advanced in the current client/render update
138138
UnsignedInt getFrame( void ); ///< Returns the current simulation frame number
139+
void quit(Bool toDesktop, Bool forceSurrender = TRUE);
139140
UnsignedInt getCRC( Int mode = CRC_CACHED, AsciiString deepCRCFileName = AsciiString::TheEmptyString ); ///< Returns the CRC
140141

141142
void setObjectIDCounter( ObjectID nextObjID ) { m_nextObjID = nextObjID; }
@@ -405,6 +406,7 @@ class GameLogic : public SubsystemInterface, public Snapshot
405406
void xferObjectTOC( Xfer *xfer ); ///< save/load object TOC for current state of map
406407
void prepareLogicForObjectLoad( void ); ///< prepare engine for object data from game file
407408

409+
Bool m_quitToDesktopAfterMatch;
408410
};
409411

410412
// INLINE /////////////////////////////////////////////////////////////////////////////////////////

GeneralsMD/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()

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

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,6 @@
9191

9292
#include "ww3d.h"
9393

94-
95-
#define dont_ALLOW_ALT_F4
96-
97-
9894
#if defined(RTS_DEBUG)
9995
/*non-static*/ Real TheSkateDistOverride = 0.0f;
10096

@@ -4076,26 +4072,12 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage
40764072

40774073
}
40784074

4079-
4080-
4081-
#ifdef ALLOW_ALT_F4
40824075
case GameMessage::MSG_META_DEMO_INSTANT_QUIT:
40834076
{
4084-
if (TheGameLogic->isInGame())
4085-
{
4086-
if (TheRecorder->getMode() == RECORDERMODETYPE_RECORD)
4087-
{
4088-
TheRecorder->stopRecording();
4089-
}
4090-
TheGameLogic->clearGameData();
4091-
}
4092-
TheGameEngine->setQuitting(TRUE);
4077+
TheGameLogic->quit(TRUE);
40934078
disp = DESTROY_MESSAGE;
40944079
break;
40954080
}
4096-
#endif
4097-
4098-
40994081

41004082
//------------------------------------------------------------------------------- DEMO MESSAGES
41014083

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

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ enum { OBJ_HASH_SIZE = 8192 };
141141
/// The GameLogic singleton instance
142142
GameLogic *TheGameLogic = nullptr;
143143

144+
extern GameInfo *TheGameInfo;
145+
146+
144147
static void findAndSelectCommandCenter(Object *obj, void* alreadyFound);
145148

146149

@@ -262,6 +265,7 @@ GameLogic::GameLogic( void )
262265
m_loadingMap = FALSE;
263266
m_loadingSave = FALSE;
264267
m_clearingGameData = FALSE;
268+
m_quitToDesktopAfterMatch = FALSE;
265269
}
266270

267271
//-------------------------------------------------------------------------------------------------
@@ -4162,14 +4166,71 @@ UnsignedInt GameLogic::getCRC( Int mode, AsciiString deepCRCFileName )
41624166
// ------------------------------------------------------------------------------------------------
41634167
void GameLogic::exitGame()
41644168
{
4165-
// TheSuperHackers @fix The logic update must not be halted to process the game exit message.
41664169
setGamePaused(FALSE);
41674170
TheScriptEngine->forceUnfreezeTime();
41684171
TheScriptEngine->doUnfreezeTime();
41694172

41704173
TheMessageStream->appendMessage(GameMessage::MSG_CLEAR_GAME_DATA);
41714174
}
41724175

4176+
// ------------------------------------------------------------------------------------------------
4177+
void GameLogic::quit(Bool toDesktop, Bool forceSurrender)
4178+
{
4179+
if (isInGame())
4180+
{
4181+
if (forceSurrender)
4182+
{
4183+
if (isInMultiplayerGame() && !isInSkirmishGame() && TheGameInfo && !TheGameInfo->isSandbox())
4184+
{
4185+
GameMessage *msg = TheMessageStream->appendMessage(GameMessage::MSG_SELF_DESTRUCT);
4186+
msg->appendBooleanArgument(TRUE);
4187+
}
4188+
}
4189+
4190+
if (TheRecorder && TheRecorder->getMode() == RECORDERMODETYPE_RECORD)
4191+
{
4192+
TheRecorder->stopRecording();
4193+
}
4194+
4195+
setGamePaused(FALSE);
4196+
if (TheScriptEngine)
4197+
{
4198+
TheScriptEngine->forceUnfreezeTime();
4199+
TheScriptEngine->doUnfreezeTime();
4200+
}
4201+
4202+
if (toDesktop)
4203+
{
4204+
if (isInMultiplayerGame())
4205+
{
4206+
m_quitToDesktopAfterMatch = TRUE;
4207+
exitGame();
4208+
}
4209+
else
4210+
{
4211+
clearGameData();
4212+
}
4213+
}
4214+
else
4215+
{
4216+
exitGame();
4217+
}
4218+
}
4219+
4220+
if (toDesktop)
4221+
{
4222+
if (!isInMultiplayerGame())
4223+
{
4224+
TheGameEngine->setQuitting(TRUE);
4225+
}
4226+
}
4227+
4228+
if (TheInGameUI)
4229+
{
4230+
TheInGameUI->setClientQuiet(TRUE);
4231+
}
4232+
}
4233+
41734234
// ------------------------------------------------------------------------------------------------
41744235
/** A new GameLogic object has been constructed, therefore create
41754236
* a corresponding drawable and bind them together. */

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

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

282282

283-
if (TheGlobalData->m_initialFile.isEmpty() == FALSE)
283+
if (TheGlobalData->m_initialFile.isEmpty() == FALSE || m_quitToDesktopAfterMatch)
284284
{
285285
TheGameEngine->setQuitting(TRUE);
286+
m_quitToDesktopAfterMatch = FALSE;
286287
}
287288

288289
HideControlBar();

0 commit comments

Comments
 (0)