Skip to content

Commit 4fda496

Browse files
committed
Implement graceful exit during loading and movie screens
1 parent 765d92b commit 4fda496

File tree

6 files changed

+74
-25
lines changed

6 files changed

+74
-25
lines changed

Core/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"
@@ -157,7 +159,8 @@ LoadScreen::~LoadScreen( void )
157159
void LoadScreen::update( Int percent )
158160
{
159161
TheGameEngine->serviceWindowsOS();
160-
if (TheGameEngine->getQuitting())
162+
TheMessageStream->propagateMessages();
163+
if (TheGameEngine->getQuitting() || TheGameLogic->m_quitToDesktopAfterMatch)
161164
return; //don't bother with any of this if the player is exiting game.
162165

163166
TheWindowManager->update();
@@ -539,20 +542,11 @@ void SinglePlayerLoadScreen::init( GameInfo *game )
539542
Int shiftedPercent = -FRAME_FUDGE_ADD + 1;
540543
while (m_videoStream->frameIndex() < m_videoStream->frameCount() - 1 )
541544
{
542-
// TheSuperHackers @feature User can now skip video by pressing ESC
543-
if (TheKeyboard)
545+
if (TheGameClient->isMovieAbortRequested())
544546
{
545-
TheKeyboard->UPDATE();
546-
KeyboardIO *io = TheKeyboard->findKey(KEY_ESC, KeyboardIO::STATUS_UNUSED);
547-
if (io && BitIsSet(io->state, KEY_STATE_DOWN))
548-
{
549-
io->setUsed();
550-
break;
551-
}
547+
break;
552548
}
553549

554-
TheGameEngine->serviceWindowsOS();
555-
556550
if(!m_videoStream->isFrameReady())
557551
{
558552
Sleep(1);
@@ -634,6 +628,11 @@ void SinglePlayerLoadScreen::init( GameInfo *game )
634628
fudgeFactor = 30 * ((currTime - begin)/ INT_TO_REAL(delay ));
635629
GadgetProgressBarSetProgress(m_progressBar, fudgeFactor);
636630

631+
if (TheGameClient->isMovieAbortRequested())
632+
{
633+
break;
634+
}
635+
637636
TheWindowManager->update();
638637
TheDisplay->draw();
639638
Sleep(100);
@@ -1054,20 +1053,11 @@ void ChallengeLoadScreen::init( GameInfo *game )
10541053
Int shiftedPercent = -FRAME_FUDGE_ADD + 1;
10551054
while (m_videoStream->frameIndex() < m_videoStream->frameCount() - 1 )
10561055
{
1057-
// TheSuperHackers @feature User can now skip video by pressing ESC
1058-
if (TheKeyboard)
1056+
if (TheGameClient->isMovieAbortRequested())
10591057
{
1060-
TheKeyboard->UPDATE();
1061-
KeyboardIO *io = TheKeyboard->findKey(KEY_ESC, KeyboardIO::STATUS_UNUSED);
1062-
if (io && BitIsSet(io->state, KEY_STATE_DOWN))
1063-
{
1064-
io->setUsed();
1065-
break;
1066-
}
1058+
break;
10671059
}
10681060

1069-
TheGameEngine->serviceWindowsOS();
1070-
10711061
if(!m_videoStream->isFrameReady())
10721062
{
10731063
Sleep(1);
@@ -1109,7 +1099,13 @@ void ChallengeLoadScreen::init( GameInfo *game )
11091099
// if we're min speced
11101100
m_videoStream->frameGoto(m_videoStream->frameCount()); // zero based
11111101
while(!m_videoStream->isFrameReady())
1102+
{
1103+
if (TheGameClient->isMovieAbortRequested())
1104+
{
1105+
break;
1106+
}
11121107
Sleep(1);
1108+
}
11131109
m_videoStream->frameDecompress();
11141110
m_videoStream->frameRender(m_videoBuffer);
11151111
if(m_videoBuffer)
@@ -1126,6 +1122,11 @@ void ChallengeLoadScreen::init( GameInfo *game )
11261122
fudgeFactor = 30 * ((currTime - begin)/ INT_TO_REAL(delay ));
11271123
GadgetProgressBarSetProgress(m_progressBar, fudgeFactor);
11281124

1125+
if (TheGameClient->isMovieAbortRequested())
1126+
{
1127+
break;
1128+
}
1129+
11291130
TheWindowManager->update();
11301131
TheDisplay->draw();
11311132
Sleep(100);

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