/* * File: z_select.c * Overlay: ovl_select * Description: Debug Scene Select Menu */ #include "ultra64.h" #include "global.h" #include "vt.h" #include "alloca.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" void Select_LoadTitle(SelectContext* this) { this->state.running = false; SET_NEXT_GAMESTATE(&this->state, Title_Init, TitleContext); } void Select_LoadGame(SelectContext* this, s32 entranceIndex) { osSyncPrintf(VT_FGCOL(BLUE)); osSyncPrintf("\n\n\nFILE_NO=%x\n\n\n", gSaveContext.fileNum); osSyncPrintf(VT_RST); if (gSaveContext.fileNum == 0xFF) { Sram_InitDebugSave(); gSaveContext.magicFillTarget = gSaveContext.magic; gSaveContext.magic = 0; gSaveContext.magicCapacity = 0; gSaveContext.magicLevel = gSaveContext.magic; } for (int buttonIndex = 0; buttonIndex < ARRAY_COUNT(gSaveContext.buttonStatus); buttonIndex++) { gSaveContext.buttonStatus[buttonIndex] = BTN_ENABLED; } gSaveContext.unk_13E7 = gSaveContext.unk_13E8 = gSaveContext.unk_13EA = gSaveContext.unk_13EC = 0; Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_STOP); gSaveContext.entranceIndex = entranceIndex; // Check the entrance to see if the exit should be overriden to a grotto return point for entrance rando if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { // Ignore return value as we want to load into the entrance specified by the debug menu Grotto_OverrideSpecialEntrance(Entrance_GetOverride(entranceIndex)); } if (CVar_GetS32("gBetterDebugWarpScreen", 0)) { CVar_SetS32("gBetterDebugWarpScreenCurrentScene", this->currentScene); CVar_SetS32("gBetterDebugWarpScreenTopDisplayedScene", this->topDisplayedScene); CVar_SetS32("gBetterDebugWarpScreenPageDownIndex", this->pageDownIndex); CVar_Save(); } gSaveContext.respawnFlag = 0; gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = -1; gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.natureAmbienceId = 0xFF; gSaveContext.showTitleCard = true; gWeatherMode = 0; this->state.running = false; SET_NEXT_GAMESTATE(&this->state, Play_Init, PlayState); } void Select_Grotto_LoadGame(SelectContext* this, s32 grottoIndex) { osSyncPrintf(VT_FGCOL(BLUE)); osSyncPrintf("\n\n\nFILE_NO=%x\n\n\n", gSaveContext.fileNum); osSyncPrintf(VT_RST); if (gSaveContext.fileNum == 0xFF) { Sram_InitDebugSave(); gSaveContext.magicFillTarget = gSaveContext.magic; gSaveContext.magic = 0; gSaveContext.magicCapacity = 0; gSaveContext.magicLevel = gSaveContext.magic; } for (int buttonIndex = 0; buttonIndex < ARRAY_COUNT(gSaveContext.buttonStatus); buttonIndex++) { gSaveContext.buttonStatus[buttonIndex] = BTN_ENABLED; } gSaveContext.unk_13E7 = gSaveContext.unk_13E8 = gSaveContext.unk_13EA = gSaveContext.unk_13EC = 0; Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_STOP); // Entrance index and grotto content data to load the correct grotto and actors gSaveContext.entranceIndex = this->betterGrottos[grottoIndex].entranceIndex; gSaveContext.respawn[RESPAWN_MODE_RETURN].data = this->betterGrottos[grottoIndex].data; // Infomation to return to the correct grotto exit gSaveContext.respawn[RESPAWN_MODE_RETURN].entranceIndex = this->betterGrottos[grottoIndex].returnEntranceIndex; gSaveContext.respawn[RESPAWN_MODE_RETURN].roomIndex = this->betterGrottos[grottoIndex].roomIndex; gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x4ff; gSaveContext.respawn[RESPAWN_MODE_RETURN].pos = this->betterGrottos[grottoIndex].pos; // Check the entrance to see if the exit should be overriden to a grotto return point for entrance rando if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { // Use grotto content and parent scene num to identify the right grotto s16 grottoEntrance = Grotto_GetRenamedGrottoIndexFromOriginal(this->betterGrottos[grottoIndex].data, this->betterGrottos[grottoIndex].exitScene); // Ignore return value as we want to load into the entrance specified by the debug menu Grotto_OverrideSpecialEntrance(Entrance_GetOverride(grottoEntrance)); } if (CVar_GetS32("gBetterDebugWarpScreen", 0)) { CVar_SetS32("gBetterDebugWarpScreenCurrentScene", this->currentScene); CVar_SetS32("gBetterDebugWarpScreenTopDisplayedScene", this->topDisplayedScene); CVar_SetS32("gBetterDebugWarpScreenPageDownIndex", this->pageDownIndex); CVar_Save(); } gSaveContext.respawnFlag = 0; gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = -1; gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.natureAmbienceId = 0xFF; gSaveContext.showTitleCard = true; gWeatherMode = 0; this->state.running = false; SET_NEXT_GAMESTATE(&this->state, Play_Init, PlayState); } static SceneSelectEntry sScenes[] = { { " 1:Hyrule Field", Select_LoadGame, 0x00CD }, { " 2:Kakariko Village", Select_LoadGame, 0x00DB }, { " 3:Graveyard", Select_LoadGame, 0x00E4 }, { " 4:Zora's River", Select_LoadGame, 0x00EA }, { " 5:Kokiri Forest", Select_LoadGame, 0x00EE }, { " 6:Sacred Forest Meadow", Select_LoadGame, 0x00FC }, { " 7:Lake Hylia", Select_LoadGame, 0x0102 }, { " 8:Zora's Domain", Select_LoadGame, 0x0108 }, { " 9:Zora's Fountain", Select_LoadGame, 0x010E }, { "10:Gerudo Valley", Select_LoadGame, 0x0117 }, { "11:Lost Woods", Select_LoadGame, 0x011E }, { "12:Desert Colossus", Select_LoadGame, 0x0123 }, { "13:Gerudo's Fortress", Select_LoadGame, 0x0129 }, { "14:Haunted Wasteland", Select_LoadGame, 0x0130 }, { "15:Hyrule Castle", Select_LoadGame, 0x0138 }, { "16:Death Mountain Trail", Select_LoadGame, 0x013D }, { "17:Death Mountain Crater", Select_LoadGame, 0x0147 }, { "18:Goron City", Select_LoadGame, 0x014D }, { "19:Lon Lon Ranch", Select_LoadGame, 0x0157 }, { "20:Temple Of Time", Select_LoadGame, 0x0053 }, { "21:Chamber of Sages", Select_LoadGame, 0x006B }, { "22:Shooting Gallery", Select_LoadGame, 0x003B }, { "23:Castle Courtyard Game", Select_LoadGame, 0x007A }, { "24:Grave 1", Select_LoadGame, 0x031C }, { "25:Grave 2", Select_LoadGame, 0x004B }, { "26:Royal Family's Tomb", Select_LoadGame, 0x002D }, { "27:Great Fairy's Fountain (Upgrades)", Select_LoadGame, 0x0315 }, { "28:Fairy's Fountain (Grotto)", Select_LoadGame, 0x036D }, { "29:Great Fairy's Fountain (Magic)", Select_LoadGame, 0x0371 }, { "30:Ganon's Tower - Collapsing", Select_LoadGame, 0x043F }, { "31:Castle Courtyard", Select_LoadGame, 0x0400 }, { "32:Fishing Pond", Select_LoadGame, 0x045F }, { "33:Bombchu Bowling Alley", Select_LoadGame, 0x0507 }, { "34:Lon Lon Ranch House", Select_LoadGame, 0x004F }, { "35:Lon Lon Ranch Silo", Select_LoadGame, 0x05D0 }, { "36:Guard House", Select_LoadGame, 0x007E }, { "37:Potion Shop", Select_LoadGame, 0x0072 }, { "38:Treasure Chest Game", Select_LoadGame, 0x0063 }, { "39:House Of Skulltula", Select_LoadGame, 0x0550 }, { "40:Entrance to Market", Select_LoadGame, 0x0033 }, { "41:Market", Select_LoadGame, 0x00B1 }, { "42:Back Alley", Select_LoadGame, 0x00AD }, { "43:Temple of Time Exterior", Select_LoadGame, 0x0171 }, { "44:Link's House", Select_LoadGame, 0x00BB }, { "45:Kakariko House 1", Select_LoadGame, 0x02FD }, { "46:Back Alley House 1", Select_LoadGame, 0x043B }, { "47:House of the Know-it-All Brothers", Select_LoadGame, 0x00C9 }, { "48:House of Twins", Select_LoadGame, 0x009C }, { "49:Mido's House", Select_LoadGame, 0x0433 }, { "50:Saria's House", Select_LoadGame, 0x0437 }, { "51:Stable", Select_LoadGame, 0x02F9 }, { "52:Grave Keeper's Hut", Select_LoadGame, 0x030D }, { "53:Dog Lady's House", Select_LoadGame, 0x0398 }, { "54:Impa's House", Select_LoadGame, 0x039C }, { "55:Lakeside Laboratory", Select_LoadGame, 0x0043 }, { "56:Running Man's Tent", Select_LoadGame, 0x03A0 }, { "57:Bazaar", Select_LoadGame, 0x00B7 }, { "58:Kokiri Shop", Select_LoadGame, 0x00C1 }, { "59:Goron Shop", Select_LoadGame, 0x037C }, { "60:Zora Shop", Select_LoadGame, 0x0380 }, { "61:Closed Shop", Select_LoadGame, 0x0384 }, { "62:Potion Shop", Select_LoadGame, 0x0388 }, { "63:Bombchu Shop ", Select_LoadGame, 0x0390 }, { "64:Happy Mask Shop", Select_LoadGame, 0x0530 }, { "65:Gerudo Training Ground", Select_LoadGame, 0x0008 }, { "66:Inside the Deku Tree", Select_LoadGame, 0x0000 }, { "67:Gohma's Lair", Select_LoadGame, 0x040F }, { "68:Dodongo's Cavern", Select_LoadGame, 0x0004 }, { "69:King Dodongo's Lair", Select_LoadGame, 0x040B }, { "70:Inside Jabu-Jabu's Belly", Select_LoadGame, 0x0028 }, { "71:Barinade's Lair", Select_LoadGame, 0x0301 }, { "72:Forest Temple", Select_LoadGame, 0x0169 }, { "73:Phantom Ganon's Lair", Select_LoadGame, 0x000C }, { "74:Bottom of the Well", Select_LoadGame, 0x0098 }, { "75:Shadow Temple", Select_LoadGame, 0x0037 }, { "76:Bongo Bongo's Lair", Select_LoadGame, 0x0413 }, { "77:Fire Temple", Select_LoadGame, 0x0165 }, { "78:Volvagia's Lair", Select_LoadGame, 0x0305 }, { "79:Water Temple", Select_LoadGame, 0x0010 }, { "80:Morpha's Lair", Select_LoadGame, 0x0417 }, { "81:Spirit Temple", Select_LoadGame, 0x0082 }, { "82:Iron Knuckle's Lair", Select_LoadGame, 0x008D }, { "83:Twinrova's Lair", Select_LoadGame, 0x05EC }, { "84:Stairs to Ganondorf's Lair", Select_LoadGame, 0x041B }, { "85:Ganondorf's Lair", Select_LoadGame, 0x041F }, { "86:Ice Cavern", Select_LoadGame, 0x0088 }, { "87:Dampe Grave Relay Game", Select_LoadGame, 0x044F }, { "88:Inside Ganon's Castle", Select_LoadGame, 0x0467 }, { "89:Ganon's Lair", Select_LoadGame, 0x0517 }, { "90:Escaping Ganon's Castle 1", Select_LoadGame, 0x0179 }, { "91:Escaping Ganon's Castle 2", Select_LoadGame, 0x01B5 }, { "92:Escaping Ganon's Castle 3", Select_LoadGame, 0x03DC }, { "93:Escaping Ganon's Castle 4", Select_LoadGame, 0x03E4 }, { "94:Escaping Ganon's Castle 5", Select_LoadGame, 0x056C }, { "95:Thieves' Hideout 1-2", Select_LoadGame, 0x0486 }, { "96:Thieves' Hideout 3-4 9-10", Select_LoadGame, 0x048E }, { "97:Thieves' Hideout 5-6", Select_LoadGame, 0x0496 }, { "98:Thieves' Hideout 7-8", Select_LoadGame, 0x049E }, { "99:Thieves' Hideout 11-12", Select_LoadGame, 0x04AE }, { "100:Thieves' Hideout 13", Select_LoadGame, 0x0570 }, { "101:Grotto 0", Select_LoadGame, 0x003F }, { "102:Grotto 1", Select_LoadGame, 0x0598 }, { "103:Grotto 2", Select_LoadGame, 0x059C }, { "104:Grotto 3", Select_LoadGame, 0x05A0 }, { "105:Grotto 4", Select_LoadGame, 0x05A4 }, { "106:Grotto 5", Select_LoadGame, 0x05A8 }, { "107:Grotto 6", Select_LoadGame, 0x05AC }, { "108:Grotto 7", Select_LoadGame, 0x05B0 }, { "109:Grotto 8", Select_LoadGame, 0x05B4 }, { "110:Grotto 9", Select_LoadGame, 0x05B8 }, { "111:Grotto 10", Select_LoadGame, 0x05BC }, { "112:Grotto 11", Select_LoadGame, 0x05C0 }, { "113:Grotto 12", Select_LoadGame, 0x05C4 }, { "114:Grotto 13", Select_LoadGame, 0x05FC }, { "115:Goddess Cutscene Environment", Select_LoadGame, 0x00A0 }, { "116:Test Room", Select_LoadGame, 0x0520 }, { "117:SRD Map", Select_LoadGame, 0x0018 }, { "118:Test Map", Select_LoadGame, 0x0094 }, { "119:Treasure Chest Warp", Select_LoadGame, 0x0024 }, { "120:Stalfos Miniboss Room", Select_LoadGame, 0x001C }, { "121:Stalfos Boss Room", Select_LoadGame, 0x0020 }, { "122:Dark Link Room", Select_LoadGame, 0x0047 }, { "123:Shooting Gallery Duplicate", Select_LoadGame, 0x02EA }, { "124:depth test", Select_LoadGame, 0x00B6 }, { "125:Hyrule Garden Game (Broken)", Select_LoadGame, 0x0076 }, { "title", Select_LoadTitle, 0x0000 }, }; static BetterSceneSelectEntry sBetterScenes[] = { { " 1:Hyrule Field", Select_LoadGame, 8, { { "Near Drawbridge", 0x00CD }, { "From Drawbridge", 0x01FD }, { "From Kakariko Village", 0x017D }, { "From Zora River", 0x0181 }, { "From Lost Woods", 0x0185 }, { "From Lake Hylia", 0x0189 }, { "From Gerudo Valley", 0x018D }, { "From Lon Lon Ranch", 0x01F9 }, }}, { " 2:Kokiri Forest", Select_LoadGame, 9, { { "From Links House", 0x0211 }, { "From Bridge", 0x020D }, { "From Lost Woods", 0x0286 }, { "From Deku Tree", 0x0209 }, { "From Kokiri Shop", 0x0266 }, { "From Know-It-All Brothers House", 0x026A }, { "From Twins House", 0x033C }, { "From Midos House", 0x0443 }, { "From Sarias House", 0x0447 }, }}, { " 3:Kokiri Buildings", Select_LoadGame, 6, { { "Links Bed", 0x00BB }, { "Kokiri Shop", 0x00C1 }, { "Twins House", 0x009C }, { "Know-It-All Brothers House", 0x00C9 }, { "Midos House", 0x0433 }, { "Sarias House", 0x0437 }, }}, { " 4:Lost Woods", Select_LoadGame, 5, { { "From Kokiri Forest", 0x011E }, { "From Sacred Meadow", 0x01A9 }, { "From Goron City", 0x04D6 }, { "From Zora River", 0x04DA }, { "Bridge", 0x05E0 }, }}, { " 5:Sacred Forest Meadow", Select_LoadGame, 3, { { "From Lost Woods", 0x00FC }, { "From Forest Temple", 0x0215 }, { "Minuet of Forest Warp", 0x0600 }, }}, { " 6:Castle Town Entrance", Select_LoadGame, 3, { { "From Hyrule Field", 0x0276 }, { "From Market", 0x0033 }, { "From Pot House", 0x026E }, }}, { " 7:Market", Select_LoadGame, 11, { { "From Castle Town Entrance", 0x00B1 }, { "From Shooting Gallery", 0x01CD }, { "From Happy Mask Shop", 0x01D1 }, { "From Treasure Box Minigame", 0x01D5 }, { "From Castle", 0x025A }, { "From Temple of Time", 0x025E }, { "From Back Alley (Right)", 0x0262 }, { "From Back Alley (Left)", 0x029E }, { "From Potion Shop", 0x02A2 }, { "From Bazaar Shop", 0x03B8 }, { "From Bomchu Bowling Minigame", 0x03BC }, }}, { " 8:Castle Town Alley", Select_LoadGame, 5, { { "From Market (Right)", 0x00AD }, { "From Market (Left)", 0x029A }, { "From Alley House", 0x0067 }, { "From Dog House", 0x038C }, { "From Bombchu Shop", 0x03C0 }, }}, { " 9:Castle Town Buildings", Select_LoadGame, 10, { { "Pot House", 0x007E }, { "Shooting Gallery Minigame", 0x016D }, { "Treasure Box Minigame", 0x0063 }, { "Potion Shop", 0x0388 }, { "Bombchu Bowling Minigame", 0x0507 }, { "Bazaar Shop", 0x052C }, { "Happy Mask Shop", 0x0530 }, { "Bombchu Shop", 0x0528 }, { "Dog House", 0x0398 }, { "Alley House", 0x043B }, }}, { "10:Temple of Time", Select_LoadGame, 5, { { "From Outside", 0x053 }, { "From Master Sword Pedestal", 0x02CA }, { "Prelude of Light Warp", 0x05F4 }, { "Outside Temple of Time - From Market", 0x0171 }, { "Outside Temple of Time - From Temple of Time", 0x0472 }, }}, { "11:Hyrule Castle", Select_LoadGame, 5, { { "From Market", 0x0138 }, { "From Castle Courtyard", 0x023D }, { "From Great Fairy", 0x0340 }, { "From Courtyard Guard Capture", 0x04FA }, { "Great Fairy", 0x04C2 }, }}, { "12:Hyrule Castle Courtyard", Select_LoadGame, 3, { { "From Crawlspace", 0x007A }, { "From Zelda", 0x0296 }, { "Zeldas Courtyard", 0x0400 }, }}, { "13:Lon Lon Ranch", Select_LoadGame, 4, { { "From Hyrule Field", 0x0157 }, { "From Ranch House", 0x0378 }, { "From Stables", 0x042F }, { "Epona Song Cutscene", 0x02AE }, }}, { "14:Lon Lon Ranch Buildings", Select_LoadGame, 3, { { "Ranch House", 0x004F }, { "Stables", 0x02F9 }, { "Back Tower", 0x05D0 }, }}, { "15:Kakariko Village", Select_LoadGame, 15, { { "From Hyrule Field", 0x00DB }, { "From Death Mountain", 0x0191 }, { "From Graveyard", 0x0195 }, { "From Bazaar", 0x0201 }, { "From Bottom of Well", 0x02A6 }, { "From Boss House", 0x0349 }, { "From Potion Shop", 0x044B }, { "From Potion Shop (Back Entrance)", 0x04FF }, { "From Grannys Potion Shop", 0x034D }, { "From Impas House", 0x0345 }, { "From Impas House (Cow)", 0x05DC }, { "From Windmill", 0x0351 }, { "From Shooting Gallery", 0x0463 }, { "From Skulltula House", 0x04EE }, { "Owl Drop Spot from Death Mountain", 0x0554 }, }}, { "16:Kakariko Buildings", Select_LoadGame, 9, { { "Shooting Gallery Minigame", 0x003B }, { "Grannys Potion Shop", 0x0072 }, { "Bazaar Shop", 0x00B7 }, { "Potion Shop", 0x0384 }, { "Impas House", 0x039C }, { "Impas House (Near Cow)", 0x05C8 }, { "Boss House", 0x02FD }, { "Windmill", 0x0453 }, { "Skulltula House", 0x0550 }, }}, { "17:Graveyard", Select_LoadGame, 9, { { "From Kakariko", 0x00E4 }, { "From Shadow Temple", 0x0205 }, { "From Gravekeepers Hut", 0x0355 }, { "From Dampes Grave", 0x0359 }, { "From Shield Grave", 0x035D }, { "From Redead Grave", 0x0361 }, { "From Royal Familys Tomb", 0x050B }, { "Inside Dampe's Hut", 0x030D }, { "Nocturne of Shadow Warp", 0x0568 }, }}, { "18:Graves", Select_LoadGame, 5, { { "Dampes Grave Minigame", 0x044F }, { "Royal Familys Tomb", 0x002D }, { "Royal Familys Tomb, Suns Song Cutscene", 0x0574 }, { "Treasure Chest Grave", 0x004B }, { "ReDead Grave", 0x031C }, }}, { "19:Death Mountain Trail", Select_LoadGame, 6, { { "From Kakariko Village", 0x013D }, { "From Goron City", 0x01B9 }, { "From Death Mountain Crater", 0x01BD }, { "From Dodongos Cavern", 0x0242 }, { "From Great Fairy", 0x045B }, { "Great Fairy", 0x0315 }, }}, { "20:Goron City", Select_LoadGame, 5, { { "From Death Mountain Trail", 0x014D }, { "From Death Mountain Crater", 0x01C1 }, { "From Goron City Shop", 0x03FC }, { "From Lost Woods", 0x04E2 }, { "Goron City Shop", 0x037C }, }}, { "21:Death Mountain Crater", Select_LoadGame, 6, { { "From Death Mountain Trail", 0x0147 }, { "From Goron City", 0x0246 }, { "From Fire Temple", 0x024A }, { "From Fairy Fountain", 0x0482 }, { "Great Fairy", 0x04BE }, { "Bolero of Fire Warp", 0x04F6 }, }}, { "22:Zora River", Select_LoadGame, 3, { { "From Hyrule Field", 0x00EA }, { "From Zoras Domain", 0x019D }, { "From Lost Woods", 0x01DD }, }}, { "23:Zoras Domain", Select_LoadGame, 5, { { "From Zora River", 0x0108 }, { "From Zoras Fountain", 0x01A1 }, { "From Lake Hylia", 0x0328 }, { "From Zora Shop", 0x03C4 }, { "Zora Shop", 0x0380 }, }}, { "24:Zoras Fountain", Select_LoadGame, 5, { { "From Zoras Domain", 0x0225 }, { "From Jabu Jabu", 0x0221 }, { "From Ice Cavern", 0x03D4 }, { "From Fairy Fountain", 0x0394 }, { "Great Fairy", 0x0371 }, }}, { "25:Lake Hylia", Select_LoadGame, 7, { { "From Hyrule Field", 0x0102 }, { "From Gerudo Valley", 0x0219 }, { "From Water Temple", 0x021D }, { "From Fishing Pond", 0x0309 }, { "From Laboratory", 0x03CC }, { "From Zoras Domain", 0x0560 }, { "Serenade Of Water Warp", 0x0604 }, }}, { "26:Lake Hylia Buildings", Select_LoadGame, 2, { { "Laboratory", 0x0043 }, { "Fishing Pond Minigame", 0x045F }, }}, { "27:Gerudo Valley", Select_LoadGame, 5, { { "From Hyrule Field", 0x0117 }, { "From Gerudo Fortress", 0x022D }, { "From Carpenter's Tent", 0x03D0 }, { "Carpenter's Tent/ Running Man Minigame", 0x03A0 }, { "Thrown out of Fortress", 0x01A5 }, }}, { "28:Gerudo Fortress", Select_LoadGame, 18, { { "From Gerudo Valley", 0x0129 }, { "From Traning Grounds", 0x03A8 }, { "From Haunted Wasteland", 0x03AC }, { "Horseback Riding Minigame", 0x03B0 }, { "Gerudo Fortress Jail", 0x03B4 }, { "From Thieves Hideout (1)", 0x0231 }, { "From Thieves Hideout (2)", 0x0235 }, { "From Thieves Hideout (3)", 0x0239 }, { "From Thieves Hideout (4)", 0x02AA }, { "From Thieves Hideout (5)", 0x02BA }, { "From Thieves Hideout (6)", 0x02BE }, { "From Thieves Hideout (7)", 0x02C2 }, { "From Thieves Hideout (8)", 0x02C6 }, { "From Thieves Hideout (9)", 0x02D2 }, { "From Thieves Hideout (10)", 0x02D6 }, { "From Thieves Hideout (11)", 0x02DA }, { "From Thieves Hideout (12)", 0x02DE }, { "From Thieves Hideout (13)", 0x03A4 }, }}, { "29:Thieves Hideout", Select_LoadGame, 13, { { "From Gerudo Fortress (1)", 0x0486 }, { "From Gerudo Fortress (2)", 0x048A }, { "From Gerudo Fortress (3)", 0x048E }, { "From Gerudo Fortress (4)", 0x0492 }, { "From Gerudo Fortress (5)", 0x0496 }, { "From Gerudo Fortress (6)", 0x049A }, { "From Gerudo Fortress (7)", 0x049E }, { "From Gerudo Fortress (8)", 0x04A2 }, { "From Gerudo Fortress (9)", 0x04A6 }, { "From Gerudo Fortress (10)", 0x04AA }, { "From Gerudo Fortress (11)", 0x04AE }, { "From Gerudo Fortress (12)", 0x04B2 }, { "From Gerudo Fortress (13)", 0x0570 }, }}, { "30:Haunted Wasteland", Select_LoadGame, 2, { { "From Gerudo Fortress", 0x0130 }, { "From Desert Colossus", 0x0365 }, }}, { "31:Desert Colossus", Select_LoadGame, 7, { { "From Haunted Wasteland", 0x0123 }, { "From Spirit Temple", 0x01E1 }, { "From Spirit Temple (Left Hand)", 0x01E5 }, { "From Spirit Temple (Right Hand)", 0x01E9 }, { "From Fairy Fountain", 0x057C }, { "Great Fairy", 0x0588 }, { "Requiem of Spirit Warp", 0x01F1 }, }}, { "32:Deku Tree", Select_LoadGame, 3, { { "Entrance", 0x0001 }, { "From Gohma Fight", 0x0252 }, { "Gohma Fight", 0x040F }, }}, { "33:Dodongos Cavern", Select_LoadGame, 3, { { "Entrance", 0x0004 }, { "From King Dodongo", 0x00C5 }, { "King Dodongo", 0x040B }, }}, { "34:Jabu Jabu", Select_LoadGame, 2, { { "Entrance", 0x0028 }, { "Barinade Fight", 0x0301 }, }}, { "35:Forest Temple", Select_LoadGame, 4, { { "Entrance", 0x0169 }, { "Crushing Room", 0x0584 }, { "Before Phantom Ganon", 0x024E }, { "Phantom Ganon Fight", 0x000C }, }}, { "36:Fire Temple", Select_LoadGame, 3, { { "Entrance", 0x0165 }, { "Before Volvagia", 0x0175 }, { "Volvagia", 0x0305 }, }}, { "37:Water Temple", Select_LoadGame, 2, { { "Entrance", 0x0010 }, { "Barinade", 0x0417 }, }}, { "38:Shadow Temple", Select_LoadGame, 3, { { "Entrance", 0x0037 }, { "Outside Bongo Bongo", 0x02B2 }, { "Bongo Bongo", 0x0413 }, }}, { "39:Spirit Temple", Select_LoadGame, 6, { { "Entrance", 0x0082 }, { "From Left Hand", 0x03F0 }, { "From Right Hand", 0x03F4 }, { "Before Twinrova", 0x02F5 }, { "Naboora Fight", 0x008D }, { "Twinrova", 0x05EC }, }}, { "40:Ganons Castle", Select_LoadGame, 9, { { "Entrance", 0x0467 }, { "From Tower", 0x0534 }, { "Stairs to Lair - From Castle", 0x041B }, { "Stairs to Lair - From Ganondorf's Lair", 0x0427 }, { "Ganondorf's Lair", 0x041F }, { "Ganondorf Defeated", 0x01C9 }, { "Ganondorf Defeated (2)", 0x04BA }, { "Ganon Battle", 0x0517 }, { "Ganon Death Cutscene", 0x043F }, }}, { "41:Bottom of the Well", Select_LoadGame, 1, { { "Entrance", 0x0098 }, }}, { "42:Ice Cavern", Select_LoadGame, 1, { { "Entrance", 0x0088 }, }}, { "43:Gerudo Training Grounds", Select_LoadGame, 1, { { "Entrance", 0x0008 }, }}, { "44:Warps", Select_LoadGame, 6, { { "Prelude of Light Warp", 0x05F4 }, { "Minuet of Forest Warp", 0x0600 }, { "Bolero of Fire Warp", 0x04F6 }, { "Serenade Of Water Warp", 0x0604 }, { "Nocturne of Shadow Warp", 0x0568 }, { "Requiem of Spirit Warp", 0x01F1 }, }}, { "45:Shops", Select_LoadGame, 9, { { "Kokiri Shop", 0x00C1 }, { "Potion Shop (Market)", 0x0388 }, { "Bazaar Shop (Market)", 0x052C }, { "Happy Mask Shop", 0x0530 }, { "Bombchu Shop", 0x0528 }, { "Bazaar Shop (Kakariko)", 0x00B7 }, { "Potion Shop (Kakariko)", 0x0384 }, { "Goron City Shop", 0x037C }, { "Zora Shop", 0x0380 }, }}, { "46:Great Fairies", Select_LoadGame, 6, { { "Hyrule Castle (Child)", 0x0578 }, { "Hyrule Castle (Adult)", 0x04C2 }, { "Death Mountain Trail", 0x0315 }, { "Death Mountain Crater", 0x04BE }, { "Zoras Fountain", 0x0371 }, { "Desert Colossus", 0x0588 }, }}, { "47:Chest Grottos", Select_Grotto_LoadGame, 11, { { "Kokiri Forest (Song of Storms)", 0x00 }, { "Lost Woods", 0x01 }, { "Sacred Forest Meadow", 0x02 }, { "Hyrule Field (Near Market)", 0x03 }, { "Hyrule Field (Open Near Lake)", 0x04 }, { "Hyrule Field (SE Boulder)", 0x05 }, { "Kakariko (Open)", 0x06 }, { "Kakariko (Redead)", 0x07 }, { "Death Mountain Trail (Song of Storms)", 0x08 }, { "Death Mountain Crater", 0x09 }, { "Zora River (Open)", 0x0A }, }}, { "48:Scrub Grottos", Select_Grotto_LoadGame, 10, { { "Hyrule Field (Near Lake)", 0x0B }, { "Death Mountain Crater", 0x0C }, { "Goron City", 0x0D }, { "Lon Lon Ranch", 0x0E }, { "Lake Hylia", 0x0F }, { "Lost Woods", 0x10 }, { "Zora River (Song of Storms)", 0x11 }, { "Sacred Forest Meadow (Song of Storms)", 0x12 }, { "Gerudo Valley (Song of Storms)", 0x13 }, { "Desert Colossus", 0x14 }, }}, { "49:Other Grottos", Select_Grotto_LoadGame, 7, { { "Scrub Theatre", 0x15 }, { "Spider Grotto (Hyrule Field)", 0x16 }, { "Spider Grotto (Hyrule Castle)", 0x17 }, { "Cow Grotto (Hyrule Field)", 0x18 }, { "Cow Grotto (Death Mountain Trail)", 0x19 }, { "Flooded Grotto (Gerudo Valley)", 0x1A }, { "Flooded Grotto (Hyrule Field)", 0x1B }, }}, { "50:Debug (Use with caution)", Select_LoadGame, 10, { { "Test Room", 0x0520 }, { "SRD Map", 0x0018 }, { "Test Map", 0x0094 }, { "Treasure Chest Warp", 0x0024 }, { "Stalfos Miniboss Room", 0x001C }, { "Stalfos Boss Room", 0x001C }, { "Dark Link Room", 0x0047 }, { "Shooting Gallery Duplicate", 0x02EA }, { "Depth Test", 0x00B6 }, { "Hyrule Garden Game (Broken)", 0x0076 }, }}, }; static BetterSceneSelectGrottoData sBetterGrottos[] = { { 0x003F, 0x00EE, 0, 0x2C, 0x55, { -504.0, 380.0, -1224.0 }}, // Kokiri Forest -> KF Storms Grotto { 0x003F, 0x04D6, 2, 0x14, 0x5B, { 922.0, 0.0, -933.0 }}, // Lost Woods -> LW Near Shortcuts Grotto { 0x05B4, 0x00FC, 0, 0xED, 0x56, { -201.0, 0.0, 1906.0 }}, // SFM Entryway -> SFM Wolfos Grotto { 0x003F, 0x00CD, 0, 0x00, 0x51, { -1428.0, 0.0, 790.0 }}, // Hyrule Field -> HF Near Market Grotto { 0x003F, 0x0189, 0, 0x03, 0x51, { -4026.0, -700.0, 13858.0 }}, // Hyrule Field -> HF Open Grotto { 0x003F, 0x0189, 0, 0x22, 0x51, { -259.0, -500.0, 12356.0 }}, // Hyrule Field -> HF Southeast Grotto { 0x003F, 0x034D, 0, 0x28, 0x52, { 861.0, 80.0, -253.0 }}, // Kak Backyard -> Kak Open Grotto { 0x05A0, 0x034D, 0, 0xE7, 0x52, { -400.0, 0.0, 408.0 }}, // Kakariko Village -> Kak Redead Grotto { 0x003F, 0x01B9, 0, 0x57, 0x60, { -389.0, 1386.0, -1202.0 }}, // Death Mountain -> DMT Storms Grotto { 0x003F, 0x0147, 1, 0x7A, 0x61, { 50.0, 1233.0, 1776.0 }}, // DMC Upper Nearby -> DMC Upper Grotto { 0x003F, 0x019D, 0, 0x29, 0x54, { 369.0, 570.0, 128.0 }}, // Zora River -> ZR Open Grotto { 0x059C, 0x0189, 0, 0xE6, 0x51, { -5002.0, -700.0, 13823.0 }}, // Hyrule Field -> HF Inside Fence Grotto { 0x05A4, 0x0246, 1, 0xF9, 0x61, { -1703.0, 722.0, -481.0 }}, // DMC Lower Nearby -> DMC Hammer Grotto { 0x05A4, 0x014D, 3, 0xFB, 0x62, { 1091.0, 580.0, -1192.0 }}, // GC Grotto Platform -> GC Grotto { 0x05A4, 0x05D4, 0, 0xFC, 0x63, { 1798.0, 0.0, 1498.0 }}, // Lon Lon Ranch -> LLR Grotto { 0x05A4, 0x021D, 0, 0xEF, 0x57, { -3044.0, -1033.0, 6070.0 }}, // Lake Hylia -> LH Grotto { 0x05B0, 0x01A9, 8, 0xF5, 0x5B, { 677.0, 0.0, -2515.0 }}, // LW Beyond Mido -> LW Scrubs Grotto { 0x05BC, 0x00EA, 0, 0xEB, 0x54, { -1632.0, 100.0, -123.0 }}, // Zora River -> ZR Storms Grotto { 0x05BC, 0x0215, 0, 0xEE, 0x56, { 317.0, 480.0, -2303.0 }}, // Sacred Forest Meadow -> SFM Storms Grotto { 0x05BC, 0x03D0, 0, 0xF0, 0x5A, { -1321.0, 15.0, -968.0 }}, // GV Fortress Side -> GV Storms Grotto { 0x05BC, 0x01F1, 0, 0xFD, 0x5C, { 71.0, -32.0, -1303.0 }}, // Desert Colossus -> Colossus Grotto { 0x05C4, 0x04D6, 6, 0xF3, 0x5B, { 75.0, -20.0, -1596.0 }}, // LW Beyond Mido -> Deku Theater { 0x0598, 0x017D, 0, 0xE5, 0x51, { 2059.0, 20.0, -174.0 }}, // Hyrule Field -> HF Near Kak Grotto { 0x05B8, 0x023D, 0, 0xF6, 0x5F, { 986.0, 1571.0, 837.0 }}, // Hyrule Castle Grounds -> HC Storms Grotto { 0x05A8, 0x018D, 0, 0xE4, 0x51, { -7873.0, -300.0, 6916.0 }}, // Hyrule Field -> HF Cow Grotto { 0x05FC, 0x01B9, 0, 0xF8, 0x60, { -678.0, 1946.0, -284.0 }}, // Death Mountain Summit -> DMT Cow Grotto { 0x05AC, 0x0117, 0, 0xF2, 0x5A, { 271.0, -555.0, 1465.0 }}, // GV Grotto Ledge -> GV Octorok Grotto { 0x05C0, 0x00CD, 0, 0xE1, 0x51, { -4945.0, -300.0, 2841.0 }}, // Hyrule Field -> HF Tektite Grotto }; void Select_UpdateMenu(SelectContext* this) { Input* input = &this->state.input[0]; s32 pad; SceneSelectEntry* selectedScene; if (this->verticalInputAccumulator == 0) { if (CHECK_BTN_ALL(input->press.button, BTN_A) || CHECK_BTN_ALL(input->press.button, BTN_START)) { selectedScene = &this->scenes[this->currentScene]; if (selectedScene->loadFunc != NULL) { selectedScene->loadFunc(this, selectedScene->entranceIndex); } } if (CHECK_BTN_ALL(input->press.button, BTN_B)) { if (LINK_AGE_IN_YEARS == YEARS_ADULT) { gSaveContext.linkAge = 1; } else { gSaveContext.linkAge = 0; } } if (CHECK_BTN_ALL(input->press.button, BTN_Z)) { if (gSaveContext.cutsceneIndex == 0x8000) { gSaveContext.cutsceneIndex = 0; } else if (gSaveContext.cutsceneIndex == 0) { gSaveContext.cutsceneIndex = 0xFFF0; } else if (gSaveContext.cutsceneIndex == 0xFFF0) { gSaveContext.cutsceneIndex = 0xFFF1; } else if (gSaveContext.cutsceneIndex == 0xFFF1) { gSaveContext.cutsceneIndex = 0xFFF2; } else if (gSaveContext.cutsceneIndex == 0xFFF2) { gSaveContext.cutsceneIndex = 0xFFF3; } else if (gSaveContext.cutsceneIndex == 0xFFF3) { gSaveContext.cutsceneIndex = 0xFFF4; } else if (gSaveContext.cutsceneIndex == 0xFFF4) { gSaveContext.cutsceneIndex = 0xFFF5; } else if (gSaveContext.cutsceneIndex == 0xFFF5) { gSaveContext.cutsceneIndex = 0xFFF6; } else if (gSaveContext.cutsceneIndex == 0xFFF6) { gSaveContext.cutsceneIndex = 0xFFF7; } else if (gSaveContext.cutsceneIndex == 0xFFF7) { gSaveContext.cutsceneIndex = 0xFFF8; } else if (gSaveContext.cutsceneIndex == 0xFFF8) { gSaveContext.cutsceneIndex = 0xFFF9; } else if (gSaveContext.cutsceneIndex == 0xFFF9) { gSaveContext.cutsceneIndex = 0xFFFA; } else if (gSaveContext.cutsceneIndex == 0xFFFA) { gSaveContext.cutsceneIndex = 0x8000; } } else if (CHECK_BTN_ALL(input->press.button, BTN_R)) { if (gSaveContext.cutsceneIndex == 0x8000) { gSaveContext.cutsceneIndex = 0xFFFA; } else if (gSaveContext.cutsceneIndex == 0) { gSaveContext.cutsceneIndex = 0x8000; } else if (gSaveContext.cutsceneIndex == 0xFFF0) { gSaveContext.cutsceneIndex = 0; } else if (gSaveContext.cutsceneIndex == 0xFFF1) { gSaveContext.cutsceneIndex = 0xFFF0; } else if (gSaveContext.cutsceneIndex == 0xFFF2) { gSaveContext.cutsceneIndex = 0xFFF1; } else if (gSaveContext.cutsceneIndex == 0xFFF3) { gSaveContext.cutsceneIndex = 0xFFF2; } else if (gSaveContext.cutsceneIndex == 0xFFF4) { gSaveContext.cutsceneIndex = 0xFFF3; } else if (gSaveContext.cutsceneIndex == 0xFFF5) { gSaveContext.cutsceneIndex = 0xFFF4; } else if (gSaveContext.cutsceneIndex == 0xFFF6) { gSaveContext.cutsceneIndex = 0xFFF5; } else if (gSaveContext.cutsceneIndex == 0xFFF7) { gSaveContext.cutsceneIndex = 0xFFF6; } else if (gSaveContext.cutsceneIndex == 0xFFF8) { gSaveContext.cutsceneIndex = 0xFFF7; } else if (gSaveContext.cutsceneIndex == 0xFFF9) { gSaveContext.cutsceneIndex = 0xFFF8; } else if (gSaveContext.cutsceneIndex == 0xFFFA) { gSaveContext.cutsceneIndex = 0xFFF9; } } gSaveContext.nightFlag = 0; if (gSaveContext.cutsceneIndex == 0) { gSaveContext.nightFlag = 1; } // user can change "opt", but it doesn't do anything if (CHECK_BTN_ALL(input->press.button, BTN_CUP)) { this->opt--; } if (CHECK_BTN_ALL(input->press.button, BTN_CDOWN)) { this->opt++; } if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) { if (this->lockUp == true) { this->timerUp = 0; } if (this->timerUp == 0) { this->timerUp = 20; this->lockUp = true; Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = R_UPDATE_RATE; } } if (CHECK_BTN_ALL(input->cur.button, BTN_DUP) && this->timerUp == 0) { Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = R_UPDATE_RATE * 3; } if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) { if (this->lockDown == true) { this->timerDown = 0; } if (this->timerDown == 0) { this->timerDown = 20; this->lockDown = true; Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = -R_UPDATE_RATE; } } if (CHECK_BTN_ALL(input->cur.button, BTN_DDOWN) && (this->timerDown == 0)) { Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = -R_UPDATE_RATE * 3; } if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT) || CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) { Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = R_UPDATE_RATE; } if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT) || CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT)) { Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = -R_UPDATE_RATE; } } if (CHECK_BTN_ALL(input->press.button, BTN_L)) { this->pageDownIndex++; this->pageDownIndex = (this->pageDownIndex + ARRAY_COUNT(this->pageDownStops)) % ARRAY_COUNT(this->pageDownStops); this->currentScene = this->topDisplayedScene = this->pageDownStops[this->pageDownIndex]; } this->verticalInputAccumulator += this->verticalInput; if (this->verticalInputAccumulator < -7) { this->verticalInput = 0; this->verticalInputAccumulator = 0; this->currentScene++; this->currentScene = (this->currentScene + this->count) % this->count; if (this->currentScene == ((this->topDisplayedScene + this->count + 19) % this->count)) { this->topDisplayedScene++; this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; } } if (this->verticalInputAccumulator > 7) { this->verticalInput = 0; this->verticalInputAccumulator = 0; if (this->currentScene == this->topDisplayedScene) { this->topDisplayedScene -= 2; this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; } this->currentScene--; this->currentScene = (this->currentScene + this->count) % this->count; if (this->currentScene == ((this->topDisplayedScene + this->count) % this->count)) { this->topDisplayedScene--; this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; } } this->currentScene = (this->currentScene + this->count) % this->count; this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; dREG(80) = this->currentScene; dREG(81) = this->topDisplayedScene; dREG(82) = this->pageDownIndex; if (this->timerUp != 0) { this->timerUp--; } if (this->timerUp == 0) { this->lockUp = false; } if (this->timerDown != 0) { this->timerDown--; } if (this->timerDown == 0) { this->lockDown = false; } } void Better_Select_UpdateMenu(SelectContext* this) { Input* input = &this->state.input[0]; s32 pad; BetterSceneSelectEntry* selectedScene; if (this->verticalInputAccumulator == 0) { if (CHECK_BTN_ALL(input->press.button, BTN_A) || CHECK_BTN_ALL(input->press.button, BTN_START)) { selectedScene = &this->betterScenes[this->currentScene]; if (selectedScene->loadFunc != NULL) { selectedScene->loadFunc(this, selectedScene->entrancePairs[this->pageDownIndex].entranceIndex); } } if (CHECK_BTN_ALL(input->press.button, BTN_B)) { if (LINK_AGE_IN_YEARS == YEARS_ADULT) { gSaveContext.linkAge = 1; Audio_PlaySoundGeneral(NA_SE_VO_LI_SWORD_N_KID, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } else { gSaveContext.linkAge = 0; Audio_PlaySoundGeneral(NA_SE_VO_LI_SWORD_N, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } } if (CHECK_BTN_ALL(input->press.button, BTN_Z) || CHECK_BTN_ALL(input->press.button, BTN_R)) { if (gSaveContext.dayTime > 0xC000 || gSaveContext.dayTime < 0x4555) { gSaveContext.nightFlag = 0; gSaveContext.dayTime = 0x8000; Audio_PlaySoundGeneral(NA_SE_EV_CHICKEN_CRY_M, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } else { gSaveContext.nightFlag = 1; gSaveContext.dayTime = 0x0000; Audio_PlaySoundGeneral(NA_SE_EV_DOG_CRY_EVENING, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } } if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT) || CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) { this->pageDownIndex--; Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); if (this->pageDownIndex < 0) { this->pageDownIndex = this->betterScenes[this->currentScene].count - 1; } } if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT) || CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) { this->pageDownIndex++; Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); if (this->pageDownIndex > this->betterScenes[this->currentScene].count - 1) { this->pageDownIndex = 0; } } if (CHECK_BTN_ALL(input->press.button, BTN_DUP) || CHECK_BTN_ALL(input->press.button, BTN_CUP)) { if (this->lockUp == true) { this->timerUp = 0; } if (this->timerUp == 0) { this->timerUp = 20; this->lockUp = true; Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = R_UPDATE_RATE; } } if ((CHECK_BTN_ALL(input->cur.button, BTN_DUP) || CHECK_BTN_ALL(input->cur.button, BTN_CUP)) && this->timerUp == 0) { Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = R_UPDATE_RATE * 3; } if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN) || CHECK_BTN_ALL(input->press.button, BTN_CDOWN)) { if (this->lockDown == true) { this->timerDown = 0; } if (this->timerDown == 0) { this->timerDown = 20; this->lockDown = true; Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = -R_UPDATE_RATE; } } if ((CHECK_BTN_ALL(input->cur.button, BTN_DDOWN) || CHECK_BTN_ALL(input->cur.button, BTN_CDOWN)) && (this->timerDown == 0)) { Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->verticalInput = -R_UPDATE_RATE * 3; } } this->verticalInputAccumulator += this->verticalInput; if (this->verticalInputAccumulator < -7) { this->verticalInput = 0; this->verticalInputAccumulator = 0; this->currentScene++; this->currentScene = (this->currentScene + this->count) % this->count; this->pageDownIndex = 0; if (this->currentScene == ((this->topDisplayedScene + this->count + 19) % this->count)) { this->topDisplayedScene++; this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; } } if (this->verticalInputAccumulator > 7) { this->verticalInput = 0; this->verticalInputAccumulator = 0; if (this->currentScene == this->topDisplayedScene) { this->topDisplayedScene -= 2; this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; } this->currentScene--; this->currentScene = (this->currentScene + this->count) % this->count; this->pageDownIndex = 0; if (this->currentScene == ((this->topDisplayedScene + this->count) % this->count)) { this->topDisplayedScene--; this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; } } this->currentScene = (this->currentScene + this->count) % this->count; this->topDisplayedScene = (this->topDisplayedScene + this->count) % this->count; dREG(80) = this->currentScene; dREG(81) = this->topDisplayedScene; dREG(82) = this->pageDownIndex; if (this->timerUp != 0) { this->timerUp--; } if (this->timerUp == 0) { this->lockUp = false; } if (this->timerDown != 0) { this->timerDown--; } if (this->timerDown == 0) { this->lockDown = false; } } void Select_PrintMenu(SelectContext* this, GfxPrint* printer) { s32 scene; s32 i; char* name; GfxPrint_SetColor(printer, 255, 155, 150, 255); GfxPrint_SetPos(printer, 12, 2); GfxPrint_Printf(printer, "ZELDA MAP SELECT"); GfxPrint_SetColor(printer, 255, 255, 255, 255); for (i = 0; i < 20; i++) { GfxPrint_SetPos(printer, 9, i + 4); scene = (this->topDisplayedScene + i + this->count) % this->count; if (scene == this->currentScene) { GfxPrint_SetColor(printer, 255, 20, 20, 255); } else { GfxPrint_SetColor(printer, 200, 200, 55, 255); } name = this->scenes[scene].name; if (name == NULL) { name = "**Null**"; } GfxPrint_Printf(printer, "%s", name); }; GfxPrint_SetColor(printer, 155, 55, 150, 255); GfxPrint_SetPos(printer, 20, 26); GfxPrint_Printf(printer, "OPT=%d", this->opt); } void Better_Select_PrintMenu(SelectContext* this, GfxPrint* printer) { s32 scene; s32 i; char* name; GfxPrint_SetColor(printer, 255, 255, 255, 255); GfxPrint_SetPos(printer, 12, 2); GfxPrint_Printf(printer, "Scene Selection"); GfxPrint_SetColor(printer, 255, 255, 255, 255); for (i = 0; i < 20; i++) { GfxPrint_SetPos(printer, 3, i + 4); scene = (this->topDisplayedScene + i + this->count) % this->count; if (scene == this->currentScene) { GfxPrint_SetColor(printer, 255, 100, 100, 255); } else { GfxPrint_SetColor(printer, 175, 175, 175, 255); } name = this->betterScenes[scene].name; if (name == NULL) { name = "**Null**"; } GfxPrint_Printf(printer, "%s", name); }; GfxPrint_SetColor(printer, 205, 100, 200, 255); GfxPrint_SetPos(printer, 3, 26); GfxPrint_Printf(printer, "%s", this->betterScenes[this->currentScene].entrancePairs[this->pageDownIndex].name); } static const char* sLoadingMessages[] = { // "Please wait a minute" GFXP_HIRAGANA "シバラクオマチクダサイ", // "Hold on a sec" GFXP_HIRAGANA "チョット マッテネ", // "Wait a moment" GFXP_KATAKANA "ウェイト ア モーメント", // "Loading" GFXP_KATAKANA "ロード" GFXP_HIRAGANA "チュウ", // "Now working" GFXP_HIRAGANA "ナウ ワーキング", // "Now creating" GFXP_HIRAGANA "イマ ツクッテマス", // "It's not broken" GFXP_HIRAGANA "コショウジャナイヨ", // "Coffee Break" GFXP_KATAKANA "コーヒー ブレイク", // "Please set B side" GFXP_KATAKANA "Bメンヲセットシテクダサイ", // "Be patient, now" GFXP_HIRAGANA "ジット" GFXP_KATAKANA "ガマン" GFXP_HIRAGANA "ノ" GFXP_KATAKANA "コ" GFXP_HIRAGANA "デアッタ", // "Please wait just a minute" GFXP_HIRAGANA "イマシバラクオマチクダサイ", // "Don't worry, don't worry. Take a break, take a break." GFXP_HIRAGANA "アワテナイアワテナイ。ヒトヤスミヒトヤスミ。", }; void Select_PrintLoadingMessage(SelectContext* this, GfxPrint* printer) { s32 randomMsg; GfxPrint_SetPos(printer, 10, 15); GfxPrint_SetColor(printer, 255, 255, 255, 255); randomMsg = Rand_ZeroOne() * ARRAY_COUNT(sLoadingMessages); GfxPrint_Printf(printer, "%s", sLoadingMessages[randomMsg]); } static const char* sAgeLabels[] = { GFXP_HIRAGANA "17(ワカモノ)", // "17(young)" GFXP_HIRAGANA "5(ワカスギ)", // "5(very young)" }; static const char* sBetterAgeLabels[] = { "Adult", "Child", }; void Select_PrintAgeSetting(SelectContext* this, GfxPrint* printer, s32 age) { GfxPrint_SetPos(printer, 4, 26); GfxPrint_SetColor(printer, 255, 255, 55, 255); GfxPrint_Printf(printer, "Age:%s", sAgeLabels[age]); } void Better_Select_PrintAgeSetting(SelectContext* this, GfxPrint* printer, s32 age) { GfxPrint_SetPos(printer, 25, 25); GfxPrint_SetColor(printer, 100, 100, 100, 255); GfxPrint_Printf(printer, "(B)Age:"); GfxPrint_SetColor(printer, 55, 200, 50, 255); GfxPrint_Printf(printer, "%s", sBetterAgeLabels[age]); } void Select_PrintCutsceneSetting(SelectContext* this, GfxPrint* printer, u16 csIndex) { char* label; GfxPrint_SetPos(printer, 4, 25); GfxPrint_SetColor(printer, 255, 255, 55, 255); switch (csIndex) { case 0: label = GFXP_HIRAGANA " ヨル " GFXP_KATAKANA "ゴロン"; gSaveContext.dayTime = 0; break; case 0x8000: // clang-format off gSaveContext.dayTime = 0x8000; label = GFXP_HIRAGANA "オヒル " GFXP_KATAKANA "ジャラ"; // clang-format on break; case 0xFFF0: // clang-format off gSaveContext.dayTime = 0x8000; label = "デモ00"; // clang-format on break; case 0xFFF1: label = "デモ01"; break; case 0xFFF2: label = "デモ02"; break; case 0xFFF3: label = "デモ03"; break; case 0xFFF4: label = "デモ04"; break; case 0xFFF5: label = "デモ05"; break; case 0xFFF6: label = "デモ06"; break; case 0xFFF7: label = "デモ07"; break; case 0xFFF8: label = "デモ08"; break; case 0xFFF9: label = "デモ09"; break; case 0xFFFA: label = "デモ0A"; break; }; gSaveContext.skyboxTime = gSaveContext.dayTime; GfxPrint_Printf(printer, "Stage:" GFXP_KATAKANA "%s", label); } void Better_Select_PrintTimeSetting(SelectContext* this, GfxPrint* printer) { char* label; GfxPrint_SetPos(printer, 22, 24); GfxPrint_SetColor(printer, 100, 100, 100, 255); if (gSaveContext.dayTime > 0xC000 || gSaveContext.dayTime < 0x4555) { label = "Night"; } else { label = "Day"; } GfxPrint_Printf(printer, "(Z/R)Time:"); GfxPrint_SetColor(printer, 200, 200, 55, 255); GfxPrint_Printf(printer, "%s", label); } void Select_DrawMenu(SelectContext* this) { GraphicsContext* gfxCtx = this->state.gfxCtx; GfxPrint* printer; OPEN_DISPS(gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x00, NULL); Gfx_SetupFrame(gfxCtx, 0, 0, 0); SET_FULLSCREEN_VIEWPORT(&this->view); func_800AAA50(&this->view, 0xF); Gfx_SetupDL_28Opa(gfxCtx); printer = alloca(sizeof(GfxPrint)); GfxPrint_Init(printer); GfxPrint_Open(printer, POLY_OPA_DISP); if (CVar_GetS32("gBetterDebugWarpScreen", 0)) { Better_Select_PrintMenu(this, printer); Better_Select_PrintAgeSetting(this, printer, ((void)0, gSaveContext.linkAge)); Better_Select_PrintTimeSetting(this, printer); } else { Select_PrintMenu(this, printer); Select_PrintAgeSetting(this, printer, ((void)0, gSaveContext.linkAge)); Select_PrintCutsceneSetting(this, printer, ((void)0, gSaveContext.cutsceneIndex)); } POLY_OPA_DISP = GfxPrint_Close(printer); GfxPrint_Destroy(printer); CLOSE_DISPS(gfxCtx); } void Select_DrawLoadingScreen(SelectContext* this) { GraphicsContext* gfxCtx = this->state.gfxCtx; GfxPrint* printer; OPEN_DISPS(gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x00, NULL); Gfx_SetupFrame(gfxCtx, 0, 0, 0); SET_FULLSCREEN_VIEWPORT(&this->view); func_800AAA50(&this->view, 0xF); Gfx_SetupDL_28Opa(gfxCtx); printer = alloca(sizeof(GfxPrint)); GfxPrint_Init(printer); GfxPrint_Open(printer, POLY_OPA_DISP); Select_PrintLoadingMessage(this, printer); POLY_OPA_DISP = GfxPrint_Close(printer); GfxPrint_Destroy(printer); CLOSE_DISPS(gfxCtx); } void Select_Draw(SelectContext* this) { GraphicsContext* gfxCtx = this->state.gfxCtx; OPEN_DISPS(gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x00, NULL); Gfx_SetupFrame(gfxCtx, 0, 0, 0); SET_FULLSCREEN_VIEWPORT(&this->view); func_800AAA50(&this->view, 0xF); if (!this->state.running) { Select_DrawLoadingScreen(this); } else { Select_DrawMenu(this); } CLOSE_DISPS(gfxCtx); } void Select_Main(GameState* thisx) { SelectContext* this = (SelectContext*)thisx; if (CVar_GetS32("gBetterDebugWarpScreen", 0)) { Better_Select_UpdateMenu(this); } else { Select_UpdateMenu(this); } Select_Draw(this); } void Select_Destroy(GameState* thisx) { osSyncPrintf("%c", BEL); // "view_cleanup will hang, so it won't be called" osSyncPrintf("*** view_cleanupはハングアップするので、呼ばない ***\n"); } void Select_Init(GameState* thisx) { SelectContext* this = (SelectContext*)thisx; size_t size; s32 pad; this->state.main = Select_Main; this->state.destroy = Select_Destroy; this->scenes = sScenes; this->betterScenes = sBetterScenes; this->betterGrottos = sBetterGrottos; this->topDisplayedScene = 0; this->currentScene = 0; this->pageDownStops[0] = 0; // Hyrule Field this->pageDownStops[1] = 19; // Temple Of Time this->pageDownStops[2] = 37; // Treasure Chest Game this->pageDownStops[3] = 51; // Gravekeeper's Hut this->pageDownStops[4] = 59; // Zora Shop this->pageDownStops[5] = 73; // Bottom of the Well this->pageDownStops[6] = 91; // Escaping Ganon's Tower 3 this->pageDownIndex = 0; this->opt = 0; this->count = CVar_GetS32("gBetterDebugWarpScreen", 0) ? ARRAY_COUNT(sBetterScenes) : ARRAY_COUNT(sScenes); View_Init(&this->view, this->state.gfxCtx); this->view.flags = (0x08 | 0x02); this->verticalInputAccumulator = 0; this->verticalInput = 0; this->timerUp = 0; this->timerDown = 0; this->lockUp = 0; this->lockDown = 0; this->unk_234 = 0; size = (uintptr_t)_z_select_staticSegmentRomEnd - (uintptr_t)_z_select_staticSegmentRomStart; if ((dREG(80) >= 0) && (dREG(80) < this->count)) { this->currentScene = dREG(80); this->topDisplayedScene = dREG(81); this->pageDownIndex = dREG(82); } if (CVar_GetS32("gBetterDebugWarpScreen", 0)) { this->currentScene = CVar_GetS32("gBetterDebugWarpScreenCurrentScene", 0); this->topDisplayedScene = CVar_GetS32("gBetterDebugWarpScreenTopDisplayedScene", 0); this->pageDownIndex = CVar_GetS32("gBetterDebugWarpScreenPageDownIndex", 0); } R_UPDATE_RATE = 1; #if !defined(_MSC_VER) && !defined(__GNUC__) this->staticSegment = GAMESTATE_ALLOC_MC(&this->state, size); DmaMgr_SendRequest1(this->staticSegment, _z_select_staticSegmentRomStart, size, __FILE__, __LINE__); #endif gSaveContext.cutsceneIndex = 0x8000; gSaveContext.linkAge = 1; gSaveContext.nightFlag = 0; gSaveContext.dayTime = 0x8000; }