First steps towards clean exit; bug #52

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3167 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2009-07-02 01:44:31 +00:00
parent bd092ca844
commit 86f36b30d5
15 changed files with 101 additions and 51 deletions
+1
View File
@@ -1,4 +1,5 @@
Changes towards version 0.7: Changes towards version 0.7:
- Game attempts to exit cleanly under normal circustances (bug #52) - Alex
- Fixed Mmrnmhrm's X-Form transformation without energy use (bug #1004) - Alex - Fixed Mmrnmhrm's X-Form transformation without energy use (bug #1004) - Alex
- Added missing sleeps in DoInput() functions (bug #893) - Alex - Added missing sleeps in DoInput() functions (bug #893) - Alex
- Starmap unit conversion corrections; fixes bug #970 - Alex - Starmap unit conversion corrections; fixes bug #970 - Alex
+2 -1
View File
@@ -1753,7 +1753,8 @@ SellMinerals (RESPONSE_REF R)
total += amount * GLOBAL (ElementWorth[i]); total += amount * GLOBAL (ElementWorth[i]);
do do
{ {
if (!Sleepy || AnyButtonPress (TRUE)) if (!Sleepy || AnyButtonPress (TRUE) ||
(GLOBAL (CurrentActivity) & CHECK_ABORT))
{ {
Sleepy = FALSE; Sleepy = FALSE;
GLOBAL_SIS (ElementAmounts[i]) = 0; GLOBAL_SIS (ElementAmounts[i]) = 0;
+11 -15
View File
@@ -84,7 +84,7 @@ BOOLEAN
DoConfirmExit (void) DoConfirmExit (void)
{ {
BOOLEAN result; BOOLEAN result;
static BOOLEAN in_confirm = FALSE;
if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE &&
LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE && LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE &&
!(LastActivity & CHECK_RESTART)) !(LastActivity & CHECK_RESTART))
@@ -93,12 +93,6 @@ DoConfirmExit (void)
PauseTrack (); PauseTrack ();
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
if (in_confirm)
{
result = FALSE;
ExitRequested = FALSE;
}
else
{ {
RECT r; RECT r;
STAMP s; STAMP s;
@@ -107,7 +101,6 @@ DoConfirmExit (void)
RECT oldRect; RECT oldRect;
BOOLEAN response = FALSE, done; BOOLEAN response = FALSE, done;
in_confirm = TRUE;
oldContext = SetContext (ScreenContext); oldContext = SetContext (ScreenContext);
GetContextClipRect (&oldRect); GetContextClipRect (&oldRect);
SetContextClipRect (NULL); SetContextClipRect (NULL);
@@ -130,16 +123,20 @@ DoConfirmExit (void)
FlushGraphics (); FlushGraphics ();
//LockMutex (GraphicsLock); //LockMutex (GraphicsLock);
GLOBAL (CurrentActivity) |= CHECK_ABORT;
FlushInput (); FlushInput ();
done = FALSE; done = FALSE;
do { do {
// Forbid recursive calls or pausing here! // Forbid recursive calls or pausing here!
ExitRequested = FALSE; ExitRequested = FALSE;
GamePaused = FALSE; GamePaused = FALSE;
UpdateInputState (); UpdateInputState ();
if (PulsedInputState.menu[KEY_MENU_SELECT]) if (GLOBAL (CurrentActivity) & CHECK_ABORT)
{ // something else triggered an exit
done = TRUE;
response = TRUE;
}
else if (PulsedInputState.menu[KEY_MENU_SELECT])
{ {
done = TRUE; done = TRUE;
PlayMenuSound (MENU_SOUND_SUCCESS); PlayMenuSound (MENU_SOUND_SUCCESS);
@@ -155,21 +152,21 @@ DoConfirmExit (void)
DrawConfirmationWindow (response); DrawConfirmationWindow (response);
PlayMenuSound (MENU_SOUND_MOVE); PlayMenuSound (MENU_SOUND_MOVE);
} }
TaskSwitch (); SleepThread (ONE_SECOND / 30);
} while (!done); } while (!done);
s.frame = F; s.frame = F;
DrawStamp (&s); DrawStamp (&s);
DestroyDrawable (ReleaseDrawable (s.frame)); DestroyDrawable (ReleaseDrawable (s.frame));
ClearSystemRect (); ClearSystemRect ();
if (response) if (response || (GLOBAL (CurrentActivity) & CHECK_ABORT))
{ {
result = TRUE; result = TRUE;
GLOBAL (CurrentActivity) |= CHECK_ABORT;
} }
else else
{ {
result = FALSE; result = FALSE;
GLOBAL (CurrentActivity) &= ~CHECK_ABORT;
} }
ExitRequested = FALSE; ExitRequested = FALSE;
GamePaused = FALSE; GamePaused = FALSE;
@@ -190,7 +187,6 @@ DoConfirmExit (void)
do_subtitles ((void *)~0); do_subtitles ((void *)~0);
} }
in_confirm = FALSE;
return (result); return (result);
} }
-1
View File
@@ -102,7 +102,6 @@ void SetDefaultMenuRepeatDelay (void);
void ResetKeyRepeat (void); void ResetKeyRepeat (void);
BOOLEAN PauseGame (void); BOOLEAN PauseGame (void);
BOOLEAN DoConfirmExit (void); BOOLEAN DoConfirmExit (void);
void TFB_Abort (void);
BOOLEAN WaitAnyButtonOrQuit (BOOLEAN CheckSpecial); BOOLEAN WaitAnyButtonOrQuit (BOOLEAN CheckSpecial);
void WaitForNoInput (SIZE Duration); void WaitForNoInput (SIZE Duration);
BOOLEAN ConfirmExit (void); BOOLEAN ConfirmExit (void);
+5 -3
View File
@@ -201,8 +201,7 @@ InitEncounter (void)
PlayMusic (MR, FALSE, 1); PlayMusic (MR, FALSE, 1);
SegueFrame = CaptureDrawable (LoadGraphic (SEGUE_PMAP_ANIM)); SegueFrame = CaptureDrawable (LoadGraphic (SEGUE_PMAP_ANIM));
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
while (PLRPlaying (MR)) WaitForSoundEnd (TFBSOUND_WAIT_ALL);
TaskSwitch ();
StopMusic (); StopMusic ();
DestroyMusic (MR); DestroyMusic (MR);
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
@@ -622,7 +621,8 @@ UninitEncounter (void)
for (j = 0; j < NUM_SHIP_FADES; ++j) for (j = 0; j < NUM_SHIP_FADES; ++j)
{ {
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
Sleepy = (BOOLEAN)!AnyButtonPress (TRUE); Sleepy = (BOOLEAN)!AnyButtonPress (TRUE) &&
!(GLOBAL (CurrentActivity) & CHECK_ABORT);
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
if (!Sleepy) if (!Sleepy)
break; break;
@@ -658,6 +658,7 @@ UninitEncounter (void)
FlushInput (); FlushInput ();
Time = GetTimeCounter () + (ONE_SECOND * 3); Time = GetTimeCounter () + (ONE_SECOND * 3);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
// TODO: handle rapid quit
while (!(AnyButtonPress (TRUE)) && GetTimeCounter () < Time) while (!(AnyButtonPress (TRUE)) && GetTimeCounter () < Time)
TaskSwitch (); TaskSwitch ();
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
@@ -688,6 +689,7 @@ UninitEncounter (void)
DrawFadeText (str1, str2, TRUE, &scavenge_r); DrawFadeText (str1, str2, TRUE, &scavenge_r);
Time = GetTimeCounter () + ONE_SECOND * 2; Time = GetTimeCounter () + ONE_SECOND * 2;
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
// TODO: handle rapid quit
while (!(AnyButtonPress (TRUE)) while (!(AnyButtonPress (TRUE))
&& GetTimeCounter () < Time) && GetTimeCounter () < Time)
TaskSwitch (); TaskSwitch ();
-4
View File
@@ -60,7 +60,6 @@ static DWORD GestaltRepeatDelay, GestaltTime;
static BOOLEAN OldGestalt, CachedGestalt; static BOOLEAN OldGestalt, CachedGestalt;
static DWORD _max_accel, _min_accel, _step_accel; static DWORD _max_accel, _min_accel, _step_accel;
static BOOLEAN _gestalt_keys; static BOOLEAN _gestalt_keys;
int ExitState;
static MENU_SOUND_FLAGS sound_0, sound_1; static MENU_SOUND_FLAGS sound_0, sound_1;
@@ -353,9 +352,6 @@ DoInput (void *pInputState, BOOLEAN resetInput)
#endif /* CREATE_JOURNAL */ #endif /* CREATE_JOURNAL */
} }
if (CurrentInputState.menu[KEY_EXIT])
ExitState = ConfirmExit ();
soundFlags = MenuKeysToSoundFlags (&PulsedInputState); soundFlags = MenuKeysToSoundFlags (&PulsedInputState);
if (MenuSounds if (MenuSounds
+4
View File
@@ -18,6 +18,7 @@
#include "gfx_common.h" #include "gfx_common.h"
#include "libs/tasklib.h" #include "libs/tasklib.h"
#include "libs/inplib.h"
#include "libs/log.h" #include "libs/log.h"
#include <string.h> #include <string.h>
@@ -606,6 +607,9 @@ XFormColorMap (COLORMAPPTR ColorMapPtr, SIZE TimeInterval)
if (!ColorMapPtr) if (!ColorMapPtr)
return (0); return (0);
if (QuitPosted) // Don't make users wait for fades
TimeInterval = 0;
what = *ColorMapPtr; what = *ColorMapPtr;
if (what >= (int)FadeAllToWhite && what <= (int)FadeSomeToColor) if (what >= (int)FadeAllToWhite && what <= (int)FadeSomeToColor)
return XFormFade (ColorMapPtr, TimeInterval); return XFormFade (ColorMapPtr, TimeInterval);
@@ -56,11 +56,7 @@ TFB_GRAPHICS_BACKEND *graphics_backend = NULL;
#define FPS_PERIOD 100 #define FPS_PERIOD 100
int RenderedFrames = 0; int RenderedFrames = 0;
void volatile int QuitPosted = 0;
TFB_Abort (void)
{
abortFlag = TRUE;
}
void void
TFB_PreInit (void) TFB_PreInit (void)
@@ -208,8 +204,7 @@ TFB_ProcessEvents ()
// TODO // TODO
break; break;
case SDL_QUIT: case SDL_QUIT:
log_showBox (false, false); QuitPosted = 1;
exit (EXIT_SUCCESS);
break; break;
case SDL_VIDEORESIZE: /* User resized video mode */ case SDL_VIDEORESIZE: /* User resized video mode */
// TODO // TODO
@@ -222,7 +217,7 @@ TFB_ProcessEvents ()
} }
} }
if (ImmediateInputState.menu[KEY_ABORT] || abortFlag) if (ImmediateInputState.menu[KEY_ABORT])
{ {
log_showBox (false, false); log_showBox (false, false);
exit (EXIT_SUCCESS); exit (EXIT_SUCCESS);
+1
View File
@@ -39,6 +39,7 @@ extern BYTE LocateMouse (SWORD *px, SWORD *py);
*/ */
extern volatile int MouseButtonDown; extern volatile int MouseButtonDown;
extern volatile int QuitPosted;
/* Functions for dealing with Character Mode */ /* Functions for dealing with Character Mode */
+9
View File
@@ -27,6 +27,8 @@ static audio_Driver audiodrv;
/* The globals that control the sound drivers. */ /* The globals that control the sound drivers. */
int snddriver, soundflags; int snddriver, soundflags;
volatile bool audio_inited = false;
/* /*
* Declarations for driver init funcs * Declarations for driver init funcs
*/ */
@@ -74,12 +76,19 @@ initAudio (sint32 driver, sint32 flags)
"NOTICE: Try running UQM with '--sound=none' option"); "NOTICE: Try running UQM with '--sound=none' option");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
audio_inited = true;
return ret; return ret;
} }
void void
unInitAudio (void) unInitAudio (void)
{ {
if (!audio_inited)
return;
audio_inited = false;
audiodrv.Uninitialize (); audiodrv.Uninitialize ();
} }
+8 -2
View File
@@ -17,8 +17,9 @@
*/ */
#include "sound.h" #include "sound.h"
#include "../compiler.h" #include "libs/compiler.h"
#include "../tasklib.h" #include "libs/tasklib.h"
#include "libs/inplib.h"
static Task FadeTask; static Task FadeTask;
static SIZE TTotal; static SIZE TTotal;
@@ -118,6 +119,8 @@ WaitForSoundEnd (COUNT Channel)
SoundPlaying () : ChannelPlaying (Channel)) SoundPlaying () : ChannelPlaying (Channel))
{ {
SleepThread (ONE_SECOND / 20); SleepThread (ONE_SECOND / 20);
if (QuitPosted) // Don't make users wait for sounds to end
break;
} }
} }
@@ -184,6 +187,9 @@ FadeMusic (BYTE end_vol, SIZE TimeInterval)
{ {
DWORD TimeOut; DWORD TimeOut;
if (QuitPosted) // Don't make users wait for fades
TimeInterval = 0;
if (FadeTask) if (FadeTask)
{ {
volume_end = musicVolume; volume_end = musicVolume;
+17 -8
View File
@@ -39,6 +39,8 @@
#include "uqmversion.h" #include "uqmversion.h"
#include "options.h" #include "options.h"
volatile int MainExited = FALSE;
// Open or close the periodically occuring QuasiSpace portal. // Open or close the periodically occuring QuasiSpace portal.
// A seperate thread is always inside this function when the player // A seperate thread is always inside this function when the player
// is in hyperspace. This thread awakens every BATTLE_FRAME_RATE seconds. // is in hyperspace. This thread awakens every BATTLE_FRAME_RATE seconds.
@@ -96,6 +98,13 @@ BackgroundInitKernel (DWORD TimeOut)
} }
} }
void
SignalStopMainThread (void)
{
GamePaused = FALSE;
GLOBAL (CurrentActivity) |= CHECK_ABORT;
}
/* TODO: Remove these declarations once threading is gone. */ /* TODO: Remove these declarations once threading is gone. */
extern int snddriver, soundflags; extern int snddriver, soundflags;
@@ -125,11 +134,13 @@ while (--ac > 0)
} }
#endif // CREATE_JOURNAL #endif // CREATE_JOURNAL
/* TODO: Put initAudio back in main where it belongs once threading {
* is gone. /* TODO: Put initAudio back in main where it belongs once threading
*/ * is gone.
extern sint32 initAudio (sint32 driver, sint32 flags); */
initAudio (snddriver, soundflags); extern sint32 initAudio (sint32 driver, sint32 flags);
initAudio (snddriver, soundflags);
}
if (!LoadKernel (0,0)) if (!LoadKernel (0,0))
{ {
@@ -258,9 +269,7 @@ while (--ac > 0)
FreeGameData (); FreeGameData ();
FreeKernel (); FreeKernel ();
// XXX: the abort can now be changed to something cleaner; MainExited = TRUE;
// something to terminate the for(;;) loop in main()
TFB_Abort ();
(void) threadArg; /* Satisfying compiler (unused parameter) */ (void) threadArg; /* Satisfying compiler (unused parameter) */
return 0; return 0;
+3
View File
@@ -17,6 +17,9 @@
#ifndef _STARCON_H #ifndef _STARCON_H
#define _STARCON_H #define _STARCON_H
extern volatile int MainExited;
extern void SignalStopMainThread (void);
extern int Starcon2Main (void *threadArg); extern int Starcon2Main (void *threadArg);
extern void FreeGameData (void); extern void FreeGameData (void);
+3 -3
View File
@@ -188,19 +188,19 @@ PauseGame (void)
FlushGraphics (); FlushGraphics ();
//LockMutex (GraphicsLock); //LockMutex (GraphicsLock);
while (ImmediateInputState.menu[KEY_PAUSE]) while (ImmediateInputState.menu[KEY_PAUSE] && GamePaused)
{ {
BeginInputFrame (); BeginInputFrame ();
TaskSwitch (); TaskSwitch ();
} }
while (!ImmediateInputState.menu[KEY_PAUSE]) while (!ImmediateInputState.menu[KEY_PAUSE] && GamePaused)
{ {
BeginInputFrame (); BeginInputFrame ();
TaskSwitch (); TaskSwitch ();
} }
while (ImmediateInputState.menu[KEY_PAUSE]) while (ImmediateInputState.menu[KEY_PAUSE] && GamePaused)
{ {
BeginInputFrame (); BeginInputFrame ();
TaskSwitch (); TaskSwitch ();
+34 -6
View File
@@ -29,6 +29,7 @@
#include "libs/graphics/gfx_common.h" #include "libs/graphics/gfx_common.h"
#include "libs/sound/sound.h" #include "libs/sound/sound.h"
#include "libs/input/input_common.h" #include "libs/input/input_common.h"
#include "libs/inplib.h"
#include "libs/tasklib.h" #include "libs/tasklib.h"
#include "controls.h" #include "controls.h"
#include "element.h" #include "element.h"
@@ -146,6 +147,7 @@ main (int argc, char *argv[])
/* .speechVolumeScale = */ 1.0f, /* .speechVolumeScale = */ 1.0f,
}; };
int optionsResult; int optionsResult;
int i;
log_init (15); log_init (15);
@@ -476,21 +478,47 @@ main (int argc, char *argv[])
StartThread (Starcon2Main, NULL, 1024, "Starcon2Main"); StartThread (Starcon2Main, NULL, 1024, "Starcon2Main");
for (;;) for (i = 0; i < 2000 && !MainExited; )
{ {
if (QuitPosted)
{ /* Try to stop the main thread, but limited number of times */
SignalStopMainThread ();
++i;
}
TFB_ProcessEvents (); TFB_ProcessEvents ();
ProcessThreadLifecycles (); ProcessThreadLifecycles ();
TFB_FlushGraphics (); TFB_FlushGraphics ();
} }
#if 0 /* Currently, we use atexit() callbacks everywhere, so we
unInitTempDir (); * cannot simply call unInitAudio() and the like, because other
#endif * tasks might still be using it */
uninitIO (); if (MainExited)
{
// Not yet: TFB_UninitInput ();
unInitAudio ();
uninit_communication ();
UninitColorMaps ();
// Not yet: TFB_UninitGraphics ();
#ifdef NETPLAY #ifdef NETPLAY
Network_uninit (); NetManager_uninit ();
Alarm_uninit ();
Network_uninit ();
#endif #endif
// Not yet: CleanupTaskSystem ();
UnInitTimeSystem ();
#if 0
unInitTempDir ();
#endif
uninitIO ();
UnInitThreadSystem ();
mem_uninit ();
}
log_showBox (false, false);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }