Skip to content

Commit 843b370

Browse files
committed
Implement graceful exit during loading and movie screens
1 parent dad98f6 commit 843b370

6 files changed

Lines changed: 74 additions & 25 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ class GameClient : public SubsystemInterface,
155155
void incrementRenderedObjectCount() { m_renderedObjectCount++; }
156156
virtual void notifyTerrainObjectMoved(Object *obj) = 0;
157157

158+
virtual Bool isMovieAbortRequested( void );
159+
158160

159161
protected:
160162

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ class GameLogic : public SubsystemInterface, public Snapshot
262262
// this should be called only by UpdateModule, thanks.
263263
void friend_awakenUpdateModule(Object* obj, UpdateModulePtr update, UnsignedInt whenToWakeUp);
264264

265+
Bool m_quitToDesktopAfterMatch;
266+
265267
protected:
266268

267269
// snapshot methods
@@ -406,7 +408,6 @@ class GameLogic : public SubsystemInterface, public Snapshot
406408
void xferObjectTOC( Xfer *xfer ); ///< save/load object TOC for current state of map
407409
void prepareLogicForObjectLoad( void ); ///< prepare engine for object data from game file
408410

409-
Bool m_quitToDesktopAfterMatch;
410411
};
411412

412413
// INLINE /////////////////////////////////////////////////////////////////////////////////////////

