#include #include #include #include #include #include #include "menus.h" #include "main.h" #include "code_800029B0.h" #include "actors.h" #include "audio/external.h" #include "code_800029B0.h" #include "code_80005FD0.h" #include "menu_items.h" #include "code_800AF9B0.h" #include "save.h" #include "staff_ghosts.h" #include "save_data.h" #include #include "spawn_players.h" #include "port/Game.h" /** BSS **/ s32 gIntroModelZEye; f32 gIntroModelScale; // XYZ scale on checkerboard flag, Z scale on intro logo f32 gIntroModelRotX; f32 gIntroModelRotY; f32 gIntroModelRotZ; f32 gIntroModelPosX; f32 gIntroModelPosY; f32 gIntroModelPosZ; s32 gMenuFadeType; s8 gCharacterGridSelections[4]; // Map from each player to current grid position (1-4 top, 5-8 bottom) bool gCharacterGridIsSelected[4]; // Sets true if a character is selected for each player s8 gSubMenuSelection; // Map Select states, Options and Ghost Data text selection s8 gMainMenuSelection; s8 gPlayerSelectMenuSelection; // grid screen state? s8 gDebugMenuSelection; s8 gControllerPakMenuSelection; s8 gScreenModeListIndex; // 0-4 index, selects a screen mode in sScreenModePlayerTable u8 gSoundMode; s8 gPlayerCount; s8 gVersusResultCursorSelection; // 4 options indexed (10-13), gets set when selecting an option s8 gTimeTrialsResultCursorSelection; // 5 options indexed (5-9), gets set when selecting an option (excluding Save Ghost) s8 gBattleResultCursorSelection; // 4 options indexed (10-13), gets set when selecting an option s8 gTimeTrialDataCourseIndex; s8 gCourseRecordsMenuSelection; // Used for selecting an option in course record data s8 gCourseRecordsSubMenuSelection; // Used for erase records and ghosts (Quit - Erase) s8 gDebugGotoScene; bool gGhostPlayerInit; bool gCourseMapInit; s32 gMenuTimingCounter; s32 gMenuDelayTimer; s8 gDemoUseController; // Sets true alongside gDemoMode, controller related s8 gCupSelection; s8 sTempCupSelection; // Same as gCupSelection but it's only set in map select, not referenced s8 gCourseIndexInCup; s8 unref_D_8018EE0C; // Set to 0 but never referenced /** Data **/ s32 gMenuSelection = HARBOUR_MASTERS_MENU; s32 gFadeModeSelection = FADE_MODE_NONE; s8 gCharacterSelections[4] = { MARIO, LUIGI, YOSHI, TOAD }; // The current row selected in the mode column for each player indexed // 0-1 1p / 0-2 2p´/ 0-1 3p / 0-1 4p s8 gGameModeMenuColumn[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 gGameModeSubMenuColumn[4][3] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; s8 gNextDemoId = 0; s8 gControllerPakSelectedTableRow = 0; // 0-4 index, value of the current visible row select // Numbers starting from the second 0 to number 6 get altered // as you move up or down the page table of content (min value is 0, max value is 16 s8 gControllerPakVisibleTableRows[12] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0 }; s8 gControllerPakScrollDirection = CONTROLLER_PAK_SCROLL_DIR_NONE; // 1 is down, 2 is up s8 unref_D_800E86D4[12] = { 0 }; s8 unref_D_800E86E0[4] = { 0, 0, 0, 1 }; u32 sVIGammaOffDitherOn = (OS_VI_GAMMA_OFF | OS_VI_DITHER_FILTER_ON); /** Rodata **/ // Sets the actual screen mode based on values set in sScreenModePlayerCount const s8 sScreenModePlayerTable[] = { SCREEN_MODE_1P, SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL, SCREEN_MODE_2P_SPLITSCREEN_VERTICAL, SCREEN_MODE_3P_4P_SPLITSCREEN, SCREEN_MODE_3P_4P_SPLITSCREEN }; // Sets how many players can load on each screen mode set in sScreenModePlayerTable const s8 sScreenModePlayerCount[] = { 1, 2, 2, 3, 4 }; // Set indexed slots numbers for one-two-three-four mode selection const s8 gPlayerModeSelection[] = { 1, 2, 1, 1 }; // Limit for each index column in one-two-three-four mode selection const s8 sGameModePlayerColumnDefault[][3] = { { 2, 1, 0 }, // 1p (GP options, TT options, ...) { 2, 2, 0 }, // 2p (GP options, VS options, Battle) { 2, 0, 0 }, // 3p (VS options, Battle, ...) { 2, 0, 0 }, // 4p (VS options, Battle, ...) }; // Limit for each index column in one-two-three-four mode selection // for extra mode (mirror mode), hence the extra value (3 instead of 2) const s8 sGameModePlayerColumnExtra[][3] = { { 3, 1, 0 }, // 1p (GP options, TT options, ...) { 3, 3, 0 }, // 2p (GP options, VS options, Battle) { 3, 0, 0 }, // 3p (VS options, Battle, ...) { 3, 0, 0 }, // 4p (VS options, Battle, ...) }; // Modes to select in one-two-three-four mode selection const s32 gGameModePlayerSelection[][3] = { { GRAND_PRIX, TIME_TRIALS, 0x00000000 }, // 1p game modes { GRAND_PRIX, VERSUS, BATTLE }, // 2p game modes { VERSUS, BATTLE, 0x00000000 }, // 3p game modes { VERSUS, BATTLE, 0x00000000 }, // 4p game modes }; // Map from character grid position id to character id // Note: changing order doesn't affect graphics, only the selection const s8 sCharacterGridOrder[] = { 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_KALIMARI_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 unref_800F2BDC[4] = { 1, 0, 0, 0 }; // Uses player count to set gScreenModeListIndex, the latter variable then selects a mode // from sScreenModePlayerTable, note the 2 is not set since that's for vertical 2p screen const s8 sScreenModeIdxFromPlayerMode[4] = { 0, 1, 3, 4 }; const union GameModePack sSoundMenuPack = { { SOUND_STEREO, SOUND_HEADPHONES, SOUND_UNUSED, SOUND_MONO } }; /**************************/ /** * Includes opening logo and splash screens */ void update_menus(void) { u16 controllerIdx; if (gFadeModeSelection == FADE_MODE_NONE) { for (controllerIdx = 0; controllerIdx < 4; controllerIdx++) { // Debug, quick jump through menus using the start button. if ((is_screen_being_faded() == 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 CHARACTER_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 HARBOUR_MASTERS_MENU: logo_intro_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 CHARACTER_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 controllerIdx) { u16 btnAndStick; // sp3E MenuItem* sp38; s32 res; struct_8018EE10_entry* sp30; bool tempVar; // cursorWasMoved or communicateStoredAction UNUSED u32 pad; btnAndStick = (controller->buttonPressed | controller->stickPressed); if (!gEnableDebugMode && (btnAndStick & START_BUTTON)) { btnAndStick |= A_BUTTON; } if (!is_screen_being_faded()) { sp38 = find_menu_items_dupe(0xF0); sp30 = (struct_8018EE10_entry*) gSomeDLBuffer; switch (gSubMenuSelection) { case SUB_MENU_OPTION_RETURN_GAME_SELECT: case SUB_MENU_OPTION_SOUND_MODE: case SUB_MENU_OPTION_COPY_CONTROLLER_PAK: case SUB_MENU_OPTION_ERASE_ALL_DATA: { tempVar = false; if ((btnAndStick & D_JPAD) && (gSubMenuSelection < SUB_MENU_OPTION_MAX)) { gSubMenuSelection += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } sp38->subState = 1; tempVar = true; } if ((btnAndStick & U_JPAD) && (gSubMenuSelection > SUB_MENU_OPTION_MIN)) { gSubMenuSelection -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } tempVar = true; sp38->subState = -1; } if (tempVar && gSoundMode != sp38->state) { gSaveData.main.saveInfo.soundMode = gSoundMode; write_save_data_grand_prix_points_and_sound_mode(); update_save_data_backup(); sp38->state = gSoundMode; } if (btnAndStick & B_BUTTON) { func_8009E280(); play_sound2(SOUND_MENU_GO_BACK); if (gSoundMode != sp38->state) { gSaveData.main.saveInfo.soundMode = gSoundMode; write_save_data_grand_prix_points_and_sound_mode(); update_save_data_backup(); sp38->state = gSoundMode; } return; } if (btnAndStick & A_BUTTON) { switch (gSubMenuSelection) { case SUB_MENU_OPTION_SOUND_MODE: if (gSoundMode < 3) { gSoundMode += 1; } else { gSoundMode = SOUND_STEREO; } if (gSoundMode == SOUND_UNUSED) { gSoundMode = SOUND_MONO; } set_sound_mode(); 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 SUB_MENU_OPTION_COPY_CONTROLLER_PAK: switch (controller_pak_2_status()) { case PFS_INVALID_DATA: gSubMenuSelection = SUB_MENU_COPY_PAK_ERROR_NO_GAME_DATA; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; case PFS_NO_ERROR: func_800B6798(); tempVar = controller_pak_1_status(); switch (tempVar) { case PFS_INVALID_DATA: gSubMenuSelection = SUB_MENU_COPY_PAK_CREATE_GAME_DATA_INIT; sp38->state = 0; play_sound2(SOUND_MENU_SELECT); break; case PFS_NO_ERROR: func_800B6708(); break; case PFS_NO_PAK_INSERTED: gSubMenuSelection = SUB_MENU_COPY_PAK_ERROR_NO_PAK_1P; play_sound2(SOUND_MENU_FILE_NOT_FOUND); break; case PFS_FILE_OVERFLOW: gSubMenuSelection = SUB_MENU_COPY_PAK_ERROR_NO_PAGES_1P; play_sound2(SOUND_MENU_FILE_NOT_FOUND); break; case PFS_PAK_BAD_READ: case PFS_PAK_CORRUPTED: // unreachable, bad reads always returns previous case default: gSubMenuSelection = SUB_MENU_COPY_PAK_ERROR_BAD_READ_1P; play_sound2(SOUND_MENU_FILE_NOT_FOUND); break; } if (tempVar == PFS_INVALID_DATA && !sp30[PLAYER_ONE].ghostDataSaved && !sp30[PLAYER_TWO].ghostDataSaved) { gSubMenuSelection = SUB_MENU_COPY_PAK_ERROR_NO_GHOST_DATA; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; } if (tempVar == PFS_NO_ERROR) { if (sp30[PLAYER_ONE].ghostDataSaved) { gSubMenuSelection = SUB_MENU_COPY_PAK_FROM_GHOST1_1P; play_sound2(SOUND_MENU_SELECT); } else if (sp30[PLAYER_TWO].ghostDataSaved) { gSubMenuSelection = SUB_MENU_COPY_PAK_FROM_GHOST2_1P; play_sound2(SOUND_MENU_SELECT); } else { gSubMenuSelection = SUB_MENU_COPY_PAK_ERROR_NO_GHOST_DATA; play_sound2(SOUND_MENU_FILE_NOT_FOUND); } } // else return? return; case PFS_NO_PAK_INSERTED: gSubMenuSelection = SUB_MENU_COPY_PAK_ERROR_NO_PAK_2P; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; case PFS_PAK_BAD_READ: default: gSubMenuSelection = SUB_MENU_COPY_PAK_ERROR_BAD_READ_2P; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; } case SUB_MENU_OPTION_ERASE_ALL_DATA: { gSubMenuSelection = SUB_MENU_ERASE_QUIT; play_sound2(SOUND_MENU_SELECT); return; } case SUB_MENU_OPTION_RETURN_GAME_SELECT: { func_8009E280(); play_sound2(SOUND_MENU_GO_BACK); return; } } } // maybe else return?; break; } case SUB_MENU_ERASE_QUIT: case SUB_MENU_ERASE_ERASE: { if ((btnAndStick & D_JPAD) && (gSubMenuSelection < SUB_MENU_ERASE_MAX)) { gSubMenuSelection += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } sp38->subState = 1; } if ((btnAndStick & U_JPAD) && (gSubMenuSelection > SUB_MENU_ERASE_MIN)) { gSubMenuSelection -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } sp38->subState = -1; } if (btnAndStick & B_BUTTON) { gSubMenuSelection = SUB_MENU_OPTION_ERASE_ALL_DATA; play_sound2(SOUND_MENU_GO_BACK); return; } if (btnAndStick & A_BUTTON) { switch (gSubMenuSelection) { case SUB_MENU_ERASE_QUIT: gSubMenuSelection = SUB_MENU_OPTION_ERASE_ALL_DATA; play_sound2(SOUND_MENU_GO_BACK); break; case SUB_MENU_ERASE_ERASE: gSubMenuSelection = SUB_MENU_SAVE_DATA_ERASED; func_800B46D0(); D_800DC5AC = 0; play_sound2(SOUND_MENU_EXPLOSION); break; } } break; // or return? } case SUB_MENU_SAVE_DATA_ERASED: { if (btnAndStick & (A_BUTTON | B_BUTTON | START_BUTTON)) { gSubMenuSelection = SUB_MENU_OPTION_ERASE_ALL_DATA; play_sound2(SOUND_MENU_GO_BACK); } break; } case SUB_MENU_COPY_PAK_FROM_GHOST1_1P: case SUB_MENU_COPY_PAK_FROM_GHOST2_1P: { if ((btnAndStick & D_JPAD) && (gSubMenuSelection < SUB_MENU_COPY_PAK_FROM_GHOST_MAX) && (sp30[PLAYER_TWO].ghostDataSaved)) { gSubMenuSelection += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } sp38->subState = 1; } if ((btnAndStick & U_JPAD) && (gSubMenuSelection > SUB_MENU_COPY_PAK_FROM_GHOST_MIN) && sp30[PLAYER_ONE].ghostDataSaved) { gSubMenuSelection -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } sp38->subState = -1; } if (btnAndStick & B_BUTTON) { gSubMenuSelection = SUB_MENU_OPTION_COPY_CONTROLLER_PAK; play_sound2(SOUND_MENU_GO_BACK); return; } if (btnAndStick & A_BUTTON) { sp38->param2 = gSubMenuSelection - SUB_MENU_COPY_PAK_FROM_GHOST_MIN; if (sp30[sp38->param2].courseIndex == D_8018EE10[PLAYER_TWO].courseIndex && D_8018EE10[PLAYER_TWO].ghostDataSaved) { gSubMenuSelection = SUB_MENU_COPY_PAK_TO_GHOST2_2P; } else { gSubMenuSelection = SUB_MENU_COPY_PAK_TO_GHOST1_2P; } play_sound2(SOUND_MENU_SELECT); } break; } case SUB_MENU_COPY_PAK_TO_GHOST1_2P: case SUB_MENU_COPY_PAK_TO_GHOST2_2P: { // bit of a fake match, but if it works it works? if ((sp30[sp38->param2].courseIndex != ((0, (D_8018EE10 + (gSubMenuSelection - SUB_MENU_COPY_PAK_TO_GHOST_MIN))->courseIndex))) || ((D_8018EE10 + (gSubMenuSelection - SUB_MENU_COPY_PAK_TO_GHOST_MIN))->ghostDataSaved == 0)) { if ((btnAndStick & D_JPAD) && (gSubMenuSelection < SUB_MENU_COPY_PAK_TO_GHOST_MAX)) { gSubMenuSelection += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } sp38->subState = 1; } if ((btnAndStick & U_JPAD) && (gSubMenuSelection > SUB_MENU_COPY_PAK_TO_GHOST_MIN)) { gSubMenuSelection -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } sp38->subState = -1; } } if (btnAndStick & B_BUTTON) { gSubMenuSelection = sp38->param2 + SUB_MENU_COPY_PAK_FROM_GHOST_MIN; play_sound2(SOUND_MENU_GO_BACK); } else if (btnAndStick & A_BUTTON) { sp38->param1 = gSubMenuSelection - SUB_MENU_COPY_PAK_TO_GHOST_MIN; if (D_8018EE10[(sp38->param1)].ghostDataSaved) { gSubMenuSelection = SUB_MENU_COPY_PAK_PROMPT_QUIT; } else { gSubMenuSelection = SUB_MENU_COPY_PAK_START; sp38->state = 0; } play_sound2(SOUND_MENU_SELECT); } break; } case SUB_MENU_COPY_PAK_ERROR_NO_GHOST_DATA: case SUB_MENU_COPY_PAK_ERROR_NO_GAME_DATA: case SUB_MENU_COPY_PAK_ERROR_NO_PAK_2P: case SUB_MENU_COPY_PAK_ERROR_BAD_READ_2P: case SUB_MENU_COPY_PAK_ERROR_NO_PAK_1P: case SUB_MENU_COPY_PAK_ERROR_BAD_READ_1P: case SUB_MENU_COPY_PAK_ERROR_NO_PAGES_1P: case SUB_MENU_COPY_PAK_COMPLETED: case SUB_MENU_COPY_PAK_UNABLE_COPY_FROM_1P: case SUB_MENU_COPY_PAK_UNABLE_READ_FROM_2P: { if (btnAndStick & (A_BUTTON | B_BUTTON | START_BUTTON)) { gSubMenuSelection = SUB_MENU_OPTION_COPY_CONTROLLER_PAK; play_sound2(SOUND_MENU_GO_BACK); } break; } case SUB_MENU_COPY_PAK_PROMPT_QUIT: case SUB_MENU_COPY_PAK_PROMPT_COPY: { if ((btnAndStick & R_JPAD) && gSubMenuSelection < SUB_MENU_COPY_PAK_PROMPT_MAX) { gSubMenuSelection += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } sp38->subState = 1; } if ((btnAndStick & L_JPAD) && gSubMenuSelection > SUB_MENU_COPY_PAK_PROMPT_MIN) { gSubMenuSelection -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp38->paramf < 4.2) { sp38->paramf += 4.0; } sp38->subState = -1; } if (btnAndStick & B_BUTTON) { gSubMenuSelection = sp38->param1 + SUB_MENU_COPY_PAK_TO_GHOST_MIN; play_sound2(SOUND_MENU_GO_BACK); return; } if (btnAndStick & A_BUTTON) { if (gSubMenuSelection == SUB_MENU_COPY_PAK_PROMPT_QUIT) { gSubMenuSelection = SUB_MENU_OPTION_COPY_CONTROLLER_PAK; play_sound2(SOUND_MENU_GO_BACK); } else { gSubMenuSelection = SUB_MENU_COPY_PAK_START; play_sound2(SOUND_MENU_SELECT); sp38->state = 0; } } // return? break; } case SUB_MENU_COPY_PAK_START: { if (controllerIdx == PLAYER_ONE) { sp38->state += 1; } if (sp38->state >= 3) { gSubMenuSelection = SUB_MENU_COPY_PAK_COPYING; } break; } case SUB_MENU_COPY_PAK_COPYING: { res = controller_pak_2_status(); if (res == PFS_NO_ERROR) { res = func_800B65F4(sp38->param2, sp38->param1); } if (res != 0) { gSubMenuSelection = SUB_MENU_COPY_PAK_UNABLE_READ_FROM_2P; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; } res = osPfsFindFile(&gControllerPak1FileHandle, gCompanyCode, gGameCode, (u8*) gGameName, (u8*) gExtCode, &gControllerPak1FileNote); if (res == PFS_NO_ERROR) { res = func_800B6178(sp38->param1); } if (res != 0) { gSubMenuSelection = SUB_MENU_COPY_PAK_UNABLE_COPY_FROM_1P; play_sound2(SOUND_MENU_FILE_NOT_FOUND); return; } gSubMenuSelection = SUB_MENU_COPY_PAK_COMPLETED; D_8018EE10[sp38->param1].courseIndex = (sp30 + sp38->param2)->courseIndex; func_800B6088(sp38->param1); break; } case SUB_MENU_COPY_PAK_CREATE_GAME_DATA_INIT: { if (controllerIdx == PLAYER_ONE) { sp38->state += 1; } if (sp38->state >= 3) { gSubMenuSelection = SUB_MENU_COPY_PAK_CREATE_GAME_DATA_DONE; } break; } case SUB_MENU_COPY_PAK_CREATE_GAME_DATA_DONE: { if (func_800B6A68()) { gSubMenuSelection = SUB_MENU_COPY_PAK_ERROR_CANT_CREATE_1P; play_sound2(SOUND_MENU_FILE_NOT_FOUND); } else if (sp30[0].ghostDataSaved) { gSubMenuSelection = SUB_MENU_COPY_PAK_FROM_GHOST1_1P; } else { gSubMenuSelection = SUB_MENU_COPY_PAK_FROM_GHOST2_1P; } break; } default: break; } } } /** * Navigation of the data menu */ void data_menu_act(struct Controller* controller, UNUSED u16 controllerIdx) { u16 btnAndStick = (controller->buttonPressed | controller->stickPressed); // Make pressing Start have the same effect as pressing A if ((gEnableDebugMode == 0) && ((btnAndStick & START_BUTTON) != 0)) { btnAndStick |= A_BUTTON; } if (is_screen_being_faded() == 0) { if (gSubMenuSelection == SUB_MENU_DATA) { // If DPad/Stick down pressed, move selection down if not already in bottom row if ((btnAndStick & D_JPAD) != 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 ((btnAndStick & U_JPAD) != 0) { if ((gTimeTrialDataCourseIndex % 4) != 0) { --gTimeTrialDataCourseIndex; play_sound2(SOUND_MENU_CURSOR_MOVE); } } // If DPad/Stick right pressed, move selection right if not already in right-most column if ((btnAndStick & R_JPAD) != 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 ((btnAndStick & L_JPAD) != 0) { if ((gTimeTrialDataCourseIndex / 4) != 0) { gTimeTrialDataCourseIndex -= 4; play_sound2(SOUND_MENU_CURSOR_MOVE); } } // If B pressed, go to main menu if ((btnAndStick & B_BUTTON) != 0) { func_8009E258(); play_sound2(SOUND_MENU_GO_BACK); return; } // If A pressed, go to selected course's records if ((btnAndStick & A_BUTTON) != 0) { gCourseRecordsMenuSelection = COURSE_RECORDS_MENU_RETURN_MENU; func_8009E1C0(); play_sound2(SOUND_MENU_OK_CLICKED); } } // If gSubMenuSelection is not SUB_MENU_DATA and A pressed, go to main menu // This condition is not reachable but this failsafe was added nonetheless else if ((btnAndStick & A_BUTTON) != 0) { func_8009E258(); play_sound2(SOUND_MENU_OK_CLICKED); } } } /** * Navigation of the course records data menu */ void course_data_menu_act(struct Controller* controller, UNUSED u16 controllerIdx) { u16 btnAndStick; // sp2E MenuItem* sp28; CourseTimeTrialRecords* sp24; s32 res; btnAndStick = (controller->buttonPressed | controller->stickPressed); if (!gEnableDebugMode && (btnAndStick & START_BUTTON)) { btnAndStick |= A_BUTTON; } if (!is_screen_being_faded()) { switch (gSubMenuSelection) { case SUB_MENU_DATA_OPTIONS: { 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_menu_items_dupe(0xE8); sp24 = &gSaveData.allCourseTimeTrialRecords.cupRecords[gTimeTrialDataCourseIndex / 4] .courseRecords[gTimeTrialDataCourseIndex % 4]; if (gCourseRecordsMenuSelection == COURSE_RECORDS_MENU_ERASE_GHOST && func_800B639C(gTimeTrialDataCourseIndex) < 0) { gCourseRecordsMenuSelection -= 1; } if (gCourseRecordsMenuSelection == COURSE_RECORDS_MENU_ERASE_RECORDS && sp24->unknownBytes[0] == 0) { gCourseRecordsMenuSelection -= 1; } if ((btnAndStick & U_JPAD) && (gCourseRecordsMenuSelection > COURSE_RECORDS_MENU_MIN)) { gCourseRecordsMenuSelection -= 1; if (gCourseRecordsMenuSelection == 1 && sp24->unknownBytes[0] == 0) { gCourseRecordsMenuSelection -= 1; } play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp28->paramf < 4.2) { sp28->paramf += 4.0; } sp28->subState = -1; } if ((btnAndStick & D_JPAD) && (gCourseRecordsMenuSelection < COURSE_RECORDS_MENU_MAX)) { gCourseRecordsMenuSelection += 1; if (gCourseRecordsMenuSelection == COURSE_RECORDS_MENU_ERASE_RECORDS && sp24->unknownBytes[0] == 0) { gCourseRecordsMenuSelection += 1; } if (gCourseRecordsMenuSelection == COURSE_RECORDS_MENU_ERASE_GHOST && func_800B639C(gTimeTrialDataCourseIndex) < 0) { if (sp24->unknownBytes[0] == 0) { gCourseRecordsMenuSelection = COURSE_RECORDS_MENU_RETURN_MENU; } else { gCourseRecordsMenuSelection = COURSE_RECORDS_MENU_ERASE_RECORDS; } } else { play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp28->paramf < 4.2) { sp28->paramf += 4.0; } sp28->subState = 1; } } if (btnAndStick & B_BUTTON) { func_8009E208(); play_sound2(SOUND_MENU_GO_BACK); } else if (btnAndStick & A_BUTTON) { if (sp28->paramf < 4.2) { sp28->paramf += 4.0; } if (gCourseRecordsMenuSelection == COURSE_RECORDS_MENU_RETURN_MENU) { func_8009E208(); play_sound2(SOUND_MENU_GO_BACK); } else { gSubMenuSelection = SUB_MENU_DATA_ERASE_CONFIRM; gCourseRecordsSubMenuSelection = COURSE_RECORDS_SUB_MENU_QUIT; play_sound2(SOUND_MENU_SELECT); } } break; } case SUB_MENU_DATA_ERASE_CONFIRM: { sp28 = find_menu_items_dupe(0xE9); if ((btnAndStick & U_JPAD) && (gCourseRecordsSubMenuSelection > COURSE_RECORDS_SUB_MENU_MIN)) { gCourseRecordsSubMenuSelection -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp28->paramf < 4.2) { sp28->paramf += 4.0; } sp28->subState = -1; } if ((btnAndStick & D_JPAD) && (gCourseRecordsSubMenuSelection < COURSE_RECORDS_SUB_MENU_MAX)) { gCourseRecordsSubMenuSelection += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); if (sp28->paramf < 4.2) { sp28->paramf += 4.0; } sp28->subState = 1; } if (btnAndStick & B_BUTTON) { gSubMenuSelection = SUB_MENU_DATA_OPTIONS; play_sound2(SOUND_MENU_GO_BACK); } else if (btnAndStick & A_BUTTON) { if (gCourseRecordsSubMenuSelection != COURSE_RECORDS_SUB_MENU_QUIT) { res = 0; switch (gCourseRecordsMenuSelection) { case COURSE_RECORDS_MENU_ERASE_RECORDS: { func_800B4728(gTimeTrialDataCourseIndex); func_800B559C(gTimeTrialDataCourseIndex); play_sound2(SOUND_MENU_EXPLOSION); res = -1; break; } case COURSE_RECORDS_MENU_ERASE_GHOST: { res = func_800B639C(gTimeTrialDataCourseIndex); if (res >= 0) { if (func_800B69BC(res) != 0) { gSubMenuSelection = SUB_MENU_DATA_CANT_ERASE; play_sound2(SOUND_MENU_FILE_NOT_FOUND); } else { play_sound2(SOUND_MENU_EXPLOSION); gSubMenuSelection = SUB_MENU_DATA_OPTIONS; } } break; } } if (!(res + 1)) { gSubMenuSelection = SUB_MENU_DATA_OPTIONS; } } else { play_sound2(SOUND_MENU_GO_BACK); gSubMenuSelection = SUB_MENU_DATA_OPTIONS; } } break; } case SUB_MENU_DATA_CANT_ERASE: { if (btnAndStick & (A_BUTTON | B_BUTTON | START_BUTTON)) { gSubMenuSelection = SUB_MENU_DATA_OPTIONS; } break; } } } } /** * On input skip logo screen **/ void logo_intro_menu_act(struct Controller* controller, UNUSED u16 controllerIdx) { u16 btnAndStick = (controller->buttonPressed | controller->stickPressed); // If any button is pressed then fade audio out if ((is_screen_being_faded() == 0) && (btnAndStick)) { //! @todo Label audio funcs func_800CA388(0x3C); func_8009E1E4(); } } /** * Navigation of the controller pak table data */ void controller_pak_menu_act(struct Controller* controller, UNUSED u16 controllerIdx) { u16 btnAndStick; OSPfsState* osPfsState; s32 selectedTableRow; UNUSED s8 pad; btnAndStick = (controller->buttonPressed | controller->stickPressed); if (is_screen_being_faded() == 0) { switch (gControllerPakMenuSelection) { case CONTROLLER_PAK_MENU_SELECT_RECORD: if ((btnAndStick & (A_BUTTON | START_BUTTON)) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_TABLE_GAME_DATA; play_sound2(SOUND_MENU_SELECT); return; } if ((btnAndStick & (L_JPAD | R_JPAD)) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_END; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } break; case CONTROLLER_PAK_MENU_END: if ((btnAndStick & (A_BUTTON | START_BUTTON)) != 0) { play_sound2(SOUND_MENU_SELECT); func_8009E1C0(); gControllerPak1State = BAD; return; } if ((btnAndStick & (L_JPAD | R_JPAD)) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_SELECT_RECORD; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } break; case CONTROLLER_PAK_MENU_TABLE_GAME_DATA: if ((btnAndStick & (A_BUTTON | START_BUTTON)) != 0) { selectedTableRow = gControllerPakVisibleTableRows[gControllerPakSelectedTableRow + 2] - 1; if (pfsError[selectedTableRow] == 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_QUIT; play_sound2(SOUND_MENU_SELECT); return; } } else if ((btnAndStick & B_BUTTON) != 0) { if (gControllerPakScrollDirection == CONTROLLER_PAK_SCROLL_DIR_NONE) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_SELECT_RECORD; play_sound2(SOUND_MENU_GO_BACK); return; } } else if ((btnAndStick & U_JPAD) != 0) { if (gControllerPakScrollDirection == CONTROLLER_PAK_SCROLL_DIR_NONE) { --gControllerPakSelectedTableRow; if (gControllerPakSelectedTableRow < 0) { gControllerPakSelectedTableRow = 0; if (gControllerPakVisibleTableRows[gControllerPakSelectedTableRow + 2] != 1) { gControllerPakScrollDirection = CONTROLLER_PAK_SCROLL_DIR_UP; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } } else { play_sound2(SOUND_MENU_CURSOR_MOVE); return; } } } else if (((btnAndStick & D_JPAD) != 0) && (gControllerPakScrollDirection == CONTROLLER_PAK_SCROLL_DIR_NONE)) { ++gControllerPakSelectedTableRow; if (gControllerPakSelectedTableRow >= CONTROLLER_PAK_MENU_TABLE_GAME_DATA) { gControllerPakSelectedTableRow = CONTROLLER_PAK_MENU_QUIT; if (gControllerPakVisibleTableRows[gControllerPakSelectedTableRow + 2] != 16) { gControllerPakScrollDirection = CONTROLLER_PAK_SCROLL_DIR_DOWN; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } } else { play_sound2(SOUND_MENU_CURSOR_MOVE); return; } } break; case CONTROLLER_PAK_MENU_QUIT: if ((btnAndStick & (A_BUTTON | B_BUTTON | START_BUTTON)) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_TABLE_GAME_DATA; play_sound2(SOUND_MENU_GO_BACK); return; } if ((btnAndStick & (L_JPAD | R_JPAD)) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_ERASE; play_sound2(SOUND_MENU_CURSOR_MOVE); return; } break; case CONTROLLER_PAK_MENU_ERASE: if ((btnAndStick & (A_BUTTON | START_BUTTON)) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_GO_TO_ERASING; play_sound2(SOUND_MENU_SELECT); return; } if ((btnAndStick & B_BUTTON) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_TABLE_GAME_DATA; play_sound2(SOUND_MENU_GO_BACK); return; } if ((btnAndStick & (L_JPAD | R_JPAD)) != 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 = gControllerPakVisibleTableRows[gControllerPakSelectedTableRow + 2] - 1; osPfsState = &pfsState[selectedTableRow]; switch (osPfsDeleteFile(&gControllerPak1FileHandle, 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: pfsError[selectedTableRow] = -1; gControllerPak1NumPagesFree += (((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: 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 ((btnAndStick & (A_BUTTON | START_BUTTON)) != 0) { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_TABLE_GAME_DATA; } break; } } } /** * Navigation of the main splash start screen menu * Also handles debug menu options */ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { u16 btnAndStick; u16 i; s32 isDebug = true; btnAndStick = controller->buttonPressed | controller->stickPressed; if (is_screen_being_faded() == 0) { if (controllerIdx == PLAYER_ONE) { gMenuDelayTimer += 1; } switch (gDebugMenuSelection) { case DEBUG_MENU_DISABLED: { isDebug = false; if ((gMenuDelayTimer >= 46) && (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 = CVarGetInteger("gEnableDebugMode", 0); } 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); NextCourse(); gCurrentCourseId = GetCourseIndex(); // if (gCurrentCourseId < (NUM_COURSES - 2)) { // gCurrentCourseId += 1; // } else { // gCurrentCourseId = 0; // } } if (btnAndStick & L_JPAD) { play_sound2(SOUND_MENU_CURSOR_MOVE); PreviousCourse(); gCurrentCourseId = GetCourseIndex(); // if (gCurrentCourseId > 0) { // gCurrentCourseId -= 1; // } else { // gCurrentCourseId = (NUM_COURSES - 2); // } } 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_CC; } break; } case DEBUG_MENU_CC: { if ((btnAndStick & R_JPAD) && (gCCSelection < 3)) { gCCSelection += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); } if ((btnAndStick & L_JPAD) && (gCCSelection > 0)) { gCCSelection -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); } if (btnAndStick & U_JPAD) { gDebugMenuSelection = DEBUG_MENU_COURSE; play_sound2(SOUND_MENU_CURSOR_MOVE); } if (btnAndStick & D_JPAD) { gDebugMenuSelection = DEBUG_MENU_SCREEN_MODE; play_sound2(SOUND_MENU_CURSOR_MOVE); } break; } case DEBUG_MENU_SCREEN_MODE: { if ((btnAndStick & R_JPAD) && (gScreenModeListIndex < 4)) { gScreenModeListIndex += 1; play_sound2(SOUND_MENU_CURSOR_MOVE); gScreenModeSelection = sScreenModePlayerTable[gScreenModeListIndex]; } if ((btnAndStick & L_JPAD) && (gScreenModeListIndex > 0)) { gScreenModeListIndex -= 1; play_sound2(SOUND_MENU_CURSOR_MOVE); gScreenModeSelection = sScreenModePlayerTable[gScreenModeListIndex]; } if (btnAndStick & U_JPAD) { gDebugMenuSelection = DEBUG_MENU_CC; 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[0] < 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); set_sound_mode(); gSaveData.main.saveInfo.soundMode = 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); set_sound_mode(); gSaveData.main.saveInfo.soundMode = 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 = gPlayerCount = sScreenModePlayerCount[gScreenModeListIndex]; if (isDebug) { if (btnAndStick & (A_BUTTON | START_BUTTON)) { func_8009E1C0(); func_800CA330(0x19); gDebugMenuSelection = DEBUG_MENU_OPTION_SELECTED; if (controller->button & CONT_L) { gDemoMode = DEMO_MODE_ACTIVE; } else { gDemoMode = DEMO_MODE_INACTIVE; } if (controller->button & Z_TRIG) { if (btnAndStick & A_BUTTON) { gDebugGotoScene = DEBUG_GOTO_ENDING; } else { gDebugGotoScene = DEBUG_GOTO_CREDITS_SEQUENCE_EXTRA; } } play_sound2(SOUND_MENU_OK_CLICKED); } else if ((btnAndStick & B_BUTTON) && (controller->button & Z_TRIG)) { func_8009E1C0(); func_800CA330(0x19); gDebugMenuSelection = DEBUG_MENU_OPTION_SELECTED; gDebugGotoScene = DEBUG_GOTO_CREDITS_SEQUENCE_DEFAULT; play_sound2(SOUND_MENU_OK_CLICKED); } else if (btnAndStick & CONT_R) { gDebugMenuSelection = DEBUG_MENU_DISABLED; play_sound2(SOUND_MENU_SELECT); } } } } void setup_game_mode_selected(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 subMenuMode = gGameModeSubMenuColumn[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; // Determine which game mode was selected based on the number of players and the row selected on the main menu switch (gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]) { case GRAND_PRIX: gCCSelection = subMenuMode; gPlaceItemBoxes = 1; gIsMirrorMode = (subMenuMode == CC_EXTRA) ? 1 : 0; break; case VERSUS: gCCSelection = subMenuMode; gPlaceItemBoxes = 1; gIsMirrorMode = (subMenuMode == CC_EXTRA) ? 1 : 0; break; case BATTLE: gPlaceItemBoxes = 1; gIsMirrorMode = 0; break; case TIME_TRIALS: gCCSelection = CC_100; gIsMirrorMode = 0; gPlaceItemBoxes = 0; if ((subMenuMode && subMenuMode) && subMenuMode) {} break; } } /** * Navigation of the main game mode select screen */ #ifdef NON_MATCHING // https://decomp.me/scratch/93qj8 // nonmatching: regalloc; controllerIdx is not AND-ed back into $a1, reg chaos follows void main_menu_act(struct Controller* controller, u16 controllerIdx) { u16 btnAndStick; s32 subMode; bool cursorMoved; s32 newMode; btnAndStick = controller->buttonPressed | controller->stickPressed; if (!gEnableDebugMode && (btnAndStick & START_BUTTON)) { btnAndStick |= A_BUTTON; } if (!is_screen_being_faded()) { switch (gMainMenuSelection) { case MAIN_MENU_NONE: { newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; break; } case MAIN_MENU_PLAYER_SELECT: { if ((btnAndStick & R_JPAD) && gPlayerCount < 4) { gPlayerCount += 1; reset_cycle_flash_menu(); play_sound2(SOUND_MENU_CURSOR_MOVE); } if ((btnAndStick & L_JPAD) && gPlayerCount >= 2) { gPlayerCount -= 1; reset_cycle_flash_menu(); play_sound2(SOUND_MENU_CURSOR_MOVE); } // L800B2B38 gPlayerCountSelection1 = gPlayerCount; 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); gMenuFadeType = MENU_FADE_TYPE_BACK; play_sound2(SOUND_MENU_GO_BACK); newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else if (btnAndStick & A_BUTTON) { // L800B2C00 gMainMenuSelection = MAIN_MENU_MODE_SELECT; reset_cycle_flash_menu(); play_sound2(SOUND_MENU_SELECT); newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else if (btnAndStick & CONT_L) { // L800B2C58 gMainMenuSelection = MAIN_MENU_OPTION; func_8009E280(); play_sound2(SOUND_MENU_OPTION); newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else if (btnAndStick & CONT_R) { gMainMenuSelection = MAIN_MENU_DATA; func_8009E258(); play_sound2(SOUND_MENU_DATA); newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else { newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } break; } case MAIN_MENU_MODE_SELECT: { if (btnAndStick & D_JPAD) { if (gGameModeMenuColumn[gPlayerCount - 1] < gPlayerModeSelection[gPlayerCount - 1]) { gGameModeMenuColumn[gPlayerCount - 1] += 1; reset_cycle_flash_menu(); play_sound2(SOUND_MENU_CURSOR_MOVE); } } // L800B2D94 if (btnAndStick & U_JPAD) { if (gGameModeMenuColumn[gPlayerCount - 1] > 0) { gGameModeMenuColumn[gPlayerCount - 1] -= 1; reset_cycle_flash_menu(); play_sound2(SOUND_MENU_CURSOR_MOVE); } } // L800B2DE0 if (btnAndStick & B_BUTTON) { gMainMenuSelection = MAIN_MENU_PLAYER_SELECT; reset_cycle_flash_menu(); play_sound2(SOUND_MENU_GO_BACK); newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else if (btnAndStick & A_BUTTON) { // L800B2E3C switch (gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]) { case 0: gMainMenuSelection = MAIN_MENU_MODE_SUB_SELECT; play_sound2(SOUND_MENU_GP); break; case 2: gMainMenuSelection = MAIN_MENU_MODE_SUB_SELECT; play_sound2(SOUND_MENU_VERSUS); break; case 1: gMainMenuSelection = MAIN_MENU_MODE_SUB_SELECT; play_sound2(SOUND_MENU_TIME_TRIALS); break; case 3: gMainMenuSelection = MAIN_MENU_OK_SELECT; play_sound2(SOUND_MENU_BATTLE); break; default: gMainMenuSelection = MAIN_MENU_OK_SELECT; break; } // L800B2F04 reset_cycle_flash_menu(); gMenuTimingCounter = 0; newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else { newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } break; } case MAIN_MENU_MODE_SUB_SELECT: case MAIN_MENU_MODE_SUB_SELECT_GO_BACK: { if (controllerIdx == PLAYER_ONE) { gMenuTimingCounter++; if ((gMenuTimingCounter == 100 || gMenuTimingCounter % 300 == 0)) { // L800B2FAC if (gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]] == 0 || gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]] == 2) { play_sound2(SOUND_MENU_SELECT_LEVEL); } } } // L800B3000 subMode = gGameModeSubMenuColumn[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; if ((btnAndStick & U_JPAD) && (subMode > 0)) { gGameModeSubMenuColumn[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]] -= 1; reset_cycle_flash_menu(); play_sound2(SOUND_MENU_CURSOR_MOVE); } // L800B3068 if (btnAndStick & D_JPAD) { cursorMoved = false; if (has_unlocked_extra_mode()) { if (subMode < sGameModePlayerColumnExtra[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]) { cursorMoved = true; } } else { if (subMode < sGameModePlayerColumnDefault[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]) { cursorMoved = true; } } // L800B3110 if (cursorMoved) { gGameModeSubMenuColumn[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]++; reset_cycle_flash_menu(); play_sound2(SOUND_MENU_CURSOR_MOVE); } } // L800B3150 subMode = gGameModeSubMenuColumn[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; if (btnAndStick & B_BUTTON) { gMainMenuSelection = MAIN_MENU_MODE_SELECT; reset_cycle_flash_menu(); play_sound2(SOUND_MENU_GO_BACK); newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else if (btnAndStick & A_BUTTON) { // L800B31DC reset_cycle_flash_menu(); if (gPlayerCount == 1 && gGameModeMenuColumn[gPlayerCount - 1] == 1 && subMode == 1) { // DATA func_8009E258(); play_sound2(SOUND_MENU_DATA); } else { // BEGIN gMainMenuSelection = MAIN_MENU_OK_SELECT; play_sound2(SOUND_MENU_SELECT); gMenuTimingCounter = 0; } newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else { // L800B3294 newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } break; } case MAIN_MENU_OK_SELECT: case MAIN_MENU_OK_SELECT_GO_BACK: { if ((controllerIdx == PLAYER_ONE) && (++gMenuTimingCounter == 60 || gMenuTimingCounter % 300 == 0)) { play_sound2(SOUND_MENU_OK); } // L800B330C if (btnAndStick & B_BUTTON) { switch (gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]) { case 0: case 1: case 2: gMainMenuSelection = MAIN_MENU_MODE_SUB_SELECT; break; case 3: default: gMainMenuSelection = MAIN_MENU_MODE_SELECT; break; } // L800B3384 reset_cycle_flash_menu(); play_sound2(SOUND_MENU_GO_BACK); gMenuTimingCounter = 0; newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else if (btnAndStick & A_BUTTON) { // L800B33D8 func_8009E1C0(); play_sound2(SOUND_MENU_OK_CLICKED); setup_game_mode_selected(); newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } else { newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; } break; } case MAIN_MENU_OPTION: case MAIN_MENU_DATA: { newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]; break; } default: { newMode = gGameModePlayerSelection[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 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` */ bool is_character_spot_free(s32 gridId) { s32 i; for (i = 0; i < ARRAY_COUNT(gCharacterGridSelections); i++) { if (gridId == gCharacterGridSelections[i]) { return false; } } return true; } // Grid positions are from right to left, then top to bottom // https://decomp.me/scratch/6R4jX #if 1 /** * Navigation of the player select screen * Grid positions are from right to left, then top to bottom */ void player_select_menu_act(struct Controller* controller, u16 controllerIdx) { s8* bar; s8 selected; s8 i; s8 savedSelection; u16 btnAndStick; btnAndStick = (controller->buttonPressed) | (controller->stickPressed); if (!gEnableDebugMode && btnAndStick & CONT_START) { btnAndStick |= A_BUTTON; } if (!is_screen_being_faded()) { switch (gPlayerSelectMenuSelection) { case PLAYER_SELECT_MENU_MAIN: { savedSelection = gCharacterGridSelections[controllerIdx]; if (savedSelection == 0) { if (btnAndStick & B_BUTTON) { func_8009E208(); play_sound2(0x49008002); } return; } // L800B3630 if (btnAndStick & B_BUTTON) { if (gCharacterGridIsSelected[controllerIdx]) { gCharacterGridIsSelected[controllerIdx] = false; play_sound2(SOUND_MENU_GO_BACK); } else { func_8009E208(); play_sound2(0x49008002); } } // L800B3684 if ((btnAndStick & A_BUTTON) && (gCharacterGridIsSelected[controllerIdx] == 0)) { gCharacterGridIsSelected[controllerIdx] = true; i = sCharacterGridOrder[gCharacterGridSelections[controllerIdx] - 1]; func_800C90F4(controllerIdx, 0x2900800e + (i << 4)); } // L800B36F4 selected = false; for (i = 0; i < ARRAY_COUNT(gCharacterGridSelections); i++) { if ((gCharacterGridSelections[i] != 0) && (gCharacterGridIsSelected[i] == 0)) { selected = true; break; } } // L800B3738 if (!selected) { gPlayerSelectMenuSelection = PLAYER_SELECT_MENU_OK; reset_cycle_flash_menu(); gMenuTimingCounter = 0; } // L800B3768 if (gCharacterGridIsSelected[controllerIdx] == 0) { if ((btnAndStick & CONT_RIGHT) && (btnAndStick & CONT_DOWN)) { if (savedSelection == 1 || savedSelection == 2 || savedSelection == 3) { // L800B37B0 savedSelection += 5; if (is_character_spot_free(savedSelection)) { gCharacterGridSelections[controllerIdx] = savedSelection; play_sound2(0x49008000); } } return; } // L800B37E4 if ((btnAndStick & CONT_LEFT) && (btnAndStick & CONT_DOWN)) { if (savedSelection == 2 || savedSelection == 3 || savedSelection == 4) { savedSelection += 3; if (is_character_spot_free(savedSelection)) { gCharacterGridSelections[controllerIdx] = savedSelection; play_sound2(0x49008000); } } return; } // L800B3844 if ((btnAndStick & CONT_RIGHT) && (btnAndStick & CONT_UP)) { if (savedSelection == 5 || savedSelection == 6 || savedSelection == 7) { savedSelection -= 3; if (is_character_spot_free(savedSelection)) { gCharacterGridSelections[controllerIdx] = savedSelection; play_sound2(0x49008000); } } return; } // L800B38A0 if ((btnAndStick & CONT_LEFT) && (btnAndStick & CONT_UP)) { if (savedSelection == 6 || savedSelection == 7 || savedSelection == 8) { savedSelection -= 5; if (is_character_spot_free(savedSelection)) { gCharacterGridSelections[controllerIdx] = savedSelection; play_sound2(0x49008000); } } return; } // L800B38FC if (btnAndStick & CONT_RIGHT) { if (savedSelection == 4 || savedSelection == 8) return; savedSelection += 1; do { // L800B391C if (is_character_spot_free(savedSelection)) { gCharacterGridSelections[controllerIdx] = savedSelection; play_sound2(0x49008000); // play_sound2(0x49008000); break; } savedSelection += 1; if ((savedSelection == 5) || (savedSelection == 9)) return; } while (savedSelection < 10); return; } // L800B3978 if (btnAndStick & CONT_LEFT) { if (savedSelection == 1 || savedSelection == 5) return; savedSelection -= 1; do { if (is_character_spot_free(savedSelection)) { gCharacterGridSelections[controllerIdx] = savedSelection; play_sound2(0x49008000); break; } savedSelection -= 1; if ((savedSelection == 0) || (savedSelection == 4)) return; } while (savedSelection >= 0); return; } // L800B39F4 if ((btnAndStick & CONT_UP) && (savedSelection >= 5)) { savedSelection = savedSelection - 4; } if ((btnAndStick & CONT_DOWN) && (savedSelection < 5)) { savedSelection = savedSelection + 4; } // L800B3A30 if (is_character_spot_free(savedSelection)) { gCharacterGridSelections[controllerIdx] = savedSelection; play_sound2(0x49008000); } } break; } case 2: case 3: if (controllerIdx == 0) { gMenuTimingCounter++; if ((gMenuTimingCounter == 60) || ((gMenuTimingCounter % 300) == 0)) { // L800B3A94 play_sound2(0x4900900F); } } // L800B3AA4 if (btnAndStick & B_BUTTON) { gPlayerSelectMenuSelection = PLAYER_SELECT_MENU_MAIN; gCharacterGridIsSelected[controllerIdx] = false; play_sound2(SOUND_MENU_GO_BACK); break; } if (btnAndStick & A_BUTTON) { func_8009E1C0(); play_sound2(0x49008016); func_8000F124(); } break; default: break; } // L800B3B24 if (gCharacterGridSelections[controllerIdx] != 0) { gCharacterSelections[controllerIdx] = sCharacterGridOrder[gCharacterGridSelections[controllerIdx] - 1]; } } // L800B3B44 } #else GLOBAL_ASM("asm/non_matchings/menus/player_select_menu_act.s") #endif u32 WorldNextCup(void); u32 WorldPreviousCup(void); u32 GetCupIndex(void); /** * Navigation of the map select course menu screen */ void course_select_menu_act(struct Controller* controller, u16 controllerIdx) { u16 btnAndStick = (controller->buttonPressed | controller->stickPressed); if ((!gEnableDebugMode) && ((btnAndStick & START_BUTTON) != 0)) { btnAndStick |= A_BUTTON; } if (is_screen_being_faded() == 0) { switch (gSubMenuSelection) { case SUB_MENU_MAP_SELECT_CUP: if ((btnAndStick & R_JPAD) != 0) { sTempCupSelection = WorldNextCup(); //++gCupSelection; //reset_cycle_flash_menu(); //play_sound2(SOUND_MENU_CURSOR_MOVE); } if (((btnAndStick & L_JPAD) != 0)) { sTempCupSelection = WorldPreviousCup(); //--gCupSelection; //reset_cycle_flash_menu(); //play_sound2(SOUND_MENU_CURSOR_MOVE); } D_800DC540 = GetCupIndex(); gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; SetCourseFromCup(); if ((btnAndStick & B_BUTTON) != 0) { func_8009E208(); play_sound2(SOUND_MENU_GO_BACK); } else if ((btnAndStick & A_BUTTON) != 0) { if (gModeSelection != GRAND_PRIX) { gSubMenuSelection = SUB_MENU_MAP_SELECT_COURSE; play_sound2(SOUND_MENU_SELECT); } else { gSubMenuSelection = SUB_MENU_MAP_SELECT_OK; play_sound2(SOUND_MENU_SELECT); //! @todo SetCourse() to course one; SetCupCursorPosition(COURSE_ONE); SetCourseFromCup(); gCurrentCourseId = gCupCourseOrder[gCupSelection][COURSE_ONE]; gMenuTimingCounter = 0; } reset_cycle_flash_menu(); } break; case SUB_MENU_MAP_SELECT_COURSE: case SUB_MENU_MAP_SELECT_BATTLE_COURSE: if (((btnAndStick & D_JPAD) != 0) && (GetCupCursorPosition() < (GetCupSize() - 1))) { ++gCourseIndexInCup; SetCupCursorPosition(GetCupCursorPosition() + 1); reset_cycle_flash_menu(); play_sound2(SOUND_MENU_CURSOR_MOVE); } if (((btnAndStick & U_JPAD) != 0) && (GetCupCursorPosition() > COURSE_ONE)) { --gCourseIndexInCup; SetCupCursorPosition(GetCupCursorPosition() - 1); reset_cycle_flash_menu(); play_sound2(SOUND_MENU_CURSOR_MOVE); } gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; SetCourseFromCup(); if ((btnAndStick & B_BUTTON) != 0) { if (gSubMenuSelection == SUB_MENU_MAP_SELECT_COURSE) { gSubMenuSelection = SUB_MENU_MAP_SELECT_CUP; } else { func_8009E208(); } reset_cycle_flash_menu(); play_sound2(SOUND_MENU_GO_BACK); return; } if ((btnAndStick & A_BUTTON) != 0) { gSubMenuSelection = SUB_MENU_MAP_SELECT_OK; play_sound2(SOUND_MENU_SELECT); reset_cycle_flash_menu(); gMenuTimingCounter = 0; } break; case SUB_MENU_MAP_SELECT_OK: if ((controllerIdx == PLAYER_ONE) && ((++gMenuTimingCounter == 0x3C) || ((gMenuTimingCounter % 300) == 0))) { play_sound2(SOUND_MENU_OK); } if ((btnAndStick & B_BUTTON) != 0) { switch (gModeSelection) { case GRAND_PRIX: gSubMenuSelection = SUB_MENU_MAP_SELECT_CUP; break; case BATTLE: gSubMenuSelection = SUB_MENU_MAP_SELECT_BATTLE_COURSE; break; default: gSubMenuSelection = SUB_MENU_MAP_SELECT_COURSE; break; } reset_cycle_flash_menu(); play_sound2(SOUND_MENU_GO_BACK); return; } if ((btnAndStick & A_BUTTON) != 0) { func_8009E1C0(); func_800CA330(0x19); play_sound2(SOUND_MENU_OK_CLICKED); } break; } } } /** * Loads menu states so they are preserved between menu changes */ void load_menu_states(s32 menuSelection) { s32 i; gDebugMenuSelection = CVarGetInteger("gEnableDebugMode", 0) + 1; gMenuTimingCounter = 0; gMenuDelayTimer = 0; gDemoUseController = 0; D_8015F890 = 0; D_8015F892 = 0; gDebugGotoScene = DEBUG_GOTO_RACING; gGhostPlayerInit = 0; D_8016556E = 0; D_80162DD4 = 1; D_80162DD8 = 1; D_80162E00 = 0; D_80162DC8 = 1; D_80162DCC = 0; switch (menuSelection) { case OPTIONS_MENU: gSubMenuSelection = SUB_MENU_OPTION_RETURN_GAME_SELECT; break; case DATA_MENU: gSubMenuSelection = SUB_MENU_DATA; break; case COURSE_DATA_MENU: gSubMenuSelection = SUB_MENU_DATA_OPTIONS; break; case HARBOUR_MASTERS_MENU: func_800CA008(0, 0); break; case LOGO_INTRO_MENU: func_800CA008(0, 0); break; case CONTROLLER_PAK_MENU: { gControllerPakMenuSelection = CONTROLLER_PAK_MENU_SELECT_RECORD; func_800CA008(0, 0); break; } case 0: case START_MENU: { gIsMirrorMode = 0; gEnableDebugMode = CVarGetInteger("gEnableDebugMode", 0); CM_SetCup(GetMushroomCup()); gCupSelection = MUSHROOM_CUP; gCourseIndexInCup = 0; gTimeTrialDataCourseIndex = 0; if (gPlayerCount <= 0) { gPlayerCount = 1; } if (gPlayerCount >= 5) { gPlayerCount = 4; } gScreenModeListIndex = sScreenModeIdxFromPlayerMode[gPlayerCount - 1]; func_800CA008(0, 0); play_sequence(MUSIC_SEQ_TITLE_SCREEN); gCourseMapInit = 0; break; } case 1: case MAIN_MENU: { gEnableDebugMode = CVarGetInteger("gEnableDebugMode", 0); gIsMirrorMode = 0; gCourseMapInit = 0; func_800B5F30(); func_8000F0E0(); if (gGamestate != 0) { func_800CA008(0, 0); func_800CB2C4(); gGamestate = 0; gGamestateNext = 0; play_sequence(MUSIC_SEQ_MAIN_MENU); } switch (gMenuFadeType) { case MENU_FADE_TYPE_MAIN: { gMainMenuSelection = MAIN_MENU_PLAYER_SELECT; play_sequence(MUSIC_SEQ_MAIN_MENU); gPlayerCount = 1; if (gScreenModeSelection >= NUM_SCREEN_MODES || gScreenModeSelection < 0) { gScreenModeSelection = SCREEN_MODE_1P; } break; } case MENU_FADE_TYPE_BACK: { gMainMenuSelection = MAIN_MENU_OK_SELECT_GO_BACK; break; } case MENU_FADE_TYPE_DATA: { // why... switch (gMainMenuSelection) { default: gMainMenuSelection = MAIN_MENU_MODE_SUB_SELECT_GO_BACK; break; case MAIN_MENU_OPTION: case MAIN_MENU_DATA: gMainMenuSelection = MAIN_MENU_PLAYER_SELECT; break; } break; } case MENU_FADE_TYPE_OPTION: { gMainMenuSelection = MAIN_MENU_PLAYER_SELECT; break; } } break; } case 2: case CHARACTER_SELECT_MENU: { switch (gMenuFadeType) { case MENU_FADE_TYPE_MAIN: { gPlayerSelectMenuSelection = PLAYER_SELECT_MENU_MAIN; if (gGamestate == 0) { for (i = 0; i < ARRAY_COUNT(gCharacterGridSelections); i++) { if (i < gPlayerCount) { gCharacterGridSelections[i] = i + 1; } else { gCharacterGridSelections[i] = 0; } gCharacterGridIsSelected[i] = false; gCharacterSelections[i] = i; } play_sound2(SOUND_MENU_SELECT_PLAYER); } else { func_800CA008(0, 0); func_800CB2C4(); gGamestate = 0; gGamestateNext = 0; play_sequence(MUSIC_SEQ_MAIN_MENU); for (i = 0; i < ARRAY_COUNT(gCharacterGridIsSelected); i++) { gCharacterGridIsSelected[i] = false; } } break; } case MENU_FADE_TYPE_BACK: { gPlayerSelectMenuSelection = PLAYER_SELECT_MENU_OK_GO_BACK; for (i = 0; i < ARRAY_COUNT(gCharacterGridIsSelected); i++) { if (gPlayerCount > i) { gCharacterGridIsSelected[i] = true; } else { gCharacterGridIsSelected[i] = false; } } break; } } break; } case 3: case COURSE_SELECT_MENU: { if (gModeSelection == BATTLE) { CM_SetCup(GetBattleCup()); // gCupSelection = BATTLE_CUP; D_800DC540 = 4; CM_SetCupIndex(BATTLE_CUP); gSubMenuSelection = SUB_MENU_MAP_SELECT_BATTLE_COURSE; } else { if (GetCup() == GetBattleCup()) { CM_SetCup(GetMushroomCup()); // gCupSelection = MUSHROOM_CUP; } gSubMenuSelection = SUB_MENU_MAP_SELECT_CUP; } if (gGamestate != 0) { func_800CA008(0, 0); func_800CB2C4(); gGamestate = 0; gGamestateNext = 0; play_sequence(MUSIC_SEQ_MAIN_MENU); } play_sound2(SOUND_MENU_SELECT_MAP); sTempCupSelection = 0; if (gModeSelection == GRAND_PRIX) { gCourseIndexInCup = 0; } for (i = 0; i < ARRAY_COUNT(gGPPointsByCharacterId); i++) { gGPPointsByCharacterId[i] = 0; } break; } } reset_cycle_flash_menu(); } /** * Resets when moving cursor option or after a fade */ void reset_cycle_flash_menu(void) { gCycleFlashMenu = 0x20; } /** * Changes sound mode pack */ void set_sound_mode(void) { UNUSED u32 pad; union GameModePack pack; pack = sSoundMenuPack; if ((gSoundMode == SOUND_STEREO) || (gSoundMode == SOUND_HEADPHONES) || (gSoundMode == SOUND_MONO)) { func_800C3448(pack.modes[gSoundMode] | 0xE0000000); } } /** * Checks is a fade render mode is active so menus can't be * interacted while a fade transition is active */ bool is_screen_being_faded(void) { if ((D_8018E7AC[4] == 2) || (D_8018E7AC[4] == 3) || (D_8018E7AC[4] == 4) || (D_8018E7AC[4] == 7)) { return true; } return false; } /** * Unused debug function, prints the character id for the player and both controller pak ghosts */ UNUSED void debug_print_ghost_kart_character_id(s32 arg0, s32 arg1) { struct_8018EE10_entry* pak1 = D_8018EE10; struct_8018EE10_entry* pak2 = (struct_8018EE10_entry*) gSomeDLBuffer; rmonPrintf("ghost_kart=%d,", D_80162DE0); rmonPrintf("pak1_ghost_kart=%d,", (pak1 + arg0)->characterId); rmonPrintf("pak2_ghost_kart=%d\n", (pak2 + arg1)->characterId); }