diff options
author | Cameron Hall <camthesaxman@users.noreply.github.com> | 2016-10-09 17:50:46 -0500 |
---|---|---|
committer | YamaArashi <YamaArashi@users.noreply.github.com> | 2016-10-09 15:50:46 -0700 |
commit | 0a32b5feb1ae85d0f8e27c5f5d199e1b931b0776 (patch) | |
tree | 018a8aed83dda20a6c58dd5c7a86f5a09936924c /src | |
parent | dbf4f101961b3c8705ebe4554f67fb5b7c0249dd (diff) |
decompile start menu code (#57)
* initial decompilation
* fix sub_80712B4
* finish decompiling start menu code
* refactor
* refactor some more
* make some variables static
* change spaces to tab
Diffstat (limited to 'src')
-rw-r--r-- | src/start_menu.c | 885 |
1 files changed, 885 insertions, 0 deletions
diff --git a/src/start_menu.c b/src/start_menu.c new file mode 100644 index 000000000..35f8330cd --- /dev/null +++ b/src/start_menu.c @@ -0,0 +1,885 @@ +#include "gba/gba.h" +#include "global.h" +#include "main.h" +#include "menu.h" +#include "palette.h" +#include "script.h" +#include "songs.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "task.h" + +//External functions +extern void sub_8064E2C(void); +extern void sub_8047A1C(void); +extern u8 sub_8125E6C(void); +extern void sub_8047A34(void); +extern void sub_8125E2C(void); +extern void remove_some_task(void); +extern void dp12_8087EA4(void); +extern void sav12_xor_increment(u8 index); +extern bool8 sub_8125D44(u8); //Saving related +extern void sub_80945C0(u8, u8); +extern void sub_80946C8(u8, u8); +extern void save_serialize_map(void); +extern void play_some_sound(void); +extern void sub_8093130(u8, void (*)(void)); +extern void sub_805469C(void); +extern void sub_80C823C(void); +extern void CB2_InitOptionMenu(void); +extern void sub_8093110(void (*)(void)); +extern void sub_80EBA5C(void); +extern void sub_80A53F8(void); +extern void sub_8089A70(void); +extern void sub_808C27C(void); +extern u16 pokedex_count(u8); +extern void fade_screen(u8, u8); +extern bool32 is_c1_link_related_active(); +extern void sub_80594C0(void); +extern void sub_80597F4(void); +extern void player_bitmagic(void); +extern bool32 GetSafariZoneFlag(void); +extern u8 *sub_8072C44(u8 *, s32, u8, u8); +extern u8 FlagGet(u16); +extern bool32 is_c1_link_related_active(void); + +//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, + MENU_ACTION_PLAYER_LINK +}; + +struct MenuItem { + u8 *text; + u8 (*callback)(void); +}; + +extern u8 (*saveDialogCallback)(void); +extern bool8 gUnknown_020297EC; +extern u16 gSaveFileStatus; +extern u8 gUnknown_030006AC; +extern u16 gScriptResult; +extern bool8 gUnknown_030006AD; +extern u8 (*gCallback_03004AE8)(void); +extern u8 gUnknown_03004860; +extern struct MenuItem gStartMenuItems[]; +extern u8 gUnknown_02038808; + +EWRAM_DATA static u8 sStartMenuCursorPos = 0; +EWRAM_DATA static u8 sNumStartMenuActions = 0; +EWRAM_DATA static u8 sCurrentStartMenuActions[10] = {0}; + +//Text strings +extern u8 gSystemText_Saving[]; +extern u8 gSaveText_PlayerSavedTheGame[]; +extern u8 gSaveText_DontTurnOff[]; +extern u8 gSystemText_SaveErrorExchangeBackup[]; +extern u8 gSaveText_ThereIsAlreadyAFile[]; +extern u8 gSaveText_ThereIsADifferentFile[]; +extern u8 gSaveText_WouldYouLikeToSave[]; +extern u8 gOtherText_SafariStock[]; + +//Public functions +void CreateStartMenuTask(void (*func)(u8)); +void sub_80712B4(u8 taskId); +void sub_8071310(void); +u8 StartMenu_PokedexCallback(void); +u8 StartMenu_PokemonCallback(void); +u8 StartMenu_BagCallback(void); +u8 StartMenu_PokenavCallback(void); +u8 StartMenu_PlayerCallback(void); +u8 StartMenu_SaveCallback(void); +u8 StartMenu_OptionCallback(void); +u8 StartMenu_ExitCallback(void); +u8 StartMenu_RetireCallback(void); +u8 StartMenu_PlayerLinkCallback(void); +void InitSaveDialog(void); +void sub_8071B28(void); +void sub_8071C20(void); +void AppendToList(u8 *list, u8 *pindex, u32 value); + +//Private functions +static void BuildStartMenuActions(void); +static void AddStartMenuAction(u8 action); +static void BuildStartMenuActions_Normal(void); +static void BuildStartMenuActions_SafariZone(void); +static void BuildStartMenuActions_Link(void); +static void DisplaySafariBallsWindow(void); +static bool32 sub_8071114(s16 *a, u32 b); +static bool32 sub_807117C(s16 *a, s16 *b); +static void sub_8071230(void); +static void Task_StartMenu(u8 taskId); +static u8 Callback_8071338(void); +static u8 SaveCallback1(void); +static u8 SaveCallback2(void); +static void sub_807160C(void); +static u8 RunSaveDialogCallback(void); +static void DisplaySaveMessageWithCallback(u8 *ptr, u8 (*func)(void)); +static void Task_SaveDialog(u8 taskId); +static void sub_8071700(void); +static void EraseSaveDialog(void); +static void sub_8071724(void); +static u8 sub_8071730(void); +static u8 sub_8071764(void); +static u8 sub_8071764(void); +static u8 SaveDialogCB_8071794(void); +static u8 SaveDialogCB_80717B8(void); +static u8 SaveDialogCB_80717D8(void); +static u8 SaveDialogCB_SaveFileExists(void); +static u8 SaveDialogCB_DisplayOverwriteYesNoMenu(void); +static u8 SaveDialogCB_ProcessOverwriteYesNoMenu(void); +static u8 SaveDialogCB_SavingMessage(void); +static u8 SaveDialogCB_DoSave(void); +static u8 SaveDialogCB_SaveSuccess(void); +static u8 SaveDialogCB_8071988(void); +static u8 SaveDialogCB_80719AC(void); +static u8 SaveDialogCB_80719D4(void); +static void sub_80719F0(void); +static bool32 sub_80719FC(u8 *ptr); +static void sub_8071B54(void); +static void Task_8071B64(u8 taskId); + + +static void BuildStartMenuActions(void) +{ + sNumStartMenuActions = 0; + if(is_c1_link_related_active() == TRUE) + BuildStartMenuActions_Link(); + else + { + if(GetSafariZoneFlag() == TRUE) + BuildStartMenuActions_SafariZone(); + else + BuildStartMenuActions_Normal(); + } +} + +static void AddStartMenuAction(u8 action) +{ + AppendToList(sCurrentStartMenuActions, &sNumStartMenuActions, action); +} + +static void BuildStartMenuActions_Normal(void) +{ + if(FlagGet(0x801) == TRUE) + AddStartMenuAction(MENU_ACTION_POKEDEX); + if(FlagGet(0x800) == TRUE) + AddStartMenuAction(MENU_ACTION_POKEMON); + AddStartMenuAction(MENU_ACTION_BAG); + if(FlagGet(0x802) == TRUE) + AddStartMenuAction(MENU_ACTION_POKENAV); + AddStartMenuAction(MENU_ACTION_PLAYER); + AddStartMenuAction(MENU_ACTION_SAVE); + AddStartMenuAction(MENU_ACTION_OPTION); + AddStartMenuAction(MENU_ACTION_EXIT); +} + +static void BuildStartMenuActions_SafariZone(void) +{ + AddStartMenuAction(MENU_ACTION_RETIRE); + 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 BuildStartMenuActions_Link(void) +{ + AddStartMenuAction(MENU_ACTION_POKEMON); + AddStartMenuAction(MENU_ACTION_BAG); + if(FlagGet(0x802) == TRUE) + AddStartMenuAction(MENU_ACTION_POKENAV); + AddStartMenuAction(MENU_ACTION_PLAYER_LINK); + AddStartMenuAction(MENU_ACTION_OPTION); + AddStartMenuAction(MENU_ACTION_EXIT); +} + +//Show number of safari balls left +static void DisplaySafariBallsWindow(void) +{ + sub_8072C44(gStringVar1, gUnknown_02038808, 12, 1); + MenuDrawTextWindow(0, 0, 10, 5); + MenuPrint(gOtherText_SafariStock, 1, 1); +} + +static bool32 sub_8071114(s16 *a, u32 b) +{ + s32 var = *a; + + do + { + MenuPrint(gStartMenuItems[sCurrentStartMenuActions[var]].text, + 0x17, var * 2 + 2); + var++; + if(var >= sNumStartMenuActions) + { + *a = var; + return 1; + } + } + while(--b != 0); + *a = var; + return 0; +} + +static bool32 sub_807117C(s16 *a, s16 *b) +{ + switch(*a) + { + case 1: + BuildStartMenuActions(); + (*a)++; + break; + case 2: + MenuDrawTextWindow(22, 0, 29, sNumStartMenuActions * 2 + 3); + *b = 0; + (*a)++; + break; + case 3: + if(GetSafariZoneFlag()) + DisplaySafariBallsWindow(); + (*a)++; + break; + case 4: + if(sub_8071114(b, 2)) + (*a)++; + break; + case 0: + (*a)++; + break; + case 5: + sStartMenuCursorPos = InitMenu(0, 0x17, 2, sNumStartMenuActions, sStartMenuCursorPos, 6); + return TRUE; + } + return FALSE; +} + +static void sub_8071230(void) +{ + s16 a = 0; + s16 b = 0; + + while(sub_807117C(&a, &b) == FALSE) + ; +} + +static void Task_StartMenu(u8 taskId) +{ + if(sub_807117C(gTasks[taskId].data, gTasks[taskId].data + 1) == TRUE) + { + *gTasks[taskId].data = 0; + SwitchTaskToFollowupFunc(taskId); + } +} + +void CreateStartMenuTask(void (*func)(u8)) +{ + u8 taskId; + + InitMenuWindow(&gWindowConfig_81E6CE4); + taskId = CreateTask(Task_StartMenu, 0x50); + SetTaskFuncWithFollowupFunc(taskId, Task_StartMenu, func); +} + +struct MyTask { + TaskFunc func; + bool8 isActive; + u8 prev; + u8 next; + u8 priority; + s16 var1; +}; + +void sub_80712B4(u8 taskId) +{ + switch(((struct MyTask *)&gTasks[taskId])->var1) + { + case 0: + gCallback_03004AE8 = Callback_8071338; + ((struct MyTask *)&gTasks[taskId])->var1++; + break; + case 1: + if(gCallback_03004AE8() == 1) + DestroyTask(taskId); + break; + } +} + +void sub_8071310(void) +{ + if(!is_c1_link_related_active()) + { + player_bitmagic(); + sub_80594C0(); + sub_80597F4(); + } + CreateStartMenuTask(sub_80712B4); + ScriptContext2_Enable(); +} + +static u8 Callback_8071338(void) +{ + if(gMain.newKeys & DPAD_UP) + { + PlaySE(SE_SELECT); + sStartMenuCursorPos = MoveMenuCursor(-1); + } + if(gMain.newKeys & DPAD_DOWN) + { + PlaySE(SE_SELECT); + sStartMenuCursorPos = MoveMenuCursor(1); + } + if(gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if(gStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].callback == StartMenu_PokedexCallback) + { + if(pokedex_count(0) == 0) + return 0; + } + gCallback_03004AE8 = gStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].callback; + if(StartMenu_SaveCallback != gCallback_03004AE8 && + StartMenu_ExitCallback != gCallback_03004AE8 && + StartMenu_RetireCallback != gCallback_03004AE8) + fade_screen(1, 0); + return 0; + } + if(gMain.newKeys & (START_BUTTON | B_BUTTON)) + { + sub_8071C20(); + return 1; + } + return 0; +} + +//When player selects POKEDEX +u8 StartMenu_PokedexCallback(void) +{ + if(!gPaletteFade.active) + { + sav12_xor_increment(0x29); + play_some_sound(); + SetMainCallback2(sub_808C27C); + return 1; + } + return 0; +} + +//When player selects POKEMON +u8 StartMenu_PokemonCallback(void) +{ + if(!gPaletteFade.active) + { + play_some_sound(); + SetMainCallback2(sub_8089A70); + return 1; + } + return 0; +} + +//When player selects BAG +u8 StartMenu_BagCallback(void) +{ + if(!gPaletteFade.active) + { + play_some_sound(); + SetMainCallback2(sub_80A53F8); + return 1; + } + return 0; +} + +//When player selects POKENAV +u8 StartMenu_PokenavCallback(void) +{ + if(!gPaletteFade.active) + { + play_some_sound(); + SetMainCallback2(sub_80EBA5C); + return 1; + } + return 0; +} + +//When player selects his/her name +u8 StartMenu_PlayerCallback(void) +{ + if(!gPaletteFade.active) + { + play_some_sound(); + sub_8093110(sub_805469C); + return 1; + } + return 0; +} + +//When player selects SAVE +u8 StartMenu_SaveCallback(void) +{ + sub_8072DEC(); + gCallback_03004AE8 = SaveCallback1; + return 0; +} + +//When player selects OPTION +u8 StartMenu_OptionCallback(void) +{ + if(!gPaletteFade.active) + { + play_some_sound(); + SetMainCallback2(CB2_InitOptionMenu); + gMain.field_8 = sub_805469C; + return 1; + } + return 0; +} + +//When player selects EXIT +u8 StartMenu_ExitCallback(void) +{ + sub_8071C20(); + return 1; +} + +//When player selects RETIRE +u8 StartMenu_RetireCallback(void) +{ + sub_8071C20(); + sub_80C823C(); + return 1; +} + +//When player selects their name in multiplayer mode +u8 StartMenu_PlayerLinkCallback(void) +{ + if(!gPaletteFade.active) + { + play_some_sound(); + sub_8093130(gUnknown_03004860, sub_805469C); + return 1; + } + return 0; +} + +static u8 SaveCallback1(void) +{ + sub_807160C(); + gCallback_03004AE8 = SaveCallback2; + return FALSE; +} + +static u8 SaveCallback2(void) +{ + switch(RunSaveDialogCallback()) + { + case 0: + return FALSE; + case 2: + MenuZeroFillScreen(); + sub_8071230(); + gCallback_03004AE8 = Callback_8071338; + return FALSE; + case 1: + case 3: + MenuZeroFillScreen(); + sub_8064E2C(); + ScriptContext2_Disable(); + return TRUE; + } + return FALSE; +} + +static void sub_807160C(void) +{ + save_serialize_map(); + saveDialogCallback = SaveDialogCB_8071794; + gUnknown_030006AD = FALSE; +} + +static u8 RunSaveDialogCallback(void) +{ + if(gUnknown_030006AD) + { + if(!MenuUpdateWindowText()) + return 0; + } + gUnknown_030006AD = FALSE; + return saveDialogCallback(); +} + +void InitSaveDialog(void) +{ + sub_807160C(); + CreateTask(Task_SaveDialog, 0x50); +} + +static void DisplaySaveMessageWithCallback(u8 *ptr, u8 (*func)(void)) +{ + StringExpandPlaceholders(gStringVar4, ptr); + MenuDisplayMessageBox(); + sub_8072044(gStringVar4); + gUnknown_030006AD = TRUE; + saveDialogCallback = func; +} + +static void Task_SaveDialog(u8 taskId) +{ + u8 b = RunSaveDialogCallback(); + + switch(b) + { + case 2: + case 3: + gScriptResult = 0; + break; + case 1: + gScriptResult = b; + break; + case 0: + return; + } + DestroyTask(taskId); + EnableBothScriptContexts(); +} + +static void sub_8071700(void) +{ + sub_80946C8(0, 0); +} + +static void EraseSaveDialog(void) +{ + MenuZeroFillWindowRect(20, 8, 26, 13); +} + +static void sub_8071724(void) +{ + gUnknown_030006AC = 0x3C; +} + + +static u8 sub_8071730(void) +{ + gUnknown_030006AC--; + if(!(gMain.heldKeys & 1)) + { + if(gUnknown_030006AC) + return 0; + } + else + PlaySE(SE_SELECT); + return 1; +} + + +static u8 sub_8071764(void) +{ + if(gUnknown_030006AC == 0) + { + if(gMain.heldKeys & 1) + return 1; + } + else + gUnknown_030006AC--; + return 0; + +} + +static u8 SaveDialogCB_8071794(void) +{ + MenuZeroFillScreen(); + sub_80945C0(0, 0); + //"Would you like to save the game?" + DisplaySaveMessageWithCallback(gSaveText_WouldYouLikeToSave, SaveDialogCB_80717B8); + return 0; +} + +static u8 SaveDialogCB_80717B8(void) +{ + DisplayYesNoMenu(20, 8, 1); + saveDialogCallback = SaveDialogCB_80717D8; + return 0; +} + +static u8 SaveDialogCB_80717D8(void) +{ + switch(ProcessMenuInputNoWrap_()) + { + case 0: //YES + EraseSaveDialog(); + switch(gSaveFileStatus) + { + case 0: + case 2: + if(gUnknown_020297EC == FALSE) + { + saveDialogCallback = SaveDialogCB_SaveFileExists; + return 0; + } + saveDialogCallback = SaveDialogCB_SavingMessage; + return 0; + default: + saveDialogCallback = SaveDialogCB_SaveFileExists; + return 0; + } + break; + case -1: //B button + case 1: //NO + EraseSaveDialog(); + sub_8071700(); + return 2; + } + return 0; +} + +static u8 SaveDialogCB_SaveFileExists(void) +{ + DisplaySaveMessageWithCallback( + gUnknown_020297EC == TRUE ? gSaveText_ThereIsADifferentFile : gSaveText_ThereIsAlreadyAFile, + SaveDialogCB_DisplayOverwriteYesNoMenu); + return 0; +} + +static u8 SaveDialogCB_DisplayOverwriteYesNoMenu(void) +{ + DisplayYesNoMenu(20, 8, 1); + saveDialogCallback = SaveDialogCB_ProcessOverwriteYesNoMenu; + return 0; +} + +static u8 SaveDialogCB_ProcessOverwriteYesNoMenu(void) +{ + switch(ProcessMenuInputNoWrap_()) + { + case 0: //YES + EraseSaveDialog(); + saveDialogCallback = SaveDialogCB_SavingMessage; + break; + case -1: //B button + case 1: //NO + EraseSaveDialog(); + sub_8071700(); + return 2; + } + return 0; +} + +static u8 SaveDialogCB_SavingMessage(void) +{ + //"SAVING... DON'T TURN OFF THE POWER." + DisplaySaveMessageWithCallback(gSaveText_DontTurnOff, SaveDialogCB_DoSave); + return 0; +} + +static u8 SaveDialogCB_DoSave(void) +{ + u8 a; + + sav12_xor_increment(0); + if(gUnknown_020297EC == TRUE) + { + a = sub_8125D44(4); + gUnknown_020297EC = FALSE; + } + else + { + a = sub_8125D44(0); + } + + if(a == 1) + { + //"(Player) saved the game." + DisplaySaveMessageWithCallback(gSaveText_PlayerSavedTheGame, SaveDialogCB_SaveSuccess); + } + else + { + //"Save error. Please exchange the backup memory." + DisplaySaveMessageWithCallback(gSystemText_SaveErrorExchangeBackup, SaveDialogCB_80719AC); + } + + sub_8071724(); + return 0; +} + +static u8 SaveDialogCB_SaveSuccess(void) +{ + if(MenuUpdateWindowText()) + { + PlaySE(SE_SAVE); + saveDialogCallback = SaveDialogCB_8071988; + } + return 0; +} + +static u8 SaveDialogCB_8071988(void) +{ + if(!IsSEPlaying() && sub_8071730()) + { + sub_8071700(); + return 1; + } + else + return 0; +} + +static u8 SaveDialogCB_80719AC(void) +{ + if(MenuUpdateWindowText()) + { + PlaySE(SE_BOO); + saveDialogCallback = SaveDialogCB_80719D4; + } + return 0; +} + +static u8 SaveDialogCB_80719D4(void) +{ + if(!sub_8071764()) + return 0; + else + { + sub_8071700(); + return 3; + } +} + +static void sub_80719F0(void) +{ + TransferPlttBuffer(); +} + +static bool32 sub_80719FC(u8 *ptr) +{ + switch(*ptr) + { + case 0: + { + u8 *addr; + u32 size; + + REG_DISPCNT = 0; + SetVBlankCallback(NULL); + remove_some_task(); + DmaClear16(3, PLTT, PLTT_SIZE); + addr = (void *)VRAM; + size = 0x18000; + while(1) + { + DmaFill16(3, 0, addr, 0x1000); + addr += 0x1000; + size -= 0x1000; + if(size <= 0x1000) + { + DmaFill16(3, 0, addr, size); + break; + } + } + break; + } + case 1: + ResetSpriteData(); + ResetTasks(); + ResetPaletteFade(); + dp12_8087EA4(); + break; + case 2: + SetUpWindowConfig(&gWindowConfig_81E6CE4); + InitMenuWindow(&gWindowConfig_81E6CE4); + REG_DISPCNT = 0x100; + break; + case 3: + { + u32 savedIme; + + BlendPalettes(-1, 0x10, 0); + SetVBlankCallback(sub_80719F0); + savedIme = REG_IME; + REG_IME = 0; + REG_IE |= 1; + REG_IME = savedIme; + break; + } + case 4: + return TRUE; + } + (*ptr)++; + return FALSE; +} + +void sub_8071B28(void) +{ + if(sub_80719FC(&gMain.state)) + { + CreateTask(Task_8071B64, 0x50); + SetMainCallback2(sub_8071B54); + } +} + +static void sub_8071B54(void) +{ + RunTasks(); + UpdatePaletteFade(); +} + +static void Task_8071B64(u8 taskId) +{ + s16 *val = gTasks[taskId].data; + + if(!gPaletteFade.active) + { + switch(*val) + { + case 0: + MenuDisplayMessageBox(); + MenuPrint(gSystemText_Saving, 2, 15); + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + (*val)++; + break; + case 1: + sub_8047A1C(); + sub_8125E2C(); + (*val)++; + break; + case 2: + if(!sub_8125E6C()) + break; + sub_8047A34(); + (*val)++; + break; + case 3: + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + (*val)++; + break; + case 4: + SetMainCallback2(gMain.field_8); + DestroyTask(taskId); + break; + } + } +} + +void sub_8071C20(void) +{ + PlaySE(SE_SELECT); + MenuZeroFillScreen(); + sub_8064E2C(); + ScriptContext2_Disable(); + sub_8072DEC(); +} + +void AppendToList(u8 *list, u8 *pindex, u32 value) +{ + list[*pindex] = value; + (*pindex)++; +} |