Cleanup of game options menus: not reusing MENU_STATE anymore; clear sub-menu functions; not relying on MENU_STATE.Initialized; clearer Load from Main menu (not perfect); clearer CurrentActivity flags manipulation

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3426 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2009-12-12 04:45:15 +00:00
parent 7365b09a95
commit 4fbe2c2477
+144 -151
View File
@@ -47,10 +47,7 @@ extern FRAME PlayFrame;
#define MAX_NAME_SIZE SIS_NAME_SIZE #define MAX_NAME_SIZE SIS_NAME_SIZE
static BOOLEAN DoSettings (MENU_STATE *pMS); static COUNT lastUsedSlot;
static BOOLEAN DoNaming (MENU_STATE *pMS);
static BYTE prev_save; //keeps track of the last slot that was saved or loaded
static NamingCallback *namingCB; static NamingCallback *namingCB;
@@ -94,11 +91,10 @@ enum
SAVE_GAME = 0, SAVE_GAME = 0,
LOAD_GAME, LOAD_GAME,
QUIT_GAME, QUIT_GAME,
SETTINGS SETTINGS,
EXIT_GAME_MENU,
}; };
static BOOLEAN DoGameOptions (MENU_STATE *pMS);
enum enum
{ {
SOUND_ON_SETTING, SOUND_ON_SETTING,
@@ -111,7 +107,7 @@ enum
CYBORG_SUPER_SETTING, CYBORG_SUPER_SETTING,
CHANGE_CAPTAIN_SETTING, CHANGE_CAPTAIN_SETTING,
CHANGE_SHIP_SETTING, CHANGE_SHIP_SETTING,
EXIT_MENU_SETTING EXIT_SETTINGS_MENU,
}; };
static void static void
@@ -180,7 +176,7 @@ FeedbackSetting (BYTE which_setting)
#define DDSHS_BLOCKCUR 2 #define DDSHS_BLOCKCUR 2
static BOOLEAN static BOOLEAN
DrawDescriptionString (MENU_STATE *pMS, UNICODE *Str, COUNT CursorPos, DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
COUNT state) COUNT state)
{ {
RECT r; RECT r;
@@ -196,7 +192,7 @@ DrawDescriptionString (MENU_STATE *pMS, UNICODE *Str, COUNT CursorPos,
r.extent.height = SHIP_NAME_HEIGHT; r.extent.height = SHIP_NAME_HEIGHT;
SetContext (StatusContext); SetContext (StatusContext);
if (pMS->CurState == CHANGE_CAPTAIN_SETTING) if (nameCaptain)
{ // Naming the captain { // Naming the captain
Font = TinyFont; Font = TinyFont;
r.corner.y = 10; r.corner.y = 10;
@@ -227,7 +223,7 @@ DrawDescriptionString (MENU_STATE *pMS, UNICODE *Str, COUNT CursorPos,
if (!(state & DDSHS_EDIT)) if (!(state & DDSHS_EDIT))
{ // normal state { // normal state
if (pMS->CurState == CHANGE_CAPTAIN_SETTING) if (nameCaptain)
DrawCaptainsName (); DrawCaptainsName ();
else else
DrawFlagshipName (TRUE); DrawFlagshipName (TRUE);
@@ -295,36 +291,33 @@ DrawDescriptionString (MENU_STATE *pMS, UNICODE *Str, COUNT CursorPos,
static BOOLEAN static BOOLEAN
OnNameChange (TEXTENTRY_STATE *pTES) OnNameChange (TEXTENTRY_STATE *pTES)
{ {
MENU_STATE *pMS = (MENU_STATE*) pTES->CbParam; bool nameCaptain = (bool) pTES->CbParam;
COUNT hl = DDSHS_EDIT; COUNT hl = DDSHS_EDIT;
if (pTES->JoystickMode) if (pTES->JoystickMode)
hl |= DDSHS_BLOCKCUR; hl |= DDSHS_BLOCKCUR;
return DrawDescriptionString (pMS, pTES->BaseStr, pTES->CursorPos, hl); return DrawNameString (nameCaptain, pTES->BaseStr, pTES->CursorPos, hl);
} }
static BOOLEAN static void
DoNaming (MENU_STATE *pMS) NameCaptainOrShip (bool nameCaptain)
{ {
UNICODE buf[MAX_NAME_SIZE] = ""; UNICODE buf[MAX_NAME_SIZE] = "";
TEXTENTRY_STATE tes; TEXTENTRY_STATE tes;
UNICODE *Setting; UNICODE *Setting;
pMS->Initialized = TRUE;
pMS->InputFunc = DoNaming;
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
SetFlashRect (NULL); SetFlashRect (NULL);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
DrawDescriptionString (pMS, buf, 0, DDSHS_EDIT); DrawNameString (nameCaptain, buf, 0, DDSHS_EDIT);
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
DrawStatusMessage (GAME_STRING (NAMING_STRING_BASE + 0)); DrawStatusMessage (GAME_STRING (NAMING_STRING_BASE + 0));
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
if (pMS->CurState == CHANGE_CAPTAIN_SETTING) if (nameCaptain)
{ {
Setting = GLOBAL_SIS (CommanderName); Setting = GLOBAL_SIS (CommanderName);
tes.MaxSize = sizeof (GLOBAL_SIS (CommanderName)); tes.MaxSize = sizeof (GLOBAL_SIS (CommanderName));
@@ -339,7 +332,7 @@ DoNaming (MENU_STATE *pMS)
tes.Initialized = FALSE; tes.Initialized = FALSE;
tes.BaseStr = buf; tes.BaseStr = buf;
tes.CursorPos = 0; tes.CursorPos = 0;
tes.CbParam = pMS; tes.CbParam = (void*) nameCaptain;
tes.ChangeCallback = OnNameChange; tes.ChangeCallback = OnNameChange;
tes.FrameCallback = 0; tes.FrameCallback = 0;
@@ -352,18 +345,12 @@ DoNaming (MENU_STATE *pMS)
SetFlashRect (SFR_MENU_3DO); SetFlashRect (SFR_MENU_3DO);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
DrawDescriptionString (pMS, buf, 0, DDSHS_NORMAL); DrawNameString (nameCaptain, buf, 0, DDSHS_NORMAL);
if (namingCB) if (namingCB)
namingCB (); namingCB ();
SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
pMS->InputFunc = DoSettings;
if (!(GLOBAL (CurrentActivity) & CHECK_ABORT))
FeedbackSetting (pMS->CurState);
return (TRUE);
} }
void void
@@ -378,28 +365,15 @@ DoSettings (MENU_STATE *pMS)
BYTE cur_speed; BYTE cur_speed;
if (GLOBAL (CurrentActivity) & CHECK_ABORT) if (GLOBAL (CurrentActivity) & CHECK_ABORT)
return (FALSE); return FALSE;
cur_speed = (BYTE)(GLOBAL (glob_flags) & COMBAT_SPEED_MASK) >> COMBAT_SPEED_SHIFT; cur_speed = (GLOBAL (glob_flags) & COMBAT_SPEED_MASK) >> COMBAT_SPEED_SHIFT;
SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
if (!pMS->Initialized) if (PulsedInputState.menu[KEY_MENU_CANCEL]
{
DrawMenuStateStrings (PM_SOUND_ON, pMS->CurState);
FeedbackSetting (pMS->CurState);
pMS->Initialized = TRUE;
pMS->InputFunc = DoSettings;
}
else if (PulsedInputState.menu[KEY_MENU_CANCEL]
|| (PulsedInputState.menu[KEY_MENU_SELECT] || (PulsedInputState.menu[KEY_MENU_SELECT]
&& pMS->CurState == EXIT_MENU_SETTING)) && pMS->CurState == EXIT_SETTINGS_MENU))
{ {
LockMutex (GraphicsLock); return FALSE;
DrawStatusMessage (NULL);
UnlockMutex (GraphicsLock);
pMS->CurState = SETTINGS;
pMS->InputFunc = DoGameOptions;
pMS->Initialized = FALSE;
} }
else if (PulsedInputState.menu[KEY_MENU_SELECT]) else if (PulsedInputState.menu[KEY_MENU_SELECT])
{ {
@@ -419,9 +393,8 @@ DoSettings (MENU_STATE *pMS)
break; break;
case CHANGE_CAPTAIN_SETTING: case CHANGE_CAPTAIN_SETTING:
case CHANGE_SHIP_SETTING: case CHANGE_SHIP_SETTING:
pMS->Initialized = FALSE; NameCaptainOrShip (pMS->CurState == CHANGE_CAPTAIN_SETTING);
pMS->InputFunc = DoNaming; break;
return (TRUE);
default: default:
if (cur_speed++ < NUM_COMBAT_SPEEDS - 1) if (cur_speed++ < NUM_COMBAT_SPEEDS - 1)
GLOBAL (glob_flags) |= CYBORG_ENABLED; GLOBAL (glob_flags) |= CYBORG_ENABLED;
@@ -431,7 +404,7 @@ DoSettings (MENU_STATE *pMS)
GLOBAL (glob_flags) &= ~CYBORG_ENABLED; GLOBAL (glob_flags) &= ~CYBORG_ENABLED;
} }
GLOBAL (glob_flags) = GLOBAL (glob_flags) =
(BYTE)((GLOBAL (glob_flags) & ~COMBAT_SPEED_MASK) ((GLOBAL (glob_flags) & ~COMBAT_SPEED_MASK)
| (cur_speed << COMBAT_SPEED_SHIFT)); | (cur_speed << COMBAT_SPEED_SHIFT));
pMS->CurState = CYBORG_OFF_SETTING + cur_speed; pMS->CurState = CYBORG_OFF_SETTING + cur_speed;
DrawMenuStateStrings (PM_SOUND_ON, pMS->CurState); DrawMenuStateStrings (PM_SOUND_ON, pMS->CurState);
@@ -442,7 +415,26 @@ DoSettings (MENU_STATE *pMS)
else if (DoMenuChooser (pMS, PM_SOUND_ON)) else if (DoMenuChooser (pMS, PM_SOUND_ON))
FeedbackSetting (pMS->CurState); FeedbackSetting (pMS->CurState);
return (TRUE); return TRUE;
}
static void
SettingsMenu (void)
{
MENU_STATE MenuState;
memset (&MenuState, 0, sizeof MenuState);
MenuState.CurState = SOUND_ON_SETTING;
DrawMenuStateStrings (PM_SOUND_ON, MenuState.CurState);
FeedbackSetting (MenuState.CurState);
MenuState.InputFunc = DoSettings;
DoInput (&MenuState, FALSE);
LockMutex (GraphicsLock);
DrawStatusMessage (NULL);
UnlockMutex (GraphicsLock);
} }
typedef struct typedef struct
@@ -450,9 +442,8 @@ typedef struct
SUMMARY_DESC summary[MAX_SAVED_GAMES]; SUMMARY_DESC summary[MAX_SAVED_GAMES];
BOOLEAN saving; BOOLEAN saving;
// TRUE when saving, FALSE when loading // TRUE when saving, FALSE when loading
BOOLEAN abortOnCancel; BOOLEAN success;
// TRUE when loading from the Main menu so that // TRUE when load/save succeeded
// we do not end up in a newly started game
FRAME SummaryFrame; FRAME SummaryFrame;
} PICK_GAME_STATE; } PICK_GAME_STATE;
@@ -878,64 +869,19 @@ DoPickGame (MENU_STATE *pMS)
if (PulsedInputState.menu[KEY_MENU_CANCEL]) if (PulsedInputState.menu[KEY_MENU_CANCEL])
{ {
ResumeMusic (); pickState->success = FALSE;
if (pickState->abortOnCancel)
{ // Selected LOAD from main menu, and now canceled
GLOBAL (CurrentActivity) |= CHECK_ABORT;
}
return FALSE; return FALSE;
} }
else if (PulsedInputState.menu[KEY_MENU_SELECT]) else if (PulsedInputState.menu[KEY_MENU_SELECT])
{ {
pSD = &pickState->summary[pMS->CurState]; pSD = &pickState->summary[pMS->CurState];
prev_save = pMS->CurState;
if (pickState->saving || pSD->year_index) if (pickState->saving || pSD->year_index)
{ { // valid slot
if (pickState->saving) PlayMenuSound (MENU_SOUND_SUCCESS);
{ pickState->success = TRUE;
STAMP MsgStamp;
LockMutex (GraphicsLock);
ConfirmSaveLoad (&MsgStamp);
UnlockMutex (GraphicsLock);
if (SaveGame (pMS->CurState, pSD))
{
DestroyDrawable (ReleaseDrawable (MsgStamp.frame));
GLOBAL (CurrentActivity) |= CHECK_LOAD;
}
else
{
LockMutex (GraphicsLock);
DrawStamp (&MsgStamp);
DestroyDrawable (ReleaseDrawable (MsgStamp.frame));
UnlockMutex (GraphicsLock);
SaveProblem ();
// reload and redraw everything
LoadGameDescriptions (pickState->summary);
LockMutex (GraphicsLock);
SetContext (SpaceContext);
RedrawPickDisplay (pickState, pMS->CurState);
UnlockMutex (GraphicsLock);
return TRUE;
}
ResumeMusic ();
}
else
{
LockMutex (GraphicsLock);
ConfirmSaveLoad (NULL);
UnlockMutex (GraphicsLock);
if (LoadGame (pMS->CurState, NULL))
GLOBAL (CurrentActivity) |= CHECK_LOAD;
}
return FALSE; return FALSE;
} }
PlayMenuSound (MENU_SOUND_FAILURE);
} }
else else
{ {
@@ -991,9 +937,34 @@ DoPickGame (MENU_STATE *pMS)
} }
static BOOLEAN static BOOLEAN
PickGame (BOOLEAN saving) SaveLoadGame (PICK_GAME_STATE *pickState, COUNT gameIndex)
{
SUMMARY_DESC *desc = pickState->summary + gameIndex;
STAMP saveStamp;
BOOLEAN success;
LockMutex (GraphicsLock);
ConfirmSaveLoad (&saveStamp);
UnlockMutex (GraphicsLock);
if (pickState->saving)
success = SaveGame (gameIndex, desc);
else
success = LoadGame (gameIndex, NULL);
// restore the screen under "Saving..." message
LockMutex (GraphicsLock);
DrawStamp (&saveStamp);
UnlockMutex (GraphicsLock);
DestroyDrawable (ReleaseDrawable (saveStamp.frame));
return success;
}
static BOOLEAN
PickGame (BOOLEAN saving, BOOLEAN fromMainMenu)
{ {
BOOLEAN retval;
CONTEXT OldContext; CONTEXT OldContext;
MENU_STATE MenuState; MENU_STATE MenuState;
PICK_GAME_STATE pickState; PICK_GAME_STATE pickState;
@@ -1005,13 +976,11 @@ PickGame (BOOLEAN saving)
memset (&pickState, 0, sizeof pickState); memset (&pickState, 0, sizeof pickState);
pickState.saving = saving; pickState.saving = saving;
pickState.SummaryFrame = SetAbsFrameIndex (PlayFrame, 39); pickState.SummaryFrame = SetAbsFrameIndex (PlayFrame, 39);
if (LastActivity == CHECK_LOAD)
pickState.abortOnCancel = TRUE;
memset (&MenuState, 0, sizeof MenuState); memset (&MenuState, 0, sizeof MenuState);
MenuState.privData = &pickState; MenuState.privData = &pickState;
// select the last used slot // select the last used slot
MenuState.CurState = prev_save; MenuState.CurState = lastUsedSlot;
TimeOut = FadeMusic (0, ONE_SECOND / 2); TimeOut = FadeMusic (0, ONE_SECOND / 2);
@@ -1042,7 +1011,7 @@ PickGame (BOOLEAN saving)
RedrawPickDisplay (&pickState, MenuState.CurState); RedrawPickDisplay (&pickState, MenuState.CurState);
DrawSaveLoad (&pickState); DrawSaveLoad (&pickState);
if (pickState.abortOnCancel) if (fromMainMenu)
{ {
UnbatchGraphics (); UnbatchGraphics ();
FadeScreen (FadeAllToColor, ONE_SECOND / 2); FadeScreen (FadeAllToColor, ONE_SECOND / 2);
@@ -1058,70 +1027,80 @@ PickGame (BOOLEAN saving)
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
SetMenuSounds (MENU_SOUND_ARROWS | MENU_SOUND_PAGEUP | MENU_SOUND_PAGEDOWN, SetMenuSounds (MENU_SOUND_ARROWS | MENU_SOUND_PAGEUP | MENU_SOUND_PAGEDOWN,
MENU_SOUND_SELECT); 0);
MenuState.InputFunc = DoPickGame; MenuState.InputFunc = DoPickGame;
MenuState.Initialized = TRUE;
DoInput (&MenuState, TRUE); // Save/load retry loop
while (1)
LockMutex (GraphicsLock);
retval = TRUE;
if (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))
{ {
if (saving) pickState.success = FALSE;
GLOBAL (CurrentActivity) &= ~CHECK_LOAD; DoInput (&MenuState, TRUE);
if (!pickState.success)
break; // canceled
retval = FALSE; lastUsedSlot = MenuState.CurState;
if (SaveLoadGame (&pickState, MenuState.CurState))
break; // all good
// something broke
if (saving)
SaveProblem ();
// TODO: Shouldn't we have a Problem() equivalent for Load too?
// reload and redraw everything
LoadGameDescriptions (pickState.summary);
LockMutex (GraphicsLock);
RedrawPickDisplay (&pickState, MenuState.CurState);
UnlockMutex (GraphicsLock);
} }
if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))) SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
if (pickState.success && !saving)
{ // Load succeeded, signal up the chain
GLOBAL (CurrentActivity) |= CHECK_LOAD;
}
if (!(GLOBAL (CurrentActivity) & CHECK_ABORT) &&
(saving || (!pickState.success && !fromMainMenu)))
{ // Restore previous screen { // Restore previous screen
LockMutex (GraphicsLock);
SetTransitionSource (&DlgRect); SetTransitionSource (&DlgRect);
BatchGraphics (); BatchGraphics ();
DrawStamp (&DlgStamp); DrawStamp (&DlgStamp);
ScreenTransition (3, &DlgRect); ScreenTransition (3, &DlgRect);
UnbatchGraphics (); UnbatchGraphics ();
UnlockMutex (GraphicsLock);
} }
DestroyDrawable (ReleaseDrawable (DlgStamp.frame)); DestroyDrawable (ReleaseDrawable (DlgStamp.frame));
LockMutex (GraphicsLock);
SetContext (OldContext); SetContext (OldContext);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
ResumeMusic ();
// Reactivate any background drawing, like planet rotation // Reactivate any background drawing, like planet rotation
SetInputCallback (oldCallback); SetInputCallback (oldCallback);
return retval; return pickState.success;
} }
static BOOLEAN static BOOLEAN
DoGameOptions (MENU_STATE *pMS) DoGameOptions (MENU_STATE *pMS)
{ {
BOOLEAN force_select = FALSE;
if (GLOBAL (CurrentActivity) & CHECK_ABORT) if (GLOBAL (CurrentActivity) & CHECK_ABORT)
return (FALSE); return FALSE;
if (LastActivity == CHECK_LOAD) if (PulsedInputState.menu[KEY_MENU_CANCEL]
force_select = TRUE; // Selected LOAD from main menu
SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
if (!pMS->Initialized)
{
if (LastActivity == CHECK_LOAD)
pMS->CurState = LOAD_GAME;
DrawMenuStateStrings (PM_SAVE_GAME, pMS->CurState);
pMS->Initialized = TRUE;
}
else if (PulsedInputState.menu[KEY_MENU_CANCEL]
|| (PulsedInputState.menu[KEY_MENU_SELECT] || (PulsedInputState.menu[KEY_MENU_SELECT]
&& pMS->CurState == SETTINGS + 1)) && pMS->CurState == EXIT_GAME_MENU))
{ {
pMS->CurState = SETTINGS + 1; return FALSE;
return (FALSE);
} }
else if (PulsedInputState.menu[KEY_MENU_SELECT] || force_select) else if (PulsedInputState.menu[KEY_MENU_SELECT])
{ {
switch (pMS->CurState) switch (pMS->CurState)
{ {
@@ -1130,7 +1109,7 @@ DoGameOptions (MENU_STATE *pMS)
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
SetFlashRect (NULL); SetFlashRect (NULL);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
if (!PickGame (pMS->CurState == SAVE_GAME)) if (PickGame (pMS->CurState == SAVE_GAME, FALSE))
return FALSE; return FALSE;
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
SetFlashRect (SFR_MENU_3DO); SetFlashRect (SFR_MENU_3DO);
@@ -1141,18 +1120,18 @@ DoGameOptions (MENU_STATE *pMS)
return FALSE; return FALSE;
break; break;
case SETTINGS: case SETTINGS:
pMS->Initialized = FALSE; SettingsMenu ();
pMS->InputFunc = DoSettings; DrawMenuStateStrings (PM_SAVE_GAME, pMS->CurState);
pMS->CurState = SOUND_ON_SETTING;
break; break;
} }
} }
else else
DoMenuChooser (pMS, PM_SAVE_GAME); DoMenuChooser (pMS, PM_SAVE_GAME);
return (TRUE); return TRUE;
} }
// Returns TRUE when the owner menu should continue
BOOLEAN BOOLEAN
GameOptions (void) GameOptions (void)
{ {
@@ -1160,20 +1139,34 @@ GameOptions (void)
memset (&MenuState, 0, sizeof MenuState); memset (&MenuState, 0, sizeof MenuState);
MenuState.InputFunc = DoGameOptions; if (LastActivity == CHECK_LOAD)
{ // Selected LOAD from main menu
BOOLEAN success;
DrawMenuStateStrings (PM_SAVE_GAME, LOAD_GAME);
success = PickGame (FALSE, TRUE);
if (!success)
{ // Selected LOAD from main menu, and canceled
GLOBAL (CurrentActivity) |= CHECK_ABORT;
}
return FALSE;
}
MenuState.CurState = SAVE_GAME; MenuState.CurState = SAVE_GAME;
DrawMenuStateStrings (PM_SAVE_GAME, MenuState.CurState);
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
SetFlashRect (SFR_MENU_3DO); SetFlashRect (SFR_MENU_3DO);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
MenuState.InputFunc = DoGameOptions;
DoInput (&MenuState, TRUE); DoInput (&MenuState, TRUE);
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
SetFlashRect (NULL); SetFlashRect (NULL);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
return ((GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)) ? FALSE : TRUE); return !(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD));
} }