pokeemerald/src/start_menu.c
aaaaaa123456789 7dc95a0103 Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.

Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 06:30:55 -03:00

1398 lines
35 KiB
C

#include "global.h"
#include "battle_pike.h"
#include "battle_pyramid.h"
#include "battle_pyramid_bag.h"
#include "bg.h"
#include "event_data.h"
#include "event_object_movement.h"
#include "event_object_lock.h"
#include "event_scripts.h"
#include "fieldmap.h"
#include "field_effect.h"
#include "field_player_avatar.h"
#include "field_specials.h"
#include "field_weather.h"
#include "field_screen_effect.h"
#include "frontier_pass.h"
#include "frontier_util.h"
#include "gpu_regs.h"
#include "international_string_util.h"
#include "item_menu.h"
#include "link.h"
#include "load_save.h"
#include "main.h"
#include "menu.h"
#include "new_game.h"
#include "option_menu.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
#include "pokedex.h"
#include "pokenav.h"
#include "safari_zone.h"
#include "save.h"
#include "scanline_effect.h"
#include "script.h"
#include "sound.h"
#include "start_menu.h"
#include "strings.h"
#include "string_util.h"
#include "task.h"
#include "text.h"
#include "text_window.h"
#include "trainer_card.h"
#include "window.h"
#include "constants/songs.h"
#include "union_room.h"
#include "constants/rgb.h"
// Menu actions
enum
{
MENU_ACTION_POKEDEX,
MENU_ACTION_POKEMON,
MENU_ACTION_BAG,
MENU_ACTION_POKENAV,
MENU_ACTION_PLAYER,
MENU_ACTION_SAVE,
MENU_ACTION_OPTION,
MENU_ACTION_EXIT,
MENU_ACTION_RETIRE_SAFARI,
MENU_ACTION_PLAYER_LINK,
MENU_ACTION_REST_FRONTIER,
MENU_ACTION_RETIRE_FRONTIER,
MENU_ACTION_PYRAMID_BAG
};
// Save status
enum
{
SAVE_IN_PROGRESS,
SAVE_SUCCESS,
SAVE_CANCELED,
SAVE_ERROR
};
// IWRAM common
bool8 (*gMenuCallback)(void);
// EWRAM
EWRAM_DATA static u8 sSafariBallsWindowId = 0;
EWRAM_DATA static u8 sBattlePyramidFloorWindowId = 0;
EWRAM_DATA static u8 sStartMenuCursorPos = 0;
EWRAM_DATA static u8 sNumStartMenuActions = 0;
EWRAM_DATA static u8 sCurrentStartMenuActions[9] = {0};
EWRAM_DATA static u8 sInitStartMenuData[2] = {0};
EWRAM_DATA static u8 (*sSaveDialogCallback)(void) = NULL;
EWRAM_DATA static u8 sSaveDialogTimer = 0;
EWRAM_DATA static bool8 sSavingComplete = FALSE;
EWRAM_DATA static u8 sSaveInfoWindowId = 0;
// Menu action callbacks
static bool8 StartMenuPokedexCallback(void);
static bool8 StartMenuPokemonCallback(void);
static bool8 StartMenuBagCallback(void);
static bool8 StartMenuPokeNavCallback(void);
static bool8 StartMenuPlayerNameCallback(void);
static bool8 StartMenuSaveCallback(void);
static bool8 StartMenuOptionCallback(void);
static bool8 StartMenuExitCallback(void);
static bool8 StartMenuSafariZoneRetireCallback(void);
static bool8 StartMenuLinkModePlayerNameCallback(void);
static bool8 StartMenuBattlePyramidRetireCallback(void);
static bool8 StartMenuBattlePyramidBagCallback(void);
// Menu callbacks
static bool8 SaveStartCallback(void);
static bool8 SaveCallback(void);
static bool8 BattlePyramidRetireStartCallback(void);
static bool8 BattlePyramidRetireReturnCallback(void);
static bool8 BattlePyramidRetireCallback(void);
static bool8 HandleStartMenuInput(void);
// Save dialog callbacks
static u8 SaveConfirmSaveCallback(void);
static u8 SaveYesNoCallback(void);
static u8 SaveConfirmInputCallback(void);
static u8 SaveFileExistsCallback(void);
static u8 SaveConfirmOverwriteDefaultNoCallback(void);
static u8 SaveConfirmOverwriteCallback(void);
static u8 SaveOverwriteInputCallback(void);
static u8 SaveSavingMessageCallback(void);
static u8 SaveDoSaveCallback(void);
static u8 SaveSuccessCallback(void);
static u8 SaveReturnSuccessCallback(void);
static u8 SaveErrorCallback(void);
static u8 SaveReturnErrorCallback(void);
static u8 BattlePyramidConfirmRetireCallback(void);
static u8 BattlePyramidRetireYesNoCallback(void);
static u8 BattlePyramidRetireInputCallback(void);
// Task callbacks
static void StartMenuTask(u8 taskId);
static void SaveGameTask(u8 taskId);
static void Task_SaveAfterLinkBattle(u8 taskId);
static void Task_WaitForBattleTowerLinkSave(u8 taskId);
static bool8 FieldCB_ReturnToFieldStartMenu(void);
static const struct WindowTemplate sSafariBallsWindowTemplate = {0, 1, 1, 9, 4, 0xF, 8};
static const u8* const sPyramindFloorNames[] =
{
gText_Floor1,
gText_Floor2,
gText_Floor3,
gText_Floor4,
gText_Floor5,
gText_Floor6,
gText_Floor7,
gText_Peak
};
static const struct WindowTemplate sPyramidFloorWindowTemplate_2 = {0, 1, 1, 0xA, 4, 0xF, 8};
static const struct WindowTemplate sPyramidFloorWindowTemplate_1 = {0, 1, 1, 0xC, 4, 0xF, 8};
static const struct MenuAction sStartMenuItems[] =
{
{gText_MenuPokedex, {.u8_void = StartMenuPokedexCallback}},
{gText_MenuPokemon, {.u8_void = StartMenuPokemonCallback}},
{gText_MenuBag, {.u8_void = StartMenuBagCallback}},
{gText_MenuPokenav, {.u8_void = StartMenuPokeNavCallback}},
{gText_MenuPlayer, {.u8_void = StartMenuPlayerNameCallback}},
{gText_MenuSave, {.u8_void = StartMenuSaveCallback}},
{gText_MenuOption, {.u8_void = StartMenuOptionCallback}},
{gText_MenuExit, {.u8_void = StartMenuExitCallback}},
{gText_MenuRetire, {.u8_void = StartMenuSafariZoneRetireCallback}},
{gText_MenuPlayer, {.u8_void = StartMenuLinkModePlayerNameCallback}},
{gText_MenuRest, {.u8_void = StartMenuSaveCallback}},
{gText_MenuRetire, {.u8_void = StartMenuBattlePyramidRetireCallback}},
{gText_MenuBag, {.u8_void = StartMenuBattlePyramidBagCallback}}
};
static const struct BgTemplate sUnknown_085105A8[] =
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
}
};
static const struct WindowTemplate sUnknown_085105AC[] =
{
{0, 2, 0xF, 0x1A, 4, 0xF, 0x194},
DUMMY_WIN_TEMPLATE
};
static const struct WindowTemplate sSaveInfoWindowTemplate = {0, 1, 1, 0xE, 0xA, 0xF, 8};
// Local functions
static void BuildStartMenuActions(void);
static void AddStartMenuAction(u8 action);
static void BuildNormalStartMenu(void);
static void BuildSafariZoneStartMenu(void);
static void BuildLinkModeStartMenu(void);
static void BuildUnionRoomStartMenu(void);
static void BuildBattlePikeStartMenu(void);
static void BuildBattlePyramidStartMenu(void);
static void BuildMultiPartnerRoomStartMenu(void);
static void ShowSafariBallsWindow(void);
static void ShowPyramidFloorWindow(void);
static void RemoveExtraStartMenuWindows(void);
static bool32 PrintStartMenuActions(s8 *pIndex, u32 count);
static bool32 InitStartMenuStep(void);
static void InitStartMenu(void);
static void CreateStartMenuTask(TaskFunc followupFunc);
static void InitSave(void);
static u8 RunSaveCallback(void);
static void ShowSaveMessage(const u8 *message, u8 (*saveCallback)(void));
static void sub_80A0014(void);
static void HideSaveInfoWindow(void);
static void SaveStartTimer(void);
static bool8 SaveSuccesTimer(void);
static bool8 SaveErrorTimer(void);
static void InitBattlePyramidRetire(void);
static void sub_80A03D8(void);
static bool32 InitSaveWindowAfterLinkBattle(u8 *par1);
static void CB2_SaveAfterLinkBattle(void);
static void ShowSaveInfoWindow(void);
static void RemoveSaveInfoWindow(void);
static void HideStartMenuWindow(void);
void SetDexPokemonPokenavFlags(void) // unused
{
FlagSet(FLAG_SYS_POKEDEX_GET);
FlagSet(FLAG_SYS_POKEMON_GET);
FlagSet(FLAG_SYS_POKENAV_GET);
}
static void BuildStartMenuActions(void)
{
sNumStartMenuActions = 0;
if (IsUpdateLinkStateCBActive() == TRUE)
{
BuildLinkModeStartMenu();
}
else if (InUnionRoom() == TRUE)
{
BuildUnionRoomStartMenu();
}
else if (GetSafariZoneFlag() == TRUE)
{
BuildSafariZoneStartMenu();
}
else if (InBattlePike())
{
BuildBattlePikeStartMenu();
}
else if (InBattlePyramid())
{
BuildBattlePyramidStartMenu();
}
else if (InMultiPartnerRoom())
{
BuildMultiPartnerRoomStartMenu();
}
else
{
BuildNormalStartMenu();
}
}
static void AddStartMenuAction(u8 action)
{
AppendToList(sCurrentStartMenuActions, &sNumStartMenuActions, action);
}
static void BuildNormalStartMenu(void)
{
if (FlagGet(FLAG_SYS_POKEDEX_GET) == TRUE)
{
AddStartMenuAction(MENU_ACTION_POKEDEX);
}
if (FlagGet(FLAG_SYS_POKEMON_GET) == TRUE)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
}
AddStartMenuAction(MENU_ACTION_BAG);
if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE)
{
AddStartMenuAction(MENU_ACTION_POKENAV);
}
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_SAVE);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
static void BuildSafariZoneStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_RETIRE_SAFARI);
AddStartMenuAction(MENU_ACTION_POKEDEX);
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_BAG);
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
static void BuildLinkModeStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_BAG);
if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE)
{
AddStartMenuAction(MENU_ACTION_POKENAV);
}
AddStartMenuAction(MENU_ACTION_PLAYER_LINK);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
static void BuildUnionRoomStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_BAG);
if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE)
{
AddStartMenuAction(MENU_ACTION_POKENAV);
}
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
static void BuildBattlePikeStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEDEX);
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
static void BuildBattlePyramidStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_PYRAMID_BAG);
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_REST_FRONTIER);
AddStartMenuAction(MENU_ACTION_RETIRE_FRONTIER);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
static void BuildMultiPartnerRoomStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
static void ShowSafariBallsWindow(void)
{
sSafariBallsWindowId = AddWindow(&sSafariBallsWindowTemplate);
PutWindowTilemap(sSafariBallsWindowId);
DrawStdWindowFrame(sSafariBallsWindowId, FALSE);
ConvertIntToDecimalStringN(gStringVar1, gNumSafariBalls, STR_CONV_MODE_RIGHT_ALIGN, 2);
StringExpandPlaceholders(gStringVar4, gText_SafariBallStock);
AddTextPrinterParameterized(sSafariBallsWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
CopyWindowToVram(sSafariBallsWindowId, 2);
}
static void ShowPyramidFloorWindow(void)
{
if (gSaveBlock2Ptr->frontier.curChallengeBattleNum == 7)
sBattlePyramidFloorWindowId = AddWindow(&sPyramidFloorWindowTemplate_1);
else
sBattlePyramidFloorWindowId = AddWindow(&sPyramidFloorWindowTemplate_2);
PutWindowTilemap(sBattlePyramidFloorWindowId);
DrawStdWindowFrame(sBattlePyramidFloorWindowId, FALSE);
StringCopy(gStringVar1, sPyramindFloorNames[gSaveBlock2Ptr->frontier.curChallengeBattleNum]);
StringExpandPlaceholders(gStringVar4, gText_BattlePyramidFloor);
AddTextPrinterParameterized(sBattlePyramidFloorWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
CopyWindowToVram(sBattlePyramidFloorWindowId, 2);
}
static void RemoveExtraStartMenuWindows(void)
{
if (GetSafariZoneFlag())
{
ClearStdWindowAndFrameToTransparent(sSafariBallsWindowId, FALSE);
CopyWindowToVram(sSafariBallsWindowId, 2);
RemoveWindow(sSafariBallsWindowId);
}
if (InBattlePyramid())
{
ClearStdWindowAndFrameToTransparent(sBattlePyramidFloorWindowId, FALSE);
RemoveWindow(sBattlePyramidFloorWindowId);
}
}
static bool32 PrintStartMenuActions(s8 *pIndex, u32 count)
{
s8 index = *pIndex;
do
{
if (sStartMenuItems[sCurrentStartMenuActions[index]].func.u8_void == StartMenuPlayerNameCallback)
{
PrintPlayerNameOnWindow(GetStartMenuWindowId(), sStartMenuItems[sCurrentStartMenuActions[index]].text, 8, (index << 4) + 9);
}
else
{
StringExpandPlaceholders(gStringVar4, sStartMenuItems[sCurrentStartMenuActions[index]].text);
AddTextPrinterParameterized(GetStartMenuWindowId(), 1, gStringVar4, 8, (index << 4) + 9, 0xFF, NULL);
}
index++;
if (index >= sNumStartMenuActions)
{
*pIndex = index;
return TRUE;
}
count--;
}
while (count != 0);
*pIndex = index;
return FALSE;
}
static bool32 InitStartMenuStep(void)
{
s8 state = sInitStartMenuData[0];
switch (state)
{
case 0:
sInitStartMenuData[0]++;
break;
case 1:
BuildStartMenuActions();
sInitStartMenuData[0]++;
break;
case 2:
LoadMessageBoxAndBorderGfx();
DrawStdWindowFrame(sub_81979C4(sNumStartMenuActions), FALSE);
sInitStartMenuData[1] = 0;
sInitStartMenuData[0]++;
break;
case 3:
if (GetSafariZoneFlag())
ShowSafariBallsWindow();
if (InBattlePyramid())
ShowPyramidFloorWindow();
sInitStartMenuData[0]++;
break;
case 4:
if (PrintStartMenuActions(&sInitStartMenuData[1], 2))
sInitStartMenuData[0]++;
break;
case 5:
sStartMenuCursorPos = sub_81983AC(GetStartMenuWindowId(), 1, 0, 9, 16, sNumStartMenuActions, sStartMenuCursorPos);
CopyWindowToVram(GetStartMenuWindowId(), TRUE);
return TRUE;
}
return FALSE;
}
static void InitStartMenu(void)
{
sInitStartMenuData[0] = 0;
sInitStartMenuData[1] = 0;
while (!InitStartMenuStep())
;
}
static void StartMenuTask(u8 taskId)
{
if (InitStartMenuStep() == TRUE)
SwitchTaskToFollowupFunc(taskId);
}
static void CreateStartMenuTask(TaskFunc followupFunc)
{
u8 taskId;
sInitStartMenuData[0] = 0;
sInitStartMenuData[1] = 0;
taskId = CreateTask(StartMenuTask, 0x50);
SetTaskFuncWithFollowupFunc(taskId, StartMenuTask, followupFunc);
}
static bool8 FieldCB_ReturnToFieldStartMenu(void)
{
if (InitStartMenuStep() == FALSE)
{
return FALSE;
}
ReturnToFieldOpenStartMenu();
return TRUE;
}
void ShowReturnToFieldStartMenu(void)
{
sInitStartMenuData[0] = 0;
sInitStartMenuData[1] = 0;
gFieldCallback2 = FieldCB_ReturnToFieldStartMenu;
}
void Task_ShowStartMenu(u8 taskId)
{
struct Task* task = &gTasks[taskId];
switch(task->data[0])
{
case 0:
if (InUnionRoom() == TRUE)
SetUsingUnionRoomStartMenu();
gMenuCallback = HandleStartMenuInput;
task->data[0]++;
break;
case 1:
if (gMenuCallback() == TRUE)
DestroyTask(taskId);
break;
}
}
void ShowStartMenu(void)
{
if (!IsUpdateLinkStateCBActive())
{
FreezeObjectEvents();
sub_808B864();
sub_808BCF4();
}
CreateStartMenuTask(Task_ShowStartMenu);
ScriptContext2_Enable();
}
static bool8 HandleStartMenuInput(void)
{
if (gMain.newKeys & DPAD_UP)
{
PlaySE(SE_SELECT);
sStartMenuCursorPos = Menu_MoveCursor(-1);
}
if (gMain.newKeys & DPAD_DOWN)
{
PlaySE(SE_SELECT);
sStartMenuCursorPos = Menu_MoveCursor(1);
}
if (gMain.newKeys & A_BUTTON)
{
PlaySE(SE_SELECT);
if (sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func.u8_void == StartMenuPokedexCallback)
{
if (GetNationalPokedexCount(FLAG_GET_SEEN) == 0)
return FALSE;
}
gMenuCallback = sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func.u8_void;
if (gMenuCallback != StartMenuSaveCallback
&& gMenuCallback != StartMenuExitCallback
&& gMenuCallback != StartMenuSafariZoneRetireCallback
&& gMenuCallback != StartMenuBattlePyramidRetireCallback)
{
FadeScreen(FADE_TO_BLACK, 0);
}
return FALSE;
}
if (gMain.newKeys & (START_BUTTON | B_BUTTON))
{
RemoveExtraStartMenuWindows();
HideStartMenu();
return TRUE;
}
return FALSE;
}
static bool8 StartMenuPokedexCallback(void)
{
if (!gPaletteFade.active)
{
IncrementGameStat(GAME_STAT_CHECKED_POKEDEX);
PlayRainStoppingSoundEffect();
RemoveExtraStartMenuWindows();
CleanupOverworldWindowsAndTilemaps();
SetMainCallback2(CB2_OpenPokedex);
return TRUE;
}
return FALSE;
}
static bool8 StartMenuPokemonCallback(void)
{
if (!gPaletteFade.active)
{
PlayRainStoppingSoundEffect();
RemoveExtraStartMenuWindows();
CleanupOverworldWindowsAndTilemaps();
SetMainCallback2(CB2_PartyMenuFromStartMenu); // Display party menu
return TRUE;
}
return FALSE;
}
static bool8 StartMenuBagCallback(void)
{
if (!gPaletteFade.active)
{
PlayRainStoppingSoundEffect();
RemoveExtraStartMenuWindows();
CleanupOverworldWindowsAndTilemaps();
SetMainCallback2(CB2_BagMenuFromStartMenu); // Display bag menu
return TRUE;
}
return FALSE;
}
static bool8 StartMenuPokeNavCallback(void)
{
if (!gPaletteFade.active)
{
PlayRainStoppingSoundEffect();
RemoveExtraStartMenuWindows();
CleanupOverworldWindowsAndTilemaps();
SetMainCallback2(CB2_InitPokeNav); // Display PokeNav
return TRUE;
}
return FALSE;
}
static bool8 StartMenuPlayerNameCallback(void)
{
if (!gPaletteFade.active)
{
PlayRainStoppingSoundEffect();
RemoveExtraStartMenuWindows();
CleanupOverworldWindowsAndTilemaps();
if (IsUpdateLinkStateCBActive() || InUnionRoom())
ShowPlayerTrainerCard(CB2_ReturnToFieldWithOpenMenu); // Display trainer card
else if (FlagGet(FLAG_SYS_FRONTIER_PASS))
ShowFrontierPass(CB2_ReturnToFieldWithOpenMenu); // Display frontier pass
else
ShowPlayerTrainerCard(CB2_ReturnToFieldWithOpenMenu); // Display trainer card
return TRUE;
}
return FALSE;
}
static bool8 StartMenuSaveCallback(void)
{
if (InBattlePyramid())
RemoveExtraStartMenuWindows();
gMenuCallback = SaveStartCallback; // Display save menu
return FALSE;
}
static bool8 StartMenuOptionCallback(void)
{
if (!gPaletteFade.active)
{
PlayRainStoppingSoundEffect();
RemoveExtraStartMenuWindows();
CleanupOverworldWindowsAndTilemaps();
SetMainCallback2(CB2_InitOptionMenu); // Display option menu
gMain.savedCallback = CB2_ReturnToFieldWithOpenMenu;
return TRUE;
}
return FALSE;
}
static bool8 StartMenuExitCallback(void)
{
RemoveExtraStartMenuWindows();
HideStartMenu(); // Hide start menu
return TRUE;
}
static bool8 StartMenuSafariZoneRetireCallback(void)
{
RemoveExtraStartMenuWindows();
HideStartMenu();
SafariZoneRetirePrompt();
return TRUE;
}
static bool8 StartMenuLinkModePlayerNameCallback(void)
{
if (!gPaletteFade.active)
{
PlayRainStoppingSoundEffect();
CleanupOverworldWindowsAndTilemaps();
ShowTrainerCardInLink(gLocalLinkPlayerId, CB2_ReturnToFieldWithOpenMenu);
return TRUE;
}
return FALSE;
}
static bool8 StartMenuBattlePyramidRetireCallback(void)
{
gMenuCallback = BattlePyramidRetireStartCallback; // Confirm retire
return FALSE;
}
// Functionally unused
void ShowBattlePyramidStartMenu(void)
{
ClearDialogWindowAndFrameToTransparent(0, FALSE);
ScriptUnfreezeObjectEvents();
CreateStartMenuTask(Task_ShowStartMenu);
ScriptContext2_Enable();
}
static bool8 StartMenuBattlePyramidBagCallback(void)
{
if (!gPaletteFade.active)
{
PlayRainStoppingSoundEffect();
RemoveExtraStartMenuWindows();
CleanupOverworldWindowsAndTilemaps();
SetMainCallback2(CB2_PyramidBagMenuFromStartMenu);
return TRUE;
}
return FALSE;
}
static bool8 SaveStartCallback(void)
{
InitSave();
gMenuCallback = SaveCallback;
return FALSE;
}
static bool8 SaveCallback(void)
{
switch (RunSaveCallback())
{
case SAVE_IN_PROGRESS:
return FALSE;
case SAVE_CANCELED: // Back to start menu
ClearDialogWindowAndFrameToTransparent(0, FALSE);
InitStartMenu();
gMenuCallback = HandleStartMenuInput;
return FALSE;
case SAVE_SUCCESS:
case SAVE_ERROR: // Close start menu
ClearDialogWindowAndFrameToTransparent(0, TRUE);
ScriptUnfreezeObjectEvents();
ScriptContext2_Disable();
SoftResetInBattlePyramid();
return TRUE;
}
return FALSE;
}
static bool8 BattlePyramidRetireStartCallback(void)
{
InitBattlePyramidRetire();
gMenuCallback = BattlePyramidRetireCallback;
return FALSE;
}
static bool8 BattlePyramidRetireReturnCallback(void)
{
InitStartMenu();
gMenuCallback = HandleStartMenuInput;
return FALSE;
}
static bool8 BattlePyramidRetireCallback(void)
{
switch (RunSaveCallback())
{
case SAVE_SUCCESS: // No (Stay in battle pyramid)
RemoveExtraStartMenuWindows();
gMenuCallback = BattlePyramidRetireReturnCallback;
return FALSE;
case SAVE_IN_PROGRESS:
return FALSE;
case SAVE_CANCELED: // Yes (Retire from battle pyramid)
ClearDialogWindowAndFrameToTransparent(0, TRUE);
ScriptUnfreezeObjectEvents();
ScriptContext2_Disable();
ScriptContext1_SetupScript(BattlePyramid_Retire);
return TRUE;
}
return FALSE;
}
static void InitSave(void)
{
save_serialize_map();
sSaveDialogCallback = SaveConfirmSaveCallback;
sSavingComplete = FALSE;
}
static u8 RunSaveCallback(void)
{
// True if text is still printing
if (RunTextPrintersAndIsPrinter0Active() == TRUE)
{
return SAVE_IN_PROGRESS;
}
sSavingComplete = FALSE;
return sSaveDialogCallback();
}
void SaveGame(void)
{
InitSave();
CreateTask(SaveGameTask, 0x50);
}
static void ShowSaveMessage(const u8 *message, u8 (*saveCallback)(void))
{
StringExpandPlaceholders(gStringVar4, message);
sub_819786C(0, TRUE);
AddTextPrinterForMessage_2(TRUE);
sSavingComplete = TRUE;
sSaveDialogCallback = saveCallback;
}
static void SaveGameTask(u8 taskId)
{
u8 status = RunSaveCallback();
switch (status)
{
case SAVE_CANCELED:
case SAVE_ERROR:
gSpecialVar_Result = 0;
break;
case SAVE_SUCCESS:
gSpecialVar_Result = status;
break;
case SAVE_IN_PROGRESS:
return;
}
DestroyTask(taskId);
EnableBothScriptContexts();
}
static void sub_80A0014(void)
{
ClearDialogWindowAndFrame(0, TRUE);
}
static void HideSaveInfoWindow(void)
{
RemoveSaveInfoWindow();
}
static void SaveStartTimer(void)
{
sSaveDialogTimer = 60;
}
static bool8 SaveSuccesTimer(void)
{
sSaveDialogTimer--;
if (gMain.heldKeys & A_BUTTON)
{
PlaySE(SE_SELECT);
return TRUE;
}
else if (sSaveDialogTimer == 0)
{
return TRUE;
}
return FALSE;
}
static bool8 SaveErrorTimer(void)
{
if (sSaveDialogTimer != 0)
{
sSaveDialogTimer--;
}
else if (gMain.heldKeys & A_BUTTON)
{
return TRUE;
}
return FALSE;
}
static u8 SaveConfirmSaveCallback(void)
{
ClearStdWindowAndFrame(GetStartMenuWindowId(), FALSE);
RemoveStartMenuWindow();
ShowSaveInfoWindow();
if (InBattlePyramid())
{
ShowSaveMessage(gText_BattlePyramidConfirmRest, SaveYesNoCallback);
}
else
{
ShowSaveMessage(gText_ConfirmSave, SaveYesNoCallback);
}
return SAVE_IN_PROGRESS;
}
static u8 SaveYesNoCallback(void)
{
DisplayYesNoMenuDefaultYes(); // Show Yes/No menu
sSaveDialogCallback = SaveConfirmInputCallback;
return SAVE_IN_PROGRESS;
}
static u8 SaveConfirmInputCallback(void)
{
switch (Menu_ProcessInputNoWrapClearOnChoose())
{
case 0: // Yes
switch (gSaveFileStatus)
{
case SAVE_STATUS_EMPTY:
case SAVE_STATUS_CORRUPT:
if (gDifferentSaveFile == FALSE)
{
sSaveDialogCallback = SaveFileExistsCallback;
return SAVE_IN_PROGRESS;
}
sSaveDialogCallback = SaveSavingMessageCallback;
return SAVE_IN_PROGRESS;
default:
sSaveDialogCallback = SaveFileExistsCallback;
return SAVE_IN_PROGRESS;
}
case -1: // B Button
case 1: // No
HideSaveInfoWindow();
sub_80A0014();
return SAVE_CANCELED;
}
return SAVE_IN_PROGRESS;
}
// A different save file exists
static u8 SaveFileExistsCallback(void)
{
if (gDifferentSaveFile == TRUE)
{
ShowSaveMessage(gText_DifferentSaveFile, SaveConfirmOverwriteDefaultNoCallback);
}
else
{
ShowSaveMessage(gText_AlreadySavedFile, SaveConfirmOverwriteCallback);
}
return SAVE_IN_PROGRESS;
}
static u8 SaveConfirmOverwriteDefaultNoCallback(void)
{
DisplayYesNoMenuWithDefault(1); // Show Yes/No menu (No selected as default)
sSaveDialogCallback = SaveOverwriteInputCallback;
return SAVE_IN_PROGRESS;
}
static u8 SaveConfirmOverwriteCallback(void)
{
DisplayYesNoMenuDefaultYes(); // Show Yes/No menu
sSaveDialogCallback = SaveOverwriteInputCallback;
return SAVE_IN_PROGRESS;
}
static u8 SaveOverwriteInputCallback(void)
{
switch (Menu_ProcessInputNoWrapClearOnChoose())
{
case 0: // Yes
sSaveDialogCallback = SaveSavingMessageCallback;
return SAVE_IN_PROGRESS;
case -1: // B Button
case 1: // No
HideSaveInfoWindow();
sub_80A0014();
return SAVE_CANCELED;
}
return SAVE_IN_PROGRESS;
}
static u8 SaveSavingMessageCallback(void)
{
ShowSaveMessage(gText_SavingDontTurnOff, SaveDoSaveCallback);
return SAVE_IN_PROGRESS;
}
static u8 SaveDoSaveCallback(void)
{
u8 saveStatus;
IncrementGameStat(GAME_STAT_SAVED_GAME);
PausePyramidChallenge();
if (gDifferentSaveFile == TRUE)
{
saveStatus = TrySavingData(SAVE_OVERWRITE_DIFFERENT_FILE);
gDifferentSaveFile = FALSE;
}
else
{
saveStatus = TrySavingData(SAVE_NORMAL);
}
if (saveStatus == SAVE_STATUS_OK)
ShowSaveMessage(gText_PlayerSavedGame, SaveSuccessCallback);
else
ShowSaveMessage(gText_SaveError, SaveErrorCallback);
SaveStartTimer();
return SAVE_IN_PROGRESS;
}
static u8 SaveSuccessCallback(void)
{
if (!IsTextPrinterActive(0))
{
PlaySE(SE_SAVE);
sSaveDialogCallback = SaveReturnSuccessCallback;
}
return SAVE_IN_PROGRESS;
}
static u8 SaveReturnSuccessCallback(void)
{
if (!IsSEPlaying() && SaveSuccesTimer())
{
HideSaveInfoWindow();
return SAVE_SUCCESS;
}
else
{
return SAVE_IN_PROGRESS;
}
}
static u8 SaveErrorCallback(void)
{
if (!IsTextPrinterActive(0))
{
PlaySE(SE_BOO);
sSaveDialogCallback = SaveReturnErrorCallback;
}
return SAVE_IN_PROGRESS;
}
static u8 SaveReturnErrorCallback(void)
{
if (!SaveErrorTimer())
{
return SAVE_IN_PROGRESS;
}
else
{
HideSaveInfoWindow();
return SAVE_ERROR;
}
}
static void InitBattlePyramidRetire(void)
{
sSaveDialogCallback = BattlePyramidConfirmRetireCallback;
sSavingComplete = FALSE;
}
static u8 BattlePyramidConfirmRetireCallback(void)
{
ClearStdWindowAndFrame(GetStartMenuWindowId(), FALSE);
RemoveStartMenuWindow();
ShowSaveMessage(gText_BattlePyramidConfirmRetire, BattlePyramidRetireYesNoCallback);
return SAVE_IN_PROGRESS;
}
static u8 BattlePyramidRetireYesNoCallback(void)
{
DisplayYesNoMenuWithDefault(1); // Show Yes/No menu (No selected as default)
sSaveDialogCallback = BattlePyramidRetireInputCallback;
return SAVE_IN_PROGRESS;
}
static u8 BattlePyramidRetireInputCallback(void)
{
switch (Menu_ProcessInputNoWrapClearOnChoose())
{
case 0: // Yes
return SAVE_CANCELED;
case -1: // B Button
case 1: // No
sub_80A0014();
return SAVE_SUCCESS;
}
return SAVE_IN_PROGRESS;
}
static void sub_80A03D8(void)
{
TransferPlttBuffer();
}
static bool32 InitSaveWindowAfterLinkBattle(u8 *state)
{
switch (*state)
{
case 0:
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0);
SetVBlankCallback(NULL);
ScanlineEffect_Stop();
DmaClear16(3, PLTT, PLTT_SIZE);
DmaFillLarge16(3, 0, (void *)(VRAM + 0x0), 0x18000, 0x1000);
break;
case 1:
ResetSpriteData();
ResetTasks();
ResetPaletteFade();
ScanlineEffect_Clear();
break;
case 2:
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sUnknown_085105A8, ARRAY_COUNT(sUnknown_085105A8));
InitWindows(sUnknown_085105AC);
LoadUserWindowBorderGfx_(0, 8, 224);
Menu_LoadStdPalAt(240);
break;
case 3:
ShowBg(0);
BlendPalettes(-1, 16, 0);
SetVBlankCallback(sub_80A03D8);
EnableInterrupts(1);
break;
case 4:
return TRUE;
}
(*state)++;
return FALSE;
}
void CB2_SetUpSaveAfterLinkBattle(void)
{
if (InitSaveWindowAfterLinkBattle(&gMain.state))
{
CreateTask(Task_SaveAfterLinkBattle, 0x50);
SetMainCallback2(CB2_SaveAfterLinkBattle);
}
}
static void CB2_SaveAfterLinkBattle(void)
{
RunTasks();
UpdatePaletteFade();
}
static void Task_SaveAfterLinkBattle(u8 taskId)
{
s16 *state = gTasks[taskId].data;
if (!gPaletteFade.active)
{
switch (*state)
{
case 0:
FillWindowPixelBuffer(0, PIXEL_FILL(1));
AddTextPrinterParameterized2(0,
1,
gText_SavingDontTurnOffPower,
TEXT_SPEED_FF,
NULL,
TEXT_COLOR_DARK_GREY,
TEXT_COLOR_WHITE,
TEXT_COLOR_LIGHT_GREY);
DrawTextBorderOuter(0, 8, 14);
PutWindowTilemap(0);
CopyWindowToVram(0, 3);
BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
if (gWirelessCommType != 0 && InUnionRoom())
{
if (Link_AnyPartnersPlayingFRLG_JP())
{
*state = 1;
}
else
{
*state = 5;
}
}
else
{
gSoftResetDisabled = 1;
*state = 1;
}
break;
case 1:
SetContinueGameWarpStatusToDynamicWarp();
FullSaveGame();
*state = 2;
break;
case 2:
if (CheckSaveFile())
{
ClearContinueGameWarpStatus2();
*state = 3;
gSoftResetDisabled = 0;
}
break;
case 3:
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
*state = 4;
break;
case 4:
FreeAllWindowBuffers();
SetMainCallback2(gMain.savedCallback);
DestroyTask(taskId);
break;
case 5:
CreateTask(Task_LinkSave, 5);
*state = 6;
break;
case 6:
if (!FuncIsActiveTask(Task_LinkSave))
{
*state = 3;
}
break;
}
}
}
static void ShowSaveInfoWindow(void)
{
struct WindowTemplate saveInfoWindow = sSaveInfoWindowTemplate;
u8 gender;
u8 color;
u32 xOffset;
u32 yOffset;
if (!FlagGet(FLAG_SYS_POKEDEX_GET))
{
saveInfoWindow.height -= 2;
}
sSaveInfoWindowId = AddWindow(&saveInfoWindow);
DrawStdWindowFrame(sSaveInfoWindowId, FALSE);
gender = gSaveBlock2Ptr->playerGender;
color = TEXT_COLOR_RED; // Red when female, blue when male.
if (gender == MALE)
{
color = TEXT_COLOR_BLUE;
}
// Print region name
yOffset = 1;
BufferSaveMenuText(SAVE_MENU_LOCATION, gStringVar4, TEXT_COLOR_GREEN);
AddTextPrinterParameterized(sSaveInfoWindowId, 1, gStringVar4, 0, yOffset, 0xFF, NULL);
// Print player name
yOffset += 16;
AddTextPrinterParameterized(sSaveInfoWindowId, 1, gText_SavingPlayer, 0, yOffset, 0xFF, NULL);
BufferSaveMenuText(SAVE_MENU_NAME, gStringVar4, color);
xOffset = GetStringRightAlignXOffset(1, gStringVar4, 0x70);
PrintPlayerNameOnWindow(sSaveInfoWindowId, gStringVar4, xOffset, yOffset);
// Print badge count
yOffset += 16;
AddTextPrinterParameterized(sSaveInfoWindowId, 1, gText_SavingBadges, 0, yOffset, 0xFF, NULL);
BufferSaveMenuText(SAVE_MENU_BADGES, gStringVar4, color);
xOffset = GetStringRightAlignXOffset(1, gStringVar4, 0x70);
AddTextPrinterParameterized(sSaveInfoWindowId, 1, gStringVar4, xOffset, yOffset, 0xFF, NULL);
if (FlagGet(FLAG_SYS_POKEDEX_GET) == TRUE)
{
// Print pokedex count
yOffset += 16;
AddTextPrinterParameterized(sSaveInfoWindowId, 1, gText_SavingPokedex, 0, yOffset, 0xFF, NULL);
BufferSaveMenuText(SAVE_MENU_CAUGHT, gStringVar4, color);
xOffset = GetStringRightAlignXOffset(1, gStringVar4, 0x70);
AddTextPrinterParameterized(sSaveInfoWindowId, 1, gStringVar4, xOffset, yOffset, 0xFF, NULL);
}
// Print play time
yOffset += 16;
AddTextPrinterParameterized(sSaveInfoWindowId, 1, gText_SavingTime, 0, yOffset, 0xFF, NULL);
BufferSaveMenuText(SAVE_MENU_PLAY_TIME, gStringVar4, color);
xOffset = GetStringRightAlignXOffset(1, gStringVar4, 0x70);
AddTextPrinterParameterized(sSaveInfoWindowId, 1, gStringVar4, xOffset, yOffset, 0xFF, NULL);
CopyWindowToVram(sSaveInfoWindowId, 2);
}
static void RemoveSaveInfoWindow(void)
{
ClearStdWindowAndFrame(sSaveInfoWindowId, FALSE);
RemoveWindow(sSaveInfoWindowId);
}
static void Task_WaitForBattleTowerLinkSave(u8 taskId)
{
if (!FuncIsActiveTask(Task_LinkSave))
{
DestroyTask(taskId);
EnableBothScriptContexts();
}
}
#define tPartialSave data[2]
void SaveForBattleTowerLink(void)
{
u8 taskId = CreateTask(Task_LinkSave, 5);
gTasks[taskId].tPartialSave = TRUE;
gTasks[CreateTask(Task_WaitForBattleTowerLinkSave, 6)].data[1] = taskId;
}
#undef tPartialSave
static void HideStartMenuWindow(void)
{
ClearStdWindowAndFrame(GetStartMenuWindowId(), TRUE);
RemoveStartMenuWindow();
ScriptUnfreezeObjectEvents();
ScriptContext2_Disable();
}
void HideStartMenu(void)
{
PlaySE(SE_SELECT);
HideStartMenuWindow();
}
void AppendToList(u8 *list, u8 *pos, u8 newEntry)
{
list[*pos] = newEntry;
(*pos)++;
}