diff options
author | Diegoisawesome <diego@domoreaweso.me> | 2018-02-17 04:03:59 -0600 |
---|---|---|
committer | Diegoisawesome <diego@domoreaweso.me> | 2018-02-17 04:03:59 -0600 |
commit | ebd88b36060e8958fbf5f3b2028629575c79a243 (patch) | |
tree | 101cf777ea827ff7e68069c5ad45822a629ea75c /src | |
parent | 1605f6253564e4e5f67dd295a1ac70145e5c1c9d (diff) | |
parent | e2932a38ded59a6b794d10024498db718c0b0bb9 (diff) |
Merge branch 'master' of https://github.com/pret/pokeemerald into intro
Diffstat (limited to 'src')
35 files changed, 5707 insertions, 153 deletions
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 75f05e86f..2da48de49 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -76,7 +76,7 @@ extern bool8 sub_81B1250(void); // ? extern bool8 InBattlePike(void); extern bool8 InBattlePyramid(void); extern u16 GetBattlePyramidPickupItemId(void); -extern u8 sav1_map_get_light_level(void); +extern u8 Overworld_GetMapTypeOfSaveblockLocation(void); extern u8 sub_813B21C(void); extern u16 get_unknown_box_id(void); @@ -10578,7 +10578,7 @@ static void atkEF_handleballthrow(void) ballMultiplier = 10; break; case ITEM_DIVE_BALL: - if (sav1_map_get_light_level() == 5) + if (Overworld_GetMapTypeOfSaveblockLocation() == 5) ballMultiplier = 35; else ballMultiplier = 10; diff --git a/src/battle_setup.c b/src/battle_setup.c index fdf6e77b6..5b2bf4d98 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -49,6 +49,8 @@ struct TrainerBattleParameter u8 ptrType; }; +extern void (*gFieldCallback)(void); + extern bool8 InBattlePyramid(void); extern bool8 InBattlePike(void); extern bool32 InTrainerHill(void); @@ -472,7 +474,7 @@ void StartWallyTutorialBattle(void) { CreateMaleMon(&gEnemyParty[0], SPECIES_RALTS, 5); ScriptContext2_Enable(); - gMain.savedCallback = c2_exit_to_overworld_1_continue_scripts_restart_music; + gMain.savedCallback = CB2_ReturnToFieldContinueScript; gBattleTypeFlags = BATTLE_TYPE_WALLY_TUTORIAL; CreateBattleStartTask(B_TRANSITION_SLICE, 0); } @@ -601,7 +603,7 @@ static void CB2_EndWildBattle(void) } else { - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); gFieldCallback = sub_80AF6F0; } } @@ -614,13 +616,13 @@ static void CB2_EndScriptedWildBattle(void) if (IsPlayerDefeated(gBattleOutcome) == TRUE) { if (InBattlePyramid()) - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); else SetMainCallback2(CB2_WhiteOut); } else { - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); } } @@ -937,7 +939,7 @@ static void CB2_StartFirstBattle(void) static void CB2_EndFirstBattle(void) { Overworld_ClearSavedMusic(); - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); } static void sub_80B1218(void) @@ -1313,18 +1315,18 @@ static void CB2_EndTrainerBattle(void) { if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT) { - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); } else if (IsPlayerDefeated(gBattleOutcome) == TRUE) { if (InBattlePyramid() || sub_81D5C18()) - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); else SetMainCallback2(CB2_WhiteOut); } else { - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); if (!InBattlePyramid() && !sub_81D5C18()) { RegisterTrainerInMatchCall(); @@ -1337,7 +1339,7 @@ static void CB2_EndRematchBattle(void) { if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT) { - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); } else if (IsPlayerDefeated(gBattleOutcome) == TRUE) { @@ -1345,7 +1347,7 @@ static void CB2_EndRematchBattle(void) } else { - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); RegisterTrainerInMatchCall(); SetBattledTrainersFlags(); HandleRematchVarsOnBattleEnd(); diff --git a/src/battle_transition.c b/src/battle_transition.c index e0d208f23..8b9b50140 100644 --- a/src/battle_transition.c +++ b/src/battle_transition.c @@ -919,7 +919,7 @@ static void CB2_TestBattleTransition(void) if (IsBattleTransitionDone()) { sTestingTransitionState = 0; - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); } break; } diff --git a/src/berry_blender.c b/src/berry_blender.c index 23594ba46..1ac52dd6c 100644 --- a/src/berry_blender.c +++ b/src/berry_blender.c @@ -161,7 +161,7 @@ extern void copy_textbox_border_tile_patterns_to_vram(u8, u16, u8); extern void sub_81AABF0(void (*callback)(void)); extern void sub_800B4C0(void); extern void ClearLinkCallback(void); -extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void); +extern void CB2_ReturnToFieldContinueScript(void); extern void sub_8153430(void); extern bool8 sub_8153474(void); extern void sub_80EECEC(void); @@ -2692,7 +2692,7 @@ static void CB2_HandlePlayerLinkPlayAgainChoice(void) if (gReceivedRemoteLinkPlayers == 0) { FREE_AND_SET_NULL(sBerryBlenderData); - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); } break; } @@ -2742,7 +2742,7 @@ static void CB2_HandlePlayerPlayAgainChoice(void) if (sBerryBlenderData->playAgainState == PLAY_AGAIN_OK) SetMainCallback2(DoBerryBlending); else - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); FreeAllWindowBuffers(); UnsetBgTilemapBuffer(2); diff --git a/src/birch_pc.c b/src/birch_pc.c new file mode 100644 index 000000000..0f44824f7 --- /dev/null +++ b/src/birch_pc.c @@ -0,0 +1,93 @@ +#include "global.h" +#include "event_data.h" +#include "field_message_box.h" +#include "pokedex.h" +#include "constants/species.h" +#include "strings.h" + +extern u16 gSpecialVar_0x8004; +extern u16 gSpecialVar_0x8005; +extern u16 gSpecialVar_0x8006; + +bool16 ScriptGetPokedexInfo(void) +{ + if (gSpecialVar_0x8004 == 0) // is national dex not present? + { + gSpecialVar_0x8005 = GetHoennPokedexCount(0); + gSpecialVar_0x8006 = GetHoennPokedexCount(1); + } + else + { + gSpecialVar_0x8005 = GetNationalPokedexCount(0); + gSpecialVar_0x8006 = GetNationalPokedexCount(1); + } + + return IsNationalPokedexEnabled(); +} + +// This shows your Hoenn Pokedex rating and not your National Dex. +const u8 *GetPokedexRatingText(u16 count) +{ + if (count < 10) + return gBirchDexRatingText_LessThan10; + if (count < 20) + return gBirchDexRatingText_LessThan20; + if (count < 30) + return gBirchDexRatingText_LessThan30; + if (count < 40) + return gBirchDexRatingText_LessThan40; + if (count < 50) + return gBirchDexRatingText_LessThan50; + if (count < 60) + return gBirchDexRatingText_LessThan60; + if (count < 70) + return gBirchDexRatingText_LessThan70; + if (count < 80) + return gBirchDexRatingText_LessThan80; + if (count < 90) + return gBirchDexRatingText_LessThan90; + if (count < 100) + return gBirchDexRatingText_LessThan100; + if (count < 110) + return gBirchDexRatingText_LessThan110; + if (count < 120) + return gBirchDexRatingText_LessThan120; + if (count < 130) + return gBirchDexRatingText_LessThan130; + if (count < 140) + return gBirchDexRatingText_LessThan140; + if (count < 150) + return gBirchDexRatingText_LessThan150; + if (count < 160) + return gBirchDexRatingText_LessThan160; + if (count < 170) + return gBirchDexRatingText_LessThan170; + if (count < 180) + return gBirchDexRatingText_LessThan180; + if (count < 190) + return gBirchDexRatingText_LessThan190; + if (count < 200) + return gBirchDexRatingText_LessThan200; + if (count == 200) + { + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(SPECIES_JIRACHI), 1) + || GetSetPokedexFlag(SpeciesToNationalPokedexNum(SPECIES_DEOXYS), 1)) // Jirachi or Deoxys is not counted towards the dex completion. If either of these flags are enabled, it means the actual count is less than 200. + return gBirchDexRatingText_LessThan200; + return gBirchDexRatingText_DexCompleted; + } + if (count == 201) + { + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(SPECIES_JIRACHI), 1) + && GetSetPokedexFlag(SpeciesToNationalPokedexNum(SPECIES_DEOXYS), 1)) // If both of these flags are enabled, it means the actual count is less than 200. + return gBirchDexRatingText_LessThan200; + return gBirchDexRatingText_DexCompleted; + } + if (count == 202) + return gBirchDexRatingText_DexCompleted; // Hoenn dex is considered complete, even though the hoenn dex count is 210. + return gBirchDexRatingText_LessThan10; +} + +void ShowPokedexRatingMessage(void) +{ + ShowFieldMessage(GetPokedexRatingText(gSpecialVar_0x8004)); +} diff --git a/src/clock.c b/src/clock.c index 7cea30166..71c433ed2 100644 --- a/src/clock.c +++ b/src/clock.c @@ -83,7 +83,7 @@ static void UpdatePerMinute(struct Time *localTime) static void ReturnFromStartWallClock(void) { InitTimeBasedEvents(); - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); } void StartWallClock(void) diff --git a/src/daycare.c b/src/daycare.c index 89c0a48d8..36e8b208d 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -46,7 +46,7 @@ extern void sub_819746C(u8, bool8); extern void NewMenuHelpers_DrawStdWindowFrame(u8, bool8); extern void sub_81B9328(void); extern void sub_81AF078(u32, bool8, struct ListMenu *); -extern void c2_exit_to_overworld_2_switch(void); +extern void CB2_ReturnToField(void); // this file's functions static void ClearDaycareMonMisc(struct DaycareMiscMon *misc); @@ -1315,5 +1315,5 @@ void ShowDaycareLevelMenu(void) void ChooseSendDaycareMon(void) { sub_81B9328(); - gMain.savedCallback = c2_exit_to_overworld_2_switch; + gMain.savedCallback = CB2_ReturnToField; } diff --git a/src/decoration.c b/src/decoration.c index 8eb875560..c1b12a4d3 100644 --- a/src/decoration.c +++ b/src/decoration.c @@ -38,6 +38,8 @@ #include "decoration.h" #include "graphics.h" +extern void (*gFieldCallback)(void); + // Static type declarations #define OVERWORLD_PLACE_DECOR_SELECTOR_PAL_TAG 0xbe5 @@ -1682,7 +1684,7 @@ void c1_overworld_prev_quest(u8 taskId) sub_812A3C8(); FreeSpritePaletteByTag(OVERWORLD_PLACE_DECOR_SELECTOR_PAL_TAG); gFieldCallback = sub_8128CD4; - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); DestroyTask(taskId); break; } @@ -2673,7 +2675,7 @@ void sub_812A25C(u8 taskId) case 1: sub_812A3C8(); gFieldCallback = sub_812A334; - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); DestroyTask(taskId); break; } diff --git a/src/egg_hatch.c b/src/egg_hatch.c index b78b9433e..e64a98ab1 100644 --- a/src/egg_hatch.c +++ b/src/egg_hatch.c @@ -63,7 +63,7 @@ extern void FadeScreen(u8, u8); extern void overworld_free_bg_tilemaps(void); extern void sub_80AF168(void); extern void ScanlineEffect_Stop(void); -extern void c2_exit_to_overworld_2_switch(void); +extern void CB2_ReturnToField(void); extern void play_some_sound(void); extern void DoNamingScreen(u8, const u8*, u16, u8, u32, MainCallback); extern u16 sub_80D22D0(void); @@ -564,7 +564,7 @@ static void EggHatchSetMonNickname(void) SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3); FreeMonSpritesGfx(); Free(sEggHatchData); - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); } static void Task_EggHatchPlayBGM(u8 taskID) @@ -688,7 +688,7 @@ static void CB2_EggHatch_1(void) UnsetBgTilemapBuffer(0); UnsetBgTilemapBuffer(1); Free(sEggHatchData); - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); } break; } diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 906eff4b7..a5be62442 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -198,7 +198,7 @@ static void npcs_clear_ids_and_state(void) void sub_808D438(void) { - strange_npc_table_clear(); + ZeroAllLinkPlayerMapObjects(); npcs_clear_ids_and_state(); ClearPlayerAvatarInfo(); sub_808D450(); @@ -1673,7 +1673,7 @@ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8 localId, u8 m } else { - mapHeader = get_mapheader_by_bank_and_number(mapGroup, mapNum); + mapHeader = Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum); templates = mapHeader->events->mapObjects; count = mapHeader->events->mapObjectCount; } diff --git a/src/fldeff_softboiled.c b/src/fldeff_softboiled.c new file mode 100644 index 000000000..b61cf9f32 --- /dev/null +++ b/src/fldeff_softboiled.c @@ -0,0 +1,109 @@ +#include "global.h" +#include "menu.h" +#include "party_menu.h" +#include "pokemon.h" +#include "constants/songs.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "strings.h" +#include "task.h" + +void sub_816166C(u8 taskId); +void sub_81617B8(u8 taskId); +void sub_81616C0(u8 taskId); +void sub_8161724(u8 taskId); + +bool8 SetUpFieldMove_SoftBoiled(void) +{ + u16 maxHp; + u16 hp; + u16 minHp; + + maxHp = GetMonData(&gPlayerParty[GetCursorSelectionMonId()], MON_DATA_MAX_HP); + hp = GetMonData(&gPlayerParty[GetCursorSelectionMonId()], MON_DATA_HP); + + minHp = (maxHp / 5); + if (hp > minHp) + return TRUE; + return FALSE; +} + +void sub_8161560(u8 taskId) +{ + gUnknown_0203CEC8.unkB = 0xA; + gUnknown_0203CEC8.unkA = gUnknown_0203CEC8.unk9; + sub_81B0FCC(GetCursorSelectionMonId(), 0x1); + display_pokemon_menu_message(0x5); + gTasks[taskId].func = sub_81B1370; +} + +void sub_81615A8(u8 taskId) +{ + u16 hp; + + u8 unk9 = gUnknown_0203CEC8.unk9; + u8 pokemonIndex = gUnknown_0203CEC8.unkA; + if(pokemonIndex > 6) + { + gUnknown_0203CEC8.unkB = 0; + display_pokemon_menu_message(0x0); + gTasks[taskId].func = sub_81B1370; + return; + } + + hp = GetMonData(&gPlayerParty[pokemonIndex], MON_DATA_HP); + if(hp == 0 || unk9 == pokemonIndex || GetMonData(&gPlayerParty[pokemonIndex], MON_DATA_MAX_HP) == hp) + { + sub_81617B8(taskId); + return; + } + + PlaySE(SE_KAIFUKU); + sub_81B1F18(taskId, unk9, -1, GetMonData(&gPlayerParty[unk9], MON_DATA_MAX_HP)/5, sub_816166C); +} + +void sub_816166C(u8 taskId) +{ + PlaySE(SE_KAIFUKU); + sub_81B1F18(taskId, gUnknown_0203CEC8.unkA, 1, GetMonData(&gPlayerParty[gUnknown_0203CEC8.unk9], MON_DATA_MAX_HP)/5, sub_81616C0); +} + +void sub_81616C0(u8 taskId) +{ + GetMonNickname(&gPlayerParty[gUnknown_0203CEC8.unkA], gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_PkmnHPRestoredByVar2); + sub_81B1B5C(gStringVar4, 0); + schedule_bg_copy_tilemap_to_vram(2); + gTasks[taskId].func = sub_8161724; +} + +void sub_8161724(u8 taskId) +{ + if(sub_81B1BD4() == 1) + return; + gUnknown_0203CEC8.unkB = 0x0; + sub_81B0FCC(gUnknown_0203CEC8.unk9, 0); + gUnknown_0203CEC8.unk9 = gUnknown_0203CEC8.unkA; + sub_81B0FCC(gUnknown_0203CEC8.unkA, 1); + sub_8198070(0x6, FALSE); + ClearWindowTilemap(0x6); + display_pokemon_menu_message(0); + gTasks[taskId].func = sub_81B1370; +} + +void sub_8161784(u8 taskId) +{ + if(sub_81B1BD4() == 1) + return; + display_pokemon_menu_message(0x5); + gTasks[taskId].func = sub_81B1370; +} + +void sub_81617B8(u8 taskId) +{ + PlaySE(SE_SELECT); + sub_81B1B5C(&gText_CantBeUsedOnPkmn, 0); + schedule_bg_copy_tilemap_to_vram(2); + gTasks[taskId].func = sub_8161784; +} diff --git a/src/fldeff_strength.c b/src/fldeff_strength.c new file mode 100644 index 000000000..c1965d983 --- /dev/null +++ b/src/fldeff_strength.c @@ -0,0 +1,44 @@ +#include "global.h" +#include "event_data.h" +#include "event_scripts.h" +#include "field_effect.h" +#include "party_menu.h" +#include "rom6.h" +#include "script.h" +#include "task.h" + +void FldEff_UseStrength(void); +void sub_8145E74(void); + +bool8 SetUpFieldMove_Strength(void) +{ + if (npc_before_player_of_type(87) == TRUE) + { + gSpecialVar_Result = GetCursorSelectionMonId(); + gUnknown_03005DB0 = FieldCallback_Teleport; + gUnknown_0203CEEC = FldEff_UseStrength; + return TRUE; + } + return FALSE; +} + +void FldEff_UseStrength(void) +{ + gFieldEffectArguments[0] = GetCursorSelectionMonId(); + ScriptContext1_SetupScript(FieryPath_EventScript_2908FD); +} + +bool8 sub_8145E2C(void) +{ + u8 taskId = oei_task_add(); + gTasks[taskId].data[8] = (u32)sub_8145E74 >> 16; + gTasks[taskId].data[9] = (u32)sub_8145E74; + GetMonNickname(&gPlayerParty[gFieldEffectArguments[0]], gStringVar1); + return FALSE; +} + +void sub_8145E74(void) +{ + FieldEffectActiveListRemove(FLDEFF_USE_STRENGTH); + EnableBothScriptContexts(); +} diff --git a/src/fldeff_sweetscent.c b/src/fldeff_sweetscent.c new file mode 100644 index 000000000..3dfcd640d --- /dev/null +++ b/src/fldeff_sweetscent.c @@ -0,0 +1,97 @@ +#include "global.h" +#include "constants/rgb.h" +#include "constants/songs.h" +#include "event_data.h" +#include "event_scripts.h" +#include "field_effect.h" +#include "field_player_avatar.h" +#include "field_screen.h" +#include "fldeff_groundshake.h" +#include "palette.h" +#include "party_menu.h" +#include "rom6.h" +#include "script.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "wild_encounter.h" + +void hm2_sweet_scent(void); +void sub_8159F5C(void); +void sub_8159FEC(u8 taskId); +void sub_815A090(u8 taskId); + +bool8 SetUpFieldMove_SweetScent(void) +{ + gUnknown_03005DB0 = FieldCallback_Teleport; + gUnknown_0203CEEC = hm2_sweet_scent; + return TRUE; +} + +void hm2_sweet_scent(void) +{ + FieldEffectStart(FLDEFF_SWEET_SCENT); + gFieldEffectArguments[0] = GetCursorSelectionMonId(); +} + +bool8 FldEff_SweetScent() +{ + u8 taskId; + + sub_80AC3D0(); + taskId = oei_task_add(); + gTasks[taskId].data[8] = (u32)sub_8159F5C >> 16; + gTasks[taskId].data[9] = (u32)sub_8159F5C; + return FALSE; +} + +void sub_8159F5C(void) +{ + u8 taskId; + + PlaySE(SE_W230); + CpuFastSet(gPlttBufferUnfaded, gPaletteDecompressionBuffer, 0x100); + CpuFastSet(gPlttBufferFaded, gPlttBufferUnfaded, 0x100); + BeginNormalPaletteFade(~(1 << (gSprites[GetPlayerAvatarObjectId()].oam.paletteNum + 16)), 4, 0, 8, RGB_RED); + taskId = CreateTask(sub_8159FEC, 0); + gTasks[taskId].data[0] = 0; + FieldEffectActiveListRemove(FLDEFF_SWEET_SCENT); +} + +void sub_8159FEC(u8 taskId) +{ + if (!gPaletteFade.active) + { + sub_81BE72C(); + BlendPalettes(0x00000040, 8, RGB_RED); + if (gTasks[taskId].data[0] == 64) + { + gTasks[taskId].data[0] = 0; + if (SweetScentWildEncounter() == TRUE) + { + DestroyTask(taskId); + } + else + { + gTasks[taskId].func = sub_815A090; + BeginNormalPaletteFade(~(1 << (gSprites[GetPlayerAvatarObjectId()].oam.paletteNum + 16)), 4, 8, 0, RGB_RED); + sub_81BE6B8(); + } + } + else + { + gTasks[taskId].data[0]++; + } + } +} + +void sub_815A090(u8 taskId) +{ + if (!gPaletteFade.active) + { + CpuFastSet(gPaletteDecompressionBuffer, gPlttBufferUnfaded, 0x100); + sub_80AC3E4(); + ScriptContext1_SetupScript(EventScript_290CAE); + DestroyTask(taskId); + } +} diff --git a/src/fldeff_teleport.c b/src/fldeff_teleport.c index 5b3492db0..e675ef0a5 100644 --- a/src/fldeff_teleport.c +++ b/src/fldeff_teleport.c @@ -7,17 +7,14 @@ #include "rom6.h" #include "task.h" -extern bool8 (*gUnknown_03005DB0)(void); -extern void (*gUnknown_0203CEEC)(void); - bool8 SetUpFieldMove_Teleport(void) { if (Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType) == TRUE) { gUnknown_03005DB0 = FieldCallback_Teleport; - gUnknown_0203CEEC = hm_teleport_run_dp02scr; + gUnknown_0203CEEC = hm_teleport_run_dp02scr; return TRUE; - } + } return FALSE; } diff --git a/src/hof_pc.c b/src/hof_pc.c index e772f04e8..e5b6f96f8 100644 --- a/src/hof_pc.c +++ b/src/hof_pc.c @@ -25,7 +25,7 @@ void AccessHallOfFamePC(void) void ReturnFromHallOfFamePC(void) { - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); gFieldCallback = ReshowPCMenuAfterHallOfFamePC; } diff --git a/src/item_menu.c b/src/item_menu.c index b14ae403e..e88d1c2d3 100755 --- a/src/item_menu.c +++ b/src/item_menu.c @@ -155,19 +155,19 @@ void sub_81AD6FC(u8 taskId); // .rodata const struct BgTemplate gUnknown_08613F90[3] = { - {0, 0, 31, 0, 0, 1, 0}, - {1, 0, 30, 0, 0, 0, 0}, + {0, 0, 31, 0, 0, 1, 0}, + {1, 0, 30, 0, 0, 0, 0}, {2, 3, 29, 0, 0, 2, 0} }; - + const struct ListMenuTemplate gUnknown_08613F9C = { NULL, bag_menu_change_item_callback, sub_81AB520, 0, 0, 0, 0, 8, 0, 1, 1, 0, 3, 0, 0, 0, 7, 0 }; const struct MenuAction gUnknown_08613FB4[] = { - {gMenuText_Use, ItemMenu_UseOutOfBattle}, - {gMenuText_Toss, ItemMenu_Toss}, - {gMenuText_Register, ItemMenu_Register}, + {gMenuText_Use, ItemMenu_UseOutOfBattle}, + {gMenuText_Toss, ItemMenu_Toss}, + {gMenuText_Register, ItemMenu_Register}, {gMenuText_Give, ItemMenu_Give}, {gText_Cancel2, ItemMenu_Cancel}, {gMenuText_Use, ItemMenu_UseInBattle}, @@ -214,12 +214,12 @@ const struct YesNoFuncTable gUnknown_08614084 = {BagMenuActuallyToss, BagMenuCan const struct YesNoFuncTable gUnknown_0861408C = {sub_81AD84C, sub_81AD6FC}; -const u16 gUnknown_08614094[] = {0x1C00, 0x110, 0x1064, -1, -1, 0x6F, 0x6F, 0}; +const struct ArrowStruct gUnknown_08614094 = {0, 0x1C, 16, 1, 100, 16, -1, -1, 0x6F, 0x6F, 0}; const u8 gUnknown_086140A4[] = INCBIN_U8("graphics/interface/select_button.4bpp"); const u8 gUnknown_08614164[][3] = { - {0, 1, 3}, + {0, 1, 3}, {0, 1, 4}, {0, 3, 6}, {2, 1, 3}, @@ -252,7 +252,7 @@ const struct WindowTemplate gUnknown_086141AC[] = { // .text struct BagStruct { - void (*bagCallback)(void); + void (*bagCallback)(void); u8 location; u8 pocket; u8 unk6[2]; @@ -339,7 +339,7 @@ void ResetBagScrollPositions(void) void CB2_BagMenuFromStartMenu(void) { - GoToBagMenu(0, 5, sub_8086194); + GoToBagMenu(0, 5, CB2_ReturnToFieldWithOpenMenu); } void sub_81AABB0(void) @@ -630,7 +630,7 @@ void load_bag_item_list_buffers(u8 pocketId) u16 i; struct BagPocket *pocket = &gBagPockets[pocketId]; struct ListMenuItem *subBuffer; - + if (!gUnknown_0203CE54->unk81B_2) { for (i = 0; i < gUnknown_0203CE54->unk829[pocketId] - 1; i++) @@ -903,7 +903,7 @@ u8 sub_81ABB2C(u8 a) void DisplayItemMessage(u8 taskId, u8 fontId, const u8 *str, void ( *callback)(u8 taskId)) { s16* data = gTasks[taskId].data; - + data[10] = AddItemMessageWindow(4); FillWindowPixelBuffer(data[10], 17); DisplayMessageAndContinueTask(taskId, data[10], 10, 13, fontId, GetPlayerTextSpeed(), str, callback); @@ -1056,7 +1056,7 @@ void SwitchBagPocket(u8 taskId, s16 deltaBagPocketId, u16 a3) s16* data = gTasks[taskId].data; u8 pocketId; - + data[13] = 0; data[12] = 0; data[11] = deltaBagPocketId; @@ -1244,7 +1244,7 @@ _081AC09A:\n\ void sub_81AC10C(u8 taskId) { s16* data = gTasks[taskId].data; - + if (!sub_81221AC() && !IsWallysBag()) { switch (GetSwitchBagPocketDirection()) @@ -1317,7 +1317,7 @@ bool8 sub_81AC2C0(void) void bag_menu_swap_items(u8 taskId) { s16* data = gTasks[taskId].data; - + sub_81AF15C(data[0], 16, 1); data[1] = gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket] + gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; gUnknown_0203CE54->unk81A = data[1]; @@ -1335,7 +1335,7 @@ void sub_81AC3C0(u8 taskId) { s16* data = gTasks[taskId].data; int r7; - + if (sub_81221EC() != TRUE) { if (gMain.newKeys & SELECT_BUTTON) @@ -1375,7 +1375,7 @@ void sub_81AC498(u8 taskId) u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; u16 realPos = (*scrollPos + *cursorPos); - + if (data[1] == realPos || data[1] == (realPos - 1)) sub_81AC590(taskId); else @@ -1398,7 +1398,7 @@ void sub_81AC590(u8 taskId) s16* data = gTasks[taskId].data; u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; - + gUnknown_0203CE54->unk81A = -1; sub_81AE6C8(data[0], scrollPos, cursorPos); if (data[1] < (*scrollPos + *cursorPos)) @@ -1689,7 +1689,7 @@ void ItemMenu_UseOutOfBattle(u8 taskId) void ItemMenu_Toss(u8 taskId) { s16* data = gTasks[taskId].data; - + bag_menu_remove_some_window(); data[8] = 1; if (data[2] == 1) @@ -1710,7 +1710,7 @@ void ItemMenu_Toss(u8 taskId) void BagMenuConfirmToss(u8 taskId) { s16* data = gTasks[taskId].data; - + CopyItemName(gSpecialVar_ItemId, gStringVar1); ConvertIntToDecimalStringN(gStringVar2, data[8], 0, 3); StringExpandPlaceholders(gStringVar4, gText_ConfirmTossItems); @@ -1722,7 +1722,7 @@ void BagMenuConfirmToss(u8 taskId) void BagMenuCancelToss(u8 taskId) { s16* data = gTasks[taskId].data; - + bag_menu_print_description_box_text(data[1]); bag_menu_print_cursor_(data[0], 0); set_callback3_to_bag(taskId); @@ -1731,7 +1731,7 @@ void BagMenuCancelToss(u8 taskId) void Task_ChooseHowManyToToss(u8 taskId) { s16* data = gTasks[taskId].data; - + if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE) { sub_81ABC54(gUnknown_0203CE54->unk817, data[8]); @@ -1753,7 +1753,7 @@ void Task_ChooseHowManyToToss(u8 taskId) void BagMenuActuallyToss(u8 taskId) { s16* data = gTasks[taskId].data; - + CopyItemName(gSpecialVar_ItemId, gStringVar1); ConvertIntToDecimalStringN(gStringVar2, data[8], 0, 3); StringExpandPlaceholders(gStringVar4, gText_ThrewAwayVar2Var1s); @@ -1767,7 +1767,7 @@ void Task_ActuallyToss(u8 taskId) s16* data = gTasks[taskId].data; u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; - + if (gMain.newKeys & (A_BUTTON | B_BUTTON)) { PlaySE(SE_SELECT); @@ -1787,7 +1787,7 @@ void ItemMenu_Register(u8 taskId) s16* data = gTasks[taskId].data; u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; - + if (gSaveBlock1Ptr->registeredItem == gSpecialVar_ItemId) gSaveBlock1Ptr->registeredItem = 0; else @@ -1852,7 +1852,7 @@ void ItemMenu_CheckTag(u8 taskId) void ItemMenu_Cancel(u8 taskId) { s16* data = gTasks[taskId].data; - + bag_menu_remove_some_window(); bag_menu_print_description_box_text(data[1]); schedule_bg_copy_tilemap_to_vram(0); @@ -1910,7 +1910,7 @@ void item_menu_type_b(u8 taskId) bool8 UseRegisteredKeyItemOnField(void) { u8 taskId; - + if (InUnionRoom() == TRUE || InBattlePyramid() || InBattlePike() || InMultiBattleRoom() == TRUE) return FALSE; HideMapNamePopUpWindow(); @@ -1938,14 +1938,14 @@ bool8 UseRegisteredKeyItemOnField(void) void display_sell_item_ask_str(u8 taskId) { s16* data = gTasks[taskId].data; - + if (itemid_get_market_price(gSpecialVar_ItemId) == 0) { CopyItemName(gSpecialVar_ItemId, gStringVar2); StringExpandPlaceholders(gStringVar4, gText_CantBuyKeyItem); DisplayItemMessage(taskId, 1, gStringVar4, bag_menu_inits_lists_menu); } - else + else { data[8] = 1; if (data[2] == 1) @@ -1965,7 +1965,7 @@ void display_sell_item_ask_str(u8 taskId) void sub_81AD680(u8 taskId) { s16* data = gTasks[taskId].data; - + ConvertIntToDecimalStringN(gStringVar1, (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8], 0, 6); StringExpandPlaceholders(gStringVar4, gText_ICanPayVar1); DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD6E4); @@ -1979,7 +1979,7 @@ void sub_81AD6E4(u8 taskId) void sub_81AD6FC(u8 taskId) { s16* data = gTasks[taskId].data; - + bag_menu_remove_money_window(); bag_menu_RemoveBagItem_message_window(4); bag_menu_print_cursor_(data[0], 0); @@ -1990,7 +1990,7 @@ void sub_81AD730(u8 taskId) { s16* data = gTasks[taskId].data; u8 windowId = bag_menu_add_window(8); - + sub_81ABCC0(windowId, 1, (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8]); bag_menu_AddMoney_window(); gTasks[taskId].func = sub_81AD794; @@ -1999,7 +1999,7 @@ void sub_81AD730(u8 taskId) void sub_81AD794(u8 taskId) { s16* data = gTasks[taskId].data; - + if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE) { sub_81ABCC0(gUnknown_0203CE54->unk818, data[8], (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8]); @@ -2024,7 +2024,7 @@ void sub_81AD794(u8 taskId) void sub_81AD84C(u8 taskId) { s16* data = gTasks[taskId].data; - + CopyItemName(gSpecialVar_ItemId, gStringVar2); ConvertIntToDecimalStringN(gStringVar1, (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8], 0, 6); StringExpandPlaceholders(gStringVar4, gText_TurnedOverVar1ForVar2); @@ -2036,7 +2036,7 @@ void sub_81AD8C8(u8 taskId) s16* data = gTasks[taskId].data; u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; - + PlaySE(SE_REGI); RemoveBagItem(gSpecialVar_ItemId, data[8]); AddMoney(&gSaveBlock1Ptr->money, (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8]); @@ -2063,7 +2063,7 @@ void sub_81AD9C0(u8 taskId) void display_deposit_item_ask_str(u8 taskId) { s16* data = gTasks[taskId].data; - + data[8] = 1; if (data[2] == 1) { @@ -2083,7 +2083,7 @@ void display_deposit_item_ask_str(u8 taskId) void sub_81ADA7C(u8 taskId) { s16* data = gTasks[taskId].data; - + if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE) { sub_81ABC54(gUnknown_0203CE54->unk817, data[8]); @@ -2107,7 +2107,7 @@ void sub_81ADA7C(u8 taskId) void sub_81ADB14(u8 taskId) { s16* data = gTasks[taskId].data; - + FillWindowPixelBuffer(1, 0); if (itemid_is_unique(gSpecialVar_ItemId)) { @@ -2132,7 +2132,7 @@ void sub_81ADB14(u8 taskId) void sub_81ADC0C(u8 taskId) { s16* data = gTasks[taskId].data; - + if (gMain.newKeys & (A_BUTTON | B_BUTTON)) { PlaySE(SE_SELECT); @@ -2152,7 +2152,7 @@ bool8 IsWallysBag(void) void PrepareBagForWallyTutorial(void) { u32 i; - + gUnknown_0203CE80 = AllocZeroed(sizeof(struct TempWallyStruct)); memcpy(gUnknown_0203CE80->bagPocket_Items, gSaveBlock1Ptr->bagPocket_Items, sizeof(gSaveBlock1Ptr->bagPocket_Items)); memcpy(gUnknown_0203CE80->bagPocket_PokeBalls, gSaveBlock1Ptr->bagPocket_PokeBalls, sizeof(gSaveBlock1Ptr->bagPocket_PokeBalls)); @@ -2170,7 +2170,7 @@ void PrepareBagForWallyTutorial(void) void RestoreBagAfterWallyTutorial(void) { u32 i; - + memcpy(gSaveBlock1Ptr->bagPocket_Items, gUnknown_0203CE80->bagPocket_Items, sizeof(gUnknown_0203CE80->bagPocket_Items)); memcpy(gSaveBlock1Ptr->bagPocket_PokeBalls, gUnknown_0203CE80->bagPocket_PokeBalls, sizeof(gUnknown_0203CE80->bagPocket_PokeBalls)); gUnknown_0203CE58.pocket = gUnknown_0203CE80->pocket; @@ -2193,7 +2193,7 @@ void DoWallyTutorialBagMenu(void) void Task_WallyTutorialBagMenu(u8 taskId) { s16* data = gTasks[taskId].data; - + if (!gPaletteFade.active) { switch (data[8]) @@ -2235,7 +2235,7 @@ void unknown_ItemMenu_Show(u8 taskId) void bag_menu_leave_maybe_3(void) { gFieldCallback = sub_819FA50; - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); } void unknown_ItemMenu_Give2(u8 taskId) @@ -2249,7 +2249,7 @@ void unknown_ItemMenu_Give2(u8 taskId) void bag_menu_leave_maybe_2(void) { gFieldCallback = sub_818DEF4; - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); } void unknown_ItemMenu_Confirm2(u8 taskId) @@ -2262,7 +2262,7 @@ void unknown_ItemMenu_Confirm2(u8 taskId) void bag_menu_leave_maybe(void) { gFieldCallback = sub_818E564; - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); } void bag_menu_print_pocket_names(u8 *pocketName1, u8 *pocketName2) @@ -2270,7 +2270,7 @@ void bag_menu_print_pocket_names(u8 *pocketName1, u8 *pocketName2) struct WindowTemplate window = {0, 0, 0, 0, 0, 0, 0}; u16 windowId; int offset; - + window.width = 16; window.height = 2; windowId = AddWindow(&window); @@ -2304,7 +2304,7 @@ void bag_menu_copy_pocket_name_to_window(u32 a) void setup_bag_menu_textboxes(void) { u8 i; - + InitWindows(gUnknown_08614174); DeactivateAllTextPrinters(); sub_809882C(0, 1, -32); @@ -2328,7 +2328,7 @@ void bag_menu_print(u8 a, u8 b, const u8 *str, u8 c, u8 d, u8 e, u8 f, u8 g, u8 u8 sub_81AE124(u8 a) { return gUnknown_0203CE54->unk810[a]; -} +} u8 bag_menu_add_window(u8 a) { @@ -2409,7 +2409,7 @@ void PrintTMHMMoveData(u16 itemId) u8 i; u16 moveId; const u8* text; - + FillWindowPixelBuffer(4, 0); if (itemId == ITEM_NONE) { diff --git a/src/item_use.c b/src/item_use.c index 2e47e6f14..3b6b286b7 100755 --- a/src/item_use.c +++ b/src/item_use.c @@ -1,6 +1,7 @@ #include "global.h" #include "item_use.h" #include "battle.h" +#include "main.h" #include "berry.h" #include "bike.h" #include "coins.h" @@ -45,7 +46,7 @@ extern void ItemUseOutOfBattle_EvolutionStone(u8 b); extern void bag_menu_mail_related(void); extern void OpenPokeblockCase(u8 a, void(*b)(void)); extern void overworld_free_bg_tilemaps(void); -extern bool32 sav1_map_is_biking_allowed(void); +extern bool32 Overworld_IsBikingAllowed(void); extern bool8 IsPlayerFacingSurfableFishableWater(void); extern bool8 sub_81221AC(void); extern u8 gText_ItemFinderNothing[]; @@ -85,11 +86,12 @@ extern void sub_81C59BC(void); extern void sub_81AB9A8(u8); extern void sub_81ABA88(u8); extern void sub_80B7CC8(void); -extern void flagmods_08054D70(void); +extern void Overworld_ResetStateAfterDigEscRope(void); extern u8* sub_806CF78(u16); extern void sub_81B89F0(void); extern u8 GetItemEffectType(u16); extern struct MapConnection *sub_8088A8C(s16, s16); +extern void (*gFieldCallback)(void); void MapPostLoadHook_UseItem(void); void sub_80AF6D4(void); @@ -119,7 +121,7 @@ void DisplayItemMessageOnField(u8 taskId, u8* str, void(*callback)(u8 taskId)); void sub_81C6714(u8 taskId); void CleanUpAfterFailingToUseRegisteredKeyItemOnField(u8 taskId); void StartFishing(u8 a); -bool8 ItemfinderCheckForHiddenItems(struct MapEvents *, u8); +bool8 ItemfinderCheckForHiddenItems(const struct MapEvents *, u8); u8 sub_80FD9B0(s16 a, s16 b); void sub_80FDA24(u8 a); void sub_80FD8E0(u8 taskId, s16 x, s16 y); @@ -236,7 +238,7 @@ void ItemUseOutOfBattle_Bike(u8 taskId) DisplayCannotDismountBikeMessage(taskId, data[3]); else { - if (sav1_map_is_biking_allowed() == TRUE && IsBikingDisallowedByPlayer() == 0) + if (Overworld_IsBikingAllowed() == TRUE && IsBikingDisallowedByPlayer() == 0) { gUnknown_0203A0F4 = ItemUseOnFieldCB_Bike; SetUpItemUseOnFieldCallback(taskId); @@ -363,7 +365,7 @@ void sub_80FD5CC(u8 taskId) DestroyTask(taskId); } -bool8 ItemfinderCheckForHiddenItems(struct MapEvents *events, u8 taskId) +bool8 ItemfinderCheckForHiddenItems(const struct MapEvents *events, u8 taskId) { int distanceX, distanceY; s16 x, y, i, newDistanceX, newDistanceY; @@ -390,7 +392,7 @@ bool8 ItemfinderCheckForHiddenItems(struct MapEvents *events, u8 taskId) return FALSE; } -bool8 sub_80FD6D4(struct MapEvents *events, s16 x, s16 y) +bool8 sub_80FD6D4(const struct MapEvents *events, s16 x, s16 y) { u8 bgEventCount = events->bgEventCount; struct BgEvent *bgEvent = events->bgEvents; @@ -637,7 +639,7 @@ void sub_80FDC00(u8 taskId) if (!gPaletteFade.active) { overworld_free_bg_tilemaps(); - OpenPokeblockCase(0, c2_exit_to_overworld_2_switch); + OpenPokeblockCase(0, CB2_ReturnToField); DestroyTask(taskId); } } @@ -678,7 +680,7 @@ void sub_80FDD10(u8 taskId) { gUnknown_0203A0F4 = sub_80FDD74; gFieldCallback = MapPostLoadHook_UseItem; - *gUnknown_0203CE54 = c2_exit_to_overworld_2_switch; + *gUnknown_0203CE54 = CB2_ReturnToField; unknown_ItemMenu_Confirm(taskId); } else @@ -904,7 +906,7 @@ void task08_080A1C44(u8 taskId) void re_escape_rope(u8 taskId) { - flagmods_08054D70(); + Overworld_ResetStateAfterDigEscRope(); sub_80FE058(); gTasks[taskId].data[0] = 0; DisplayItemMessageOnField(taskId, gStringVar4, task08_080A1C44); diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index dcdf9b45a..81a10f8a4 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -1079,7 +1079,7 @@ void sub_818E914(void) void sub_818E92C(void) { - OpenPokeblockCase(3, c2_exit_to_overworld_2_switch); + OpenPokeblockCase(3, CB2_ReturnToField); } void sub_818E940(void) diff --git a/src/link.c b/src/link.c index 8f7aa71b6..292ffecf2 100644 --- a/src/link.c +++ b/src/link.c @@ -28,6 +28,8 @@ #include "link.h" #include "link_rfu.h" +extern u16 gUnknown_03005DA8; + // Static type declarations struct BlockTransfer diff --git a/src/link_rfu.c b/src/link_rfu.c index 186d54fd3..a1917ed24 100644 --- a/src/link_rfu.c +++ b/src/link_rfu.c @@ -16,6 +16,8 @@ #include "rom_8011DC0.h" #include "link_rfu.h" +extern u16 gUnknown_03005DA8; + // Static type declarations // Static RAM declarations diff --git a/src/load_save.c b/src/load_save.c index a516c08c2..e3de66bb8 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -133,12 +133,12 @@ void MoveSaveBlocks_ResetHeap(void) } -u8 sav2_x1_query_bit1(void) +u32 GetSecretBase2Field_9(void) { return gSaveBlock2Ptr->specialSaveWarp & 1; } -void sav2_x9_clear_bit1(void) +void ClearSecretBase2Field_9(void) { gSaveBlock2Ptr->specialSaveWarp &= ~1; } diff --git a/src/main_menu.c b/src/main_menu.c index 8608159c2..3d6c1df76 100644 --- a/src/main_menu.c +++ b/src/main_menu.c @@ -1,15 +1,1977 @@ // Includes #include "global.h" +#include "battle_dome_cards.h" +#include "bg.h" +#include "constants/flags.h" +#include "constants/rgb.h" +#include "constants/songs.h" +#include "constants/species.h" +#include "decompress.h" +#include "event_data.h" +#include "field_effect.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "international_string_util.h" +#include "link.h" +#include "main.h" +#include "menu.h" +#include "menu_indicators.h" +#include "mystery_event_menu.h" +#include "naming_screen.h" +#include "option_menu.h" +#include "overworld.h" +#include "palette.h" +#include "pokeball.h" +#include "pokedex.h" +#include "pokemon_3.h" +#include "random.h" +#include "rtc.h" +#include "save.h" +#include "scanline_effect.h" +#include "sound.h" +#include "sprite.h" +#include "string.h" +#include "strings.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "text_window.h" +#include "title_screen.h" +#include "window.h" // Static type declarations // Static RAM declarations +EWRAM_DATA u8 gUnknown_02022D04 = 0; +EWRAM_DATA u16 gUnknown_02022D06 = 0; + IWRAM_DATA u8 gUnknown_03000DD0; // Static ROM declarations +u32 InitMainMenu(bool8); +void Task_MainMenuCheckSaveFile(u8); +void Task_MainMenuCheckBattery(u8); +void Task_WaitForSaveFileErrorWindow(u8); +void CreateMainMenuErrorWindow(const u8*); +void sub_8032250(const struct WindowTemplate*); +void Task_DisplayMainMenu(u8); +void Task_WaitForBatteryDryErrorWindow(u8); +void fmt_savegame(void); +void HighlightSelectedMainMenuItem(u8, u8, s16); +void Task_HandleMainMenuInput(u8); +void Task_HandleMainMenuAPressed(u8); +void Task_HandleMainMenuBPressed(u8); +void task_new_game_prof_birch_speech_1(u8); +void Task_DisplayMainMenuInvalidActionError(u8); +void AddBirchSpeechObjects(u8); +void task_new_game_prof_birch_speech_2(u8); +void sub_8031BAC(u8, u8); +void sub_8031D34(u8, u8); +void task_new_game_prof_birch_speech_3(u8); +void unknown_rbox_to_vram(u8, u8); +void sub_8032318(u8); +void task_new_game_prof_birch_speech_4(u8); +void task_new_game_prof_birch_speech_5(u8); +void sub_80323A0(struct TextSubPrinter *printer, u16 a); +void task_new_game_prof_birch_speech_6(u8); +void sub_8030B14(u8); +void task_new_game_prof_birch_speech_7(u8); +void sub_8031ACC(u8, u8); +void sub_8031C88(u8, u8); +void task_new_game_prof_birch_speech_8(u8); +void task_new_game_prof_birch_speech_9(u8); +void task_new_game_prof_birch_speech_10(u8); +void task_new_game_prof_birch_speech_11(u8); +void LoadMainMenuWindowFrameTiles(u8, u16); +void DrawMainMenuWindowBorder(const struct WindowTemplate*, u16); +void Task_HighlightSelectedMainMenuItem(u8); +void task_new_game_prof_birch_speech_12(u8); +void task_new_game_prof_birch_speech_13(u8); +void sub_8031D74(void); +s8 sub_8031DB4(void); +void sub_80322E0(u8, u8); +void task_new_game_prof_birch_speech_14(u8); +void sub_8030ED4(u8); +void sub_8030F7C(u8); +void task_new_game_prof_birch_speech_15(u8); +void task_new_game_prof_birch_speech_16(u8); +void task_new_game_prof_birch_speech_17(u8); +void new_game_prof_birch_speech_part2_start(void); +void set_default_player_name(u8); +void task_new_game_prof_birch_speech_part2_3(u8); +void task_new_game_prof_birch_speech_part2_4(u8); +void sub_80323CC(u8, u8, u16, u16, u8, u8); +void task_new_game_prof_birch_speech_part2_5(u8); +void task_new_game_prof_birch_speech_part2_6(u8); +void task_new_game_prof_birch_speech_part2_7(u8); +void task_new_game_prof_birch_speech_part2_8(u8); +void task_new_game_prof_birch_speech_part2_9(u8); +void sub_80318D8(struct Sprite*); +void task_new_game_prof_birch_speech_part2_10(u8); +void task_new_game_prof_birch_speech_part2_11(u8); +void task_new_game_prof_birch_speech_part2_12(u8); +void nullsub_11(); +void task_new_game_prof_birch_speech_part2_1(u8); +void fmt_time(void); +void fmt_pokedex(void); +void fmt_player(void); +void fmt_badges(void); +void sub_8032474(u8, u8, u8, u8, u8, u8); + // .rodata +const u16 gUnknown_082FECFC[][16] = { + INCBIN_U16("graphics/birch_speech/bg0.gbapal"), + INCBIN_U16("graphics/birch_speech/bg1.gbapal") +}; + +const u8 gBirchIntroShadowGfx[] = INCBIN_U8("graphics/birch_speech/shadow.4bpp.lz"); +const u8 gUnknown_082FEEF0[] = INCBIN_U8("graphics/birch_speech/map.bin.lz"); +const u16 gUnknown_082FF018[] = INCBIN_U16("graphics/birch_speech/bg2.gbapal"); +const u16 gUnknown_082FF028[] = {0, 0, 0, 0, 0, 0, 0, 0}; + +const struct WindowTemplate gUnknown_082FF038[] = { + {0, 2, 1, 26, 2, 15, 1}, + {0, 2, 5, 26, 2, 15, 0x35} +}; + +const struct WindowTemplate gUnknown_082FF048[] = { + {0, 2, 1, 26, 6, 15, 1}, + {0, 2, 9, 26, 2, 15, 0x9D}, + {0, 2, 13, 26, 2, 15, 0xD1}, + {0, 2, 17, 26, 2, 15, 0x105}, + {0, 2, 21, 26, 2, 15, 0x139} +}; + +const struct WindowTemplate gUnknown_082FF070[] = { + {0, 2, 15, 26, 4, 15, 0x16D}, + {0xFF, 0, 0, 0, 0, 0, 0} +}; + +const struct WindowTemplate gUnknown_082FF080[] = { + {0, 2, 15, 27, 4, 15, 1}, + {0, 3, 5, 6, 4, 15, 0x6D}, + {0, 3, 2, 9, 10, 15, 0x85}, + {0xFF, 0, 0, 0, 0, 0, 0} +}; + +const u16 gMainMenuBgPal[] = INCBIN_U16("graphics/misc/main_menu_bg.gbapal"); +const u16 gMainMenuTextPal[] = INCBIN_U16("graphics/misc/main_menu_text.gbapal"); + +const u8 gUnknown_082FF0E0[] = {10, 11, 12}; +const u8 gUnknown_082FF0E3[] = {10, 1, 12}; + +const struct BgTemplate gUnknown_082FF0E8[] = { + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0 + }, + { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 7, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0 + } +}; + +const struct BgTemplate gUnknown_082FF0F0 = { + .bg = 0, + .charBaseIndex = 3, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0 +}; + +const struct ArrowStruct gUnknown_082FF0F4 = {2, 0x78, 8, 3, 0x78, 0x98, 3, 4, 1, 1, 0}; + +const union AffineAnimCmd gUnknown_082FF104[] = { + AFFINEANIMCMD_FRAME(-2, -2, 0, 0x30), + AFFINEANIMCMD_END +}; + +const union AffineAnimCmd *const gUnknown_082FF114 = gUnknown_082FF104; + +const struct MenuAction gUnknown_082FF118[] = { + {gText_BirchBoy, NULL}, + {gText_BirchGirl, NULL} +}; + +const u8 *const gMalePresetNames[] = { + gText_DefaultNameStu, + gText_DefaultNameMilton, + gText_DefaultNameTom, + gText_DefaultNameKenny, + gText_DefaultNameReid, + gText_DefaultNameJude, + gText_DefaultNameJaxson, + gText_DefaultNameEaston, + gText_DefaultNameWalker, + gText_DefaultNameTeru, + gText_DefaultNameJohnny, + gText_DefaultNameBrett, + gText_DefaultNameSeth, + gText_DefaultNameTerry, + gText_DefaultNameCasey, + gText_DefaultNameDarren, + gText_DefaultNameLandon, + gText_DefaultNameCollin, + gText_DefaultNameStanley, + gText_DefaultNameQuincy +}; + +const u8 *const gFemalePresetNames[] = { + gText_DefaultNameKimmy, + gText_DefaultNameTiara, + gText_DefaultNameBella, + gText_DefaultNameJayla, + gText_DefaultNameAllie, + gText_DefaultNameLianna, + gText_DefaultNameSara, + gText_DefaultNameMonica, + gText_DefaultNameCamila, + gText_DefaultNameAubree, + gText_DefaultNameRuthie, + gText_DefaultNameHazel, + gText_DefaultNameNadine, + gText_DefaultNameTanja, + gText_DefaultNameYasmin, + gText_DefaultNameNicola, + gText_DefaultNameLillie, + gText_DefaultNameTerra, + gText_DefaultNameLucy, + gText_DefaultNameHalie +}; + // .text + +enum +{ + HAS_NO_SAVED_GAME, //NEW GAME, OPTION + HAS_SAVED_GAME, //CONTINUE, NEW GAME, OPTION + HAS_MYSTERY_GIFT, //CONTINUE, NEW GAME, MYSTERY EVENTS, OPTION + HAS_MYSTERY_EVENTS, +}; + +#define MAIN_MENU_BORDER_TILE 0x1D5 + +void CB2_MainMenu(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +void VBlankCB_MainMenu(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +void CB2_InitMainMenu(void) +{ + InitMainMenu(FALSE); +} + +void CB2_ReinitMainMenu(void) +{ + InitMainMenu(TRUE); +} + +u32 InitMainMenu(bool8 returningFromOptionsMenu) +{ + SetVBlankCallback(NULL); + + SetGpuReg(REG_OFFSET_DISPCNT, 0); + SetGpuReg(REG_OFFSET_BG2CNT, 0); + SetGpuReg(REG_OFFSET_BG1CNT, 0); + SetGpuReg(REG_OFFSET_BG0CNT, 0); + SetGpuReg(REG_OFFSET_BG2HOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG1HOFS, 0); + SetGpuReg(REG_OFFSET_BG1VOFS, 0); + SetGpuReg(REG_OFFSET_BG0HOFS, 0); + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + + DmaFill16(3, 0, (void *)VRAM, VRAM_SIZE); + DmaFill32(3, 0, (void *)OAM, OAM_SIZE); + DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2); + + ResetPaletteFade(); + LoadPalette(gMainMenuBgPal, 0, 32); + LoadPalette(gMainMenuTextPal, 0xF0, 32); + ScanlineEffect_Stop(); + ResetTasks(); + ResetSpriteData(); + FreeAllSpritePalettes(); + if (returningFromOptionsMenu) + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0x0000); // fade to black + else + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0xFFFF); // fade to white + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, gUnknown_082FF0E8, 2); + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + InitWindows(gUnknown_082FF038); + DeactivateAllTextPrinters(); + LoadMainMenuWindowFrameTiles(0, MAIN_MENU_BORDER_TILE); + + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + + EnableInterrupts(1); + SetVBlankCallback(VBlankCB_MainMenu); + SetMainCallback2(CB2_MainMenu); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + ShowBg(0); + HideBg(1); + CreateTask(Task_MainMenuCheckSaveFile, 0); + + return 0; +} + +void Task_MainMenuCheckSaveFile(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + if (!gPaletteFade.active) + { + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WININ, 17); + SetGpuReg(REG_OFFSET_WINOUT, 0x31); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_DARKEN | BLDCNT_TGT1_BG0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 7); + + if (sub_80093CC()) + data[15] = 1; + switch (gSaveFileStatus) + { + case 1: + data[0] = HAS_SAVED_GAME; + if (IsMysteryGiftEnabled()) + data[0]++; + gTasks[taskId].func = Task_MainMenuCheckBattery; + break; + case 2: + CreateMainMenuErrorWindow(gText_SaveFileErased); + data[0] = 0; + gTasks[taskId].func = Task_WaitForSaveFileErrorWindow; + break; + case 0xFF: + CreateMainMenuErrorWindow(gText_SaveFileCorrupted); + gTasks[taskId].func = Task_WaitForSaveFileErrorWindow; + data[0] = HAS_SAVED_GAME; + if (IsMysteryGiftEnabled() == TRUE) + data[0]++; + break; + case 0: + default: + data[0] = HAS_NO_SAVED_GAME; + gTasks[taskId].func = Task_MainMenuCheckBattery; + break; + case 4: + CreateMainMenuErrorWindow(gJPText_No1MSubCircuit); + gTasks[taskId].data[0] = HAS_NO_SAVED_GAME; + gTasks[taskId].func = Task_WaitForSaveFileErrorWindow; + break; + } + if (gUnknown_02022D06 & 0x8000) + { + switch (data[0]) + { + case HAS_NO_SAVED_GAME: + case HAS_SAVED_GAME: + gUnknown_02022D06 = data[0] + 1; + break; + case HAS_MYSTERY_GIFT: + gUnknown_02022D06 = 3; + break; + case 3: + gUnknown_02022D06 = 4; + break; + } + } + gUnknown_02022D06 &= 0x7FFF; + data[1] = gUnknown_02022D06; + data[12] = data[0] + 2; + } +} + +void Task_WaitForSaveFileErrorWindow(u8 taskId) +{ + RunTextPrinters(); + if (!IsTextPrinterActive(7) && (gMain.newKeys & A_BUTTON)) + { + ClearWindowTilemap(7); + sub_8032250(gUnknown_082FF070); + gTasks[taskId].func = Task_MainMenuCheckBattery; + } +} + +void Task_MainMenuCheckBattery(u8 taskId) +{ + if (!gPaletteFade.active) + { + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WININ, 17); + SetGpuReg(REG_OFFSET_WINOUT, 0x31); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_DARKEN | BLDCNT_TGT1_BG0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 7); + + if (!(RtcGetErrorStatus() & RTC_ERR_FLAG_MASK)) + { + gTasks[taskId].func = Task_DisplayMainMenu; + } + else + { + CreateMainMenuErrorWindow(gText_BatteryRunDry); + gTasks[taskId].func = Task_WaitForBatteryDryErrorWindow; + } + } +} + +void Task_WaitForBatteryDryErrorWindow(u8 taskId) +{ + RunTextPrinters(); + if (!IsTextPrinterActive(7) && (gMain.newKeys & A_BUTTON)) + { + ClearWindowTilemap(7); + sub_8032250(gUnknown_082FF070); + gTasks[taskId].func = Task_DisplayMainMenu; + } +} + +void Task_DisplayMainMenu(u8 taskId) +{ + s16* data = gTasks[taskId].data; + u16 palette; + + if (!gPaletteFade.active) + { + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WININ, 17); + SetGpuReg(REG_OFFSET_WINOUT, 0x31); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_DARKEN | BLDCNT_TGT1_BG0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 7); + + palette = RGB_BLACK; + LoadPalette(&palette, 254, 2); + + palette = RGB_WHITE; + LoadPalette(&palette, 250, 2); + + palette = RGB(12, 12, 12); + LoadPalette(&palette, 251, 2); + + palette = RGB(26, 26, 25); + LoadPalette(&palette, 252, 2); + + if (gSaveBlock2Ptr->playerGender == MALE) + { + palette = RGB(4, 16, 31); + LoadPalette(&palette, 241, 2); + } + else + { + palette = RGB(31, 3, 21); + LoadPalette(&palette, 241, 2); + } + + switch (gTasks[taskId].data[0]) + { + case HAS_NO_SAVED_GAME: + default: + FillWindowPixelBuffer(0, 0xAA); + FillWindowPixelBuffer(1, 0xAA); + box_print(0, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuNewGame); + box_print(1, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuOption); + PutWindowTilemap(0); + PutWindowTilemap(1); + CopyWindowToVram(0, 2); + CopyWindowToVram(1, 2); + DrawMainMenuWindowBorder(gUnknown_082FF038, MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF038[1], MAIN_MENU_BORDER_TILE); + break; + case HAS_SAVED_GAME: + FillWindowPixelBuffer(2, 0xAA); + FillWindowPixelBuffer(3, 0xAA); + FillWindowPixelBuffer(4, 0xAA); + box_print(2, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuContinue); + box_print(3, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuNewGame); + box_print(4, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuOption); + fmt_savegame(); + PutWindowTilemap(2); + PutWindowTilemap(3); + PutWindowTilemap(4); + CopyWindowToVram(2, 2); + CopyWindowToVram(3, 2); + CopyWindowToVram(4, 2); + DrawMainMenuWindowBorder(gUnknown_082FF048, MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF048[1], MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF048[2], MAIN_MENU_BORDER_TILE); + break; + case HAS_MYSTERY_GIFT: + FillWindowPixelBuffer(2, 0xAA); + FillWindowPixelBuffer(3, 0xAA); + FillWindowPixelBuffer(4, 0xAA); + FillWindowPixelBuffer(5, 0xAA); + box_print(2, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuContinue); + box_print(3, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuNewGame); + box_print(4, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuMysteryGift); + box_print(5, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuOption); + fmt_savegame(); + PutWindowTilemap(2); + PutWindowTilemap(3); + PutWindowTilemap(4); + PutWindowTilemap(5); + CopyWindowToVram(2, 2); + CopyWindowToVram(3, 2); + CopyWindowToVram(4, 2); + CopyWindowToVram(5, 2); + DrawMainMenuWindowBorder(gUnknown_082FF048, MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF048[1], MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF048[2], MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF048[3], MAIN_MENU_BORDER_TILE); + break; + case HAS_MYSTERY_EVENTS: + FillWindowPixelBuffer(2, 0xAA); + FillWindowPixelBuffer(3, 0xAA); + FillWindowPixelBuffer(4, 0xAA); + FillWindowPixelBuffer(5, 0xAA); + FillWindowPixelBuffer(6, 0xAA); + box_print(2, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuContinue); + box_print(3, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuNewGame); + box_print(4, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuMysteryGift2); + box_print(5, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuMysteryEvents); + box_print(6, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuOption); + fmt_savegame(); + PutWindowTilemap(2); + PutWindowTilemap(3); + PutWindowTilemap(4); + PutWindowTilemap(5); + PutWindowTilemap(6); + CopyWindowToVram(2, 2); + CopyWindowToVram(3, 2); + CopyWindowToVram(4, 2); + CopyWindowToVram(5, 2); + CopyWindowToVram(6, 2); + DrawMainMenuWindowBorder(gUnknown_082FF048, MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF048[1], MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF048[2], MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF048[3], MAIN_MENU_BORDER_TILE); + DrawMainMenuWindowBorder(&gUnknown_082FF048[4], MAIN_MENU_BORDER_TILE); + data[13] = AddScrollIndicatorArrowPair(&gUnknown_082FF0F4, &gUnknown_02022D06); + gTasks[data[13]].func = Task_ScrollIndicatorArrowPairOnMainMenu; + if (gUnknown_02022D06 == 4) + { + ChangeBgY(0, 0x2000, 1); + ChangeBgY(1, 0x2000, 1); + data[14] = 1; + gTasks[data[13]].data[15] = 1; + } + break; + } + gTasks[taskId].func = Task_HighlightSelectedMainMenuItem; + } +} + +void Task_HighlightSelectedMainMenuItem(u8 taskId) +{ + HighlightSelectedMainMenuItem(gTasks[taskId].data[0], gTasks[taskId].data[1], gTasks[taskId].data[14]); + gTasks[taskId].func = Task_HandleMainMenuInput; +} + +bool8 HandleMainMenuInput(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + sub_80093CC(); + BeginNormalPaletteFade(-1, 0, 0, 0x10, RGB_BLACK); + gTasks[taskId].func = Task_HandleMainMenuAPressed; + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + BeginNormalPaletteFade(-1, 0, 0, 0x10, RGB_WHITEALPHA); + SetGpuReg(REG_OFFSET_WIN0H, 0xF0); + SetGpuReg(REG_OFFSET_WIN0V, 0xA0); + gTasks[taskId].func = Task_HandleMainMenuBPressed; + } + else if ((gMain.newKeys & DPAD_UP) && data[1] > 0) + { + if (data[0] == 3 && data[14] == 1 && data[1] == 1) + { + ChangeBgY(0, 0x2000, 2); + ChangeBgY(1, 0x2000, 2); + gTasks[data[13]].data[15] = data[14] = 0; + } + data[1]--; + gUnknown_02022D06 = data[1]; + return TRUE; + } + else if ((gMain.newKeys & DPAD_DOWN) && data[1] < data[12] - 1) + { + if (data[0] == 3 && data[1] == 3 && data[14] == 0) + { + ChangeBgY(0, 0x2000, 1); + ChangeBgY(1, 0x2000, 1); + gTasks[data[13]].data[15] = data[14] = 1; + } + data[1]++; + gUnknown_02022D06 = data[1]; + return TRUE; + } + return FALSE; +} + +void Task_HandleMainMenuInput(u8 taskId) +{ + if (HandleMainMenuInput(taskId)) + gTasks[taskId].func = Task_HighlightSelectedMainMenuItem; +} + +void Task_HandleMainMenuAPressed(u8 taskId) +{ + bool8 r2; + u8 action; + + if (!gPaletteFade.active) + { + if (gTasks[taskId].data[0] == 3) + RemoveScrollIndicatorArrowPair(gTasks[taskId].data[13]); + sub_819746C(0, 1); + sub_819746C(1, 1); + sub_819746C(2, 1); + sub_819746C(3, 1); + sub_819746C(4, 1); + sub_819746C(5, 1); + sub_819746C(6, 1); + sub_819746C(7, 1); + r2 = sub_80093CC(); + switch (gTasks[taskId].data[0]) + { + case HAS_NO_SAVED_GAME: + default: + switch (gTasks[taskId].data[1]) + { + case 0: + default: + action = 0; + break; + case 1: + action = 2; + break; + } + break; + case HAS_SAVED_GAME: + switch (gTasks[taskId].data[1]) + { + case 0: + default: + action = 1; + break; + case 1: + action = 0; + break; + case 2: + action = 2; + break; + } + break; + case HAS_MYSTERY_GIFT: + switch (gTasks[taskId].data[1]) + { + case 0: + default: + action = 1; + break; + case 1: + action = 0; + break; + case 2: + action = 3; + if (r2 == FALSE) + { + action = 6; + gTasks[taskId].data[0] = 0; + } + break; + case 3: + action = 2; + break; + } + break; + case HAS_MYSTERY_EVENTS: + switch (gTasks[taskId].data[1]) + { + case 0: + default: + action = 1; + break; + case 1: + action = 0; + break; + case 2: + if (gTasks[taskId].data[15]) + { + action = 3; + if (r2 == FALSE) + { + action = 6; + gTasks[taskId].data[0] = 0; + } + } + else if (r2) + { + action = 6; + gTasks[taskId].data[0] = 1; + } + else + { + action = 5; + } + break; + case 3: + if (r2) + { + action = 6; + gTasks[taskId].data[0] = 2; + } + else + { + action = 4; + } + break; + case 4: + action = 2; + break; + } + break; + } + ChangeBgY(0, 0, 0); + ChangeBgY(1, 0, 0); + switch (action) + { + case 0: + default: + gPlttBufferUnfaded[0] = RGB_BLACK; + gPlttBufferFaded[0] = RGB_BLACK; + gTasks[taskId].func = task_new_game_prof_birch_speech_1; + break; + case 1: + gPlttBufferUnfaded[0] = RGB_BLACK; + gPlttBufferFaded[0] = RGB_BLACK; + SetMainCallback2(CB2_ContinueSavedGame); + DestroyTask(taskId); + break; + case 2: + gMain.savedCallback = CB2_ReinitMainMenu; + SetMainCallback2(CB2_InitOptionMenu); + DestroyTask(taskId); + break; + case 3: + SetMainCallback2(c2_mystery_gift); + DestroyTask(taskId); + break; + case 4: + SetMainCallback2(CB2_InitMysteryEventMenu); + DestroyTask(taskId); + break; + case 5: + SetMainCallback2(sub_801867C); + DestroyTask(taskId); + break; + case 6: + gTasks[taskId].data[1] = 0; + gTasks[taskId].func = Task_DisplayMainMenuInvalidActionError; + gPlttBufferUnfaded[0xF1] = RGB_WHITE; + gPlttBufferFaded[0xF1] = RGB_WHITE; + SetGpuReg(REG_OFFSET_BG2HOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG1HOFS, 0); + SetGpuReg(REG_OFFSET_BG1VOFS, 0); + SetGpuReg(REG_OFFSET_BG0HOFS, 0); + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + BeginNormalPaletteFade(-1, 0, 16, 0, 0); + return; + } + FreeAllWindowBuffers(); + if (action != 2) + gUnknown_02022D06 = 0; + else + gUnknown_02022D06 |= 0x8000; + } +} + +void Task_HandleMainMenuBPressed(u8 taskId) +{ + if (!gPaletteFade.active) + { + if (gTasks[taskId].data[0] == 3) + RemoveScrollIndicatorArrowPair(gTasks[taskId].data[13]); + gUnknown_02022D06 = 0; + FreeAllWindowBuffers(); + SetMainCallback2(CB2_InitTitleScreen); + DestroyTask(taskId); + } +} + +void Task_DisplayMainMenuInvalidActionError(u8 taskId) +{ + switch (gTasks[taskId].data[1]) + { + case 0: + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 30, 20); + switch (gTasks[taskId].data[0]) + { + case 0: + CreateMainMenuErrorWindow(gText_WirelessNotConnected); + break; + case 1: + CreateMainMenuErrorWindow(gText_MysteryGiftCantUse); + break; + case 2: + CreateMainMenuErrorWindow(gText_MysteryEventsCantUse); + break; + } + gTasks[taskId].data[1]++; + break; + case 1: + if (!gPaletteFade.active) + gTasks[taskId].data[1]++; + break; + case 2: + RunTextPrinters(); + if (!IsTextPrinterActive(7)) + gTasks[taskId].data[1]++; + break; + case 3: + if (gMain.newKeys & (A_BUTTON | B_BUTTON)) + { + PlaySE(SE_SELECT); + BeginNormalPaletteFade(-1, 0, 0, 16, RGB_BLACK); + gTasks[taskId].func = Task_HandleMainMenuBPressed; + } + } +} + +void HighlightSelectedMainMenuItem(u8 menuType, u8 selectedMenuItem, s16 a) +{ + SetGpuReg(REG_OFFSET_WIN0H, 0x9E7); + + switch (menuType) + { + case HAS_NO_SAVED_GAME: + default: + switch (selectedMenuItem) + { + case 0: + default: + SetGpuReg(REG_OFFSET_WIN0V, 0x11F); + break; + case 1: + SetGpuReg(REG_OFFSET_WIN0V, 0x213F); + break; + } + break; + case HAS_SAVED_GAME: + switch (selectedMenuItem) + { + case 0: + default: + SetGpuReg(REG_OFFSET_WIN0V, 0x13F); + break; + case 1: + SetGpuReg(REG_OFFSET_WIN0V, 0x415F); + break; + case 2: + SetGpuReg(REG_OFFSET_WIN0V, 0x617F); + break; + } + break; + case HAS_MYSTERY_GIFT: + switch (selectedMenuItem) + { + case 0: + default: + SetGpuReg(REG_OFFSET_WIN0V, 0x13F); + break; + case 1: + SetGpuReg(REG_OFFSET_WIN0V, 0x415F); + break; + case 2: + SetGpuReg(REG_OFFSET_WIN0V, 0x617F); + break; + case 3: + SetGpuReg(REG_OFFSET_WIN0V, 0x819F); + break; + } + break; + case HAS_MYSTERY_EVENTS: + switch (selectedMenuItem) + { + case 0: + default: + SetGpuReg(REG_OFFSET_WIN0V, 0x13F); + break; + case 1: + if (a) + SetGpuReg(REG_OFFSET_WIN0V, 0x213F); + else + SetGpuReg(REG_OFFSET_WIN0V, 0x415F); + break; + case 2: + if (a) + SetGpuReg(REG_OFFSET_WIN0V, 0x415F); + else + SetGpuReg(REG_OFFSET_WIN0V, 0x617F); + break; + case 3: + if (a) + SetGpuReg(REG_OFFSET_WIN0V, 0x617F); + else + SetGpuReg(REG_OFFSET_WIN0V, 0x819F); + break; + case 4: + SetGpuReg(REG_OFFSET_WIN0V, 0x819F); + break; + } + break; + } +} + +void task_new_game_prof_birch_speech_1(u8 taskId) +{ + SetGpuReg(REG_OFFSET_DISPCNT, 0); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + InitBgFromTemplate(&gUnknown_082FF0F0); + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + + LZ77UnCompVram(gBirchIntroShadowGfx, (void*)VRAM); + LZ77UnCompVram(gUnknown_082FEEF0, (void*)(VRAM + 0x3800)); + LoadPalette(gUnknown_082FECFC, 0, 64); + LoadPalette(gUnknown_082FF028, 1, 16); + ScanlineEffect_Stop(); + ResetSpriteData(); + FreeAllSpritePalettes(); + dp13_810BB8C(); + AddBirchSpeechObjects(taskId); + BeginNormalPaletteFade(-1, 0, 16, 0, 0); + gTasks[taskId].data[4] = 0; + gTasks[taskId].func = task_new_game_prof_birch_speech_2; + gTasks[taskId].data[2] = 0xFF; + gTasks[taskId].data[3] = 0xFF; + gTasks[taskId].data[7] = 0xD8; + PlayBGM(MUS_DOORO_X4); + ShowBg(0); + ShowBg(1); +} + +void task_new_game_prof_birch_speech_2(u8 taskId) +{ + u8 spriteId; + + if (gTasks[taskId].data[7]) + { + gTasks[taskId].data[7]--; + } + else + { + spriteId = gTasks[taskId].data[8]; + gSprites[spriteId].pos1.x = 0x88; + gSprites[spriteId].pos1.y = 0x3C; + gSprites[spriteId].invisible = 0; + gSprites[spriteId].oam.objMode = 1; + sub_8031BAC(taskId, 10); + sub_8031D34(taskId, 20); + gTasks[taskId].data[7] = 0x50; + gTasks[taskId].func = task_new_game_prof_birch_speech_3; + } +} + +void task_new_game_prof_birch_speech_3(u8 taskId) +{ + if (gTasks[taskId].data[5]) + { + gSprites[gTasks[taskId].data[8]].oam.objMode = 0; + if (gTasks[taskId].data[7]) + { + gTasks[taskId].data[7]--; + } + else + { + InitWindows(gUnknown_082FF080); + LoadMainMenuWindowFrameTiles(0, 0xF3); + copy_textbox_border_tile_patterns_to_vram(0, 0xFC, 0xF0); + unknown_rbox_to_vram(0, 1); + PutWindowTilemap(0); + CopyWindowToVram(0, 2); + sub_8032318(0); + StringExpandPlaceholders(gStringVar4, gText_Birch_Welcome); + AddTextPrinterForMessage(1); + gTasks[taskId].func = task_new_game_prof_birch_speech_4; + } + } +} + +void task_new_game_prof_birch_speech_4(u8 taskId) +{ + if (!gPaletteFade.active && !sub_8197224()) + { + gTasks[taskId].func = task_new_game_prof_birch_speech_5; + StringExpandPlaceholders(gStringVar4, gText_ThisIsAPokemon); + AddTextPrinterWithCallbackForMessage(1, sub_80323A0); + gUnknown_03000DD0 = taskId; + } +} + +void task_new_game_prof_birch_speech_5(u8 taskId) +{ + if (!sub_8197224()) + { + StringExpandPlaceholders(gStringVar4, gText_Birch_MainSpeech); + AddTextPrinterForMessage(1); + gTasks[taskId].func = task_new_game_prof_birch_speech_6; + } +} + +void sub_8030A70(u8 taskId) +{ + u8 spriteId = gTasks[gUnknown_03000DD0].data[9]; + + gSprites[spriteId].pos1.x = 0x64; + gSprites[spriteId].pos1.y = 0x4B; + gSprites[spriteId].invisible = 0; + gSprites[spriteId].data[0] = 0; + + CreatePokeballSpriteToReleaseMon(spriteId, gSprites[spriteId].oam.paletteNum, 0x70, 0x3A, 0, 0, 0x20, 0xFFFF, SPECIES_LOTAD); + gTasks[taskId].func = sub_8030B14; + gTasks[gUnknown_03000DD0].data[7] = 0; +} + +void sub_8030B14(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + struct Sprite *sprite = &gSprites[gTasks[gUnknown_03000DD0].data[9]]; + + switch (data[0]) + { + case 0: + if (sprite->callback == SpriteCallbackDummy) + { + sprite->oam.affineMode = 0; + goto _08030B98_inc_data0; + } + break; + case 1: + if (gTasks[gUnknown_03000DD0].data[7] >= 0x60) + { + DestroyTask(taskId); + if (gTasks[gUnknown_03000DD0].data[7] < 0x4000) + gTasks[gUnknown_03000DD0].data[7]++; + } + break; + _08030B98_inc_data0: + default: + data[0]++; + if (gTasks[gUnknown_03000DD0].data[7] < 0x4000) + gTasks[gUnknown_03000DD0].data[7]++; + break; + } +} + +void task_new_game_prof_birch_speech_6(u8 taskId) +{ + if (!sub_8197224()) + { + gUnknown_02022D04 = 0; + StringExpandPlaceholders(gStringVar4, gText_Birch_AndYouAre); + AddTextPrinterForMessage(1); + gTasks[taskId].func = task_new_game_prof_birch_speech_7; + } +} + +void task_new_game_prof_birch_speech_7(u8 taskId) +{ + if (!sub_8197224()) + { + gSprites[gTasks[taskId].data[8]].oam.objMode = 1; + gSprites[gTasks[taskId].data[9]].oam.objMode = 1; + sub_8031ACC(taskId, 2); + sub_8031C88(taskId, 1); + gTasks[taskId].data[7] = 0x40; + gTasks[taskId].func = task_new_game_prof_birch_speech_8; + } +} + +void task_new_game_prof_birch_speech_8(u8 taskId) +{ + if (gTasks[taskId].data[4] != -60) + { + gTasks[taskId].data[4] -= 2; + SetGpuReg(REG_OFFSET_BG1HOFS, gTasks[taskId].data[4]); + } + else + { + gTasks[taskId].data[4] = -60; + gTasks[taskId].func = task_new_game_prof_birch_speech_9; + } +} + +void task_new_game_prof_birch_speech_9(u8 taskId) +{ + if (gTasks[taskId].data[5]) + { + gSprites[gTasks[taskId].data[8]].invisible = 1; + gSprites[gTasks[taskId].data[9]].invisible = 1; + if (gTasks[taskId].data[7]) + { + gTasks[taskId].data[7]--; + } + else + { + u8 spriteId = gTasks[taskId].data[10]; + + gSprites[spriteId].pos1.x = 0xB4; + gSprites[spriteId].pos1.y = 0x3C; + gSprites[spriteId].invisible = 0; + gSprites[spriteId].oam.objMode = 1; + gTasks[taskId].data[2] = spriteId; + gTasks[taskId].data[6] = 0; + sub_8031BAC(taskId, 2); + sub_8031D34(taskId, 1); + gTasks[taskId].func = task_new_game_prof_birch_speech_10; + } + } +} + +void task_new_game_prof_birch_speech_10(u8 taskId) +{ + if (gTasks[taskId].data[5]) + { + gSprites[gTasks[taskId].data[2]].oam.objMode = 0; + gTasks[taskId].func = task_new_game_prof_birch_speech_11; + } +} + +void task_new_game_prof_birch_speech_11(u8 taskId) +{ + sub_8032318(0); + StringExpandPlaceholders(gStringVar4, gText_Birch_BoyOrGirl); + AddTextPrinterForMessage(1); + gTasks[taskId].func = task_new_game_prof_birch_speech_12; +} + +void task_new_game_prof_birch_speech_12(u8 taskId) +{ + if (!sub_8197224()) + { + sub_8031D74(); + gTasks[taskId].func = task_new_game_prof_birch_speech_13; + } +} + +void task_new_game_prof_birch_speech_13(u8 taskId) +{ + int gender = sub_8031DB4(); + int r3; + + switch (gender) + { + case MALE: + PlaySE(SE_SELECT); + gSaveBlock2Ptr->playerGender = gender; + sub_80322E0(1, 1); + gTasks[taskId].func = task_new_game_prof_birch_speech_14; + break; + case FEMALE: + PlaySE(SE_SELECT); + gSaveBlock2Ptr->playerGender = gender; + sub_80322E0(1, 1); + gTasks[taskId].func = task_new_game_prof_birch_speech_14; + break; + } + r3 = GetMenuCursorPos(); + if (r3 != gTasks[taskId].data[6]) + { + gTasks[taskId].data[6] = r3; + gSprites[gTasks[taskId].data[2]].oam.objMode = 1; + sub_8031ACC(taskId, 0); + gTasks[taskId].func = sub_8030ED4; + } +} + +void sub_8030ED4(u8 taskId) +{ + u8 spriteId = gTasks[taskId].data[2]; + if (gTasks[taskId].data[5] == 0) + { + gSprites[spriteId].pos1.x += 4; + } + else + { + gSprites[spriteId].invisible = 1; + if (gTasks[taskId].data[6]) + spriteId = gTasks[taskId].data[11]; + else + spriteId = gTasks[taskId].data[10]; + gSprites[spriteId].pos1.x = 0xF0; + gSprites[spriteId].pos1.y = 0x3C; + gSprites[spriteId].invisible = 0; + gTasks[taskId].data[2] = spriteId; + gSprites[spriteId].oam.objMode = 1; + sub_8031BAC(taskId, 0); + gTasks[taskId].func = sub_8030F7C; + } +} + +void sub_8030F7C(u8 taskId) +{ + u8 spriteId = gTasks[taskId].data[2]; + + if (gSprites[spriteId].pos1.x > 0xB4) + { + gSprites[spriteId].pos1.x -= 4; + } + else + { + gSprites[spriteId].pos1.x = 0xB4; + if (gTasks[taskId].data[5]) + { + gSprites[spriteId].oam.objMode = 0; + gTasks[taskId].func = task_new_game_prof_birch_speech_13; + } + } +} + +void task_new_game_prof_birch_speech_14(u8 taskId) +{ + sub_8032318(0); + StringExpandPlaceholders(gStringVar4, gText_Birch_WhatsYourName); + AddTextPrinterForMessage(1); + gTasks[taskId].func = task_new_game_prof_birch_speech_15; +} + +void task_new_game_prof_birch_speech_15(u8 taskId) +{ + if (!sub_8197224()) + gTasks[taskId].func = task_new_game_prof_birch_speech_16; +} + +void task_new_game_prof_birch_speech_16(u8 taskId) +{ + if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON)) + { + BeginNormalPaletteFade(-1, 0, 0, 16, RGB_BLACK); + gTasks[taskId].func = task_new_game_prof_birch_speech_17; + } +} + +void task_new_game_prof_birch_speech_17(u8 taskId) +{ + if (!gPaletteFade.active) + { + FreeAllWindowBuffers(); + sub_818D820(gTasks[taskId].data[9]); + set_default_player_name(Random() % 20); + DestroyTask(taskId); + DoNamingScreen(0, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, new_game_prof_birch_speech_part2_start); + } +} + +void task_new_game_prof_birch_speech_part2_2(u8 taskId) +{ + sub_8032318(0); + StringExpandPlaceholders(gStringVar4, gText_Birch_SoItsPlayer); + AddTextPrinterForMessage(1); + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_3; +} + +void task_new_game_prof_birch_speech_part2_3(u8 taskId) +{ + if (!sub_8197224()) + { + sub_80323CC(2, 1, 0xF3, 0xDF, 2, 15); + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_4; + } +} + +void task_new_game_prof_birch_speech_part2_4(u8 taskId) +{ + switch (ProcessMenuInputNoWrap_()) + { + case 0: + PlaySE(SE_SELECT); + gSprites[gTasks[taskId].data[2]].oam.objMode = 1; + sub_8031ACC(taskId, 2); + sub_8031C88(taskId, 1); + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_5; + break; + case -1: + case 1: + PlaySE(SE_SELECT); + gTasks[taskId].func = task_new_game_prof_birch_speech_11; + } +} + +void task_new_game_prof_birch_speech_part2_5(u8 taskId) +{ + if (gTasks[taskId].data[4]) + { + gTasks[taskId].data[4] += 2; + SetGpuReg(REG_OFFSET_BG1HOFS, gTasks[taskId].data[4]); + } + else + { + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_6; + } +} + +void task_new_game_prof_birch_speech_part2_6(u8 taskId) +{ + u8 spriteId; + + if (gTasks[taskId].data[5]) + { + gSprites[gTasks[taskId].data[10]].invisible = TRUE; + gSprites[gTasks[taskId].data[11]].invisible = TRUE; + spriteId = gTasks[taskId].data[8]; + gSprites[spriteId].pos1.x = 0x88; + gSprites[spriteId].pos1.y = 0x3C; + gSprites[spriteId].invisible = FALSE; + gSprites[spriteId].oam.objMode = 1; + spriteId = gTasks[taskId].data[9]; + gSprites[spriteId].pos1.x = 0x64; + gSprites[spriteId].pos1.y = 0x4B; + gSprites[spriteId].invisible = FALSE; + gSprites[spriteId].oam.objMode = 1; + sub_8031BAC(taskId, 2); + sub_8031D34(taskId, 1); + sub_8032318(0); + StringExpandPlaceholders(gStringVar4, gText_Birch_YourePlayer); + AddTextPrinterForMessage(1); + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_7; + } +} + +void task_new_game_prof_birch_speech_part2_7(u8 taskId) +{ + if (gTasks[taskId].data[5]) + { + gSprites[gTasks[taskId].data[8]].oam.objMode = 0; + gSprites[gTasks[taskId].data[9]].oam.objMode = 0; + if (!sub_8197224()) + { + gSprites[gTasks[taskId].data[8]].oam.objMode = 1; + gSprites[gTasks[taskId].data[9]].oam.objMode = 1; + sub_8031ACC(taskId, 2); + sub_8031C88(taskId, 1); + gTasks[taskId].data[7] = 64; + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_8; + } + } +} + +void task_new_game_prof_birch_speech_part2_8(u8 taskId) +{ + u8 spriteId; + + if (gTasks[taskId].data[5]) + { + gSprites[gTasks[taskId].data[8]].invisible = 1; + gSprites[gTasks[taskId].data[9]].invisible = 1; + if (gTasks[taskId].data[7]) + { + gTasks[taskId].data[7]--; + return; + } + if (gSaveBlock2Ptr->playerGender != MALE) + spriteId = gTasks[taskId].data[11]; + else + spriteId = gTasks[taskId].data[10]; + gSprites[spriteId].pos1.x = 0x78; + gSprites[spriteId].pos1.y = 0x3C; + gSprites[spriteId].invisible = 0; + gSprites[spriteId].oam.objMode = 1; + gTasks[taskId].data[2] = spriteId; + sub_8031BAC(taskId, 2); + sub_8031D34(taskId, 1); + StringExpandPlaceholders(gStringVar4, gText_Birch_AreYouReady); + AddTextPrinterForMessage(1); + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_9; + } +} + +void task_new_game_prof_birch_speech_part2_9(u8 taskId) +{ + u8 spriteId; + + if (gTasks[taskId].data[5]) + { + gSprites[gTasks[taskId].data[2]].oam.objMode = 0; + if (!sub_8197224()) + { + spriteId = gTasks[taskId].data[2]; + gSprites[spriteId].oam.affineMode = 1; + gSprites[spriteId].affineAnims = &gUnknown_082FF114; + InitSpriteAffineAnim(&gSprites[spriteId]); + StartSpriteAffineAnim(&gSprites[spriteId], 0); + gSprites[spriteId].callback = sub_80318D8; + BeginNormalPaletteFade(0x0000FFFF, 0, 0, 16, RGB_BLACK); + FadeOutBGM(4); + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_10; + } + } +} + +void task_new_game_prof_birch_speech_part2_10(u8 taskId) +{ + u8 spriteId = gTasks[taskId].data[2]; + + if (gSprites[spriteId].affineAnimEnded) + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_11; +} + +void task_new_game_prof_birch_speech_part2_11(u8 taskId) +{ + u8 spriteId; + + if (!gPaletteFade.active) + { + spriteId = gTasks[taskId].data[2]; + gSprites[spriteId].callback = nullsub_11; + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + BeginNormalPaletteFade(0xFFFF0000, 0, 0, 16, RGB_WHITEALPHA); + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_12; + } +} + +void task_new_game_prof_birch_speech_part2_12(u8 taskId) +{ + if (!gPaletteFade.active) + { + FreeAllWindowBuffers(); + sub_818D820(gTasks[taskId].data[9]); + dp13_810BB8C(); + SetMainCallback2(CB2_NewGame); + DestroyTask(taskId); + } +} + +void new_game_prof_birch_speech_part2_start(void) +{ + u8 taskId; + u8 spriteId; + u16 savedIme; + + ResetBgsAndClearDma3BusyFlags(0); + SetGpuReg(REG_OFFSET_DISPCNT, 0); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + InitBgsFromTemplates(0, gUnknown_082FF0E8, 2); + InitBgFromTemplate(&gUnknown_082FF0F0); + SetVBlankCallback(NULL); + SetGpuReg(REG_OFFSET_BG2CNT, 0); + SetGpuReg(REG_OFFSET_BG1CNT, 0); + SetGpuReg(REG_OFFSET_BG0CNT, 0); + SetGpuReg(REG_OFFSET_BG2HOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG1HOFS, 0); + SetGpuReg(REG_OFFSET_BG1VOFS, 0); + SetGpuReg(REG_OFFSET_BG0HOFS, 0); + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + DmaFill16(3, 0, VRAM, VRAM_SIZE); + DmaFill32(3, 0, OAM, OAM_SIZE); + DmaFill16(3, 0, PLTT, PLTT_SIZE); + ResetPaletteFade(); + LZ77UnCompVram(gBirchIntroShadowGfx, (u8*)VRAM); + LZ77UnCompVram(gUnknown_082FEEF0, (u8*)(VRAM + 0x3800)); + LoadPalette(gUnknown_082FECFC, 0, 64); + LoadPalette(&gUnknown_082FF018[1], 1, 16); + ResetTasks(); + taskId = CreateTask(task_new_game_prof_birch_speech_part2_1, 0); + gTasks[taskId].data[7] = 5; + gTasks[taskId].data[4] = -60; + ScanlineEffect_Stop(); + ResetSpriteData(); + FreeAllSpritePalettes(); + dp13_810BB8C(); + AddBirchSpeechObjects(taskId); + if (gSaveBlock2Ptr->playerGender != MALE) + { + gTasks[taskId].data[6] = FEMALE; + spriteId = gTasks[taskId].data[11]; + } + else + { + gTasks[taskId].data[6] = MALE; + spriteId = gTasks[taskId].data[10]; + } + gSprites[spriteId].pos1.x = 0xB4; + gSprites[spriteId].pos1.y = 0x3C; + gSprites[spriteId].invisible = 0; + gTasks[taskId].data[2] = spriteId; + SetGpuReg(REG_OFFSET_BG1HOFS, -60); + BeginNormalPaletteFade(-1, 0, 16, 0, 0); + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + ShowBg(0); + ShowBg(1); + savedIme = REG_IME; + REG_IME = 0; + REG_IE |= 1; + REG_IME = savedIme; + SetVBlankCallback(VBlankCB_MainMenu); + SetMainCallback2(CB2_MainMenu); + InitWindows(gUnknown_082FF080); + LoadMainMenuWindowFrameTiles(0, 0xF3); + copy_textbox_border_tile_patterns_to_vram(0, 0xFC, 0xF0); + PutWindowTilemap(0); + CopyWindowToVram(0, 3); +} + +void nullsub_11(struct Sprite *sprite) +{ +} + +void sub_80318D8(struct Sprite *sprite) +{ + u32 y; + + y = (sprite->pos1.y << 16) + sprite->data[0] + 0xC000; + sprite->pos1.y = y >> 16; + sprite->data[0] = y; +} + +u8 sub_80318F4(u8 a, u8 b) +{ + return sub_818D3E4(SPECIES_LOTAD, 8, 0, 1, a, b, 14, -1); +} + +void AddBirchSpeechObjects(u8 taskId) +{ + u8 spriteId = AddNewGameBirchObject(0x88, 0x3C, 1); + u8 spriteId2; + u8 spriteId3; + u8 spriteId4; + + gSprites[spriteId].callback = nullsub_11; + gSprites[spriteId].oam.priority = 0; + gSprites[spriteId].invisible = TRUE; + gTasks[taskId].data[8] = spriteId; + spriteId2 = sub_80318F4(100, 0x4B); + gSprites[spriteId2].callback = nullsub_11; + gSprites[spriteId2].oam.priority = 0; + gSprites[spriteId2].invisible = TRUE; + gTasks[taskId].data[9] = spriteId2; + spriteId3 = CreateTrainerSprite(FacilityClassToPicIndex(0x3C), 0x78, 0x3C, 0, gDecompressionBuffer); + gSprites[spriteId3].callback = nullsub_11; + gSprites[spriteId3].invisible = TRUE; + gSprites[spriteId3].oam.priority = 0; + gTasks[taskId].data[10] = spriteId3; + spriteId4 = CreateTrainerSprite(FacilityClassToPicIndex(0x3F), 0x78, 0x3C, 0, &gDecompressionBuffer[0x800]); + gSprites[spriteId4].callback = nullsub_11; + gSprites[spriteId4].invisible = TRUE; + gSprites[spriteId4].oam.priority = 0; + gTasks[taskId].data[11] = spriteId4; +} + +void sub_8031A5C(u8 taskId) +{ + int alpha; + + if (gTasks[taskId].data[1] == 0) + { + gTasks[gTasks[taskId].data[0]].data[5] = 1; + DestroyTask(taskId); + } + else if (gTasks[taskId].data[4]) + { + gTasks[taskId].data[4]--; + } + else + { + gTasks[taskId].data[4] = gTasks[taskId].data[3]; + gTasks[taskId].data[1]--; + gTasks[taskId].data[2]++; + alpha = gTasks[taskId].data[2] << 8; + SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1] + alpha); + } +} + +void sub_8031ACC(u8 taskId, u8 a) +{ + u8 taskId2; + + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_OBJ); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); + SetGpuReg(REG_OFFSET_BLDY, 0); + gTasks[taskId].data[5] = 0; + taskId2 = CreateTask(sub_8031A5C, 0); + gTasks[taskId2].data[0] = taskId; + gTasks[taskId2].data[1] = 16; + gTasks[taskId2].data[2] = 0; + gTasks[taskId2].data[3] = a; + gTasks[taskId2].data[4] = a; +} + +void sub_8031B3C(u8 taskId) +{ + int alpha; + + if (gTasks[taskId].data[1] == 16) + { + gTasks[gTasks[taskId].data[0]].data[5] = 1; + DestroyTask(taskId); + } + else if (gTasks[taskId].data[4]) + { + gTasks[taskId].data[4]--; + } + else + { + gTasks[taskId].data[4] = gTasks[taskId].data[3]; + gTasks[taskId].data[1]++; + gTasks[taskId].data[2]--; + alpha = gTasks[taskId].data[2] << 8; + SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1] + alpha); + } +} + +void sub_8031BAC(u8 taskId, u8 a) +{ + u8 taskId2; + + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_OBJ); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + SetGpuReg(REG_OFFSET_BLDY, 0); + gTasks[taskId].data[5] = 0; + taskId2 = CreateTask(sub_8031B3C, 0); + gTasks[taskId2].data[0] = taskId; + gTasks[taskId2].data[1] = 0; + gTasks[taskId2].data[2] = 16; + gTasks[taskId2].data[3] = a; + gTasks[taskId2].data[4] = a; +} + +void sub_8031C1C(u8 taskId) +{ + if (gTasks[taskId].data[2]) + { + gTasks[taskId].data[2]--; + } + else if (gTasks[taskId].data[1] == 8) + { + DestroyTask(taskId); + } + else if (gTasks[taskId].data[4]) + { + gTasks[taskId].data[4]--; + } + else + { + gTasks[taskId].data[4] = gTasks[taskId].data[3]; + gTasks[taskId].data[1]++; + LoadPalette(&gUnknown_082FF018[gTasks[taskId].data[1]], 1, 16); + } +} + +void sub_8031C88(u8 taskId, u8 a) +{ + u8 taskId2; + + taskId2 = CreateTask(sub_8031C1C, 0); + gTasks[taskId2].data[0] = taskId; + gTasks[taskId2].data[1] = 0; + gTasks[taskId2].data[2] = 8; + gTasks[taskId2].data[3] = a; + gTasks[taskId2].data[4] = a; +} + +void sub_8031CC8(u8 taskId) +{ + if (gTasks[taskId].data[2]) + { + gTasks[taskId].data[2]--; + } + else if (gTasks[taskId].data[1] == 0) + { + DestroyTask(taskId); + } + else if (gTasks[taskId].data[4]) + { + gTasks[taskId].data[4]--; + } + else + { + gTasks[taskId].data[4] = gTasks[taskId].data[3]; + gTasks[taskId].data[1]--; + LoadPalette(&gUnknown_082FF018[gTasks[taskId].data[1]], 1, 16); + } +} + +void sub_8031D34(u8 taskId, u8 a) +{ + u8 taskId2; + + taskId2 = CreateTask(sub_8031CC8, 0); + gTasks[taskId2].data[0] = taskId; + gTasks[taskId2].data[1] = 8; + gTasks[taskId2].data[2] = 8; + gTasks[taskId2].data[3] = a; + gTasks[taskId2].data[4] = a; +} + +void sub_8031D74(void) +{ + DrawMainMenuWindowBorder(&gUnknown_082FF080[1], 0xF3); + FillWindowPixelBuffer(1, 17); + PrintMenuTable(1, 2, gUnknown_082FF118); + InitMenuInUpperLeftCornerPlaySoundWhenAPressed(1, 2, 0); + PutWindowTilemap(1); + CopyWindowToVram(1, 3); +} + +s8 sub_8031DB4(void) +{ + return ProcessMenuInputNoWrapAround(); +} + +void set_default_player_name(u8 nameId) +{ + const u8* name; + u8 i; + + if (gSaveBlock2Ptr->playerGender == MALE) + name = gMalePresetNames[nameId]; + else + name = gFemalePresetNames[nameId]; + for (i = 0; i < 7; i++) + gSaveBlock2Ptr->playerName[i] = name[i]; + gSaveBlock2Ptr->playerName[7] = 0xFF; +} + +void CreateMainMenuErrorWindow(const u8* str) +{ + FillWindowPixelBuffer(7, 17); + PrintTextOnWindow(7, 1, str, 0, 1, 2, 0); + PutWindowTilemap(7); + CopyWindowToVram(7, 2); + DrawMainMenuWindowBorder(gUnknown_082FF070, MAIN_MENU_BORDER_TILE); + SetGpuReg(REG_OFFSET_WIN0H, 0x9E7); + SetGpuReg(REG_OFFSET_WIN0V, 0x719F); +} + +void fmt_savegame(void) +{ + fmt_time(); + fmt_pokedex(); + fmt_player(); + fmt_badges(); +} + +void fmt_time(void) +{ + StringExpandPlaceholders(gStringVar4, gText_ContinueMenuPlayer); + box_print(2, 1, 0, 17, gUnknown_082FF0E3, -1, gStringVar4); + box_print(2, 1, GetStringRightAlignXOffset(1, gSaveBlock2Ptr->playerName, 100), 17, gUnknown_082FF0E3, -1, gSaveBlock2Ptr->playerName); +} + +void fmt_player(void) +{ + u8 str[0x20]; + u8* ptr; + + StringExpandPlaceholders(gStringVar4, gText_ContinueMenuTime); + box_print(2, 1, 0x6C, 17, gUnknown_082FF0E3, -1, gStringVar4); + ptr = ConvertIntToDecimalStringN(str, gSaveBlock2Ptr->playTimeHours, 0, 3); + *ptr = 0xF0; + ConvertIntToDecimalStringN(ptr + 1, gSaveBlock2Ptr->playTimeMinutes, 2, 2); + box_print(2, 1, GetStringRightAlignXOffset(1, str, 0xD0), 17, gUnknown_082FF0E3, -1, str); +} + +void fmt_pokedex(void) +{ + u8 str[0x20]; + u16 dexCount; + + if (FlagGet(FLAG_SYS_POKEDEX_GET) == TRUE) + { + if (IsNationalPokedexEnabled()) + dexCount = GetNationalPokedexCount(1); + else + dexCount = GetHoennPokedexCount(1); + StringExpandPlaceholders(gStringVar4, gText_ContinueMenuPokedex); + box_print(2, 1, 0, 33, gUnknown_082FF0E3, -1, gStringVar4); + ConvertIntToDecimalStringN(str, dexCount, 0, 3); + box_print(2, 1, GetStringRightAlignXOffset(1, str, 100), 33, gUnknown_082FF0E3, -1, str); + } +} + +void fmt_badges(void) +{ + u8 str[0x20]; + u8 badgeCount = 0; + u32 i; + + for (i = FLAG_BADGE01_GET; i <= FLAG_BADGE08_GET; i++) + { + if (FlagGet(i)) + badgeCount++; + } + StringExpandPlaceholders(gStringVar4, gText_ContinueMenuBadges); + box_print(2, 1, 0x6C, 33, gUnknown_082FF0E3, -1, gStringVar4); + ConvertIntToDecimalStringN(str, badgeCount, 2, 1); + box_print(2, 1, GetStringRightAlignXOffset(1, str, 0xD0), 33, gUnknown_082FF0E3, -1, str); +} + +void LoadMainMenuWindowFrameTiles(u8 bgId, u16 tileOffset) +{ + LoadBgTiles(bgId, GetWindowFrameTilesPal(gSaveBlock2Ptr->optionsWindowFrameType)->tiles, 0x120, tileOffset); + LoadPalette(GetWindowFrameTilesPal(gSaveBlock2Ptr->optionsWindowFrameType)->pal, 32, 32); +} + +void DrawMainMenuWindowBorder(const struct WindowTemplate *template, u16 baseTileNum) +{ + u16 r9 = 1 + baseTileNum; + u16 r10 = 2 + baseTileNum; + u16 sp18 = 3 + baseTileNum; + u16 spC = 5 + baseTileNum; + u16 sp10 = 6 + baseTileNum; + u16 sp14 = 7 + baseTileNum; + u16 r6 = 8 + baseTileNum; + + FillBgTilemapBufferRect(template->priority, baseTileNum, template->tilemapLeft - 1, template->tilemapTop - 1, 1, 1, 2); + FillBgTilemapBufferRect(template->priority, r9, template->tilemapLeft, template->tilemapTop - 1, template->width, 1, 2); + FillBgTilemapBufferRect(template->priority, r10, template->tilemapLeft + template->width, template->tilemapTop - 1, 1, 1, 2); + FillBgTilemapBufferRect(template->priority, sp18, template->tilemapLeft - 1, template->tilemapTop, 1, template->height, 2); + FillBgTilemapBufferRect(template->priority, spC, template->tilemapLeft + template->width, template->tilemapTop, 1, template->height, 2); + FillBgTilemapBufferRect(template->priority, sp10, template->tilemapLeft - 1, template->tilemapTop + template->height, 1, 1, 2); + FillBgTilemapBufferRect(template->priority, sp14, template->tilemapLeft, template->tilemapTop + template->height, template->width, 1, 2); + FillBgTilemapBufferRect(template->priority, r6, template->tilemapLeft + template->width, template->tilemapTop + template->height, 1, 1, 2); + CopyBgTilemapBufferToVram(template->priority); +} + +void sub_8032250(const struct WindowTemplate *template) +{ + FillBgTilemapBufferRect(template->priority, 0, template->tilemapLeft - 1, template->tilemapTop - 1, template->tilemapLeft + template->width + 1, template->tilemapTop + template->height + 1, 2); + CopyBgTilemapBufferToVram(template->priority); +} + +void sub_8032298(u8 a, u8 b, u8 c, u8 d, u8 e, u8 unused) +{ + FillBgTilemapBufferRect(a, 0, b + 0xFF, c + 0xFF, d + 2, e + 2, 2); +} + +void sub_80322E0(u8 windowId, u8 a) +{ + CallWindowFunction(windowId, sub_8032298); + FillWindowPixelBuffer(windowId, 0x11); + ClearWindowTilemap(windowId); + if (a == 1) + CopyWindowToVram(windowId, 3); +} + +void sub_8032318(u8 a) +{ + u8 fontAttribute = GetFontAttribute(1, 6); + u8 fontAttribute2 = GetFontAttribute(1, 0); + u8 fontAttribute3 = GetFontAttribute(1, 1); + u8 windowAttribute = GetWindowAttribute(a, 3); + u8 windowAttribute2 = GetWindowAttribute(a, 4); + + FillWindowPixelRect(a, fontAttribute, 0, 0, fontAttribute2 * windowAttribute, fontAttribute3 * windowAttribute2); + CopyWindowToVram(a, 2); +} + +void sub_80323A0(struct TextSubPrinter *printer, u16 a) +{ + if (*(printer->current_text_offset - 2) == 8 && gUnknown_02022D04 == 0) + { + gUnknown_02022D04 = 1; + CreateTask(sub_8030A70, 0); + } +} + +void sub_80323CC(u8 a, u8 b, u16 c, u16 d, u8 e, u8 f) +{ + struct WindowTemplate sp; + + sp = sub_8198A50(0, a + 1, b + 1, 5, 4, f, d); + CreateYesNoMenu(&sp, c, e, 0); +} + +void unknown_rbox_to_vram(u8 windowId, u8 a) +{ + CallWindowFunction(windowId, sub_8032474); + FillWindowPixelBuffer(windowId, 17); + PutWindowTilemap(windowId); + if (a == 1) + CopyWindowToVram(windowId, 3); +} + +void sub_8032474 (u8 a, u8 b, u8 c, u8 d, u8 e, u8 f) +{ + FillBgTilemapBufferRect(a, 0xFD, b-2, c-1, 1, 1, f); + FillBgTilemapBufferRect(a, 0xFF, b-1, c-1, 1, 1, f); + FillBgTilemapBufferRect(a, 0x100, b, c-1, d, 1, f); + FillBgTilemapBufferRect(a, 0x101, b+d-1, c-1, 1, 1, f); + FillBgTilemapBufferRect(a, 0x102, b+d, c-1, 1, 1, f); + FillBgTilemapBufferRect(a, 0x103, b-2, c, 1, 5, f); + FillBgTilemapBufferRect(a, 0x105, b-1, c, d+1, 5, f); + FillBgTilemapBufferRect(a, 0x106, b+d, c, 1, 5, f); + FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0xFD), b-2, c+e, 1, 1, f); + FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0xFF), b-1, c+e, 1, 1, f); + FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0x100), b, c+e, d-1, 1, f); + FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0x101), b+d-1, c+e, 1, 1, f); + FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0x102), b+d, c+e, 1, 1, f); +} + +void task_new_game_prof_birch_speech_part2_1(u8 taskId) +{ + if (gTasks[taskId].data[7]-- <= 0) + { + unknown_rbox_to_vram(0, 1); + gTasks[taskId].func = task_new_game_prof_birch_speech_part2_2; + } +} diff --git a/src/menu.c b/src/menu.c index d06f950d3..b20ab5164 100644 --- a/src/menu.c +++ b/src/menu.c @@ -63,7 +63,7 @@ static EWRAM_DATA void *gUnknown_0203CDAC[0x20] = {NULL}; const u16 gUnknown_0860F074[] = INCBIN_U16("graphics/interface/860F074.gbapal"); static const u8 gUnknown_0860F094[] = { 8, 4, 1 }; -static const struct WindowTemplate gUnknown_0860F098[] = +static const struct WindowTemplate gUnknown_0860F098[] = { { 0x00, 0x02, 0x0F, 0x1B, 0x04, 0x0F, 0x194 }, DUMMY_WIN_TEMPLATE @@ -76,7 +76,7 @@ static const struct WindowTemplate gUnknown_0860F0A8 = const u16 gUnknown_0860F0B0[] = INCBIN_U16("graphics/interface/860F0B0.gbapal"); const u8 gUnknown_0860F0D0[] = { 15, 1, 2 }; -const struct SomeUnkStruct_60F0D4 gUnknown_0860F0D4[] = +const struct SomeUnkStruct_60F0D4 gUnknown_0860F0D4[] = { { 12, 12, 0x00 }, { 32, 12, 0x20 }, @@ -151,7 +151,7 @@ u16 sub_8197224(void) u16 AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 speed, void (*callback)(struct TextSubPrinter *, u16), u8 fgColor, u8 bgColor, u8 shadowColor) { struct TextSubPrinter printer; - + printer.current_text_offset = str; printer.windowId = windowId; printer.fontId = fontId; @@ -165,9 +165,9 @@ u16 AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 speed, printer.fgColor = fgColor; printer.bgColor = bgColor; printer.shadowColor = shadowColor; - + gTextFlags.flag_1 = 0; - return AddTextPrinter(&printer, speed, callback); + return AddTextPrinter(&printer, speed, callback); } void AddTextPrinterForMessage(bool8 allowSkippingDelayWithButtonPress) @@ -234,7 +234,7 @@ void sub_819746C(u8 windowId, bool8 copyToVram) void DrawStandardFrame(u8 bg, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height, u8 paletteNum) { int i; - + FillBgTilemapBufferRect(bg, STD_WINDOW_BASE_TILE_NUM + 0, tilemapLeft - 1, @@ -256,7 +256,7 @@ void DrawStandardFrame(u8 bg, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height 1, 1, STD_WINDOW_PALETTE_NUM); - + for (i = tilemapTop; i < tilemapTop + height; i++) { FillBgTilemapBufferRect(bg, @@ -274,7 +274,7 @@ void DrawStandardFrame(u8 bg, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height 1, STD_WINDOW_PALETTE_NUM); } - + FillBgTilemapBufferRect(bg, STD_WINDOW_BASE_TILE_NUM + 6, tilemapLeft - 1, @@ -1941,7 +1941,7 @@ void box_print(u8 windowId, u8 fontId, u8 left, u8 top, const u8 *color, s8 spee printer.fgColor = color[1]; printer.bgColor = color[0]; printer.shadowColor = color[2]; - + AddTextPrinter(&printer, speed, NULL); } @@ -1962,7 +1962,7 @@ void AddTextPrinterParameterized2(u8 windowId, u8 fontId, u8 left, u8 top, u8 le printer.fgColor = color[1]; printer.bgColor = color[0]; printer.shadowColor = color[2]; - + AddTextPrinter(&printer, speed, NULL); } @@ -2373,14 +2373,14 @@ void sub_819A344(u8 a0, u8 *a1, u8 a2) s32 flagCount; u8 *endOfString; u8 *string = a1; - + *(string++) = EXT_CTRL_CODE_BEGIN; *(string++) = EXT_CTRL_CODE_COLOR; *(string++) = a2; *(string++) = EXT_CTRL_CODE_BEGIN; *(string++) = EXT_CTRL_CODE_SHADOW; *(string++) = a2 + 1; - + switch (a0) { case 0: @@ -2388,9 +2388,9 @@ void sub_819A344(u8 a0, u8 *a1, u8 a2) break; case 1: if (IsNationalPokedexEnabled()) - string = ConvertIntToDecimalStringN(string, pokedex_count(1), 0, 3); + string = ConvertIntToDecimalStringN(string, GetNationalPokedexCount(1), 0, 3); else - string = ConvertIntToDecimalStringN(string, sub_80C0844(1), 0, 3); + string = ConvertIntToDecimalStringN(string, GetHoennPokedexCount(1), 0, 3); *string = EOS; break; case 2: diff --git a/src/naming_screen.c b/src/naming_screen.c index 47d8b8ad1..be306c765 100644 --- a/src/naming_screen.c +++ b/src/naming_screen.c @@ -1798,22 +1798,22 @@ static bool8 sub_80E503C(u8 character) static void sub_80E5074(void) { - DoNamingScreen(0, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, sub_8086194); + DoNamingScreen(0, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_ReturnToFieldWithOpenMenu); } static void sub_80E509C(void) { - DoNamingScreen(1, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, sub_8086194); + DoNamingScreen(1, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_ReturnToFieldWithOpenMenu); } static void sub_80E50C4(void) { - DoNamingScreen(2, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, sub_8086194); + DoNamingScreen(2, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_ReturnToFieldWithOpenMenu); } static void sub_80E50EC(void) { - DoNamingScreen(3, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, sub_8086194); + DoNamingScreen(3, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_ReturnToFieldWithOpenMenu); } //-------------------------------------------------- diff --git a/src/overworld.c b/src/overworld.c index c538595f2..6ee338cb8 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -1,19 +1,3185 @@ - -// Includes #include "global.h" +#include "overworld.h" +#include "main.h" +#include "battle_setup.h" +#include "berry.h" +// #include "cable_club.h" +#include "clock.h" +#include "event_data.h" +#include "field_camera.h" +#include "field_control_avatar.h" +#include "field_effect.h" +#include "field_fadetransition.h" +#include "field_ground_effect.h" +#include "field_map_obj.h" +#include "field_map_obj_helpers.h" +#include "field_message_box.h" +#include "field_player_avatar.h" +#include "field_screen_effect.h" +// #include "field_special_scene.h" +#include "field_specials.h" +#include "field_tasks.h" +#include "field_weather.h" +#include "fieldmap.h" +// #include "fldeff_flash.h" +#include "heal_location.h" +#include "link.h" +#include "load_save.h" +#include "main.h" +#include "m4a.h" +#include "constants/maps.h" +#include "map_name_popup.h" +#include "menu.h" +#include "metatile_behavior.h" +#include "new_game.h" +#include "palette.h" +#include "play_time.h" +#include "random.h" +#include "roamer.h" +// #include "rotating_gate.h" +#include "safari_zone.h" +#include "script.h" +// #include "script_pokemon_80C4.h" +#include "secret_base.h" +#include "constants/songs.h" +#include "sound.h" +#include "constants/species.h" +#include "start_menu.h" +#include "task.h" +// #include "tileset_anim.h" +#include "time_events.h" +#include "tv.h" +#include "scanline_effect.h" +#include "wild_encounter.h" +#include "bg.h" +#include "money.h" +#include "save_location.h" +#include "constants/abilities.h" +#include "malloc.h" +#include "gpu_regs.h" +#include "link_rfu.h" + +// event scripts +extern const u8 EventScript_WhiteOut[]; +extern const u8 EventScript_271862[]; +extern const u8 EventScript_277513[]; +extern const u8 EventScript_TradeRoom_TooBusyToNotice[]; +extern const u8 EventScript_TradeRoom_ReadTrainerCard1[]; +extern const u8 EventScript_TradeRoom_ReadTrainerCard2[]; +extern const u8 gUnknown_08277388[]; +extern const u8 gUnknown_082773A3[]; +extern const u8 gUnknown_082773BE[]; +extern const u8 gUnknown_082773D9[]; +extern const u8 gUnknown_0827741D[]; +extern const u8 gUnknown_08277432[]; +extern const u8 gUnknown_08277447[]; +extern const u8 gUnknown_0827745C[]; +extern const u8 gUnknown_08277374[]; +extern const u8 gUnknown_0827737E[]; +extern const u8 gUnknown_082773FF[]; +extern const u8 gUnknown_082773F5[]; +extern const u8 gUnknown_082774EF[]; +extern const u8 gUnknown_08277509[]; + +// vars +extern const struct MapData *const gMapAttributes[]; +extern const struct MapHeader *const *const gMapGroups[]; +extern const s32 gMaxFlashLevel; +extern const u16 gUnknown_82EC7C4[]; + +extern u16 gSaveFileStatus; +extern u16 gUnknown_03005DA8; +extern u8 *gUnknown_03005DA0; +extern u8 *gUnknown_03005D9C; +extern u8 *gUnknown_03005DA4; +extern bool8 (*gUnknown_03005DB0)(void); +extern u8 gUnknown_03005DB4; +extern u8 gFieldLinkPlayerCount; +extern MainCallback gFieldCallback; + +// functions +extern void HealPlayerParty(void); +extern void move_tilemap_camera_to_upper_left_corner(void); +extern void cur_mapheader_run_tileset_funcs_after_some_cpuset(void); +extern void DrawWholeMapView(void); +extern void copy_map_tileset1_tileset2_to_vram(const struct MapData *); +extern void apply_map_tileset1_tileset2_palette(const struct MapData *); +extern void ResetCyclingRoadChallengeData(void); +extern void ApplyNewEncryptionKeyToWord(u32 *word, u32 newKey); +extern void mapheader_run_script_with_tag_x5(void); +extern void ResetFieldTasksArgs(void); +extern void sub_80A0A2C(void); +extern void not_trainer_hill_battle_pyramid(void); +extern void apply_map_tileset2_palette(const struct MapData *); +extern void copy_map_tileset2_to_vram_2(const struct MapData *); +extern void prev_quest_postbuffer_cursor_backup_reset(void); +extern void ShowMapNamePopup(void); +extern bool32 InTrainerHill(void); +extern bool32 sub_808651C(void); +extern bool8 sub_80AF6A4(void); +extern bool8 sub_81A9E6C(void); +extern bool8 sub_80E909C(void); +extern void sub_81AA1D8(void); +extern void c2_change_map(void); +extern void sub_81D5DF8(void); +extern void sub_80EB218(void); +extern void sub_81BE72C(void); +extern void sub_80AF3C8(void); +extern void sub_81971F4(void); +extern void sub_808B578(void); +extern void sub_80AF314(void); +extern void sub_80AF214(void); +extern void sub_80AF188(void); +extern void door_upload_tiles(void); +extern void RotatingGate_InitPuzzleAndGraphics(void); +extern void sub_80AF168(void); +extern void sub_80AF3C8(void); +extern void ExecuteTruckSequence(void); +extern void sub_80A0A38(void); +extern void trainer_hill_map_load_related(void); +extern void sub_8087D74(void); +extern void battle_pyramid_map_load_related(u8); +extern void sub_80B00E8(u8); +extern void UpdateTVScreensOnMap(u32, u32); +extern void sub_80E9238(u8); +extern void sub_81A3908(void); +extern void sub_81AA2F8(void); +extern void sub_8195E10(void); +extern void sub_80EDB44(void); +extern void sub_81D64C0(void); +extern void sub_81BE6AC(void); +extern void sub_8098128(void); +extern void copy_map_tileset1_to_vram(const struct MapData *); +extern void copy_map_tileset2_to_vram(const struct MapData *); +extern void FieldUpdateBgTilemapScroll(void); +extern void TransferTilesetAnimsBuffer(void); +extern bool32 sub_81D5F48(void); +extern u8 GetCurrentTrainerHillMapId(void); +extern bool8 warp0_in_pokecenter(void); +extern void dp13_810BB8C(void); +extern void FieldEffectActiveListClear(void); +extern void SetUpFieldTasks(void); +extern void sub_81BE6B8(void); +extern void sub_80AAFA4(void); +extern void sub_809FA9C(void); +extern void sub_80AEE84(void); +extern void mapldr_default(void); +extern void npc_paltag_set_load(u8); +extern void sub_8088B3C(u16, u16); +extern bool32 sub_800F0B8(void); +extern bool32 sub_8009F3C(void); +extern void sub_8010198(void); +extern u32 sub_800B4DC(void); +extern bool32 sub_80B39D4(u8); +extern const u8* sub_809C2C8(struct MapPosition *a1, u8, u8); +extern u8 *sub_809D0F4(void*); +extern u8 sub_808BD6C(u8); +extern u8 sub_808BD7C(u8); +extern void sub_80979D4(struct Sprite*, u8); + +// this file's functions +static void Overworld_ResetStateAfterWhiteOut(void); +static void c2_80567AC(void); +static void CB2_LoadMap2(void); +static void VBlankCB_Field(void); +static void SpriteCB_LinkPlayer(struct Sprite *sprite); +static void ChooseAmbientCrySpecies(void); +static void do_load_map_stuff_loop(u8 *state); +static bool32 map_loading_iteration_3(u8 *state); +static bool32 sub_8086638(u8 *state); +static bool32 load_map_stuff(u8 *state, u32); +static bool32 map_loading_iteration_2_link(u8 *state); +static void mli4_mapscripts_and_other(void); +static void map_loading_lcd_reset(void); +static u8 sub_8087858(u8); +static u16 sub_80871C0(u32 a1); +static void sub_80867C8(void); +static void sub_80867D8(void); +static void sub_8086AE4(void); +static void sub_80869DC(void); +static void sub_8086B14(void); +static void sub_8086AAC(void); +static void sub_8086988(bool32 arg0); +static void sub_8086A80(void); +static void sub_8086A68(void); +static void sub_8086860(void); +static void sub_8086AC8(void); +static void sub_8086B9C(void); +static void sub_8086C40(void); +static void sub_8086C90(void); +static void sub_8086FA0(u16); +static void sub_8086F38(u16*, s32); +static u8 npc_something3(u8 a1, u8 a2); +static u8 LinkPlayerDetectCollision(u8 selfMapObjId, u8 a2, s16 x, s16 y); +static void CreateLinkPlayerSprite(u8 linkPlayerId, u8 gameVersion); +static void sub_8087878(u8 linkPlayerId, u16 *x, u16 *y); +static u8 sub_80878A0(u8 linkPlayerId); +static u8 sub_80878C0(u8 linkPlayerId); +static s32 sub_80878E4(u8 linkPlayerId); +static u8 GetLinkPlayerIdAt(s16 x, s16 y); +static void sub_808796C(u8 linkPlayerId, u8 a2); +static void ZeroMapObject(struct MapObject *mapObj); +static void SpawnLinkPlayerMapObject(u8 linkPlayerId, s16 x, s16 y, u8 a4); +static void InitLinkPlayerMapObjectPos(struct MapObject *mapObj, s16 x, s16 y); +static void sub_80877DC(u8 linkPlayerId, u8 a2); +static void sub_808780C(u8 linkPlayerId); +static u8 sub_8087858(u8 linkPlayerId); +static void sub_8087584(void); +static u32 sub_8087690(void); +static void ZeroLinkPlayerMapObject(struct LinkPlayerMapObject *linkPlayerMapObj); +static const u8 *sub_80873B4(struct UnkStruct_8054FF8 *a1); +static u16 sub_8087480(const u8 *script); +static void sub_8087510(void); +static void sub_808751C(void); +static void sub_8087530(const u8 *script); +static void sub_808754C(void); +static void sub_8087568(const u8 *script); +static void sub_80872D8(s32 linkPlayerId, s32 a2, struct UnkStruct_8054FF8 *a3); +static bool32 sub_8087340(struct UnkStruct_8054FF8 *a1); +static bool32 sub_8087358(struct UnkStruct_8054FF8 *a1); +static u8 *sub_8087370(struct UnkStruct_8054FF8 *a1); +static bool32 sub_8087388(struct UnkStruct_8054FF8 *a1); +static const u8 *sub_80873B4(struct UnkStruct_8054FF8 *a1); +static u16 sub_808711C(u32); +static u16 sub_8087140(u32); +static void sub_808709C(u16 *a1); +static u16 sub_80870B0(u32 a1); +static u16 sub_80870F8(u32 a1); +static u16 sub_8087068(u16 a1); +static void c1_link_related(void); +static void c1_link_related_func_set(u16 (*func)(u32)); +static void SetFieldVBlankCallback(void); +static void FieldClearVBlankHBlankCallbacks(void); +static void sub_8085810(void); +static u8 sub_808532C(struct UnkPlayerStruct *playerStruct, u16 a2, u8 a3); +static u8 sub_808538C(struct UnkPlayerStruct *playerStruct, u8 a2, u16 a3, u8 a4); +static u16 cur_mapdata_block_role_at_screen_center_acc_to_sav1(void); + +// IWRAM bss vars +IWRAM_DATA static void *sUnknown_03000E0C; +IWRAM_DATA static u8 sUnknown_03000E10[4]; +IWRAM_DATA static u16 (*sUnknown_03000E14)(u32); +IWRAM_DATA static u8 sUnknown_03000E18; +IWRAM_DATA static u8 sUnknown_03000E19; +IWRAM_DATA static u32 sUnusedVar; + +// EWRAM vars +EWRAM_DATA static u8 sUnknown_020322D8 = 0; +EWRAM_DATA struct WarpData gUnknown_020322DC = {0}; +EWRAM_DATA static struct WarpData sWarpDestination = {0}; // new warp position +EWRAM_DATA static struct WarpData sUnknown_020322EC = {0}; +EWRAM_DATA static struct WarpData sUnknown_020322F4 = {0}; +EWRAM_DATA static u16 sLastMapSectionId = 0; +EWRAM_DATA static struct UnkPlayerStruct sUnknown_02032300 = {0}; +EWRAM_DATA static u16 sAmbientCrySpecies = 0; +EWRAM_DATA static bool8 sIsAmbientCryWaterMon = FALSE; +EWRAM_DATA struct LinkPlayerMapObject gLinkPlayerMapObjects[4] = {0}; + +// const rom data +static const struct WarpData sDummyWarpData = +{ + .mapGroup = -1, + .mapNum = -1, + .warpId = -1, + .x = -1, + .y = -1, +}; + +static const u8 sUnusedData[] = +{ + 0xB0, 0x04, 0x00, 0x00, + 0x10, 0x0E, 0x00, 0x00, + 0xB0, 0x04, 0x00, 0x00, + 0x60, 0x09, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, + 0xD4, 0xFF, 0xFF, 0xFF, + 0x2C, 0x00, 0x00, 0x00, +}; + +const struct UCoords32 gUnknown_08339D64[] = +{ + { 0, 0}, + { 0, 1}, + { 0, -1}, + {-1, 0}, + { 1, 0}, + {-1, 1}, + { 1, 1}, + {-1, -1}, + { 1, -1}, +}; + +static const struct BgTemplate gUnknown_08339DAC[] = +{ + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0 + }, + { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 29, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0 + }, + { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 28, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0 + }, + { + .bg = 3, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0 + } +}; + +static const struct ScanlineEffectParams gUnknown_08339DBC = +{ + (void *)REG_ADDR_WIN0H, + ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1, + 1, + 0, +}; + +static u8 sub_80879D8(struct LinkPlayerMapObject *, struct MapObject *, u8); +static u8 sub_80879F8(struct LinkPlayerMapObject *, struct MapObject *, u8); +static u8 sub_80879FC(struct LinkPlayerMapObject *, struct MapObject *, u8); + +static u8 (*const gUnknown_08339DC8[])(struct LinkPlayerMapObject *, struct MapObject *, u8) = +{ + sub_80879D8, + sub_80879F8, + sub_80879FC, +}; + +static u8 sub_8087A1C(struct LinkPlayerMapObject *, struct MapObject *, u8); +static u8 sub_8087A20(struct LinkPlayerMapObject *, struct MapObject *, u8); +static u8 sub_8087A88(struct LinkPlayerMapObject *, struct MapObject *, u8); + +static u8 (*const gUnknown_08339DD4[])(struct LinkPlayerMapObject *, struct MapObject *, u8) = +{ + sub_8087A1C, + sub_8087A20, + sub_8087A20, + sub_8087A20, + sub_8087A20, + sub_8087A1C, + sub_8087A1C, + sub_8087A88, + sub_8087A88, + sub_8087A88, + sub_8087A88, +}; + +static void sub_8087AA0(struct LinkPlayerMapObject *, struct MapObject *); +static void sub_8087AA8(struct LinkPlayerMapObject *, struct MapObject *); + +static void (*const gUnknown_08339E00[])(struct LinkPlayerMapObject *, struct MapObject *) = +{ + sub_8087AA0, + sub_8087AA8, +}; + +// code +void DoWhiteOut(void) +{ + ScriptContext2_RunNewScript(EventScript_WhiteOut); + SetMoney(&gSaveBlock1Ptr->money, GetMoney(&gSaveBlock1Ptr->money) / 2); + HealPlayerParty(); + Overworld_ResetStateAfterWhiteOut(); + Overworld_SetWarpDestToLastHealLoc(); + warp_in(); +} + +void Overworld_ResetStateAfterFly(void) +{ + player_avatar_init_params_reset(); + FlagClear(FLAG_SYS_CYCLING_ROAD); + FlagClear(FLAG_SYS_CRUISE_MODE); + FlagClear(FLAG_SYS_SAFARI_MODE); + FlagClear(FLAG_SYS_USE_STRENGTH); + FlagClear(FLAG_SYS_USE_FLASH); +} + +void Overworld_ResetStateAfterTeleport(void) +{ + player_avatar_init_params_reset(); + FlagClear(FLAG_SYS_CYCLING_ROAD); + FlagClear(FLAG_SYS_CRUISE_MODE); + FlagClear(FLAG_SYS_SAFARI_MODE); + FlagClear(FLAG_SYS_USE_STRENGTH); + FlagClear(FLAG_SYS_USE_FLASH); + ScriptContext2_RunNewScript(EventScript_271862); +} + +void Overworld_ResetStateAfterDigEscRope(void) +{ + player_avatar_init_params_reset(); + FlagClear(FLAG_SYS_CYCLING_ROAD); + FlagClear(FLAG_SYS_CRUISE_MODE); + FlagClear(FLAG_SYS_SAFARI_MODE); + FlagClear(FLAG_SYS_USE_STRENGTH); + FlagClear(FLAG_SYS_USE_FLASH); +} + +static void Overworld_ResetStateAfterWhiteOut(void) +{ + player_avatar_init_params_reset(); + FlagClear(FLAG_SYS_CYCLING_ROAD); + FlagClear(FLAG_SYS_CRUISE_MODE); + FlagClear(FLAG_SYS_SAFARI_MODE); + FlagClear(FLAG_SYS_USE_STRENGTH); + FlagClear(FLAG_SYS_USE_FLASH); + if (VarGet(VAR_0x4039) == 1) + { + VarSet(VAR_0x4039, 0); + VarSet(VAR_0x4037, 0); + } +} + +static void sub_8084788(void) +{ + FlagClear(FLAG_SYS_SAFARI_MODE); + ChooseAmbientCrySpecies(); + ResetCyclingRoadChallengeData(); + UpdateLocationHistoryForRoamer(); + RoamerMoveToOtherLocationSet(); +} + +void ResetGameStats(void) +{ + s32 i; + + for (i = 0; i < NUM_GAME_STATS; i++) + SetGameStat(i, 0); +} + +void IncrementGameStat(u8 index) +{ + if (index < NUM_USED_GAME_STATS) + { + u32 statVal = GetGameStat(index); + if (statVal < 0xFFFFFF) + statVal++; + else + statVal = 0xFFFFFF; + + SetGameStat(index, statVal); + } +} + +u32 GetGameStat(u8 index) +{ + if (index >= NUM_USED_GAME_STATS) + return 0; + + return gSaveBlock1Ptr->gameStats[index] ^ gSaveBlock2Ptr->encryptionKey; +} + +void SetGameStat(u8 index, u32 value) +{ + if (index < NUM_USED_GAME_STATS) + gSaveBlock1Ptr->gameStats[index] = value ^ gSaveBlock2Ptr->encryptionKey; +} + +void ApplyNewEncryptionKeyToGameStats(u32 newKey) +{ + u8 i; + + for (i = 0; i < NUM_GAME_STATS; i++) + ApplyNewEncryptionKeyToWord(&gSaveBlock1Ptr->gameStats[i], newKey); +} + +void LoadMapObjTemplatesFromHeader(void) +{ + // Clear map object templates + CpuFill32(0, gSaveBlock1Ptr->mapObjectTemplates, sizeof(gSaveBlock1Ptr->mapObjectTemplates)); + + // Copy map header events to save block + CpuCopy32(gMapHeader.events->mapObjects, + gSaveBlock1Ptr->mapObjectTemplates, + gMapHeader.events->mapObjectCount * sizeof(struct MapObjectTemplate)); +} + +void LoadSaveblockMapObjScripts(void) +{ + struct MapObjectTemplate *mapHeaderObjTemplates = gMapHeader.events->mapObjects; + struct MapObjectTemplate *savObjTemplates = gSaveBlock1Ptr->mapObjectTemplates; + s32 i; + + for (i = 0; i < 64; i++) + savObjTemplates[i].script = mapHeaderObjTemplates[i].script; +} + +void Overworld_SetMapObjTemplateCoords(u8 localId, s16 x, s16 y) +{ + s32 i; + struct MapObjectTemplate *savObjTemplates = gSaveBlock1Ptr->mapObjectTemplates; + + for (i = 0; i < 64; i++) + { + struct MapObjectTemplate *mapObjectTemplate = &savObjTemplates[i]; + if (mapObjectTemplate->localId == localId) + { + mapObjectTemplate->x = x; + mapObjectTemplate->y = y; + return; + } + } +} + +void Overworld_SetMapObjTemplateMovementType(u8 localId, u8 movementType) +{ + s32 i; + + struct MapObjectTemplate *savObjTemplates = gSaveBlock1Ptr->mapObjectTemplates; + for (i = 0; i < 64; i++) + { + struct MapObjectTemplate *mapObjectTemplate = &savObjTemplates[i]; + if (mapObjectTemplate->localId == localId) + { + mapObjectTemplate->movementType = movementType; + return; + } + } +} + +static void mapdata_load_assets_to_gpu_and_full_redraw(void) +{ + move_tilemap_camera_to_upper_left_corner(); + copy_map_tileset1_tileset2_to_vram(gMapHeader.mapData); + apply_map_tileset1_tileset2_palette(gMapHeader.mapData); + DrawWholeMapView(); + cur_mapheader_run_tileset_funcs_after_some_cpuset(); +} + +const struct MapData *get_mapdata_header(void) +{ + u16 mapDataId = gSaveBlock1Ptr->mapDataId; + if (mapDataId) + return gMapAttributes[mapDataId - 1]; + return NULL; +} + +void ApplyCurrentWarp(void) +{ + gUnknown_020322DC = gSaveBlock1Ptr->location; + gSaveBlock1Ptr->location = sWarpDestination; + sUnknown_020322EC = sDummyWarpData; + sUnknown_020322F4 = sDummyWarpData; +} + +void set_warp2_warp3_to_neg_1(void) +{ + sUnknown_020322EC = sDummyWarpData; + sUnknown_020322F4 = sDummyWarpData; +} + +void SetWarpData(struct WarpData *warp, s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y) +{ + warp->mapGroup = mapGroup; + warp->mapNum = mapNum; + warp->warpId = warpId; + warp->x = x; + warp->y = y; +} + +bool32 warp_data_is_not_neg_1(struct WarpData *warp) +{ + if (warp->mapGroup != -1) + return FALSE; + else if (warp->mapNum != -1) + return FALSE; + else if (warp->warpId != -1) + return FALSE; + else if (warp->x != -1) + return FALSE; + else if (warp->y != -1) + return FALSE; + else + return TRUE; +} + +const struct MapHeader *Overworld_GetMapHeaderByGroupAndId(u16 mapGroup, u16 mapNum) +{ + return gMapGroups[mapGroup][mapNum]; +} + +const struct MapHeader *warp1_get_mapheader(void) +{ + return Overworld_GetMapHeaderByGroupAndId(sWarpDestination.mapGroup, sWarpDestination.mapNum); +} + +void set_current_map_header_from_sav1_save_old_name(void) +{ + sLastMapSectionId = gMapHeader.regionMapSectionId; + gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum); + gSaveBlock1Ptr->mapDataId = gMapHeader.mapDataId; + gMapHeader.mapData = get_mapdata_header(); +} + +void LoadSaveblockMapHeader(void) +{ + gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum); + gMapHeader.mapData = get_mapdata_header(); +} + +void update_camera_pos_from_warpid(void) +{ + if (gSaveBlock1Ptr->location.warpId >= 0 && gSaveBlock1Ptr->location.warpId < gMapHeader.events->warpCount) + { + gSaveBlock1Ptr->pos.x = gMapHeader.events->warps[gSaveBlock1Ptr->location.warpId].x; + gSaveBlock1Ptr->pos.y = gMapHeader.events->warps[gSaveBlock1Ptr->location.warpId].y; + } + else if (gSaveBlock1Ptr->location.x >= 0 && gSaveBlock1Ptr->location.y >= 0) + { + gSaveBlock1Ptr->pos.x = gSaveBlock1Ptr->location.x; + gSaveBlock1Ptr->pos.y = gSaveBlock1Ptr->location.y; + } + else + { + gSaveBlock1Ptr->pos.x = gMapHeader.mapData->width / 2; + gSaveBlock1Ptr->pos.y = gMapHeader.mapData->height / 2; + } +} + +void warp_in(void) +{ + ApplyCurrentWarp(); + set_current_map_header_from_sav1_save_old_name(); + update_camera_pos_from_warpid(); +} + +void Overworld_SetWarpDestination(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y) +{ + SetWarpData(&sWarpDestination, mapGroup, mapNum, warpId, x, y); +} + +void warp1_set_2(s8 mapGroup, s8 mapNum, s8 warpId) +{ + Overworld_SetWarpDestination(mapGroup, mapNum, warpId, -1, -1); +} + +void saved_warp2_set(s32 unused, s8 mapGroup, s8 mapNum, s8 warpId) +{ + SetWarpData(&gSaveBlock1Ptr->warp2, mapGroup, mapNum, warpId, gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y); +} + +void saved_warp2_set_2(s32 unused, s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y) +{ + SetWarpData(&gSaveBlock1Ptr->warp2, mapGroup, mapNum, warpId, x, y); +} + +void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused) +{ + sWarpDestination = gSaveBlock1Ptr->warp2; +} + +void sub_8084CCC(u8 a1) +{ + const struct HealLocation *warp = GetHealLocationPointer(a1); + + if (warp) + Overworld_SetWarpDestination(warp->group, warp->map, -1, warp->x, warp->y); +} + +void Overworld_SetWarpDestToLastHealLoc(void) +{ + sWarpDestination = gSaveBlock1Ptr->lastHealLocation; +} + +void Overworld_SetHealLocationWarp(u8 healLocationId) +{ + const struct HealLocation *healLocation = GetHealLocationPointer(healLocationId); + + if (healLocation != NULL) + SetWarpData(&gSaveBlock1Ptr->lastHealLocation, healLocation->group, healLocation->map, -1, healLocation->x, healLocation->y); +} + +void sub_8084D5C(s16 a1, s16 a2) +{ + u8 currMapType = Overworld_GetMapTypeOfSaveblockLocation(); + u8 destMapType = GetMapTypeByGroupAndId(sWarpDestination.mapGroup, sWarpDestination.mapNum); + if (is_light_level_1_2_3_5_or_6(currMapType) && is_light_level_1_2_3_5_or_6(destMapType) != TRUE) + sub_8084DD4(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1, a1 - 7, a2 - 6); +} + +void sub_8084DD4(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y) +{ + SetWarpData(&gSaveBlock1Ptr->warp4, mapGroup, mapNum, warpId, x, y); +} + +void sub_8084E14(void) +{ + sWarpDestination = gSaveBlock1Ptr->warp4; +} + +void sub_8084E2C(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y) +{ + SetWarpData(&sUnknown_020322EC, mapGroup, mapNum, warpId, x, y); +} + +void warp1_set_to_warp2(void) +{ + sWarpDestination = sUnknown_020322EC; +} + +void sub_8084E80(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y) +{ + SetWarpData(&sUnknown_020322F4, mapGroup, mapNum, warpId, x, y); +} + +void sub_8084EBC(s16 x, s16 y) +{ + if (warp_data_is_not_neg_1(&sUnknown_020322F4) == TRUE) + sWarpDestination = gUnknown_020322DC; + else + Overworld_SetWarpDestination(sUnknown_020322F4.mapGroup, sUnknown_020322F4.mapNum, -1, x, y); +} + +void warp1_set_to_sav1w(void) +{ + sWarpDestination = gSaveBlock1Ptr->warp1; +} + +void sub_8084F2C(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y) +{ + SetWarpData(&gSaveBlock1Ptr->warp1, mapGroup, mapNum, warpId, x, y); +} + +void sub_8084F6C(u8 a1) +{ + const struct HealLocation *warp = GetHealLocationPointer(a1); + if (warp) + SetWarpData(&gSaveBlock1Ptr->warp1, warp->group, warp->map, -1, warp->x, warp->y); +} + +void sub_8084FAC(void) +{ + gSaveBlock1Ptr->warp1 = gSaveBlock1Ptr->warp2; +} + +const struct MapConnection *GetMapConnection(u8 dir) +{ + s32 i; + s32 count = gMapHeader.connections->count; + const struct MapConnection *connection = gMapHeader.connections->connections; + + if (connection == NULL) + return NULL; + + for(i = 0; i < count; i++, connection++) + if (connection->direction == dir) + return connection; + + return NULL; +} + +bool8 sub_8084FF8(u8 dir, u16 x, u16 y) +{ + const struct MapConnection *connection = GetMapConnection(dir); + + if (connection != NULL) + { + Overworld_SetWarpDestination(connection->mapGroup, connection->mapNum, -1, x, y); + } + else + { + mapheader_run_script_with_tag_x6(); + if (warp_data_is_not_neg_1(&sUnknown_020322EC)) + return FALSE; + warp1_set_to_warp2(); + } + return TRUE; +} + +bool8 sub_8085058(u16 x, u16 y) +{ + return sub_8084FF8(CONNECTION_EMERGE, x, y); +} + +bool8 sub_8085078(u16 x, u16 y) +{ + return sub_8084FF8(CONNECTION_DIVE, x, y); +} + +void mliX_load_map(u8 mapGroup, u8 mapNum) +{ + s32 paletteIndex; + + Overworld_SetWarpDestination(mapGroup, mapNum, -1, -1, -1); + if (gMapHeader.regionMapSectionId != 0x3A) + sub_8085810(); + + ApplyCurrentWarp(); + set_current_map_header_from_sav1_save_old_name(); + LoadMapObjTemplatesFromHeader(); + TrySetMapSaveWarpStatus(); + ClearTempFieldEventData(); + ResetCyclingRoadChallengeData(); + prev_quest_postbuffer_cursor_backup_reset(); + TryUpdateRandomTrainerRematches(mapGroup, mapNum); + DoTimeBasedEvents(); + SetSav1WeatherFromCurrMapHeader(); + ChooseAmbientCrySpecies(); + SetDefaultFlashLevel(); + Overworld_ClearSavedMusic(); + mapheader_run_script_with_tag_x3(); + not_trainer_hill_battle_pyramid(); + copy_map_tileset2_to_vram_2(gMapHeader.mapData); + apply_map_tileset2_palette(gMapHeader.mapData); + + for (paletteIndex = 6; paletteIndex < 13; paletteIndex++) + ApplyWeatherGammaShiftToPal(paletteIndex); + + sub_80A0A2C(); + UpdateLocationHistoryForRoamer(); + RoamerMove(); + DoCurrentWeather(); + ResetFieldTasksArgs(); + mapheader_run_script_with_tag_x5(); + + if (gMapHeader.regionMapSectionId != 0x3A || gMapHeader.regionMapSectionId != sLastMapSectionId) + ShowMapNamePopup(); +} + +static void mli0_load_map(u32 a1) +{ + bool8 v2; + bool8 indoors; + + set_current_map_header_from_sav1_save_old_name(); + if (!(sUnknown_020322D8 & 1)) + { + if (gMapHeader.mapDataId == 0x169) + sub_81AA1D8(); + else if (InTrainerHill()) + sub_81D5DF8(); + else + LoadMapObjTemplatesFromHeader(); + } + + v2 = is_light_level_1_2_3_5_or_6(gMapHeader.mapType); + indoors = Overworld_MapTypeIsIndoors(gMapHeader.mapType); + + sub_80EB218(); + TrySetMapSaveWarpStatus(); + ClearTempFieldEventData(); + ResetCyclingRoadChallengeData(); + prev_quest_postbuffer_cursor_backup_reset(); + TryUpdateRandomTrainerRematches(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum); + if (a1 != 1) + DoTimeBasedEvents(); + SetSav1WeatherFromCurrMapHeader(); + ChooseAmbientCrySpecies(); + if (v2) + FlagClear(FLAG_SYS_USE_FLASH); + SetDefaultFlashLevel(); + Overworld_ClearSavedMusic(); + mapheader_run_script_with_tag_x3(); + UpdateLocationHistoryForRoamer(); + RoamerMoveToOtherLocationSet(); + if (gMapHeader.mapDataId == 0x169) + battle_pyramid_map_load_related(0); + else if (InTrainerHill()) + trainer_hill_map_load_related(); + else + not_trainer_hill_battle_pyramid(); + + if (a1 != 1 && indoors) + { + UpdateTVScreensOnMap(gUnknown_03005DC0.width, gUnknown_03005DC0.height); + sub_80E9238(1); + } +} + +void player_avatar_init_params_reset(void) +{ + sUnknown_02032300.player_field_1 = 1; + sUnknown_02032300.player_field_0 = 1; +} + +void walkrun_find_lowest_active_bit_in_bitfield(void) +{ + sUnknown_02032300.player_field_1 = player_get_direction_lower_nybble(); + + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE)) + sUnknown_02032300.player_field_0 = 2; + else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE)) + sUnknown_02032300.player_field_0 = 4; + else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) + sUnknown_02032300.player_field_0 = 8; + else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_4)) + sUnknown_02032300.player_field_0 = 16; + else + sUnknown_02032300.player_field_0 = 1; +} + +static struct UnkPlayerStruct *sub_80852D4(void) +{ + struct UnkPlayerStruct playerStruct; + u8 mapType = Overworld_GetMapTypeOfSaveblockLocation(); + u16 v2 = cur_mapdata_block_role_at_screen_center_acc_to_sav1(); + u8 v4 = sub_808532C(&sUnknown_02032300, v2, mapType); + playerStruct.player_field_0 = v4; + playerStruct.player_field_1 = sub_808538C(&sUnknown_02032300, v4, v2, mapType); + sUnknown_02032300 = playerStruct; + return &sUnknown_02032300; +} + +static u8 sub_808532C(struct UnkPlayerStruct *playerStruct, u16 a2, u8 a3) +{ + if (a3 != 8 && FlagGet(FLAG_SYS_CRUISE_MODE)) + return 1; + else if (a3 == 5) + return 16; + else if (MetatileBehavior_IsSurfableWaterOrUnderwater(a2) == 1) + return 8; + else if (Overworld_IsBikingAllowed() != TRUE) + return 1; + else if (playerStruct->player_field_0 == 2) + return 2; + else if (playerStruct->player_field_0 != 4) + return 1; + else + return 4; +} + +static u8 sub_808538C(struct UnkPlayerStruct *playerStruct, u8 a2, u16 a3, u8 a4) +{ + if (FlagGet(FLAG_SYS_CRUISE_MODE) && a4 == 6) + return 4; + else if (MetatileBehavior_IsDeepSouthWarp(a3) == TRUE) + return 2; + else if (MetatileBehavior_IsNonAnimDoor(a3) == TRUE || MetatileBehavior_IsDoor(a3) == TRUE) + return 1; + else if (MetatileBehavior_IsSouthArrowWarp(a3) == TRUE) + return 2; + else if (MetatileBehavior_IsNorthArrowWarp(a3) == TRUE) + return 1; + else if (MetatileBehavior_IsWestArrowWarp(a3) == TRUE) + return 4; + else if (MetatileBehavior_IsEastArrowWarp(a3) == TRUE) + return 3; + else if ((playerStruct->player_field_0 == 16 && a2 == 8) + || (playerStruct->player_field_0 == 8 && a2 == 16)) + return playerStruct->player_field_1; + else if (MetatileBehavior_IsLadder(a3) == TRUE) + return playerStruct->player_field_1; + else + return 1; +} + +static u16 cur_mapdata_block_role_at_screen_center_acc_to_sav1(void) +{ + return MapGridGetMetatileBehaviorAt(gSaveBlock1Ptr->pos.x + 7, gSaveBlock1Ptr->pos.y + 7); +} + +bool32 Overworld_IsBikingAllowed(void) +{ + if (!(gMapHeader.flags & 1)) + return FALSE; + else + return TRUE; +} + +void SetDefaultFlashLevel(void) +{ + if (!gMapHeader.cave) + gSaveBlock1Ptr->flashLevel = 0; + else if (FlagGet(FLAG_SYS_USE_FLASH)) + gSaveBlock1Ptr->flashLevel = 1; + else + gSaveBlock1Ptr->flashLevel = gMaxFlashLevel - 1; +} + +void Overworld_SetFlashLevel(s32 flashLevel) +{ + if (flashLevel < 0 || flashLevel > gMaxFlashLevel) + flashLevel = 0; + gSaveBlock1Ptr->flashLevel = flashLevel; +} + +u8 Overworld_GetFlashLevel(void) +{ + return gSaveBlock1Ptr->flashLevel; +} + +void sub_8085524(u16 mapDataId) +{ + gSaveBlock1Ptr->mapDataId = mapDataId; + gMapHeader.mapData = get_mapdata_header(); +} + +void sub_8085540(u8 var) +{ + sUnknown_020322D8 = var; +} + +u8 sub_808554C(void) +{ + return sUnknown_020322D8; +} + +static bool16 ShouldLegendaryMusicPlayAtLocation(struct WarpData *warp) +{ + if (!FlagGet(FLAG_SYS_WEATHER_CTRL)) + return FALSE; + if (warp->mapGroup == 0) + { + switch (warp->mapNum) + { + case MAP_NUM(LILYCOVE_CITY): + case MAP_NUM(MOSSDEEP_CITY): + case MAP_NUM(SOOTOPOLIS_CITY): + case MAP_NUM(EVER_GRANDE_CITY): + case MAP_NUM(ROUTE124): + case MAP_NUM(ROUTE125): + case MAP_NUM(ROUTE126): + case MAP_NUM(ROUTE127): + case MAP_NUM(ROUTE128): + return TRUE; + default: + if (VarGet(VAR_0x405E) < 4) + return FALSE; + switch (warp->mapNum) + { + case MAP_NUM(ROUTE129): + case MAP_NUM(ROUTE130): + case MAP_NUM(ROUTE131): + return TRUE; + } + } + } + return FALSE; +} + +static bool16 NoMusicInSotopolisWithLegendaries(struct WarpData *warp) +{ + if (VarGet(VAR_0x40CA) != 1) + return FALSE; + else if (warp->mapGroup != MAP_GROUP(SOOTOPOLIS_CITY)) + return FALSE; + else if (warp->mapNum == MAP_NUM(SOOTOPOLIS_CITY)) + return TRUE; + else + return FALSE; +} + +static bool16 IsInfiltratedWeatherInstitute(struct WarpData *warp) +{ + if (VarGet(VAR_WEATHER_INSTITUTE_STATE)) + return FALSE; + else if (warp->mapGroup != MAP_GROUP(ROUTE119_WEATHER_INSTITUTE_1F)) + return FALSE; + else if (warp->mapNum == MAP_NUM(ROUTE119_WEATHER_INSTITUTE_1F) + || warp->mapNum == MAP_NUM(ROUTE119_WEATHER_INSTITUTE_2F)) + return TRUE; + else + return FALSE; +} + +static bool16 IsInflitratedSpaceCenter(struct WarpData *warp) +{ + if (VarGet(VAR_0x405D) == 0) + return FALSE; + else if (VarGet(VAR_0x405D) > 2) + return FALSE; + else if (warp->mapGroup != MAP_GROUP(MOSSDEEP_CITY_SPACE_CENTER_1F)) + return FALSE; + else if (warp->mapNum == MAP_NUM(MOSSDEEP_CITY_SPACE_CENTER_1F) + || warp->mapNum == MAP_NUM(MOSSDEEP_CITY_SPACE_CENTER_2F)) + return TRUE; + return FALSE; +} + +u16 GetLocationMusic(struct WarpData *warp) +{ + if (NoMusicInSotopolisWithLegendaries(warp) == TRUE) + return 0xFFFF; + else if (ShouldLegendaryMusicPlayAtLocation(warp) == TRUE) + return MUS_OOAME; + else if (IsInflitratedSpaceCenter(warp) == TRUE) + return MUS_MGM0; + else if (IsInfiltratedWeatherInstitute(warp) == TRUE) + return MUS_TOZAN; + else + return Overworld_GetMapHeaderByGroupAndId(warp->mapGroup, warp->mapNum)->music; +} + +u16 GetCurrLocationDefaultMusic(void) +{ + u16 music; + + // Play the desert music only when the sandstorm is active on Route 111. + if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE111) + && gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE111) + && GetSav1Weather() == 8) + return MUS_ASHROAD; + + music = GetLocationMusic(&gSaveBlock1Ptr->location); + if (music != 0x7FFF) + { + return music; + } + else + { + if (gSaveBlock1Ptr->pos.x < 24) + return MUS_DOORO_X1; + else + return MUS_GRANROAD; + } +} + +u16 GetWarpDestinationMusic(void) +{ + u16 music = GetLocationMusic(&sWarpDestination); + if (music != 0x7FFF) + { + return music; + } + else + { + if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(MAUVILLE_CITY) + && gSaveBlock1Ptr->location.mapNum == MAP_NUM(MAUVILLE_CITY)) + return MUS_DOORO_X1; + else + return MUS_GRANROAD; + } +} + +void Overworld_ResetMapMusic(void) +{ + ResetMapMusic(); +} + +void Overworld_PlaySpecialMapMusic(void) +{ + u16 music = GetCurrLocationDefaultMusic(); + + if (music != MUS_OOAME && music != 0xFFFF) + { + if (gSaveBlock1Ptr->savedMusic) + music = gSaveBlock1Ptr->savedMusic; + else if (Overworld_GetMapTypeOfSaveblockLocation() == MAP_TYPE_UNDERWATER) + music = MUS_DEEPDEEP; + else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) + music = MUS_NAMINORI; + } + + if (music != GetCurrentMapMusic()) + PlayNewMapMusic(music); +} + +void Overworld_SetSavedMusic(u16 songNum) +{ + gSaveBlock1Ptr->savedMusic = songNum; +} + +void Overworld_ClearSavedMusic(void) +{ + gSaveBlock1Ptr->savedMusic = 0; +} + +static void sub_8085810(void) +{ + if (FlagGet(FLAG_SPECIAL_FLAG_0x4001) != TRUE) + { + u16 newMusic = GetWarpDestinationMusic(); + u16 currentMusic = GetCurrentMapMusic(); + if (newMusic != MUS_OOAME && newMusic != 0xFFFF) + { + if (currentMusic == MUS_DEEPDEEP || currentMusic == MUS_NAMINORI) + return; + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) + newMusic = MUS_NAMINORI; + } + if (newMusic != currentMusic) + { + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE)) + FadeOutAndFadeInNewMapMusic(newMusic, 4, 4); + else + FadeOutAndPlayNewMapMusic(newMusic, 8); + } + } +} + +void Overworld_ChangeMusicToDefault(void) +{ + u16 currentMusic = GetCurrentMapMusic(); + if (currentMusic != GetCurrLocationDefaultMusic()) + FadeOutAndPlayNewMapMusic(GetCurrLocationDefaultMusic(), 8); +} + +void Overworld_ChangeMusicTo(u16 newMusic) +{ + u16 currentMusic = GetCurrentMapMusic(); + if (currentMusic != newMusic && currentMusic != MUS_OOAME) + FadeOutAndPlayNewMapMusic(newMusic, 8); +} + +u8 GetMapMusicFadeoutSpeed(void) +{ + const struct MapHeader *mapHeader = warp1_get_mapheader(); + if (Overworld_MapTypeIsIndoors(mapHeader->mapType) == TRUE) + return 2; + else + return 4; +} + +void music_something(void) +{ + u16 currentMusic = GetCurrentMapMusic(); + u16 warpMusic = GetWarpDestinationMusic(); + if (FlagGet(FLAG_SPECIAL_FLAG_0x4001) != TRUE && warpMusic != GetCurrentMapMusic()) + { + if (currentMusic == MUS_NAMINORI + && VarGet(VAR_0x40CA) == 2 + && gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(SOOTOPOLIS_CITY) + && gSaveBlock1Ptr->location.mapNum == MAP_NUM(SOOTOPOLIS_CITY) + && sWarpDestination.mapGroup == MAP_GROUP(SOOTOPOLIS_CITY) + && sWarpDestination.mapNum == MAP_NUM(SOOTOPOLIS_CITY) + && sWarpDestination.x == 0x1D + && sWarpDestination.y == 0x35) + return; + FadeOutMapMusic(GetMapMusicFadeoutSpeed()); + } +} + +bool8 sub_80859A0(void) +{ + return IsNotWaitingForBGMStop(); +} + +void Overworld_FadeOutMapMusic(void) +{ + FadeOutMapMusic(4); +} + +static void PlayAmbientCry(void) +{ + s16 x, y; + s8 pan; + s8 volume; + + PlayerGetDestCoords(&x, &y); + if (sIsAmbientCryWaterMon == TRUE + && !MetatileBehavior_IsSurfableWaterOrUnderwater(MapGridGetMetatileBehaviorAt(x, y))) + return; + pan = (Random() % 88) + 212; + volume = (Random() % 30) + 50; + PlayCry2(sAmbientCrySpecies, pan, volume, 1); +} + +void UpdateAmbientCry(s16 *state, u16 *delayCounter) +{ + u8 i, monsCount, divBy; + + switch (*state) + { + case 0: + if (sAmbientCrySpecies == SPECIES_NONE) + *state = 4; + else + *state = 1; + break; + case 1: + *delayCounter = (Random() % 2400) + 1200; + *state = 3; + break; + case 2: + divBy = 1; + monsCount = CalculatePlayerPartyCount(); + for (i = 0; i < monsCount; i++) + { + if (!GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT3) + && GetMonAbility(&gPlayerParty[0]) == ABILITY_SWARM) + { + divBy = 2; + break; + } + } + *delayCounter = ((Random() % 1200) + 1200) / divBy; + *state = 3; + break; + case 3: + (*delayCounter)--; + if (*delayCounter == 0) + { + PlayAmbientCry(); + *state = 2; + } + break; + case 4: + break; + } +} + +static void ChooseAmbientCrySpecies(void) +{ + if ((gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE130) + && gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE130)) + && !IsMirageIslandPresent()) + { + // Only play water pokemon cries on this route + // when Mirage Island is not present + sIsAmbientCryWaterMon = TRUE; + sAmbientCrySpecies = GetLocalWaterMon(); + } + else + { + sAmbientCrySpecies = GetLocalWildMon(&sIsAmbientCryWaterMon); + } +} + +u8 GetMapTypeByGroupAndId(s8 mapGroup, s8 mapNum) +{ + return Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum)->mapType; +} + +u8 GetMapTypeByWarpData(struct WarpData *warp) +{ + return GetMapTypeByGroupAndId(warp->mapGroup, warp->mapNum); +} + +u8 Overworld_GetMapTypeOfSaveblockLocation(void) +{ + return GetMapTypeByWarpData(&gSaveBlock1Ptr->location); +} + +u8 get_map_light_from_warp0(void) +{ + return GetMapTypeByWarpData(&gUnknown_020322DC); +} + +bool8 is_light_level_1_2_3_5_or_6(u8 mapType) +{ + if (mapType == MAP_TYPE_ROUTE + || mapType == MAP_TYPE_TOWN + || mapType == MAP_TYPE_UNDERWATER + || mapType == MAP_TYPE_CITY + || mapType == MAP_TYPE_6) + return TRUE; + else + return FALSE; +} + +bool8 Overworld_MapTypeAllowsTeleportAndFly(u8 mapType) +{ + if (mapType == MAP_TYPE_ROUTE + || mapType == MAP_TYPE_TOWN + || mapType == MAP_TYPE_6 + || mapType == MAP_TYPE_CITY) + return TRUE; + else + return FALSE; +} + +bool8 Overworld_MapTypeIsIndoors(u8 mapType) +{ + if (mapType == MAP_TYPE_INDOOR + || mapType == MAP_TYPE_SECRET_BASE) + return TRUE; + else + return FALSE; +} + +u8 sav1_saved_warp2_map_get_name(void) +{ + return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->warp2.mapGroup, gSaveBlock1Ptr->warp2.mapNum)->regionMapSectionId; +} + +u8 sav1_map_get_name(void) +{ + return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum)->regionMapSectionId; +} + +u8 GetCurrentMapBattleScene(void) +{ + return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum)->battleType; +} + +static void overworld_bg_setup(void) +{ + InitBgsFromTemplates(0, gUnknown_08339DAC, ARRAY_COUNT(gUnknown_08339DAC)); + SetBgAttribute(1, BG_CTRL_ATTR_PALETTEMODE, 1); + SetBgAttribute(2, BG_CTRL_ATTR_PALETTEMODE, 1); + SetBgAttribute(3, BG_CTRL_ATTR_PALETTEMODE, 1); + gUnknown_03005DA0 = AllocZeroed(0x800); + gUnknown_03005D9C = AllocZeroed(0x800); + gUnknown_03005DA4 = AllocZeroed(0x800); + SetBgTilemapBuffer(1, gUnknown_03005DA0); + SetBgTilemapBuffer(2, gUnknown_03005D9C); + SetBgTilemapBuffer(3, gUnknown_03005DA4); + sub_81971D0(); +} + +void overworld_free_bg_tilemaps(void) +{ + sub_81BE72C(); + sub_81971F4(); + if (gUnknown_03005DA4 != NULL) + FREE_AND_SET_NULL(gUnknown_03005DA4); + if (gUnknown_03005D9C != NULL) + FREE_AND_SET_NULL(gUnknown_03005D9C); + if (gUnknown_03005DA0 != NULL) + FREE_AND_SET_NULL(gUnknown_03005DA0); +} + +static void ResetSafariZoneFlag_(void) +{ + ResetSafariZoneFlag(); +} + +bool32 is_c1_link_related_active(void) +{ + if (gMain.callback1 == c1_link_related) + return TRUE; + else + return FALSE; +} + +static void DoCB1_Overworld(u16 newKeys, u16 heldKeys) +{ + struct FieldInput inputStruct; + + sub_808B578(); + FieldClearPlayerInput(&inputStruct); + FieldGetPlayerInput(&inputStruct, newKeys, heldKeys); + if (!ScriptContext2_IsEnabled()) + { + if (sub_809C014(&inputStruct) == 1) + { + ScriptContext2_Enable(); + HideMapNamePopUpWindow(); + } + else + { + player_step(inputStruct.dpadDirection, newKeys, heldKeys); + } + } +} + +void CB1_Overworld(void) +{ + if (gMain.callback2 == CB2_Overworld) + DoCB1_Overworld(gMain.newKeys, gMain.heldKeys); +} + +static void OverworldBasic(void) +{ + ScriptContext2_RunScript(); + RunTasks(); + AnimateSprites(); + CameraUpdate(); + UpdateCameraPanning(); + BuildOamBuffer(); + UpdatePaletteFade(); + sub_80A0A38(); + do_scheduled_bg_tilemap_copies_to_vram(); +} + +// This CB2 is used when starting +void CB2_OverworldBasic(void) +{ + OverworldBasic(); +} + +void CB2_Overworld(void) +{ + bool32 fading = (gPaletteFade.active != 0); + if (fading) + SetVBlankCallback(NULL); + OverworldBasic(); + if (fading) + SetFieldVBlankCallback(); +} + +void SetMainCallback1(MainCallback cb) +{ + gMain.callback1 = cb; +} + +void sub_8085E94(void *a0) +{ + sUnknown_03000E0C = a0; +} + +static bool8 map_post_load_hook_exec(void) +{ + if (gUnknown_03005DB0 != NULL) + { + if (!gUnknown_03005DB0()) + { + return FALSE; + } + else + { + gUnknown_03005DB0 = NULL; + gFieldCallback = NULL; + } + } + else + { + if (gFieldCallback != NULL) + gFieldCallback(); + else + mapldr_default(); + + gFieldCallback = NULL; + } + + return TRUE; +} + +void CB2_NewGame(void) +{ + FieldClearVBlankHBlankCallbacks(); + StopMapMusic(); + ResetSafariZoneFlag_(); + NewGameInitData(); + player_avatar_init_params_reset(); + PlayTimeCounter_Start(); + ScriptContext1_Init(); + ScriptContext2_Disable(); + gFieldCallback = ExecuteTruckSequence; + gUnknown_03005DB0 = NULL; + do_load_map_stuff_loop(&gMain.state); + SetFieldVBlankCallback(); + SetMainCallback1(CB1_Overworld); + SetMainCallback2(CB2_Overworld); +} + +void CB2_WhiteOut(void) +{ + u8 val; + + if (++gMain.state >= 120) + { + FieldClearVBlankHBlankCallbacks(); + StopMapMusic(); + ResetSafariZoneFlag_(); + DoWhiteOut(); + player_avatar_init_params_reset(); + ScriptContext1_Init(); + ScriptContext2_Disable(); + gFieldCallback = sub_80AF3C8; + val = 0; + do_load_map_stuff_loop(&val); + SetFieldVBlankCallback(); + SetMainCallback1(CB1_Overworld); + SetMainCallback2(CB2_Overworld); + } +} + +void CB2_LoadMap(void) +{ + FieldClearVBlankHBlankCallbacks(); + ScriptContext1_Init(); + ScriptContext2_Disable(); + SetMainCallback1(NULL); + SetMainCallback2(c2_change_map); + gMain.savedCallback = CB2_LoadMap2; +} + +static void CB2_LoadMap2(void) +{ + do_load_map_stuff_loop(&gMain.state); + SetFieldVBlankCallback(); + SetMainCallback1(CB1_Overworld); + SetMainCallback2(CB2_Overworld); +} + +void sub_8086024(void) +{ + if (!gMain.state) + { + FieldClearVBlankHBlankCallbacks(); + ScriptContext1_Init(); + ScriptContext2_Disable(); + SetMainCallback1(NULL); + } + if (load_map_stuff(&gMain.state, 1)) + { + SetFieldVBlankCallback(); + SetMainCallback1(CB1_Overworld); + SetMainCallback2(CB2_Overworld); + } +} + +void sub_8086074(void) +{ + FieldClearVBlankHBlankCallbacks(); + gFieldCallback = sub_80AF314; + SetMainCallback2(c2_80567AC); +} + +static void c2_80567AC(void) +{ + if (map_loading_iteration_3(&gMain.state)) + { + SetFieldVBlankCallback(); + SetMainCallback1(c1_link_related); + sub_8086C2C(); + SetMainCallback2(CB2_Overworld); + } +} + +void CB2_ReturnToField(void) +{ + if (is_c1_link_related_active() == TRUE) + { + SetMainCallback2(CB2_ReturnToFieldLink); + } + else + { + FieldClearVBlankHBlankCallbacks(); + SetMainCallback2(CB2_ReturnToFieldLocal); + } +} + +void CB2_ReturnToFieldLocal(void) +{ + if (sub_8086638(&gMain.state)) + { + SetFieldVBlankCallback(); + SetMainCallback2(CB2_Overworld); + } +} + +void CB2_ReturnToFieldLink(void) +{ + if (!sub_8087598() && map_loading_iteration_2_link(&gMain.state)) + SetMainCallback2(CB2_Overworld); +} + +void c2_8056854(void) +{ + FieldClearVBlankHBlankCallbacks(); + StopMapMusic(); + SetMainCallback1(c1_link_related); + sub_8086C2C(); + + if (gWirelessCommType != 0) + gFieldCallback = sub_80AF314; + else + gFieldCallback = sub_80AF214; + + ScriptContext1_Init(); + ScriptContext2_Disable(); + CB2_ReturnToField(); +} + +void CB2_ReturnToFieldWithOpenMenu(void) +{ + FieldClearVBlankHBlankCallbacks(); + gUnknown_03005DB0 = sub_80AF6A4; + CB2_ReturnToField(); +} + +void sub_80861B0(void) +{ + FieldClearVBlankHBlankCallbacks(); + gFieldCallback = sub_80AF188; + CB2_ReturnToField(); +} + +void CB2_ReturnToFieldContinueScript(void) +{ + FieldClearVBlankHBlankCallbacks(); + gFieldCallback = sub_80AF168; + CB2_ReturnToField(); +} + +void sub_80861E8(void) +{ + FieldClearVBlankHBlankCallbacks(); + gFieldCallback = sub_80AF3C8; + CB2_ReturnToField(); +} + +static void sub_8086204(void) +{ + if ((gMapHeader.flags & 0xF8) == 8 && sub_80E909C() == TRUE) + ShowMapNamePopup(); + sub_80AF3C8(); +} + +void CB2_ContinueSavedGame(void) +{ + u8 trainerHillMapId; + + FieldClearVBlankHBlankCallbacks(); + StopMapMusic(); + ResetSafariZoneFlag_(); + if (gSaveFileStatus == 0xFF) + sub_81A3908(); + + LoadSaveblockMapHeader(); + set_warp2_warp3_to_neg_1(); + trainerHillMapId = GetCurrentTrainerHillMapId(); + if (gMapHeader.mapDataId == 0x169) + sub_81AA2F8(); + else if (trainerHillMapId != 0 && trainerHillMapId != 6) + sub_81D5F48(); + else + LoadSaveblockMapObjScripts(); + + UnfreezeMapObjects(); + DoTimeBasedEvents(); + sub_8084788(); + if (gMapHeader.mapDataId == 0x169) + battle_pyramid_map_load_related(1); + else if (trainerHillMapId != 0) + trainer_hill_map_load_related(); + else + sub_8087D74(); + + PlayTimeCounter_Start(); + ScriptContext1_Init(); + ScriptContext2_Disable(); + sub_8195E10(); + if (GetSecretBase2Field_9() == 1) + { + ClearSecretBase2Field_9(); + warp1_set_to_sav1w(); + warp_in(); + sub_80EDB44(); + SetMainCallback2(CB2_LoadMap); + } + else + { + sub_80EDB44(); + gFieldCallback = sub_8086204; + SetMainCallback1(CB1_Overworld); + CB2_ReturnToField(); + } +} + +static void FieldClearVBlankHBlankCallbacks(void) +{ + if (warp0_in_pokecenter() == TRUE) + CloseLink(); + + if (gWirelessCommType != 0) + { + EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); + DisableInterrupts(INTR_FLAG_HBLANK); + } + else + { + u16 savedIme = REG_IME; + REG_IME = 0; + REG_IE &= ~INTR_FLAG_HBLANK; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = savedIme; + } + + SetVBlankCallback(NULL); + SetHBlankCallback(NULL); +} + +static void SetFieldVBlankCallback(void) +{ + SetVBlankCallback(VBlankCB_Field); +} + +static void VBlankCB_Field(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + ScanlineEffect_InitHBlankDmaTransfer(); + FieldUpdateBgTilemapScroll(); + TransferPlttBuffer(); + TransferTilesetAnimsBuffer(); +} + +static void sub_80863B0(void) +{ + u8 val; + + if (sub_81A9E6C()) + { + door_upload_tiles(); + ScanlineEffect_SetParams(gUnknown_08339DBC); + } + else if ((val = Overworld_GetFlashLevel())) + { + sub_80B00E8(val); + ScanlineEffect_SetParams(gUnknown_08339DBC); + } +} + +static bool32 map_loading_iteration_3(u8 *state) +{ + switch (*state) + { + case 0: + overworld_bg_setup(); + ScriptContext1_Init(); + ScriptContext2_Disable(); + sub_80867C8(); + sub_80867D8(); + (*state)++; + break; + case 1: + mli0_load_map(1); + (*state)++; + break; + case 2: + sub_8086988(TRUE); + (*state)++; + break; + case 3: + sub_8086AE4(); + sub_80869DC(); + sub_8086B14(); + sub_8086AAC(); + (*state)++; + break; + case 4: + sub_80863B0(); + map_loading_lcd_reset(); + sub_8197200(); + (*state)++; + break; + case 5: + move_tilemap_camera_to_upper_left_corner(); + (*state)++; + break; + case 6: + copy_map_tileset1_to_vram(gMapHeader.mapData); + (*state)++; + break; + case 7: + copy_map_tileset2_to_vram(gMapHeader.mapData); + (*state)++; + break; + case 8: + if (free_temp_tile_data_buffers_if_possible() != TRUE) + { + apply_map_tileset1_tileset2_palette(gMapHeader.mapData); + (*state)++; + } + break; + case 9: + DrawWholeMapView(); + (*state)++; + break; + case 10: + cur_mapheader_run_tileset_funcs_after_some_cpuset(); + (*state)++; + break; + case 11: + if (gWirelessCommType != 0) + { + sub_800E0E8(); + CreateWirelessStatusIndicatorSprite(0, 0); + } + (*state)++; + break; + case 12: + if (map_post_load_hook_exec()) + (*state)++; + break; + case 13: + return TRUE; + } + + return FALSE; +} + +static bool32 load_map_stuff(u8 *state, u32 a2) +{ + switch (*state) + { + case 0: + FieldClearVBlankHBlankCallbacks(); + mli0_load_map(a2); + (*state)++; + break; + case 1: + sub_80867C8(); + sub_80867D8(); + (*state)++; + break; + case 2: + sub_8086988(a2); + (*state)++; + break; + case 3: + mli4_mapscripts_and_other(); + sub_8086A80(); + (*state)++; + break; + case 4: + sub_80863B0(); + map_loading_lcd_reset(); + sub_8197200(); + (*state)++; + break; + case 5: + move_tilemap_camera_to_upper_left_corner(); + (*state)++; + break; + case 6: + copy_map_tileset1_to_vram(gMapHeader.mapData); + (*state)++; + break; + case 7: + copy_map_tileset2_to_vram(gMapHeader.mapData); + (*state)++; + break; + case 8: + if (free_temp_tile_data_buffers_if_possible() != TRUE) + { + apply_map_tileset1_tileset2_palette(gMapHeader.mapData); + (*state)++; + } + break; + case 9: + DrawWholeMapView(); + (*state)++; + break; + case 10: + cur_mapheader_run_tileset_funcs_after_some_cpuset(); + (*state)++; + break; + case 11: + if ((gMapHeader.flags & 0xF8) == 8 && sub_80E909C() == 1) + ShowMapNamePopup(); + (*state)++; + break; + case 12: + if (map_post_load_hook_exec()) + (*state)++; + break; + case 13: + return TRUE; + } + + return FALSE; +} + +static bool32 sub_8086638(u8 *state) +{ + switch (*state) + { + case 0: + sub_80867C8(); + sub_80867D8(); + sub_8086988(0); + sub_8086A68(); + sub_8086A80(); + (*state)++; + break; + case 1: + sub_8086860(); + sub_81D64C0(); + (*state)++; + break; + case 2: + if (map_post_load_hook_exec()) + (*state)++; + break; + case 3: + return TRUE; + } + + return FALSE; +} + +static bool32 map_loading_iteration_2_link(u8 *state) +{ + switch (*state) + { + case 0: + FieldClearVBlankHBlankCallbacks(); + sub_80867C8(); + sub_80867D8(); + (*state)++; + break; + case 1: + sub_8086988(1); + (*state)++; + break; + case 2: + sub_8086B9C(); + sub_8086A68(); + sub_8086AC8(); + (*state)++; + break; + case 3: + sub_80863B0(); + map_loading_lcd_reset(); + sub_8197200(); + (*state)++; + break; + case 4: + move_tilemap_camera_to_upper_left_corner(); + (*state)++; + break; + case 5: + copy_map_tileset1_to_vram(gMapHeader.mapData); + (*state)++; + break; + case 6: + copy_map_tileset2_to_vram(gMapHeader.mapData); + (*state)++; + break; + case 7: + if (free_temp_tile_data_buffers_if_possible() != TRUE) + { + apply_map_tileset1_tileset2_palette(gMapHeader.mapData); + (*state)++; + } + break; + case 8: + DrawWholeMapView(); + (*state)++; + break; + case 9: + cur_mapheader_run_tileset_funcs_after_some_cpuset(); + (*state)++; + break; + case 11: + if (gWirelessCommType != 0) + { + sub_800E0E8(); + CreateWirelessStatusIndicatorSprite(0, 0); + } + (*state)++; + break; + case 12: + if (map_post_load_hook_exec()) + (*state)++; + break; + case 10: + (*state)++; + break; + case 13: + SetFieldVBlankCallback(); + (*state)++; + return TRUE; + } + + return FALSE; +} + +static void do_load_map_stuff_loop(u8 *state) +{ + while (!load_map_stuff(state, 0)); +} + +static void sub_80867C8(void) +{ + sub_81BE6AC(); + MoveSaveBlocks_ResetHeap(); +} + +static void sub_80867D8(void) +{ + SetGpuReg(REG_OFFSET_DISPCNT, 0); + ScanlineEffect_Stop(); + + DmaClear16(3, PLTT + 2, PLTT_SIZE - 2); + DmaFillLarge16(3, 0, (void *)(VRAM + 0x0), 0x18000, 0x1000); + ResetOamRange(0, 128); + LoadOam(); +} + +static void sub_8086860(void) +{ + sub_80863B0(); + map_loading_lcd_reset(); + sub_8197200(); + mapdata_load_assets_to_gpu_and_full_redraw(); +} + +static void map_loading_lcd_reset(void) +{ + clear_scheduled_bg_copies_to_vram(); + reset_temp_tile_data_buffers(); + SetGpuReg(REG_OFFSET_MOSAIC, 0); + SetGpuReg(REG_OFFSET_WININ, 0x1F1F); + SetGpuReg(REG_OFFSET_WINOUT, 0x101); + SetGpuReg(REG_OFFSET_WIN0H, 0xFF); + SetGpuReg(REG_OFFSET_WIN0V, 0xFF); + SetGpuReg(REG_OFFSET_WIN1H, 0xFFFF); + SetGpuReg(REG_OFFSET_WIN1V, 0xFFFF); + SetGpuReg(REG_OFFSET_BLDCNT, gUnknown_82EC7C4[1] | gUnknown_82EC7C4[2] | gUnknown_82EC7C4[3] + | BLDCNT_TGT2_OBJ | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(13, 7)); + overworld_bg_setup(); + schedule_bg_copy_tilemap_to_vram(1); + schedule_bg_copy_tilemap_to_vram(2); + schedule_bg_copy_tilemap_to_vram(3); + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + ChangeBgX(2, 0, 0); + ChangeBgY(2, 0, 0); + ChangeBgX(3, 0, 0); + ChangeBgY(3, 0, 0); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON + | DISPCNT_OBJ_1D_MAP | DISPCNT_HBLANK_INTERVAL); + ShowBg(0); + ShowBg(1); + ShowBg(2); + ShowBg(3); + sub_8098128(); +} + +static void sub_8086988(u32 a1) +{ + ResetTasks(); + ResetSpriteData(); + ResetPaletteFade(); + ScanlineEffect_Clear(); + dp13_810BB8C(); + ResetCameraUpdateInfo(); + InstallCameraPanAheadCallback(); + if (!a1) + npc_paltag_set_load(0); + else + npc_paltag_set_load(1); + + FieldEffectActiveListClear(); + sub_80AAFA4(); + sub_80AEE84(); + if (!a1) + SetUpFieldTasks(); + mapheader_run_script_with_tag_x5(); + sub_81BE6B8(); +} + +static void sub_80869DC(void) +{ + gUnknown_03005DEC = 0; + gUnknown_03005DE8 = 0; + sub_808D438(); + SpawnFieldObjectsInView(0, 0); + mapheader_run_first_tag4_script_list_match(); +} + +static void mli4_mapscripts_and_other(void) +{ + s16 x, y; + struct UnkPlayerStruct *player; + + gUnknown_03005DEC = 0; + gUnknown_03005DE8 = 0; + sub_808D438(); + sav1_camera_get_focus_coords(&x, &y); + player = sub_80852D4(); + InitPlayerAvatar(x, y, player->player_field_1, gSaveBlock2Ptr->playerGender); + SetPlayerAvatarTransitionFlags(player->player_field_0); + player_avatar_init_params_reset(); + SpawnFieldObjectsInView(0, 0); + mapheader_run_first_tag4_script_list_match(); +} + +static void sub_8086A68(void) +{ + sub_808E16C(0, 0); + RotatingGate_InitPuzzleAndGraphics(); + mapheader_run_script_with_tag_x7(); +} + +static void sub_8086A80(void) +{ + gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_15 = 1; + InitCameraUpdateCallback(gPlayerAvatar.spriteId); +} + +static void sub_8086AAC(void) +{ + InitCameraUpdateCallback(sub_8087858(gUnknown_03005DB4)); +} + +static void sub_8086AC8(void) +{ + InitCameraUpdateCallback(sub_8087858(gUnknown_03005DB4)); +} + +static void sub_8086AE4(void) +{ + u16 x, y; + sav1_camera_get_focus_coords(&x, &y); + sub_8088B3C(x + gUnknown_03005DB4, y); +} + +static void sub_8086B14(void) +{ + u16 i; + u16 x, y; + + sav1_camera_get_focus_coords(&x, &y); + x -= gUnknown_03005DB4; + + for (i = 0; i < gFieldLinkPlayerCount; i++) + { + SpawnLinkPlayerMapObject(i, i + x, y, gLinkPlayers[i].gender); + CreateLinkPlayerSprite(i, gLinkPlayers[i].version); + } + + sub_8086C40(); +} + +static void sub_8086B9C(void) +{ + u16 i; + for (i = 0; i < gFieldLinkPlayerCount; i++) + CreateLinkPlayerSprite(i, gLinkPlayers[i].version); +} + +static void c1_link_related(void) +{ + if (gWirelessCommType == 0 || !sub_800F0B8() || !sub_8009F3C()) + { + u8 var = gUnknown_03005DB4; + sub_8086F38(gLinkPartnersHeldKeys, var); + sub_8086FA0(sUnknown_03000E14(var)); + sub_8086C40(); + } +} + +void sub_8086C2C(void) +{ + sub_8086C90(); + c1_link_related_func_set(sub_80870B0); +} + +static void sub_8086C40(void) +{ + sub_808709C(gLinkPartnersHeldKeys); +} + +static void c1_link_related_func_set(u16 (*func)(u32)) +{ + sUnknown_03000E19 = 0; + sUnknown_03000E14 = func; +} + +static void sub_8086C64(void) +{ + if (gWirelessCommType != 0 && ++sUnknown_03000E19 > 60) + sub_8010198(); +} + +static void sub_8086C90(void) +{ + s32 i; + for (i = 0; i < 4; i++) + sUnknown_03000E10[i] = 0x80; +} + +static bool32 sub_8086CA8(u16 a1) +{ + s32 i; + s32 count = gFieldLinkPlayerCount; + + for (i = 0; i < count; i++) + if (sUnknown_03000E10[i] != a1) + return FALSE; + return TRUE; +} + +static bool32 sub_8086CE0(u16 a1) +{ + s32 i; + s32 count = gFieldLinkPlayerCount; + + for (i = 0; i < count; i++) + if (sUnknown_03000E10[i] == a1) + return TRUE; + return FALSE; +} + +static void sub_8086D18(u32 a1, u16 a2, struct UnkStruct_8054FF8 *a3, u16 *a4) +{ + const u8 *script; + + if (sUnknown_03000E10[a1] == 0x80) + { + script = sub_8087370(a3); + if (script) + { + *a4 = sub_8087480(script); + sUnknown_03000E10[a1] = 0x81; + if (a3->b) + { + c1_link_related_func_set(sub_80870F8); + sub_8087530(script); + } + return; + } + if (sub_8086CE0(0x83) == 1) + { + sUnknown_03000E10[a1] = 0x81; + if (a3->b) + { + c1_link_related_func_set(sub_80870F8); + sub_8087584(); + } + return; + } + switch (a2) + { + case 24: + if (sub_8087358(a3)) + { + sUnknown_03000E10[a1] = 0x81; + if (a3->b) + { + c1_link_related_func_set(sub_80870F8); + sub_808751C(); + } + } + break; + case 18: + if (sub_8087388(a3) == TRUE) + { + sUnknown_03000E10[a1] = 0x81; + if (a3->b) + { + c1_link_related_func_set(sub_80870F8); + sub_808754C(); + } + } + break; + case 25: + script = sub_80873B4(a3); + if (script) + { + sUnknown_03000E10[a1] = 0x81; + if (a3->b) + { + c1_link_related_func_set(sub_80870F8); + sub_8087568(script); + } + } + break; + case 27: + if (sub_8087340(a3)) + { + sUnknown_03000E10[a1] = 0x81; + if (a3->b) + { + c1_link_related_func_set(sub_808711C); + sub_8087510(); + } + } + break; + case 28: + if (sub_8087340(a3)) + { + sUnknown_03000E10[a1] = 0x81; + if (a3->b) + { + c1_link_related_func_set(sub_8087140); + sub_8087510(); + } + } + break; + } + } + + switch (a2) + { + case 23: + sUnknown_03000E10[a1] = 0x83; + break; + case 22: + sUnknown_03000E10[a1] = 0x82; + break; + case 26: + sUnknown_03000E10[a1] = 0x80; + if (a3->b) + c1_link_related_func_set(sub_80870B0); + break; + case 29: + if (sUnknown_03000E10[a1] == 0x82) + sUnknown_03000E10[a1] = 0x81; + break; + } +} + +static void sub_8086F38(u16 *a1, s32 a2) +{ + struct UnkStruct_8054FF8 st; + s32 i; + + for (i = 0; i < 4; i++) + { + u8 v5 = a1[i]; + u16 v8 = 0; + sub_80872D8(i, a2, &st); + sub_8086D18(i, v5, &st, &v8); + if (sUnknown_03000E10[i] == 0x80) + v8 = sub_8087068(v5); + sub_808796C(i, v8); + } +} + +static void sub_8086FA0(u16 a1) +{ + if (a1 >= 17 && a1 < 30) + gUnknown_03005DA8 = a1; + else + gUnknown_03005DA8 = 17; + + if (gWirelessCommType != 0 + && sub_8087690() > 1 + && is_c1_link_related_active() == TRUE + && sub_8009F3C() == TRUE) + { + switch (a1) + { + case 17: + case 18: + case 19: + case 20: + case 21: + case 24: + case 25: + gUnknown_03005DA8 = 0; + break; + } + } +} + +static u16 sub_808700C(u32 a1) +{ + if (gMain.heldKeys & DPAD_UP) + return 19; + else if (gMain.heldKeys & DPAD_DOWN) + return 18; + else if (gMain.heldKeys & DPAD_LEFT) + return 20; + else if (gMain.heldKeys & DPAD_RIGHT) + return 21; + else if (gMain.newKeys & START_BUTTON) + return 24; + else if (gMain.newKeys & A_BUTTON) + return 25; + else + return 17; +} + +static u16 sub_8087068(u16 a1) +{ + switch (a1) + { + case 21: + return 4; + case 20: + return 3; + case 19: + return 1; + case 18: + return 2; + default: + return 0; + } +} + +static void sub_808709C(u16 *a1) +{ + s32 i; + for (i = 0; i < 4; i++) + a1[i] = 17; +} + +static u16 sub_80870B0(u32 a1) +{ + if (ScriptContext2_IsEnabled() == 1) + return 17; + if (sub_800B4DC() > 4) + return 27; + if (sub_8087690() <= 4) + return sub_808700C(a1); + return 28; +} + +static u16 sub_80870EC(u32 a1) +{ + sub_8086C64(); + return 17; +} + +static u16 sub_80870F8(u32 a1) +{ + u16 retVal; + if (ScriptContext2_IsEnabled() == TRUE) + { + retVal = 17; + } + else + { + retVal = 26; + c1_link_related_func_set(sub_80870EC); + } + return retVal; +} + +static u16 sub_808711C(u32 a1) +{ + u16 retVal; + if (sub_800B4DC() > 2) + { + retVal = 17; + } + else + { + retVal = 26; + ScriptContext2_Disable(); + c1_link_related_func_set(sub_80870EC); + } + return retVal; +} + +static u16 sub_8087140(u32 a1) +{ + u16 retVal; + if (sub_8087690() > 2) + { + retVal = 17; + } + else + { + retVal = 26; + ScriptContext2_Disable(); + c1_link_related_func_set(sub_80870EC); + } + return retVal; +} + +static u16 sub_8087164(u32 a1) +{ + sub_8086C64(); + return 17; +} + +static u16 sub_8087170(u32 linkPlayerId) +{ + if (sUnknown_03000E10[linkPlayerId] == 0x82) + { + if (gMain.newKeys & B_BUTTON) + { + c1_link_related_func_set(sub_8087164); + return 29; + } + else + { + return 17; + } + } + else + { + sub_8086C64(); + return 17; + } +} + +static u16 sub_80871AC(u32 a1) +{ + c1_link_related_func_set(sub_8087170); + return 22; +} + +static u16 sub_80871C0(u32 a1) +{ + return 17; +} + +static u16 sub_80871C4(u32 a1) +{ + if (sUnknown_03000E10[a1] != 0x83) + sub_8086C64(); + if (sub_8086CA8(0x83) == TRUE) + { + ScriptContext1_SetupScript(EventScript_277513); + c1_link_related_func_set(sub_80871C0); + } + return 17; +} + +static u16 sub_80871FC(u32 a1) +{ + c1_link_related_func_set(sub_80871C4); + return 23; +} + +static u16 sub_8087210(u32 a1) +{ + return 17; +} + +u32 sub_8087214(void) +{ + if (sub_8086CE0(0x83) == TRUE) + return 2; + if (sUnknown_03000E14 == sub_8087170 && sUnknown_03000E10[gUnknown_03005DB4] != 0x82) + return 0; + if (sUnknown_03000E14 == sub_8087164 && sUnknown_03000E10[gUnknown_03005DB4] == 0x81) + return 2; + if (sub_8086CA8(0x82) != 0) + return 1; + return 0; +} + +bool32 sub_808727C(void) +{ + return sub_8086CE0(0x83); +} + +u16 sub_8087288(void) +{ + c1_link_related_func_set(sub_80871AC); + return 0; +} + +u16 sub_808729C(void) +{ + c1_link_related_func_set(sub_80870F8); + return 0; +} + +u16 sub_80872B0(void) +{ + c1_link_related_func_set(sub_80871FC); + return 0; +} + +u16 sub_80872C4(void) +{ + c1_link_related_func_set(sub_8087210); + return 0; +} + +static void sub_80872D8(s32 linkPlayerId, s32 a2, struct UnkStruct_8054FF8 *a3) +{ + s16 x, y; + + a3->a = linkPlayerId; + a3->b = (linkPlayerId == a2) ? 1 : 0; + a3->c = gLinkPlayerMapObjects[linkPlayerId].mode; + a3->d = sub_80878A0(linkPlayerId); + sub_8087878(linkPlayerId, &x, &y); + a3->sub.x = x; + a3->sub.y = y; + a3->sub.height = sub_80878C0(linkPlayerId); + a3->field_C = MapGridGetMetatileBehaviorAt(x, y); +} + +static bool32 sub_8087340(struct UnkStruct_8054FF8 *a1) +{ + u8 v1 = a1->c; + if (v1 == 2 || v1 == 0) + return TRUE; + else + return FALSE; +} + +static bool32 sub_8087358(struct UnkStruct_8054FF8 *a1) +{ + u8 v1 = a1->c; + if (v1 == 2 || v1 == 0) + return TRUE; + else + return FALSE; +} + +static u8 *sub_8087370(struct UnkStruct_8054FF8 *a1) +{ + if (a1->c != 2) + return 0; + return sub_809D0F4(&a1->sub); +} + +static bool32 sub_8087388(struct UnkStruct_8054FF8 *a1) +{ + if (a1->c != 2 && a1->c != 0) + return FALSE; + else if (!MetatileBehavior_IsSouthArrowWarp(a1->field_C)) + return FALSE; + else if (a1->d != 1) + return FALSE; + else + return TRUE; +} + +static const u8 *sub_80873B4(struct UnkStruct_8054FF8 *a1) +{ + struct MapPosition unkStruct; + u8 linkPlayerId; + + if (a1->c && a1->c != 2) + return 0; + + unkStruct = a1->sub; + unkStruct.x += gUnknown_08339D64[a1->d].x; + unkStruct.y += gUnknown_08339D64[a1->d].y; + unkStruct.height = 0; + linkPlayerId = GetLinkPlayerIdAt(unkStruct.x, unkStruct.y); + + if (linkPlayerId != 4) + { + if (!a1->b) + return EventScript_TradeRoom_TooBusyToNotice; + else if (sUnknown_03000E10[linkPlayerId] != 0x80) + return EventScript_TradeRoom_TooBusyToNotice; + else if (!sub_80B39D4(linkPlayerId)) + return EventScript_TradeRoom_ReadTrainerCard1; + else + return EventScript_TradeRoom_ReadTrainerCard2; + } + + return sub_809C2C8(&unkStruct, a1->field_C, a1->d); +} + +static u16 sub_8087480(const u8 *script) +{ + if (script == gUnknown_08277388) + return 10; + else if (script == gUnknown_082773A3) + return 9; + else if (script == gUnknown_082773BE) + return 10; + else if (script == gUnknown_082773D9) + return 9; + else if (script == gUnknown_0827741D) + return 10; + else if (script == gUnknown_08277432) + return 9; + else if (script == gUnknown_08277447) + return 10; + else if (script == gUnknown_0827745C) + return 9; + else if (script == gUnknown_08277374) + return 10; + else if (script == gUnknown_0827737E) + return 9; + else if (script == gUnknown_082773F5) + return 10; + else if (script == gUnknown_082773FF) + return 9; + else + return 0; +} + +static void sub_8087510(void) +{ + ScriptContext2_Enable(); +} + +static void sub_808751C(void) +{ + PlaySE(SE_WIN_OPEN); + sub_809FA9C(); + ScriptContext2_Enable(); +} + +static void sub_8087530(const u8 *script) +{ + PlaySE(SE_SELECT); + ScriptContext1_SetupScript(script); + ScriptContext2_Enable(); +} + +static void sub_808754C(void) +{ + PlaySE(SE_WIN_OPEN); + ScriptContext1_SetupScript(gUnknown_082774EF); + ScriptContext2_Enable(); +} + +static void sub_8087568(const u8 *script) +{ + PlaySE(SE_SELECT); + ScriptContext1_SetupScript(script); + ScriptContext2_Enable(); +} + +static void sub_8087584(void) +{ + ScriptContext1_SetupScript(gUnknown_08277509); + ScriptContext2_Enable(); +} + +bool32 sub_8087598(void) +{ + if (!is_c1_link_related_active()) + return 0; + if (sub_800B4DC() >= 3) + sUnknown_03000E18 = 1; + else + sUnknown_03000E18 = 0; + return sUnknown_03000E18; +} + +bool32 sub_80875C8(void) +{ + u8 temp; + + if (sub_800B4DC() < 2) + return FALSE; + else if (is_c1_link_related_active() != TRUE) + return FALSE; + else if (sub_8009F3C() != TRUE) + return FALSE; + else if (sUnknown_03000E14 == sub_808711C) + return TRUE; + else if (sUnknown_03000E14 != sub_80870F8) + return FALSE; + + temp = sUnknown_03000E18; + sUnknown_03000E18 = 0; + + if (temp == TRUE) + return TRUE; + else if (gPaletteFade.active && gPaletteFade.softwareFadeFinishing) + return TRUE; + else + return FALSE; +} + +bool32 sub_8087634(void) +{ + if (sub_8087690() < 2) + return FALSE; + else if (is_c1_link_related_active() != TRUE) + return FALSE; + else if (sub_8009F3C() != TRUE) + return FALSE; + else if (sUnknown_03000E14 == sub_8087140) + return TRUE; + else + return FALSE; +} + +bool32 sub_808766C(void) +{ + if (gWirelessCommType != 0) + return FALSE; + else if (!sub_8009F3C()) + return FALSE; + else + return TRUE; +} + +static u32 sub_8087690(void) +{ + if (gWirelessCommType != 0) + return gUnknown_03005000.unk_9e8.unk_232; + else + return gLink.sendQueue.count; +} + +static void ZeroLinkPlayerMapObject(struct LinkPlayerMapObject *linkPlayerMapObj) +{ + memset(linkPlayerMapObj, 0, sizeof(struct LinkPlayerMapObject)); +} + +void ZeroAllLinkPlayerMapObjects(void) +{ + memset(gLinkPlayerMapObjects, 0, sizeof(gLinkPlayerMapObjects)); +} + +static void ZeroMapObject(struct MapObject *mapObj) +{ + memset(mapObj, 0, sizeof(struct MapObject)); +} + +static void SpawnLinkPlayerMapObject(u8 linkPlayerId, s16 x, s16 y, u8 a4) +{ + u8 mapObjId = sub_808D4F4(); + struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId]; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + + ZeroLinkPlayerMapObject(linkPlayerMapObj); + ZeroMapObject(mapObj); + + linkPlayerMapObj->active = 1; + linkPlayerMapObj->linkPlayerId = linkPlayerId; + linkPlayerMapObj->mapObjId = mapObjId; + linkPlayerMapObj->mode = 0; + + mapObj->active = 1; + mapObj->mapobj_bit_1 = a4; + mapObj->range.as_byte = 2; + mapObj->spriteId = 64; + + InitLinkPlayerMapObjectPos(mapObj, x, y); +} + +static void InitLinkPlayerMapObjectPos(struct MapObject *mapObj, s16 x, s16 y) +{ + mapObj->coords2.x = x; + mapObj->coords2.y = y; + mapObj->coords3.x = x; + mapObj->coords3.y = y; + sub_8093038(x, y, &mapObj->coords1.x, &mapObj->coords1.y); + mapObj->coords1.x += 8; + FieldObjectUpdateZCoord(mapObj); +} + +static void sub_80877DC(u8 linkPlayerId, u8 a2) +{ + if (gLinkPlayerMapObjects[linkPlayerId].active) + { + u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + mapObj->range.as_byte = a2; + } +} + +static void sub_808780C(u8 linkPlayerId) +{ + struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId]; + u8 mapObjId = linkPlayerMapObj->mapObjId; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + if (mapObj->spriteId != 64 ) + DestroySprite(&gSprites[mapObj->spriteId]); + linkPlayerMapObj->active = 0; + mapObj->active = 0; +} + +static u8 sub_8087858(u8 linkPlayerId) +{ + u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + return mapObj->spriteId; +} + +static void sub_8087878(u8 linkPlayerId, u16 *x, u16 *y) +{ + u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + *x = mapObj->coords2.x; + *y = mapObj->coords2.y; +} + +static u8 sub_80878A0(u8 linkPlayerId) +{ + u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + return mapObj->range.as_byte; +} + +static u8 sub_80878C0(u8 linkPlayerId) +{ + u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + return mapObj->mapobj_unk_0B_0; +} + +static s32 sub_80878E4(u8 linkPlayerId) +{ + u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + return 16 - (s8)mapObj->mapobj_unk_21; +} + +static u8 GetLinkPlayerIdAt(s16 x, s16 y) +{ + u8 i; + for (i = 0; i < 4; i++) + { + if (gLinkPlayerMapObjects[i].active + && (gLinkPlayerMapObjects[i].mode == 0 || gLinkPlayerMapObjects[i].mode == 2)) + { + struct MapObject *mapObj = &gMapObjects[gLinkPlayerMapObjects[i].mapObjId]; + if (mapObj->coords2.x == x && mapObj->coords2.y == y) + return i; + } + } + return 4; +} + +static void sub_808796C(u8 linkPlayerId, u8 a2) +{ + struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId]; + u8 mapObjId = linkPlayerMapObj->mapObjId; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + + if (linkPlayerMapObj->active) + { + if (a2 > 10) + mapObj->mapobj_bit_2 = 1; + else + gUnknown_08339E00[gUnknown_08339DC8[linkPlayerMapObj->mode](linkPlayerMapObj, mapObj, a2)](linkPlayerMapObj, mapObj); + } +} + +static u8 sub_80879D8(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3) +{ + return gUnknown_08339DD4[a3](linkPlayerMapObj, mapObj, a3); +} + +static u8 sub_80879F8(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3) +{ + return 1; +} + +static u8 sub_80879FC(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3) +{ + return gUnknown_08339DD4[a3](linkPlayerMapObj, mapObj, a3); +} + +static u8 sub_8087A1C(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3) +{ + return 0; +} + +static u8 sub_8087A20(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3) +{ + s16 x, y; + + mapObj->range.as_byte = npc_something3(a3, mapObj->range.as_byte); + FieldObjectMoveDestCoords(mapObj, mapObj->range.as_byte, &x, &y); + + if (LinkPlayerDetectCollision(linkPlayerMapObj->mapObjId, mapObj->range.as_byte, x, y)) + { + return 0; + } + else + { + mapObj->mapobj_unk_21 = 16; + npc_coords_shift(mapObj, x, y); + FieldObjectUpdateZCoord(mapObj); + return 1; + } +} + +static u8 sub_8087A88(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3) +{ + mapObj->range.as_byte = npc_something3(a3, mapObj->range.as_byte); + return 0; +} + +static void sub_8087AA0(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj) +{ + linkPlayerMapObj->mode = 0; +} + +static void sub_8087AA8(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj) +{ + mapObj->mapobj_unk_21--; + linkPlayerMapObj->mode = 1; + MoveCoords(mapObj->range.as_byte, &mapObj->coords1.x, &mapObj->coords1.y); + if (!mapObj->mapobj_unk_21) + { + npc_coords_shift_still(mapObj); + linkPlayerMapObj->mode = 2; + } +} + +static u8 npc_something3(u8 a1, u8 a2) +{ + switch (a1 - 1) + { + case 0: + case 6: + return 2; + case 1: + case 7: + return 1; + case 2: + case 8: + return 3; + case 3: + case 9: + return 4; + } + return a2; +} + +static u8 LinkPlayerDetectCollision(u8 selfMapObjId, u8 a2, s16 x, s16 y) +{ + u8 i; + for (i = 0; i < 16; i++) + { + if (i != selfMapObjId) + { + if ((gMapObjects[i].coords2.x == x && gMapObjects[i].coords2.y == y) + || (gMapObjects[i].coords3.x == x && gMapObjects[i].coords3.y == y)) + { + return 1; + } + } + } + return MapGridIsImpassableAt(x, y); +} + +static void CreateLinkPlayerSprite(u8 linkPlayerId, u8 gameVersion) +{ + struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId]; + u8 mapObjId = linkPlayerMapObj->mapObjId; + struct MapObject *mapObj = &gMapObjects[mapObjId]; + struct Sprite *sprite; -// Static type declarations + if (linkPlayerMapObj->active) + { + switch (gameVersion) + { + case VERSION_FIRE_RED: + case VERSION_LEAF_GREEN: + mapObj->spriteId = AddPseudoFieldObject(sub_808BD6C(mapObj->mapobj_bit_1), SpriteCB_LinkPlayer, 0, 0, 0); + break; + case VERSION_RUBY: + case VERSION_SAPPHIRE: + mapObj->spriteId = AddPseudoFieldObject(sub_808BD7C(mapObj->mapobj_bit_1), SpriteCB_LinkPlayer, 0, 0, 0); + break; + case VERSION_EMERALD: + mapObj->spriteId = AddPseudoFieldObject(GetRivalAvatarGraphicsIdByStateIdAndGender(0, mapObj->mapobj_bit_1), SpriteCB_LinkPlayer, 0, 0, 0); + break; + } -// Static RAM declarations -IWRAM_DATA void *gUnknown_03000E0C; -IWRAM_DATA u8 gUnknown_03000E10[4]; -IWRAM_DATA u8 (*gUnknown_03000E14)(u32); -IWRAM_DATA u8 gUnknown_03000E18; -IWRAM_DATA u8 gUnknown_03000E19; -IWRAM_DATA void *rom4_c_unused_03000e1c; + sprite = &gSprites[mapObj->spriteId]; + sprite->coordOffsetEnabled = TRUE; + sprite->data[0] = linkPlayerId; + mapObj->mapobj_bit_2 = 0; + } +} -// Static ROM declarations +static void SpriteCB_LinkPlayer(struct Sprite *sprite) +{ + struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[sprite->data[0]]; + struct MapObject *mapObj = &gMapObjects[linkPlayerMapObj->mapObjId]; + sprite->pos1.x = mapObj->coords1.x; + sprite->pos1.y = mapObj->coords1.y; + SetObjectSubpriorityByZCoord(mapObj->elevation, sprite, 1); + sprite->oam.priority = ZCoordToPriority(mapObj->elevation); -// .rodata + if (!linkPlayerMapObj->mode) + StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(mapObj->range.as_byte)); + else + StartSpriteAnimIfDifferent(sprite, get_go_image_anim_num(mapObj->range.as_byte)); -// .text + sub_80979D4(sprite, 0); + if (mapObj->mapobj_bit_2) + { + sprite->invisible = ((sprite->data[7] & 4) >> 2); + sprite->data[7]++; + } +} diff --git a/src/pokeblock.c b/src/pokeblock.c index b9d1d94c6..b9a1f6bf3 100644 --- a/src/pokeblock.c +++ b/src/pokeblock.c @@ -74,7 +74,7 @@ extern void (*gFieldCallback)(void); extern const u16 gUnknown_0860F074[]; -extern void c2_exit_to_overworld_2_switch(void); +extern void CB2_ReturnToField(void); extern bool8 sub_81221EC(void); extern void sub_809882C(u8, u16, u8); extern void copy_textbox_border_tile_patterns_to_vram(u8, u16, u8); @@ -374,7 +374,7 @@ void OpenPokeblockCaseInBattle(void) void OpenPokeblockCaseOnFeeder(void) { - OpenPokeblockCase(PBLOCK_CASE_FEEDER, c2_exit_to_overworld_2_switch); + OpenPokeblockCase(PBLOCK_CASE_FEEDER, CB2_ReturnToField); } static void CB2_PokeblockMenu(void) diff --git a/src/region_map.c b/src/region_map.c index 086c0ba68..f16787fc9 100644 --- a/src/region_map.c +++ b/src/region_map.c @@ -881,7 +881,7 @@ static void RegionMap_InitializeStateBasedOnPlayerLocation(void) return; } - switch (get_map_light_level_by_bank_and_number(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum)) + switch (GetMapTypeByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum)) { default: case 1: @@ -904,7 +904,7 @@ static void RegionMap_InitializeStateBasedOnPlayerLocation(void) case 7: if (gMapHeader.flags & 0x02) { - mapHeader = get_mapheader_by_bank_and_number(gSaveBlock1Ptr->warp4.mapGroup, gSaveBlock1Ptr->warp4.mapNum); + mapHeader = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->warp4.mapGroup, gSaveBlock1Ptr->warp4.mapNum); gRegionMap->mapSecId = mapHeader->regionMapSectionId; gRegionMap->playerIsInCave = TRUE; mapWidth = mapHeader->mapData->width; @@ -923,7 +923,7 @@ static void RegionMap_InitializeStateBasedOnPlayerLocation(void) } break; case 9: - mapHeader = get_mapheader_by_bank_and_number((u16)gSaveBlock1Ptr->warp2.mapGroup, (u16)gSaveBlock1Ptr->warp2.mapNum); + mapHeader = Overworld_GetMapHeaderByGroupAndId((u16)gSaveBlock1Ptr->warp2.mapGroup, (u16)gSaveBlock1Ptr->warp2.mapNum); gRegionMap->mapSecId = mapHeader->regionMapSectionId; gRegionMap->playerIsInCave = TRUE; mapWidth = mapHeader->mapData->width; @@ -937,12 +937,12 @@ static void RegionMap_InitializeStateBasedOnPlayerLocation(void) if (gRegionMap->mapSecId != MAPSEC_DYNAMIC) { storedWarp = &gSaveBlock1Ptr->warp4; - mapHeader = get_mapheader_by_bank_and_number(storedWarp->mapGroup, storedWarp->mapNum); + mapHeader = Overworld_GetMapHeaderByGroupAndId(storedWarp->mapGroup, storedWarp->mapNum); } else { storedWarp = &gSaveBlock1Ptr->warp2; - mapHeader = get_mapheader_by_bank_and_number(storedWarp->mapGroup, storedWarp->mapNum); + mapHeader = Overworld_GetMapHeaderByGroupAndId(storedWarp->mapGroup, storedWarp->mapNum); gRegionMap->mapSecId = mapHeader->regionMapSectionId; } if (RegionMap_IsPlayerInCave(gRegionMap->mapSecId)) @@ -1065,7 +1065,7 @@ static void RegionMap_InitializeStateBasedOnSSTidalLocation(void) break; default: case 0: - mapHeader = get_mapheader_by_bank_and_number(mapGroup, mapNum); + mapHeader = Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum); gRegionMap->mapSecId = mapHeader->regionMapSectionId; dimensionScale = mapHeader->mapData->width / gRegionMapEntries[gRegionMap->mapSecId].width; @@ -1581,7 +1581,7 @@ void MCB2_FlyMap(void) gUnknown_0203A148 = malloc(sizeof(*gUnknown_0203A148)); if (gUnknown_0203A148 == NULL) { - SetMainCallback2(sub_8086194); + SetMainCallback2(CB2_ReturnToFieldWithOpenMenu); } else { diff --git a/src/reset_save_heap.c b/src/reset_save_heap.c index 81321b86d..1d90448b2 100644 --- a/src/reset_save_heap.c +++ b/src/reset_save_heap.c @@ -26,5 +26,5 @@ void sub_81700F8(void) Sav2_ClearSetDefault(); SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound); InitHeap(gHeap, HEAP_SIZE); - SetMainCallback2(sub_8086230); + SetMainCallback2(CB2_ContinueSavedGame); } diff --git a/src/safari_zone.c b/src/safari_zone.c index dd3cf3733..ab5c38f3a 100644 --- a/src/safari_zone.c +++ b/src/safari_zone.c @@ -30,9 +30,9 @@ extern void sub_80EE44C(u8, u8); extern void IncrementGameStat(u8 index); extern void ScriptContext1_SetupScript(u8*); extern void ScriptContext2_RunNewScript(u8*); -extern void c2_exit_to_overworld_2_switch(void); -extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void); -extern void c2_load_new_map(void); +extern void CB2_ReturnToField(void); +extern void CB2_ReturnToFieldContinueScript(void); +extern void CB2_LoadMap(void); extern void sub_80AF6F0(void); extern void ScriptContext1_Stop(void); extern void warp_in(void); @@ -112,20 +112,20 @@ void CB2_EndSafariBattle(void) sSafariZoneCaughtMons++; if (gNumSafariBalls != 0) { - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); } else if (gBattleOutcome == B_OUTCOME_NO_SAFARI_BALLS) { ScriptContext2_RunNewScript(EventScript_2A4B4C); warp_in(); gFieldCallback = sub_80AF6F0; - SetMainCallback2(c2_load_new_map); + SetMainCallback2(CB2_LoadMap); } else if (gBattleOutcome == B_OUTCOME_CAUGHT) { ScriptContext1_SetupScript(EventScript_2A4B9B); ScriptContext1_Stop(); - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetMainCallback2(CB2_ReturnToFieldContinueScript); } } diff --git a/src/scrcmd.c b/src/scrcmd.c index deb170c68..ef3fcbcac 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -2054,7 +2054,7 @@ bool8 ScrCmd_playslotmachine(struct ScriptContext *ctx) { u8 slotMachineIndex = VarGet(ScriptReadHalfword(ctx)); - PlaySlotMachine(slotMachineIndex, c2_exit_to_overworld_1_continue_scripts_restart_music); + PlaySlotMachine(slotMachineIndex, CB2_ReturnToFieldContinueScript); ScriptContext1_Stop(); return TRUE; } diff --git a/src/script.c b/src/script.c index 5a1c5daa9..8c868128b 100644 --- a/src/script.c +++ b/src/script.c @@ -243,7 +243,7 @@ void ScriptContext2_RunNewScript(const u8 *ptr) u8 *mapheader_get_tagged_pointer(u8 tag) { - u8 *mapScripts = gMapHeader.mapScripts; + const u8 *mapScripts = gMapHeader.mapScripts; if (!mapScripts) return NULL; diff --git a/src/secret_base.c b/src/secret_base.c index e3c06a75d..df754f2a0 100644 --- a/src/secret_base.c +++ b/src/secret_base.c @@ -3,6 +3,7 @@ #include "global.h" #include "constants/decorations.h" #include "malloc.h" +#include "main.h" #include "task.h" #include "palette.h" #include "list_menu.h" @@ -39,6 +40,10 @@ #include "tv.h" #include "secret_base.h" +extern void (*gFieldCallback)(void); + +extern void mapldr_default(void); + // Static type declarations struct SecretBaseListMenuBuffer { @@ -244,7 +249,7 @@ void sub_80E8C98(void) void sub_80E8CB0(s16 *xPtr, s16 *yPtr, u16 tile) { - struct MapData *mapData; + const struct MapData *mapData; s16 x; s16 y; @@ -386,7 +391,7 @@ void sub_80E8FD0(u8 taskId) sub_80E8F9C(); warp_in(); gFieldCallback = sub_80AF168; - SetMainCallback2(c2_load_new_map); + SetMainCallback2(CB2_LoadMap); DestroyTask(taskId); break; } @@ -444,7 +449,7 @@ void sub_80E916C(u8 taskId) Overworld_SetWarpDestination(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1, gUnknown_0858CFE8[idx + 2], gUnknown_0858CFE8[idx + 3]); warp_in(); gFieldCallback = sub_80E9108; - SetMainCallback2(c2_load_new_map); + SetMainCallback2(CB2_LoadMap); DestroyTask(taskId); } } @@ -642,7 +647,7 @@ void sub_80E96A4(u8 taskId) copy_saved_warp2_bank_and_enter_x_to_warp1(0x7e); warp_in(); gFieldCallback = mapldr_default; - SetMainCallback2(c2_load_new_map); + SetMainCallback2(CB2_LoadMap); ScriptContext2_Disable(); DestroyTask(taskId); break; @@ -773,7 +778,7 @@ void sub_80E9AD0(void) u16 i; u16 j; s16 tile; - struct MapEvents *events; + const struct MapEvents *events; events = gMapHeader.events; for (i = 0; i < events->bgEventCount; i ++) diff --git a/src/smokescreen.c b/src/smokescreen.c new file mode 100644 index 000000000..9b37cd234 --- /dev/null +++ b/src/smokescreen.c @@ -0,0 +1,71 @@ +#include "global.h" +#include "data2.h" +#include "decompress.h" +#include "sprite.h" +#include "util.h" + +static void sub_8075370(struct Sprite *); + +u8 sub_807521C(s16 x, s16 y, u8 a3) +{ + u8 mainSpriteId; + u8 spriteId1, spriteId2, spriteId3, spriteId4; + struct Sprite *mainSprite; + + if (GetSpriteTileStartByTag(gUnknown_0831C620.tag) == 0xFFFF) + { + LoadCompressedObjectPicUsingHeap(&gUnknown_0831C620); + LoadCompressedObjectPaletteUsingHeap(&gUnknown_0831C628); + } + + mainSpriteId = CreateInvisibleSpriteWithCallback(sub_8075370); + mainSprite = &gSprites[mainSpriteId]; + mainSprite->data[1] = a3; + + spriteId1 = CreateSprite(&gUnknown_0831C688, x - 16, y - 16, 2); + gSprites[spriteId1].data[0] = mainSpriteId; + mainSprite->data[0]++; + AnimateSprite(&gSprites[spriteId1]); + + spriteId2 = CreateSprite(&gUnknown_0831C688, x, y - 16, 2); + gSprites[spriteId2].data[0] = mainSpriteId; + mainSprite->data[0]++; + StartSpriteAnim(&gSprites[spriteId2], 1); + AnimateSprite(&gSprites[spriteId2]); + + spriteId3 = CreateSprite(&gUnknown_0831C688, x - 16, y, 2); + gSprites[spriteId3].data[0] = mainSpriteId; + mainSprite->data[0]++; + StartSpriteAnim(&gSprites[spriteId3], 2); + AnimateSprite(&gSprites[spriteId3]); + + spriteId4 = CreateSprite(&gUnknown_0831C688, x, y, 2); + gSprites[spriteId4].data[0] = mainSpriteId; + mainSprite->data[0]++; + StartSpriteAnim(&gSprites[spriteId4], 3); + AnimateSprite(&gSprites[spriteId4]); + + return mainSpriteId; +} + +static void sub_8075370(struct Sprite *sprite) +{ + if (!sprite->data[0]) + { + FreeSpriteTilesByTag(gUnknown_0831C620.tag); + FreeSpritePaletteByTag(gUnknown_0831C628.tag); + if (!sprite->data[1]) + DestroySprite(sprite); + else + sprite->callback = SpriteCallbackDummy; + } +} + +void sub_80753B4(struct Sprite *sprite) +{ + if (sprite->animEnded) + { + gSprites[sprite->data[0]].data[0]--; + DestroySprite(sprite); + } +} @@ -1957,11 +1957,11 @@ void sub_80EDB44(void) show->rivalTrainer.badgeCount = nBadges; if (IsNationalPokedexEnabled()) { - show->rivalTrainer.dexCount = pokedex_count(0x01); + show->rivalTrainer.dexCount = GetNationalPokedexCount(0x01); } else { - show->rivalTrainer.dexCount = sub_80C0844(0x01); + show->rivalTrainer.dexCount = GetHoennPokedexCount(0x01); } show->rivalTrainer.location = gMapHeader.regionMapSectionId; show->rivalTrainer.mapDataId = gMapHeader.mapDataId; @@ -3633,7 +3633,7 @@ void ChangePokemonNickname(void) void ChangePokemonNickname_CB(void) { SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2); - c2_exit_to_overworld_1_continue_scripts_restart_music(); + CB2_ReturnToFieldContinueScript(); } void ChangeBoxPokemonNickname(void) @@ -3649,7 +3649,7 @@ void ChangeBoxPokemonNickname(void) void ChangeBoxPokemonNickname_CB(void) { SetBoxMonNickFromAnyBox(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar2); - c2_exit_to_overworld_1_continue_scripts_restart_music(); + CB2_ReturnToFieldContinueScript(); } void TV_CopyNicknameToStringVar1AndEnsureTerminated(void) diff --git a/src/walda_phrase.c b/src/walda_phrase.c index 59fd3fedb..04789bfb5 100644 --- a/src/walda_phrase.c +++ b/src/walda_phrase.c @@ -14,7 +14,7 @@ extern const u8 gText_Peekaboo[]; extern u8 *GetWaldaPhrasePtr(void); extern bool32 IsWaldaPhraseEmpty(void); extern void sub_80AF168(void); -extern void c2_exit_to_overworld_2_switch(void); +extern void CB2_ReturnToField(void); extern void SetWaldaPhrase(const u8 *src); extern void SetWaldaWallpaperPatternId(u8 patternId); extern void SetWaldaWallpaperIconId(u8 iconId); @@ -80,7 +80,7 @@ static void CB2_HandleGivenWaldaPhrase(void) StringCopy(gStringVar1, GetWaldaPhrasePtr()); gFieldCallback = sub_80AF168; - SetMainCallback2(c2_exit_to_overworld_2_switch); + SetMainCallback2(CB2_ReturnToField); } static u32 GetWaldaPhraseInputCase(u8 *inputPtr) |