#include #include #include #include #include #include "menus.h" #include "actors.h" #include "audio/external.h" #include "code_80005FD0.h" #include "code_80091750.h" #include "code_800AF9B0.h" #include "code_800B45E0.h" #include "main.h" #include "staff_ghosts.h" #include /** Externs to be put into headers **/ extern s16 D_8015F892; // bss unknown extern u32 D_800DC5AC; // data? from this file or another (main.c?)? extern void rmonPrintf(const char *, ...); // not in a libultra header? /** BSS **/ s32 D_8018EDC0; f32 D_8018EDC4; f32 D_8018EDC8; f32 D_8018EDCC; f32 D_8018EDD0; f32 D_8018EDD4; f32 D_8018EDD8; f32 D_8018EDDC; s32 D_8018EDE0; s8 gCharacterGridSelections[4]; // map from player id to current grid position s8 D_8018EDE8[4]; // bool8; map player id to isCharSelected on CSS s8 D_8018EDEC; s8 gMainMenuSelectionDepth; s8 D_8018EDEE; // grid screen state? s8 gDebugMenuSelection; s8 gControllerPakMenuSelection; s8 D_8018EDF1; u8 gSoundMode; s8 D_8018EDF3; // main menu row id? but it is also the number of players define s8 D_8018EDF4; s8 D_8018EDF5; s8 D_8018EDF6; s8 gTimeTrialDataCourseIndex; s8 gCourseRecordsMenuSelection; s8 D_8018EDF9; s8 gDebugGotoScene; s8 D_8018EDFB; s8 D_8018EDFC; s32 gMenuTimingCounter; s32 gMenuDelayTimer; s8 D_8018EE08; s8 gCupSelection; s8 D_8018EE0A; s8 gCupCourseSelection; s8 D_8018EE0C; struct_8018EE10_entry D_8018EE10[2]; /** Data **/ s32 gMenuSelection = LOGO_INTRO_MENU; s32 D_800E86A4 = 0; s8 gCharacterSelections[4] = { MARIO, LUIGI, YOSHI, TOAD }; // gGameModeRowSelectionForNumPlayers is (D_800E86AC - 1) // gGameModeSubMenuRowSelectionForNumPlayers (D_800E86AC + 1) // the current row selected in column i on main menu s8 D_800E86AC[4] = { 0, 0, 0, 0 }; // For Grand Prix and Versus, this will be the CC mode selected. For Time Trials, it will // be whether 'Begin' or 'Data' is selected. Not used for Battle. // indexed as [column][row] s8 D_800E86B0[4][3] = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; s8 gNextDemoId = 0; s8 gControllerPakSelectedTableRow = 0; s8 D_800E86C4[12] = {0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0}; s8 D_800E86D0[16] = {0}; // this doesn't make a lot of sense... s8 unref_800E86E0[4] = {0, 0, 0, 1}; u32 sVIGammaOffDitherOn = OS_VI_GAMMA_OFF | OS_VI_DITHER_FILTER_ON; /*** Const/rodata Data ***/ // used to set gScreenModeSelection; might be smaller; could be function static data const s8 D_800F2B50[] = {0, 1, 2, 3, 3}; // set to D_8018EDF3, then that sets gPlayerCountSelection1 const s8 D_800F2B58[] = {1, 2, 2, 3, 4}; // Limit for each column in one-two-three-four players selection const s8 D_800F2B60[5][3] = { {1, 2, 1}, {1, 2, 1}, {0, 2, 2}, {0, 2, 0}, {0, 2, 0}, // {0, 3, 1}, // {0, 3, 3}, // {0, 3, 0}, // {0, 3, 0}, }; // is this another union GameModePack? Figure out when decomping. const s32 gGameModeFromNumPlayersAndRowSelection[5][3] = { { 0x03010003, 0x03000300, 0x00030000 }, // Despite this matching, there is no way this line belongs in this array { GRAND_PRIX, TIME_TRIALS, 0x00000000 }, //first column { GRAND_PRIX, VERSUS, BATTLE }, //second { VERSUS, BATTLE, 0x00000000 }, //third { VERSUS, BATTLE, 0x00000000 }, //four }; // map from character grid position id to character id const s8 D_800F2BAC[] = { MARIO, LUIGI, PEACH, TOAD, YOSHI, DK, WARIO, BOWSER, }; const s16 gCupCourseOrder[5][4] = { // mushroom cup { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, // flower cup { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY }, // star cup { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, // special cup { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_RAINBOW_ROAD }, // battle mode { COURSE_BIG_DONUT, COURSE_BLOCK_FORT, COURSE_DOUBLE_DECK, COURSE_SKYSCRAPER }, }; const s8 D_800F2BDC[8] = {1, 0, 0, 0, 0, 1, 3, 4}; // needs to be a union (or array...?) to go into rodata as a const // terrible for endianness... Best guess as to what this is for.. union GameModePack { u8 modes[4]; s32 word; }; const union GameModePack D_800F2BE4 = { {0, 1, 2, 3} }; /**************************/ /** * Includes opening logo and splash screens */ void update_menus(void) { u16 controllerIdx; if (D_800E86A4 == 0) { for (controllerIdx = 0; controllerIdx < 4; controllerIdx++) { // Debug, quick jump through menus using the start button. if ((func_800B4520() == 0) && (gEnableDebugMode) && ((gControllers[controllerIdx].buttonPressed & START_BUTTON) != 0)) { // this is certainly a way to write these... switch (gMenuSelection) { case COURSE_SELECT_MENU: func_800CA330(0x19); // deliberate (?) fallthru case MAIN_MENU: case PLAYER_SELECT_MENU: play_sound2(SOUND_MENU_OK_CLICKED); break; } switch (gMenuSelection) { case CONTROLLER_PAK_MENU: case START_MENU: break; default: func_8009E1C0(); } } osViSetSpecialFeatures(sVIGammaOffDitherOn); switch (gMenuSelection) { case OPTIONS_MENU: options_menu_act(&gControllers[controllerIdx], controllerIdx); break; case DATA_MENU: data_menu_act(&gControllers[controllerIdx], controllerIdx); break; case COURSE_DATA_MENU: course_data_menu_act(&gControllers[controllerIdx], controllerIdx); break; case LOGO_INTRO_MENU: logo_intro_menu_act(&gControllers[controllerIdx], controllerIdx); break; case CONTROLLER_PAK_MENU: if (controllerIdx == PLAYER_ONE) { controller_pak_menu_act(&gControllers[controllerIdx], controllerIdx); } break; case START_MENU_FROM_QUIT: case START_MENU: splash_menu_act(&gControllers[controllerIdx], controllerIdx); break; case MAIN_MENU_FROM_QUIT: case MAIN_MENU: main_menu_act(&gControllers[controllerIdx], controllerIdx); break; case PLAYER_SELECT_MENU_FROM_QUIT: case PLAYER_SELECT_MENU: player_select_menu_act(&gControllers[controllerIdx], controllerIdx); break; case COURSE_SELECT_MENU_FROM_QUIT: case COURSE_SELECT_MENU: course_select_menu_act(&gControllers[controllerIdx], controllerIdx); break; } } } } // navigation of the options menu void options_menu_act(struct Controller *controller, u16 arg1) { u16 btnAndStick; // sp3E struct_8018D9E0_entry *sp38; s32 res; struct_8018EE10_entry *sp30; s32 sp2C; // cursorWasMoved or communicateStoredAction UNUSED u32 pad; btnAndStick = (controller->buttonPressed | controller->stickPressed); if (!gEnableDebugMode && (btnAndStick & START_BUTTON)) { btnAndStick |= A_BUTTON; } if (!func_800B4520()) { sp38 = find_8018D9E0_entry_dupe(0xF0); sp30 = D_8018D9C0; switch (D_8018EDEC) { case 0x15: case 0x16: case 0x17: case 0x18: { sp2C = FALSE; if ((btnAndStick & D_JPAD) && (D_8018EDEC < 0x18)) { D_8018EDEC += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp38->unk8 = 1; sp2C = TRUE; } if ((btnAndStick & U_JPAD) && (D_8018EDEC >= 0x16)) { D_8018EDEC -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp2C = TRUE; sp38->unk8 = -1; } if (sp2C && gSoundMode != sp38->unk4) { gSaveDataSoundMode = gSoundMode; write_save_data_grand_prix_points_and_sound_mode(); update_save_data_backup(); sp38->unk4 = gSoundMode; } if (btnAndStick & B_BUTTON) { func_8009E280(); play_sound2(SOUND_MENU_GO_BACK); if (gSoundMode != sp38->unk4) { gSaveDataSoundMode = gSoundMode; write_save_data_grand_prix_points_and_sound_mode(); update_save_data_backup(); sp38->unk4 = gSoundMode; } return; } if (btnAndStick & A_BUTTON) { switch (D_8018EDEC) { case 0x16: if (gSoundMode < 3) { gSoundMode += 1; } else { gSoundMode = SOUND_STEREO; } if (gSoundMode == SOUND_UNUSED) { gSoundMode = SOUND_MONO; } func_800B44BC(); switch (gSoundMode) { case SOUND_STEREO: play_sound2(SOUND_MENU_STEREO); return; case SOUND_HEADPHONES: play_sound2(SOUND_MENU_HEADPHONES); return; case SOUND_MONO: play_sound2(SOUND_MENU_MONO); return; } break; case 0x17: switch(func_800B5DA4()) { case -1: D_8018EDEC = 0x2B; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; case 0: func_800B6798(); sp2C = func_800B5B94(); switch (sp2C) { case -1: D_8018EDEC = 0x46; sp38->unk4 = 0; play_sound2(SOUND_MENU_SELECT); break; case 0: func_800B6708(); break; case 1: D_8018EDEC = 0x34; play_sound2(SOUND_MENU_FILE_NOT_FOUND); break; case 4: D_8018EDEC = 0x37; play_sound2(SOUND_MENU_FILE_NOT_FOUND); break; case 2: case 3: default: D_8018EDEC = 0x35; play_sound2(SOUND_MENU_FILE_NOT_FOUND); break; } if (sp2C == -1 && !sp30[0].ghostDataSaved && !sp30[1].ghostDataSaved) { D_8018EDEC = 0x2A; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; } if (sp2C == 0) { if (sp30[0].ghostDataSaved) { D_8018EDEC = 0x28; play_sound2(SOUND_MENU_SELECT); } else if (sp30[1].ghostDataSaved) { D_8018EDEC = 0x29; play_sound2(SOUND_MENU_SELECT); } else { D_8018EDEC = 0x2A; play_sound2(SOUND_MENU_FILE_NOT_FOUND); } } // else return? return; case 1: D_8018EDEC = 0x2C; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; case 2: default: D_8018EDEC = 0x2D; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; } case 0x18: { D_8018EDEC = 0x1E; play_sound2(SOUND_MENU_SELECT); return; } case 0x15: { func_8009E280(); play_sound2(SOUND_MENU_GO_BACK); return; } } } // maybe else return?; break; } case 0x1E: case 0x1F: { if ((btnAndStick & D_JPAD) && (D_8018EDEC < 0x1F)) { D_8018EDEC += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp38->unk8 = 1; } if ((btnAndStick & U_JPAD) && (D_8018EDEC >= 0x1F)) { D_8018EDEC -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp38->unk8 = -1; } if (btnAndStick & B_BUTTON) { D_8018EDEC = 0x18; play_sound2(SOUND_MENU_GO_BACK); return; } if (btnAndStick & A_BUTTON) { switch (D_8018EDEC) { case 0x1E: D_8018EDEC = 0x18; play_sound2(SOUND_MENU_GO_BACK); break; case 0x1F: D_8018EDEC = 0x20; func_800B46D0(); D_800DC5AC = 0; play_sound2(SOUND_MENU_EXPLOSION); break; } } break; // or return? } case 0x20: { if (btnAndStick & (A_BUTTON | B_BUTTON | START_BUTTON)) { D_8018EDEC = 0x18; play_sound2(SOUND_MENU_GO_BACK); } break; } case 0x28: case 0x29: { if ((btnAndStick & D_JPAD) && (D_8018EDEC < 0x29) && (sp30[1].ghostDataSaved)) { D_8018EDEC += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp38->unk8 = 1; } if ((btnAndStick & U_JPAD) && (D_8018EDEC >= 0x29) && sp30[0].ghostDataSaved) { D_8018EDEC -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp38->unk8 = -1; } if (btnAndStick & B_BUTTON) { D_8018EDEC = 0x17; play_sound2(SOUND_MENU_GO_BACK); return; } if (btnAndStick & A_BUTTON) { sp38->unk20 = D_8018EDEC - 0x28; if (sp30[sp38->unk20].courseIndex == D_8018EE10[1].courseIndex && D_8018EE10[1].ghostDataSaved) { D_8018EDEC = 0x33; } else { D_8018EDEC = 0x32; } play_sound2(SOUND_MENU_SELECT); } break; } case 0x32: case 0x33: { // bit of a fake match, but if it works it works? if ((sp30[sp38->unk20].courseIndex != ((0, (D_8018EE10 + (D_8018EDEC - 0x32))->courseIndex))) || ((D_8018EE10 + (D_8018EDEC - 0x32))->ghostDataSaved == 0)) { if ((btnAndStick & D_JPAD) && (D_8018EDEC < 0x33)) { D_8018EDEC += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp38->unk8 = 1; } if ((btnAndStick & U_JPAD) && (D_8018EDEC >= 0x33)) { D_8018EDEC -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp38->unk8 = -1; } } if (btnAndStick & B_BUTTON) { D_8018EDEC = sp38->unk20 + 0x28; play_sound2(SOUND_MENU_GO_BACK); } else if (btnAndStick & A_BUTTON) { sp38->unk1C = D_8018EDEC - 0x32; if (D_8018EE10[(sp38->unk1C)].ghostDataSaved) { D_8018EDEC = 0x38; } else { D_8018EDEC = 0x3A; sp38->unk4 = 0; } play_sound2(SOUND_MENU_SELECT); } break; } case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x34: case 0x35: case 0x37: case 0x3C: case 0x41: case 0x42: { if (btnAndStick & (A_BUTTON | B_BUTTON | START_BUTTON)) { D_8018EDEC = 0x17; play_sound2(SOUND_MENU_GO_BACK); } break; } case 0x38: case 0x39: { if ((btnAndStick & R_JPAD) && D_8018EDEC < 0x39) { D_8018EDEC += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp38->unk8 = 1; } if ((btnAndStick & L_JPAD) && D_8018EDEC >= 0x39) { D_8018EDEC -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->unk24 < 4.2) { sp38->unk24 += 4.0; } sp38->unk8 = -1; } if (btnAndStick & B_BUTTON) { D_8018EDEC = sp38->unk1C + 0x32; play_sound2(SOUND_MENU_GO_BACK); return; } if (btnAndStick & A_BUTTON) { if (D_8018EDEC == 0x38) { D_8018EDEC = 0x17; play_sound2(SOUND_MENU_GO_BACK); } else { D_8018EDEC = 0x3A; play_sound2(SOUND_MENU_SELECT); sp38->unk4 = 0; } } // return? break; } case 0x3A: { if (arg1 == 0) { sp38->unk4 += 1; } if (sp38->unk4 >= 3) { D_8018EDEC = 0x3B; } break; } case 0x3B: { res = func_800B5DA4(); if (res == 0) { res = func_800B65F4(sp38->unk20, sp38->unk1C); } if (res != 0) { D_8018EDEC = 0x42; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; } res = osPfsFindFile(&D_8018E868, D_800E86F0, D_800E86F4, (u8 *)D_800F2E64, (u8 *)D_800F2E74, &D_8018EB84); if (res == 0) { res = func_800B6178(sp38->unk1C); } if (res != 0) { D_8018EDEC = 0x41; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; } D_8018EDEC = 0x3C; D_8018EE10[sp38->unk1C].courseIndex = (sp30 + sp38->unk20)->courseIndex; func_800B6088(sp38->unk1C); break; } case 0x46: { if (arg1 == 0) { sp38->unk4 += 1; } if (sp38->unk4 >= 3) { D_8018EDEC = 0x47; } break; } case 0x47: { if (func_800B6A68()) { D_8018EDEC = 0x36; play_sound2(SOUND_MENU_FILE_NOT_FOUND); } else if (sp30[0].ghostDataSaved) { D_8018EDEC = 0x28; } else { D_8018EDEC = 0x29; } break; } default: break; } } } // Handle navigating the data menu interface void data_menu_act(struct Controller *controller, UNUSED u16 arg1) { u16 buttonAndStickPress = (controller->buttonPressed | controller->stickPressed); // Make pressing Start have the same effect as pressing A if ((gEnableDebugMode == 0) && ((buttonAndStickPress & 0x1000) != 0)) { buttonAndStickPress |= 0x8000; } if (func_800B4520() == 0) { if (D_8018EDEC == 1) { // If DPad/Stick down pressed, move selection down if not already in bottom row if ((buttonAndStickPress & 0x400) != 0) { if ((gTimeTrialDataCourseIndex % 4) != 3) { ++gTimeTrialDataCourseIndex; play_sound2(SOUND_MENU_CURSOR_MOVE); } } // If DPad/Stick up pressed, move selection up if not already in top row if ((buttonAndStickPress & 0x800) != 0) { if ((gTimeTrialDataCourseIndex & 3) != 0) { --gTimeTrialDataCourseIndex; play_sound2(SOUND_MENU_CURSOR_MOVE); } } // If DPad/Stick right pressed, move selection right if not already in right-most column if ((buttonAndStickPress & 0x100) != 0) { if ((gTimeTrialDataCourseIndex / 4) != 3) { gTimeTrialDataCourseIndex += 4; play_sound2(SOUND_MENU_CURSOR_MOVE); } } // If DPad/Stick left pressed, move selection left if not already in left-most column if ((buttonAndStickPress & 0x200) != 0) { if ((gTimeTrialDataCourseIndex / 4) != 0) { gTimeTrialDataCourseIndex -= 4; play_sound2(SOUND_MENU_CURSOR_MOVE); } } // If B pressed, go to main menu if ((buttonAndStickPress & 0x4000) != 0) { func_8009E258(); play_sound2(SOUND_MENU_GO_BACK); return; } // If A pressed, go to selected course's records if ((buttonAndStickPress & 0x8000) != 0) { gCourseRecordsMenuSelection = 0; func_8009E1C0(); play_sound2(SOUND_MENU_OK_CLICKED); } } // If D_8018EDEC != 1 and A pressed, go to main menu // (Will D_8018EDEC ever not equal 1 when entering the data menu?) else if ((buttonAndStickPress & 0x8000) != 0) { func_8009E258(); play_sound2(SOUND_MENU_OK_CLICKED); } } } void course_data_menu_act(struct Controller *controller, UNUSED u16 arg1) { u16 btnAndStick; // sp2E struct_8018D9E0_entry *sp28; CourseTimeTrialRecords *sp24; s32 res; btnAndStick = (controller->buttonPressed | controller->stickPressed); if (!gEnableDebugMode && (btnAndStick & START_BUTTON)) { btnAndStick |= A_BUTTON; } if (!func_800B4520()) { switch(D_8018EDEC) { case 0x0B: { if ((btnAndStick & L_JPAD) && (gTimeTrialDataCourseIndex > 0)) { gTimeTrialDataCourseIndex -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); } if ((btnAndStick & R_JPAD) && (gTimeTrialDataCourseIndex < 15)) { gTimeTrialDataCourseIndex += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); } sp28 = find_8018D9E0_entry_dupe(0xE8); sp24 = &D_8018EB90.allCourseTimeTrialRecords .cupRecords[gTimeTrialDataCourseIndex / 4] .courseRecords[gTimeTrialDataCourseIndex % 4]; if (gCourseRecordsMenuSelection == 2 && func_800B639C(gTimeTrialDataCourseIndex) < 0) { gCourseRecordsMenuSelection -= 1; } if (gCourseRecordsMenuSelection == 1 && sp24->unknownBytes[0] == 0) { gCourseRecordsMenuSelection -= 1; } if ((btnAndStick & U_JPAD) && (gCourseRecordsMenuSelection > 0)) { gCourseRecordsMenuSelection -= 1; if (gCourseRecordsMenuSelection == 1 && sp24->unknownBytes[0] == 0) { gCourseRecordsMenuSelection -= 1; } play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp28->unk24 < 4.2) { sp28->unk24 += 4.0; } sp28->unk8 = -1; } if ((btnAndStick & D_JPAD) && (gCourseRecordsMenuSelection < 2)) { gCourseRecordsMenuSelection += 1; if (gCourseRecordsMenuSelection == 1 && sp24->unknownBytes[0] == 0) { gCourseRecordsMenuSelection += 1; } if (gCourseRecordsMenuSelection == 2 && func_800B639C(gTimeTrialDataCourseIndex) < 0) { if (sp24->unknownBytes[0] == 0) { gCourseRecordsMenuSelection = 0; } else { gCourseRecordsMenuSelection = 1; } } else { play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp28->unk24 < 4.2) { sp28->unk24 += 4.0; } sp28->unk8 = 1; } } if (btnAndStick & B_BUTTON) { func_8009E208(); play_sound2(SOUND_MENU_GO_BACK); } else if (btnAndStick & A_BUTTON) { if (sp28->unk24 < 4.2) { sp28->unk24 += 4.0; } if (gCourseRecordsMenuSelection == 0) { func_8009E208(); play_sound2(SOUND_MENU_GO_BACK); } else { D_8018EDEC = 0x0C; D_8018EDF9 = 0; play_sound2(SOUND_MENU_SELECT); } } break; } case 0x0C: { sp28 = find_8018D9E0_entry_dupe(0xE9); if ((btnAndStick & U_JPAD) && (D_8018EDF9 > 0)) { D_8018EDF9 -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp28->unk24 < 4.2) { sp28->unk24 += 4.0; } sp28->unk8 = -1; } if ((btnAndStick & D_JPAD) && (D_8018EDF9 <= 0)) { D_8018EDF9 += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp28->unk24 < 4.2) { sp28->unk24 += 4.0; } sp28->unk8 = 1; } if (btnAndStick & B_BUTTON) { D_8018EDEC = 0xB; play_sound2(SOUND_MENU_GO_BACK); } else if (btnAndStick & A_BUTTON) { if (D_8018EDF9 != 0) { res = 0; switch (gCourseRecordsMenuSelection) { case 1: { func_800B4728(gTimeTrialDataCourseIndex); func_800B559C(gTimeTrialDataCourseIndex); play_sound2(SOUND_MENU_EXPLOSION); res = -1; break; } case 2: { res = func_800B639C(gTimeTrialDataCourseIndex); if (res >= 0) { if (func_800B69BC(res) != 0){ D_8018EDEC = 0x0D; play_sound2(SOUND_MENU_FILE_NOT_FOUND); } else { play_sound2(SOUND_MENU_EXPLOSION); D_8018EDEC = 0x0B; } } break; } } if (!(res + 1)) { D_8018EDEC = 0xB; } } else { play_sound2(SOUND_MENU_GO_BACK); D_8018EDEC = 0xB; } } break; } case 0x0D: { if (btnAndStick & (A_BUTTON | B_BUTTON | START_BUTTON)) { D_8018EDEC = 0xB; } break; } } } } /** * On input skip logo screen **/ void logo_intro_menu_act(struct Controller *arg0, UNUSED u16 arg1) { u16 anyInput = arg0->buttonPressed | arg0->stickPressed; if ((func_800B4520() == 0) && (anyInput)) { // Audio related func_800CA388(0x3C); func_8009E1E4(); } } void controller_pak_menu_act(struct Controller* controller, UNUSED u16 arg1) { u16 buttonAndStickPress; OSPfsState* osPfsState; s32 selectedTableRow; UNUSED s8 pad; buttonAndStickPress = controller->buttonPressed | controller->stickPressed; if (func_800B4520() == 0) { switch (gControllerPakMenuSelection) { case CONTROLLER_PAK_MENU_SELECT_RECORD: if ((buttonAndStickPress & 0x9000) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_TABLE_GAME_DATA; play_sound2(SOUND_MENU_SELECT); return; } if ((buttonAndStickPress & 0x300) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_END; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } break; case CONTROLLER_PAK_MENU_END: if ((buttonAndStickPress & 0x9000) != 0) { play_sound2(SOUND_MENU_SELECT); func_8009E1C0(); D_800E86F8 = 0; return; } if ((buttonAndStickPress & 0x300) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_SELECT_RECORD; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } break; case CONTROLLER_PAK_MENU_TABLE_GAME_DATA: if ((buttonAndStickPress & 0x9000) != 0) { selectedTableRow = D_800E86C4[gControllerPakSelectedTableRow + 2] - 1; if (D_8018EB38[selectedTableRow] == 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_QUIT; play_sound2(SOUND_MENU_SELECT); return; } } else if ((buttonAndStickPress & 0x4000) != 0) { if (D_800E86D0[0] == 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_SELECT_RECORD; play_sound2(SOUND_MENU_GO_BACK); return; } } else if ((buttonAndStickPress & 0x800) != 0) { if (D_800E86D0[0] == 0) { --gControllerPakSelectedTableRow; if (gControllerPakSelectedTableRow < 0) { gControllerPakSelectedTableRow = 0; if (D_800E86C4[gControllerPakSelectedTableRow + 2] != 1) { D_800E86D0[0] = 2; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } } else { play_sound2(SOUND_MENU_CURSOR_MOVE); return; } } } else if (((buttonAndStickPress & 0x400) != 0) && (D_800E86D0[0] == 0)) { ++gControllerPakSelectedTableRow; if (gControllerPakSelectedTableRow >= CONTROLLER_PAK_MENU_TABLE_GAME_DATA) { gControllerPakSelectedTableRow = CONTROLLER_PAK_MENU_QUIT; if (D_800E86C4[gControllerPakSelectedTableRow + 2] != 0x10) { D_800E86D0[0] = 1; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } } else { play_sound2(SOUND_MENU_CURSOR_MOVE); return; } } break; case CONTROLLER_PAK_MENU_QUIT: if ((buttonAndStickPress & 0xD000) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_TABLE_GAME_DATA; play_sound2(SOUND_MENU_GO_BACK); return; } if ((buttonAndStickPress & 0x300) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_ERASE; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } break; case CONTROLLER_PAK_MENU_ERASE: if ((buttonAndStickPress & 0x9000) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_GO_TO_ERASING; play_sound2(SOUND_MENU_SELECT); return; } if ((buttonAndStickPress & 0x4000) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_TABLE_GAME_DATA; play_sound2(SOUND_MENU_GO_BACK); return; } if ((buttonAndStickPress & 0x300) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_QUIT; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } break; case CONTROLLER_PAK_MENU_GO_TO_ERASING: gControllerPakMenuSelection = CONTROLLER_PAK_MENU_ERASING; return; case CONTROLLER_PAK_MENU_ERASING: selectedTableRow = D_800E86C4[gControllerPakSelectedTableRow + 2] - 1; osPfsState = &D_8018E938[selectedTableRow]; switch (osPfsDeleteFile(&D_8018E868, osPfsState->company_code, osPfsState->game_code, (u8 *)&osPfsState->game_name, (u8 *)&osPfsState->ext_name)) { default: gControllerPakMenuSelection = CONTROLLER_PAK_MENU_ERASE_ERROR_NOT_ERASED; return; case 0: D_8018EB38[selectedTableRow] = -1; gControllerPakNumPagesFree += (((osPfsState->file_size + 0xFF) >> 8) & 0xFF); gControllerPakMenuSelection = CONTROLLER_PAK_MENU_TABLE_GAME_DATA; return; case PFS_ERR_NOPACK: gControllerPakMenuSelection = CONTROLLER_PAK_MENU_ERASE_ERROR_NO_PAK; return; case PFS_ERR_NEW_PACK: /* switch 1 */ gControllerPakMenuSelection = CONTROLLER_PAK_MENU_ERASE_ERROR_PAK_CHANGED; return; } break; case CONTROLLER_PAK_MENU_ERASE_ERROR_NOT_ERASED: case CONTROLLER_PAK_MENU_ERASE_ERROR_NO_PAK: case CONTROLLER_PAK_MENU_ERASE_ERROR_PAK_CHANGED: if ((buttonAndStickPress & 0x9000) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_TABLE_GAME_DATA; } break; } } } void splash_menu_act(struct Controller *controller, u16 arg1) { u16 btnAndStick; u16 i; s32 sp28; sp28 = TRUE; btnAndStick = controller->buttonPressed | controller->stickPressed; if (func_800B4520() == 0) { if (arg1 == 0) { gMenuDelayTimer += 1; } switch (gDebugMenuSelection) { case DEBUG_MENU_DISABLED: { sp28 = FALSE; if ((gMenuDelayTimer >= 0x2E) && (btnAndStick & (A_BUTTON | START_BUTTON))) { func_8009E1C0(); func_800CA330(0x19); play_sound2(SOUND_INTRO_ENTER_MENU); } else { break; } break; } case DEBUG_MENU_DEBUG_MODE: { if (btnAndStick & (R_JPAD | L_JPAD)) { play_sound2(SOUND_MENU_CURSOR_MOVE); if (gEnableDebugMode) { gEnableDebugMode = DEBUG_MODE; } else { gEnableDebugMode = TRUE; } } if (btnAndStick & D_JPAD) { play_sound2(SOUND_MENU_CURSOR_MOVE); gDebugMenuSelection = DEBUG_MENU_COURSE; } break; } case DEBUG_MENU_COURSE: { if (btnAndStick & R_JPAD) { play_sound2(SOUND_MENU_CURSOR_MOVE); if (gCurrentCourseId < 0x13) { gCurrentCourseId += 1; } else { gCurrentCourseId = 0; } } if (btnAndStick & L_JPAD) { play_sound2(SOUND_MENU_CURSOR_MOVE); if (gCurrentCourseId > 0) { gCurrentCourseId -= 1; } else { gCurrentCourseId = 0x13; } } if (btnAndStick & U_JPAD) { play_sound2(SOUND_MENU_CURSOR_MOVE); gDebugMenuSelection = DEBUG_MENU_DEBUG_MODE; } if (btnAndStick & D_JPAD) { play_sound2(SOUND_MENU_CURSOR_MOVE); gDebugMenuSelection = DEBUG_MENU_SCREEN_MODE; } break; } case DEBUG_MENU_SCREEN_MODE: { if ((btnAndStick & R_JPAD) && (D_8018EDF1 < 4)) { D_8018EDF1 += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); gScreenModeSelection = D_800F2B50[D_8018EDF1]; } if ((btnAndStick & L_JPAD) && (D_8018EDF1 > 0)) { D_8018EDF1 -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); gScreenModeSelection = D_800F2B50[D_8018EDF1]; } if (btnAndStick & U_JPAD) { gDebugMenuSelection = DEBUG_MENU_COURSE; play_sound2(SOUND_MENU_CURSOR_MOVE); } if (btnAndStick & D_JPAD) { gDebugMenuSelection = DEBUG_MENU_PLAYER; play_sound2(SOUND_MENU_CURSOR_MOVE); } break; } case DEBUG_MENU_PLAYER: { if ((btnAndStick & R_JPAD) && (*gCharacterSelections < 7)) { gCharacterSelections[0] += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); } if ((btnAndStick & L_JPAD) && (gCharacterSelections[0] > 0)) { gCharacterSelections[0] -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); } if (btnAndStick & U_JPAD) { gDebugMenuSelection = DEBUG_MENU_SCREEN_MODE; play_sound2(SOUND_MENU_CURSOR_MOVE); } if (btnAndStick & D_JPAD) { gDebugMenuSelection = DEBUG_MENU_SOUND_MODE; play_sound2(SOUND_MENU_CURSOR_MOVE); } break; } case DEBUG_MENU_SOUND_MODE: { if ((btnAndStick & R_JPAD) && (gSoundMode < 3)) { gSoundMode += 1; if (gSoundMode == SOUND_UNUSED) { gSoundMode = SOUND_MONO; } play_sound2(SOUND_MENU_CURSOR_MOVE); func_800B44BC(); gSaveDataSoundMode = gSoundMode; write_save_data_grand_prix_points_and_sound_mode(); update_save_data_backup(); } if ((btnAndStick & L_JPAD) && (gSoundMode > 0)) { gSoundMode -= 1; if (gSoundMode == SOUND_UNUSED) { gSoundMode = SOUND_HEADPHONES; } play_sound2(SOUND_MENU_CURSOR_MOVE); func_800B44BC(); gSaveDataSoundMode = gSoundMode; write_save_data_grand_prix_points_and_sound_mode(); } if (btnAndStick & U_JPAD) { gDebugMenuSelection = DEBUG_MENU_PLAYER; play_sound2(SOUND_MENU_CURSOR_MOVE); } if (btnAndStick & D_JPAD) { gDebugMenuSelection = DEBUG_MENU_GIVE_ALL_GOLD_CUP; play_sound2(SOUND_MENU_CURSOR_MOVE); } break; } case DEBUG_MENU_GIVE_ALL_GOLD_CUP: { if (btnAndStick & U_JPAD) { gDebugMenuSelection = DEBUG_MENU_SOUND_MODE; play_sound2(SOUND_MENU_CURSOR_MOVE); } if (btnAndStick & B_BUTTON) { for (i = 0; i < 16; i++) { func_800B5404(0, i); } play_sound2(SOUND_MENU_SELECT); break; } else if (btnAndStick & CONT_L) { reset_save_data_grand_prix_points_and_sound_mode(); for (i = 0; i < 16; i++) { func_800B5404(i / 4, i); } play_sound2(SOUND_MENU_SELECT); break; } else if (btnAndStick & L_JPAD) { reset_save_data_grand_prix_points_and_sound_mode(); for (i = 0; i < 16; i++) { if (i % 4 == 2) { func_800B5404(0, i); } else { func_800B5404(i / 4, i); } } play_sound2(SOUND_MENU_SELECT); } else { break; } break; } default: break; } gPlayerCountSelection1 = D_8018EDF3 = D_800F2B58[D_8018EDF1]; if (sp28) { if (btnAndStick & (A_BUTTON | START_BUTTON)) { func_8009E1C0(); func_800CA330(0x19); gDebugMenuSelection = DEBUG_MENU_EXITED; if (controller->button & CONT_L) { D_800DC51C = 1; } else { D_800DC51C = 0; } if (controller->button & Z_TRIG) { if (btnAndStick & A_BUTTON) { gDebugGotoScene = DEBUG_GOTO_ENDING_SEQUENCE; } else { gDebugGotoScene = DEBUG_GOTO_CREDITS_SEQUENCE_CC_EXTRA; } } play_sound2(SOUND_MENU_OK_CLICKED); } else if ((btnAndStick & B_BUTTON) && (controller->button & Z_TRIG)) { func_8009E1C0(); func_800CA330(0x19); gDebugMenuSelection = DEBUG_MENU_EXITED; gDebugGotoScene = DEBUG_GOTO_CREDITS_SEQUENCE_CC_50; play_sound2(SOUND_MENU_OK_CLICKED); } else if (btnAndStick & CONT_R) { gDebugMenuSelection = DEBUG_MENU_DISABLED; play_sound2(SOUND_MENU_SELECT); } } } } void func_800B28C8(void) { // For Grand Prix and Versus, this will be the CC mode selected. For Time Trials, it will // be whether 'Begin' or 'Data' is selected. Not used for Battle. s8 temp_v0 = D_800E86B0[D_8018EDF3 - 1][D_800E86AC[D_8018EDF3 - 1]]; // Determine which game mode was selected based on the number of players and the row selected on the main menu switch (gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]) { case GRAND_PRIX: gCCSelection = temp_v0; gPlaceItemBoxes = 1; gIsMirrorMode = (temp_v0 == CC_EXTRA) ? 1 : 0; break; case VERSUS: gCCSelection = temp_v0; gPlaceItemBoxes = 1; gIsMirrorMode = (temp_v0 == CC_EXTRA) ? 1 : 0; break; case BATTLE: gPlaceItemBoxes = 1; gIsMirrorMode = 0; break; case TIME_TRIALS: gCCSelection = CC_100; gIsMirrorMode = 0; gPlaceItemBoxes = 0; if ((temp_v0 && temp_v0) && temp_v0) { } break; } } #ifdef NON_MATCHING // nonmatching: regalloc; arg1 is not AND-ed back into $a1, reg chaos follows void main_menu_act(struct Controller *controller, u16 arg1) { u16 btnAndStick; // sp2E s32 sp28; s32 sp24; s32 newMode; // temp_v1_2? btnAndStick = controller->buttonPressed | controller->stickPressed; if (!gEnableDebugMode && (btnAndStick & START_BUTTON)) { btnAndStick |= A_BUTTON; } if (!func_800B4520()) { switch (gMainMenuSelectionDepth) { case BLANK_MAIN_MENU: { newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; break; } case PLAYER_NUM_SELECTION: { if ((btnAndStick & R_JPAD) && D_8018EDF3 < 4) { D_8018EDF3 += 1; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } if ((btnAndStick & L_JPAD) && D_8018EDF3 >= 2) { D_8018EDF3 -= 1; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } // L800B2B38 gPlayerCountSelection1 = D_8018EDF3; switch (gPlayerCountSelection1){ case 1: gScreenModeSelection = SCREEN_MODE_1P; break; case 2: gScreenModeSelection = SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL; break; case 3: case 4: gScreenModeSelection = SCREEN_MODE_3P_4P_SPLITSCREEN; break; } // L800B2B94 if (btnAndStick & B_BUTTON) { func_8009E0F0(0x14); func_800CA330(0x19); D_8018EDE0 = 1; play_sound2(SOUND_MENU_GO_BACK); newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else if (btnAndStick & A_BUTTON) { // L800B2C00 gMainMenuSelectionDepth = GAME_MODE_SELECTION; func_800B44AC(); play_sound2(SOUND_MENU_SELECT); newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else if (btnAndStick & CONT_L) { // L800B2C58 gMainMenuSelectionDepth = OPTIONS_SELECTION; func_8009E280(); play_sound2(SOUND_MENU_OPTION); newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else if (btnAndStick & CONT_R) { gMainMenuSelectionDepth = DATA_SELECTION; func_8009E258(); play_sound2(SOUND_MENU_DATA); newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else { newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } break; } case GAME_MODE_SELECTION: { if (btnAndStick & D_JPAD) { if (D_800E86AC[D_8018EDF3 - 1] < D_800F2B58[D_8018EDF3 + 7]) { D_800E86AC[D_8018EDF3 - 1] += 1; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } } // L800B2D94 if (btnAndStick & U_JPAD) { if (D_800E86AC[D_8018EDF3 - 1] > 0) { D_800E86AC[D_8018EDF3 - 1] -= 1; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } } // L800B2DE0 if (btnAndStick & B_BUTTON) { gMainMenuSelectionDepth = PLAYER_NUM_SELECTION; func_800B44AC(); play_sound2(SOUND_MENU_GO_BACK); newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else if (btnAndStick & A_BUTTON) { // L800B2E3C switch(gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]) { case 0: gMainMenuSelectionDepth = GAME_MODE_CC_OR_TIME_TRIALS_OPTIONS_SELECTION; play_sound2(SOUND_MENU_GP); break; case 2: gMainMenuSelectionDepth = GAME_MODE_CC_OR_TIME_TRIALS_OPTIONS_SELECTION; play_sound2(SOUND_MENU_VERSUS); break; case 1: gMainMenuSelectionDepth = GAME_MODE_CC_OR_TIME_TRIALS_OPTIONS_SELECTION; play_sound2(SOUND_MENU_TIME_TRIALS); break; case 3: gMainMenuSelectionDepth = CONFIRM_OK_SELECTION; play_sound2(SOUND_MENU_BATTLE); break; default: gMainMenuSelectionDepth = CONFIRM_OK_SELECTION; break; } // L800B2F04 func_800B44AC(); gMenuTimingCounter = 0; newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else { newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } break; } case GAME_MODE_CC_OR_TIME_TRIALS_OPTIONS_SELECTION: case TIME_TRIALS_DATA_SELECTION_FROM_BACK_OUT: { if (1); if ((arg1 == 0) && (++gMenuTimingCounter == 100 || gMenuTimingCounter % 300 == 0)) { // L800B2FAC if (gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]] == 0 || gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]] == 2) { play_sound2(SOUND_MENU_SELECT_LEVEL); } } // L800B3000 sp28 = D_800E86B0[D_8018EDF3 - 1][D_800E86AC[D_8018EDF3 - 1]]; if ((btnAndStick & U_JPAD) && (sp28 > 0)) { D_800E86B0[D_8018EDF3 - 1][D_800E86AC[D_8018EDF3 - 1]] -= 1; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } // L800B3068 if (btnAndStick & D_JPAD) { sp24 = FALSE; if (func_800B555C()) { if (sp28 < D_800F2B60[D_8018EDF3 + 4][D_800E86AC[D_8018EDF3 - 1] + 1]) { sp24 = TRUE; } } else { // L800B30D4 if (sp28 < D_800F2B60[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1] + 1]) { sp24 = TRUE; } } // L800B3110 if (sp24) { D_800E86B0[D_8018EDF3 - 1][D_8018EDF3] += 1; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } } // L800B3150 sp28 = D_800E86B0[D_8018EDF3 - 1][D_800E86AC[D_8018EDF3 - 1]]; if (btnAndStick & B_BUTTON) { gMainMenuSelectionDepth = GAME_MODE_SELECTION; func_800B44AC(); play_sound2(SOUND_MENU_GO_BACK); newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else if (btnAndStick & A_BUTTON) { // L800B31DC func_800B44AC(); if (D_8018EDF3 == 1 && D_800E86AC[D_8018EDF3 - 1] == 1 && sp28 == 1) { func_8009E258(); play_sound2(SOUND_MENU_DATA); } else { gMainMenuSelectionDepth = CONFIRM_OK_SELECTION; play_sound2(SOUND_MENU_SELECT); gMenuTimingCounter = 0; } newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else { // L800B3294 newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } break; } case CONFIRM_OK_SELECTION: case CONFIRM_OK_SELECTION_FROM_BACK_OUT: { if ((arg1 == 0) && (++gMenuTimingCounter == 60 || gMenuTimingCounter % 300 == 0)) { play_sound2(SOUND_MENU_OK); } // L800B330C if (btnAndStick & B_BUTTON) { switch (gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]) { case 0: case 1: case 2: gMainMenuSelectionDepth = GAME_MODE_CC_OR_TIME_TRIALS_OPTIONS_SELECTION; break; case 3: default: gMainMenuSelectionDepth = GAME_MODE_SELECTION; break; } // L800B3384 func_800B44AC(); play_sound2(SOUND_MENU_GO_BACK); gMenuTimingCounter = 0; newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else if (btnAndStick & A_BUTTON) { // L800B33D8 func_8009E1C0(); play_sound2(SOUND_MENU_OK_CLICKED); func_800B28C8(); newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } else { newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; } break; } case OPTIONS_SELECTION: case DATA_SELECTION: { newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; break; } default: { newMode = gGameModeFromNumPlayersAndRowSelection[D_8018EDF3][D_800E86AC[D_8018EDF3 - 1]]; break; } } gModeSelection = newMode; } } #else GLOBAL_ASM("asm/non_matchings/menus/main_menu_act.s") #endif // check if there is no currently selected and/or hovered character at grid position `gridId` s32 is_character_spot_free(s32 gridId) { s32 i; for (i = 0; i < ARRAY_COUNT(gCharacterGridSelections); i++) { if (gridId == gCharacterGridSelections[i]) { return FALSE; } } return TRUE; } #ifdef NON_MATCHING // grid positions are from right to left, then top to bottom // nonmatching: the gCharacterGridSelections pointer is not promoted to $s0 void player_select_menu_act(struct Controller *controller, u16 arg1) { u16 btnAndStick; // sp36 s8 selected; s8 i; btnAndStick = (controller->buttonPressed) | (controller->stickPressed); if (!gEnableDebugMode && btnAndStick & START_BUTTON) { btnAndStick |= A_BUTTON; } if (!func_800B4520()) { switch (D_8018EDEE) { case 1: { if (gCharacterGridSelections[arg1] == 0) { if (btnAndStick & B_BUTTON) { func_8009E208(); play_sound2(SOUND_MENU_GO_BACK); } return; } // L800B3630 if (btnAndStick & B_BUTTON) { if (D_8018EDE8[arg1]) { D_8018EDE8[arg1] = FALSE; play_sound2(SOUND_MENU_GO_BACK); } else { func_8009E208(); play_sound2(SOUND_MENU_GO_BACK); } } // L800B3684 if ((btnAndStick & A_BUTTON) && !D_8018EDE8[arg1]) { D_8018EDE8[arg1] = TRUE; func_800C90F4( arg1, (((uintptr_t)D_800F2BAC[gCharacterGridSelections[arg1] - 1]) << 4) + 0x2900800EU ); } // L800B36F4 selected = FALSE; for (i = 0; i < ARRAY_COUNT(gCharacterGridSelections); i++) { if (gCharacterGridSelections[i] && D_8018EDE8[i]) { selected = TRUE; break; } } // L800B3738 if (!selected) { D_8018EDEE = 2; func_800B44AC(); gMenuTimingCounter = 0; } // L800B3768 if (D_8018EDE8[arg1]) { if ((btnAndStick & R_JPAD) && (btnAndStick & D_JPAD)) { if (gCharacterGridSelections[arg1] == 1 || gCharacterGridSelections[arg1] == 2 || gCharacterGridSelections[arg1] == 3) { // L800B37B0 if (is_character_spot_free(gCharacterGridSelections[arg1] + 5)) { gCharacterGridSelections[arg1] += 5; play_sound2(SOUND_MENU_CURSOR_MOVE); } } return; } // L800B37E4 if ((btnAndStick & L_JPAD) && (btnAndStick & D_JPAD)) { if (gCharacterGridSelections[arg1] == 2 || gCharacterGridSelections[arg1] == 3 || gCharacterGridSelections[arg1] == 4) { if (is_character_spot_free(gCharacterGridSelections[arg1] + 3)) { gCharacterGridSelections[arg1] += 3; play_sound2(SOUND_MENU_CURSOR_MOVE); } } return; } // L800B3844 if ((btnAndStick & R_JPAD) && (btnAndStick & U_JPAD)) { if (gCharacterGridSelections[arg1] == 5 || gCharacterGridSelections[arg1] == 6 || gCharacterGridSelections[arg1] == 7) { if (is_character_spot_free(gCharacterGridSelections[arg1] - 3)) { gCharacterGridSelections[arg1] -= 3; play_sound2(SOUND_MENU_CURSOR_MOVE); } } return; } // L800B38A0 if ((btnAndStick & L_JPAD) && (btnAndStick & U_JPAD)) { if (gCharacterGridSelections[arg1] == 6 || gCharacterGridSelections[arg1] == 7 || gCharacterGridSelections[arg1] == 8) { if (is_character_spot_free(gCharacterGridSelections[arg1] - 5)) { gCharacterGridSelections[arg1] -= 5; play_sound2(SOUND_MENU_CURSOR_MOVE); } } return; } // L800B38FC if (btnAndStick & R_JPAD) { if (gCharacterGridSelections[arg1] != 4 && gCharacterGridSelections[arg1] != 8) { do { // L800B391C if (is_character_spot_free(gCharacterGridSelections[arg1] + 1)) { gCharacterGridSelections[arg1] += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); break; } gCharacterGridSelections[arg1] += 1; } while (gCharacterGridSelections[arg1] != 5 && gCharacterGridSelections[arg1] != 9 && gCharacterGridSelections[arg1] <= 10); } return; } // L800B3978 if (btnAndStick & L_JPAD) { if (gCharacterGridSelections[arg1] != 1 && gCharacterGridSelections[arg1] != 5) { do { if (is_character_spot_free(gCharacterGridSelections[arg1] - 1)) { gCharacterGridSelections[arg1] -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); break; } gCharacterGridSelections[arg1] -= 1; } while (gCharacterGridSelections[arg1] != 0 && gCharacterGridSelections[arg1] != 4 && gCharacterGridSelections[arg1] >= 0); } return; } // L800B39F4 if ((btnAndStick & U_JPAD) && (gCharacterGridSelections[arg1] >= 5)) { gCharacterGridSelections[arg1] -= 4; } if ((btnAndStick & D_JPAD) && (gCharacterGridSelections[arg1] < 5)) { gCharacterGridSelections[arg1] += 4; } // L800B3A30 if (is_character_spot_free(gCharacterGridSelections[arg1])) { play_sound2(SOUND_MENU_CURSOR_MOVE); } } break; } case 2: case 3: { if (!arg1 && (++gMenuTimingCounter == 60 || gMenuSelection % 300 == 0)) { // L800B3A94 play_sound2(SOUND_MENU_OK); } // L800B3AA4 if (btnAndStick & B_BUTTON) { D_8018EDEE = 1; D_8018EDE8[arg1] = FALSE; play_sound2(SOUND_MENU_GO_BACK); } else if (btnAndStick & A_BUTTON) { func_8009E1C0(); play_sound2(SOUND_MENU_OK_CLICKED); func_8000F124(); } break; } } // L800B3B24 if (gCharacterGridSelections[arg1] != 0) { gCharacterSelections[arg1] = D_800F2BAC[gCharacterGridSelections[arg1] - 1]; } } // L800B3B44 } #else GLOBAL_ASM("asm/non_matchings/menus/player_select_menu_act.s") #endif // Handle navigating the course menu interface void course_select_menu_act(struct Controller *arg0, u16 arg1) { u16 buttonAndStickPress = (arg0->buttonPressed | arg0->stickPressed); if ((!gEnableDebugMode) && ((buttonAndStickPress & 0x1000) != 0)) { buttonAndStickPress |= 0x8000; } if (func_800B4520() == 0) { switch (D_8018EDEC) { case 1: if ((buttonAndStickPress & 0x100) != 0) { if (gCupSelection < SPECIAL_CUP) { D_8018EE0A = gCupSelection; ++gCupSelection; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } } if (((buttonAndStickPress & 0x200) != 0) && (gCupSelection > MUSHROOM_CUP)) { D_8018EE0A = gCupSelection; --gCupSelection; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } D_800DC540 = gCupSelection; gCurrentCourseId = gCupCourseOrder[gCupSelection][gCupCourseSelection]; if ((buttonAndStickPress & 0x4000) != 0) { func_8009E208(); play_sound2(SOUND_MENU_GO_BACK); } else if ((buttonAndStickPress & 0x8000) != 0) { if (gModeSelection != GRAND_PRIX) { D_8018EDEC = 2; play_sound2(SOUND_MENU_SELECT); } else { D_8018EDEC = 3; play_sound2(SOUND_MENU_SELECT); gCurrentCourseId = gCupCourseOrder[gCupSelection][CUP_COURSE_ONE]; gMenuTimingCounter = 0; } func_800B44AC(); } break; case 2: case 4: if (((buttonAndStickPress & 0x400) != 0) && (gCupCourseSelection < CUP_COURSE_FOUR)) { ++gCupCourseSelection; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } if (((buttonAndStickPress & 0x800) != 0) && (gCupCourseSelection > CUP_COURSE_ONE)) { --gCupCourseSelection; func_800B44AC(); play_sound2(SOUND_MENU_CURSOR_MOVE); } gCurrentCourseId = gCupCourseOrder[gCupSelection][gCupCourseSelection]; if ((buttonAndStickPress & 0x4000) != 0) { if (D_8018EDEC == 2) { D_8018EDEC = 1; } else { func_8009E208(); } func_800B44AC(); play_sound2(SOUND_MENU_GO_BACK); return; } if ((buttonAndStickPress & 0x8000) != 0) { D_8018EDEC = 3; play_sound2(SOUND_MENU_SELECT); func_800B44AC(); gMenuTimingCounter = 0; } break; case 3: if ((arg1 == 0) && ((++gMenuTimingCounter == 0x3C) || ((gMenuTimingCounter % 300) == 0))) { play_sound2(SOUND_MENU_OK); } if ((buttonAndStickPress & 0x4000) != 0) { switch(gModeSelection) { case GRAND_PRIX: D_8018EDEC = 1; break; case BATTLE: D_8018EDEC = 4; break; default: D_8018EDEC = 2; break; } func_800B44AC(); play_sound2(SOUND_MENU_GO_BACK); return; } if ((buttonAndStickPress & 0x8000) != 0) { func_8009E1C0(); func_800CA330(0x19); play_sound2(SOUND_MENU_OK_CLICKED); } break; } } } void func_800B3F74(s32 menuSelection) { s32 i; gDebugMenuSelection = DEBUG_MENU_DISABLED; gMenuTimingCounter = 0; gMenuDelayTimer = 0; D_8018EE08 = 0; D_8015F890 = 0; D_8015F892 = 0; gDebugGotoScene = DEBUG_GOTO_RACING; D_8018EDFB = 0; D_8016556E = 0; *D_80162DD4 = 1; D_80162DD8 = 1; D_80162E00 = 0; D_80162DC8 = 1; D_80162DCC = 0; switch (menuSelection) { case 5: D_8018EDEC = 21; break; case 6: D_8018EDEC = 1; break; case 7: D_8018EDEC = 11; break; case 8: func_800CA008(0, 0); break; case 9: { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_SELECT_RECORD; func_800CA008(0, 0); break; } case 0: case 10: { gIsMirrorMode = 0; gEnableDebugMode = DEBUG_MODE; gCupSelection = MUSHROOM_CUP; gCupCourseSelection = 0; gTimeTrialDataCourseIndex = 0; if (D_8018EDF3 <= 0) { D_8018EDF3 = 1; } if (D_8018EDF3 >= 5) { D_8018EDF3 = 4; } D_8018EDF1 = D_800F2BDC[D_8018EDF3 + 3]; func_800CA008(0, 0); func_800C8EAC(1); D_8018EDFC = 0; break; } case 1: case 11: { gEnableDebugMode = DEBUG_MODE; gIsMirrorMode = 0; D_8018EDFC = 0; func_800B5F30(); func_8000F0E0(); if (gGamestate != 0) { func_800CA008(0, 0); func_800CB2C4(); gGamestate = 0; gGamestateNext = 0; func_800C8EAC(2); } switch (D_8018EDE0) { case 0: { gMainMenuSelectionDepth = PLAYER_NUM_SELECTION; func_800C8EAC(2); D_8018EDF3 = 1; if (gScreenModeSelection >= NUM_SCREEN_MODES || gScreenModeSelection < 0) { gScreenModeSelection = SCREEN_MODE_1P; } break; } case 1: { gMainMenuSelectionDepth = CONFIRM_OK_SELECTION_FROM_BACK_OUT; break; } case 3: { // why... switch (gMainMenuSelectionDepth) { default: gMainMenuSelectionDepth = TIME_TRIALS_DATA_SELECTION_FROM_BACK_OUT; break; case OPTIONS_SELECTION: case DATA_SELECTION: gMainMenuSelectionDepth = PLAYER_NUM_SELECTION; break; } break; } case 4: { gMainMenuSelectionDepth = PLAYER_NUM_SELECTION; break; } } break; } case 2: case 12: { switch (D_8018EDE0) { case 0: { D_8018EDEE = 1; if (gGamestate == 0) { for (i = 0; i < 4; i++) { if (i < D_8018EDF3) { gCharacterGridSelections[i] = i + 1; } else { gCharacterGridSelections[i] = 0; } D_8018EDE8[i] = FALSE; gCharacterSelections[i] = i; } play_sound2(SOUND_MENU_SELECT_PLAYER); } else { func_800CA008(0, 0); func_800CB2C4(); gGamestate = 0; gGamestateNext = 0; func_800C8EAC(2); for (i = 0; i < ARRAY_COUNT(D_8018EDE8); i++) { D_8018EDE8[i] = FALSE; } } break; } case 1: { D_8018EDEE = 3; for (i = 0; i < ARRAY_COUNT(D_8018EDE8); i++) { if (D_8018EDF3 > i) { D_8018EDE8[i] = TRUE; } else { D_8018EDE8[i] = FALSE; } } break; } } break; } case 3: case 13: { if (gModeSelection == BATTLE) { gCupSelection = BATTLE_CUP; D_800DC540 = 4; D_8018EDEC = 4; } else { if (gCupSelection == BATTLE_CUP) { gCupSelection = MUSHROOM_CUP; } D_8018EDEC = 1; } if (gGamestate != 0) { func_800CA008(0, 0); func_800CB2C4(); gGamestate = 0; gGamestateNext = 0; func_800C8EAC(2); } play_sound2(SOUND_MENU_SELECT_MAP); D_8018EE0A = 0; if (gModeSelection == GRAND_PRIX) { gCupCourseSelection = 0; } for (i = 0; i < ARRAY_COUNT(gGPPointsByCharacterId); i++) { gGPPointsByCharacterId[i] = 0; } break; } } func_800B44AC(); } void func_800B44AC(void) { D_8018E7A8 = 0x20; } void func_800B44BC(void) { UNUSED u32 pad; union GameModePack pack; pack = D_800F2BE4; if ((gSoundMode == SOUND_STEREO) || (gSoundMode == SOUND_HEADPHONES) || (gSoundMode == SOUND_MONO)) { func_800C3448(pack.modes[gSoundMode] | 0xE0000000); } } // Likely checks that the user is actually in the menus and not racing. s32 func_800B4520(void) { if ((D_8018E7B0 == 2) || (D_8018E7B0 == 3) || (D_8018E7B0 == 4) || (D_8018E7B0 == 7)) { return 1; } return 0; } UNUSED void func_800B4560(s32 arg0, s32 arg1) { struct_8018EE10_entry *pak1 = D_8018EE10; struct_8018EE10_entry *pak2 = D_8018D9C0; rmonPrintf("ghost_kart=%d,", D_80162DE0); rmonPrintf("pak1_ghost_kart=%d,", (pak1 + arg0)->characterId); rmonPrintf("pak2_ghost_kart=%d\n", (pak2 + arg1)->characterId); }