GeneralsMD/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@
6868
#include "GameClient/Display.h"
6969
#include "GameClient/GadgetProgressBar.h"
7070
#include "GameClient/GadgetStaticText.h"
71+
#include "GameClient/GameClient.h"
7172
#include "GameClient/GameText.h"
7273
#include "GameClient/GameWindowManager.h"
7374
#include "GameClient/GameWindowTransitions.h"
7475
#include "GameClient/Keyboard.h"
7576
#include "GameClient/LoadScreen.h"
7677
#include "GameClient/MapUtil.h"
7778
#include "GameClient/Mouse.h"
79+
#include "Common/MessageStream.h"
7880
#include "GameClient/Shell.h"
7981
#include "GameClient/VideoPlayer.h"
8082
#include "GameClient/WindowLayout.h"
@@ -160,7 +162,8 @@ LoadScreen::~LoadScreen( void )
160162
void LoadScreen::update( Int percent )
161163
{
162164
TheGameEngine->serviceWindowsOS();
163-
if (TheGameEngine->getQuitting())
165+
TheMessageStream->propagateMessages();
166+
if (TheGameEngine->getQuitting() || TheGameLogic->m_quitToDesktopAfterMatch)
164167
return; //don't bother with any of this if the player is exiting game.
165168

166169
TheWindowManager->update();
@@ -534,20 +537,11 @@ void SinglePlayerLoadScreen::init( GameInfo *game )
534537
Int shiftedPercent = -FRAME_FUDGE_ADD + 1;
535538
while (m_videoStream->frameIndex() < m_videoStream->frameCount() - 1 )
536539
{
537-
// TheSuperHackers @feature User can now skip video by pressing ESC
538-
if (TheKeyboard)
540+
if (TheGameClient->isMovieAbortRequested())
539541
{
540-
TheKeyboard->UPDATE();
541-
KeyboardIO *io = TheKeyboard->findKey(KEY_ESC, KeyboardIO::STATUS_UNUSED);
542-
if (io && BitIsSet(io->state, KEY_STATE_DOWN))
543-
{
544-
io->setUsed();
545-
break;
546-
}
542+
break;
547543
}
548544

549-
TheGameEngine->serviceWindowsOS();
550-
551545
if(!m_videoStream->isFrameReady())
552546
{
553547
Sleep(1);
@@ -602,6 +596,11 @@ void SinglePlayerLoadScreen::init( GameInfo *game )
602596
fudgeFactor = 30 * ((currTime - begin)/ INT_TO_REAL(delay ));
603597
GadgetProgressBarSetProgress(m_progressBar, fudgeFactor);
604598

599+
if (TheGameClient->isMovieAbortRequested())
600+
{
601+
break;
602+
}
603+
605604
TheWindowManager->update();
606605
TheDisplay->draw();
607606
Sleep(100);
@@ -1060,20 +1059,11 @@ void ChallengeLoadScreen::init( GameInfo *game )
10601059
Int shiftedPercent = -FRAME_FUDGE_ADD + 1;
10611060
while (m_videoStream->frameIndex() < m_videoStream->frameCount() - 1 )
10621061
{
1063-
// TheSuperHackers @feature User can now skip video by pressing ESC
1064-
if (TheKeyboard)
1062+
if (TheGameClient->isMovieAbortRequested())
10651063
{
1066-
TheKeyboard->UPDATE();
1067-
KeyboardIO *io = TheKeyboard->findKey(KEY_ESC, KeyboardIO::STATUS_UNUSED);
1068-
if (io && BitIsSet(io->state, KEY_STATE_DOWN))
1069-
{
1070-
io->setUsed();
1071-
break;
1072-
}
1064+
break;
10731065
}
10741066

1075-
TheGameEngine->serviceWindowsOS();
1076-
10771067
if(!m_videoStream->isFrameReady())
10781068
{
10791069
Sleep(1);
@@ -1115,7 +1105,13 @@ void ChallengeLoadScreen::init( GameInfo *game )
11151105
// if we're min speced
11161106
m_videoStream->frameGoto(m_videoStream->frameCount()); // zero based
11171107
while(!m_videoStream->isFrameReady())
1108+
{
1109+
if (TheGameClient->isMovieAbortRequested())
1110+
{
1111+
break;
1112+
}
11181113
Sleep(1);
1114+
}
11191115
m_videoStream->frameDecompress();
11201116
m_videoStream->frameRender(m_videoBuffer);
11211117
if(m_videoBuffer)
@@ -1132,6 +1128,11 @@ void ChallengeLoadScreen::init( GameInfo *game )
11321128
fudgeFactor = 30 * ((currTime - begin)/ INT_TO_REAL(delay ));
11331129
GadgetProgressBarSetProgress(m_progressBar, fudgeFactor);
11341130

1131+
if (TheGameClient->isMovieAbortRequested())
1132+
{
1133+
break;
1134+
}
1135+
11351136
TheWindowManager->update();
11361137
TheDisplay->draw();
11371138
Sleep(100);

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,11 @@ void GameClient::update( void )
556556
Int beginTime = timeGetTime();
557557
while(beginTime + 4000 > timeGetTime() )
558558
{
559+
if (TheGameClient->isMovieAbortRequested())
560+
{
561+
break;
562+
}
563+
559564
TheWindowManager->update();
560565
// redraw all views, update the GUI
561566
TheDisplay->draw();
@@ -793,6 +798,33 @@ void GameClient::updateHeadless()
793798
TheParticleSystemManager->reset();
794799
}
795800

801+
// TheSuperHackers Check if the user has requested to abort movie
802+
Bool GameClient::isMovieAbortRequested( void )
803+
{
804+
// User can skip video by pressing ESC
805+
if (TheKeyboard)
806+
{
807+
TheKeyboard->UPDATE();
808+
KeyboardIO *io = TheKeyboard->findKey(KEY_ESC, KeyboardIO::STATUS_UNUSED);
809+
if (io && BitIsSet(io->state, KEY_STATE_DOWN))
810+
{
811+
io->setUsed();
812+
return TRUE;
813+
}
814+
}
815+
816+
// Service OS for Window Close / Alt-F4 events
817+
TheGameEngine->serviceWindowsOS();
818+
TheMessageStream->propagateMessages();
819+
820+
if (TheGameEngine->getQuitting() || (TheGameLogic && TheGameLogic->m_quitToDesktopAfterMatch))
821+
{
822+
return TRUE;
823+
}
824+
825+
return FALSE;
826+
}
827+
796828
/** -----------------------------------------------------------------------------------------------
797829
* Call the given callback function for each object contained within the given region.
798830
*/

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5568,6 +5568,7 @@ static Bool isSystemMessage( const GameMessage *msg )
55685568
case GameMessage::MSG_LOGIC_CRC:
55695569
case GameMessage::MSG_SET_REPLAY_CAMERA:
55705570
case GameMessage::MSG_FRAME_TICK:
5571+
case GameMessage::MSG_META_DEMO_INSTANT_QUIT:
55715572
return TRUE;
55725573
}
55735574
return FALSE;

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,8 @@ static void populateRandomStartPosition( GameInfo *game )
10551055
}
10561056
}
10571057

1058+
struct QuitGameException {};
1059+
10581060
// ------------------------------------------------------------------------------------------------
10591061
/** Update the load screen progress */
10601062
// ------------------------------------------------------------------------------------------------
@@ -1064,6 +1066,10 @@ void GameLogic::updateLoadProgress( Int progress )
10641066
if( m_loadScreen )
10651067
m_loadScreen->update( progress );
10661068

1069+
if (TheGameEngine->getQuitting() || m_quitToDesktopAfterMatch)
1070+
{
1071+
throw QuitGameException();
1072+
}
10671073
}
10681074

10691075
// ------------------------------------------------------------------------------------------------
@@ -1105,6 +1111,8 @@ void GameLogic::setGameMode( GameMode mode )
11051111
// ------------------------------------------------------------------------------------------------
11061112
void GameLogic::startNewGame( Bool loadingSaveGame )
11071113
{
1114+
try
1115+
{
11081116

11091117
#ifdef DUMP_PERF_STATS
11101118
__int64 startTime64;
@@ -2372,7 +2380,11 @@ void GameLogic::startNewGame( Bool loadingSaveGame )
23722380
TheInGameUI->messageNoFormat( TheGameText->FETCH_OR_SUBSTITUTE( "GUI:FastForwardInstructions", L"Press F to toggle Fast Forward" ) );
23732381
}
23742382

2375-
2383+
}
2384+
catch (QuitGameException&)
2385+
{
2386+
// TheSuperHackers: The application is cleanly aborting the loading process.
2387+
}
23762388
}
23772389

23782390
//-----------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)