summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorscnorton <scnorton@biociphers.org>2018-01-18 12:53:31 -0500
committerscnorton <scnorton@biociphers.org>2018-01-18 12:53:31 -0500
commitc6ff1a6ce39cb67c6de21f2e4938ea62c97ee7e5 (patch)
tree47e2f5eaa84c3cc97b96bdf06170136abe446d81 /src
parent3c2b1731eeb7037a1b681444b1c126fc239a904e (diff)
parent24e0edee9f428a68715c47051ebba3cda5a3e5a7 (diff)
Merge branch 'master' into link
Diffstat (limited to 'src')
-rw-r--r--src/battle_2.c72
-rw-r--r--src/battle_ai_script_commands.c451
-rw-r--r--src/battle_anim.c77
-rw-r--r--src/battle_bg.c754
-rw-r--r--src/battle_controller_link_opponent.c9
-rw-r--r--src/battle_controller_link_partner.c1
-rw-r--r--src/battle_controller_opponent.c9
-rw-r--r--src/battle_controller_player.c13
-rw-r--r--src/battle_controller_player_partner.c3
-rw-r--r--src/battle_controller_recorded_opponent.c9
-rw-r--r--src/battle_controller_recorded_player.c7
-rw-r--r--src/battle_controller_safari.c8
-rw-r--r--src/battle_controller_wally.c3
-rw-r--r--src/battle_gfx_sfx_util.c31
-rw-r--r--src/battle_interface.c1
-rw-r--r--src/battle_message.c17
-rw-r--r--src/battle_script_commands.c18
-rw-r--r--src/battle_setup.c1881
-rw-r--r--src/battle_transition.c4346
-rw-r--r--src/battle_util.c1
-rw-r--r--src/berry_blender.c26
-rw-r--r--src/berry_fix_program.c116
-rw-r--r--src/bg.c4
-rw-r--r--src/bike.c1078
-rw-r--r--src/daycare.c9
-rw-r--r--src/decoration.c26
-rw-r--r--src/dma3_manager.c553
-rw-r--r--src/egg_hatch.c22
-rw-r--r--src/evolution_scene.c128
-rw-r--r--src/field_door.c898
-rwxr-xr-xsrc/field_map_obj.c22
-rwxr-xr-xsrc/field_special_scene.c2
-rw-r--r--src/fldeff_teleport.c46
-rw-r--r--src/hall_of_fame.c42
-rw-r--r--src/landmark.c441
-rw-r--r--src/libc.c173
-rwxr-xr-xsrc/libisagbprn.c177
-rw-r--r--src/lilycove_lady.c34
-rw-r--r--src/link.c10
-rw-r--r--src/load_save.c168
-rw-r--r--src/m4a_2.c8
-rw-r--r--src/mail.c326
-rw-r--r--src/mail_data.c203
-rw-r--r--src/main.c3
-rw-r--r--src/new_game.c3
-rw-r--r--src/palette.c114
-rw-r--r--src/pokeball.c8
-rw-r--r--src/pokeblock.c1337
-rw-r--r--src/pokeblock_feed.c1108
-rw-r--r--src/pokedex.c542
-rw-r--r--src/pokemon_2.c2
-rw-r--r--src/pokemon_3.c99
-rw-r--r--src/pokemon_icon.c1014
-rw-r--r--src/pokemon_storage_system.c67
-rwxr-xr-xsrc/pokemon_summary_screen.c34
-rw-r--r--src/rayquaza_scene.c1164
-rw-r--r--src/recorded_battle.c2
-rw-r--r--src/region_map.c31
-rw-r--r--src/reset_save_heap.c4
-rw-r--r--src/reshow_battle_screen.c4
-rw-r--r--src/rom_8034C54.c (renamed from src/battle_1.c)12
-rw-r--r--src/safari_zone.c4
-rwxr-xr-xsrc/save_failed_screen.c8
-rw-r--r--src/scrcmd.c36
-rw-r--r--src/secret_base.c26
-rw-r--r--src/sound.c78
-rw-r--r--src/sprite.c10
-rw-r--r--src/start_menu.c102
-rw-r--r--src/text.c4
-rw-r--r--src/tileset_anims.c5
-rw-r--r--src/trainer_see.c781
-rw-r--r--src/tv.c7
-rw-r--r--src/unk_81BAD84.c36
-rw-r--r--src/unk_text_util_2.c14
-rw-r--r--src/use_pokeblock.c230
-rw-r--r--src/wallclock.c32
-rw-r--r--src/window.c736
77 files changed, 17428 insertions, 2452 deletions
diff --git a/src/battle_2.c b/src/battle_2.c
index 356a3bb8f..aa033c537 100644
--- a/src/battle_2.c
+++ b/src/battle_2.c
@@ -17,6 +17,7 @@
#include "item.h"
#include "constants/items.h"
#include "constants/hold_effects.h"
+#include "constants/trainers.h"
#include "link.h"
#include "link_rfu.h"
#include "bg.h"
@@ -39,7 +40,6 @@
#include "pokedex.h"
#include "constants/abilities.h"
#include "constants/moves.h"
-#include "trainer_classes.h"
#include "evolution_scene.h"
#include "roamer.h"
#include "tv.h"
@@ -93,8 +93,8 @@ extern struct UnknownPokemonStruct2 gUnknown_02022FF8[3]; // what is it used for
extern struct UnknownPokemonStruct2* gUnknown_02023058; // what is it used for?
extern u8 gUnknown_02039B28[]; // possibly a struct?
extern struct UnknownStruct6 gUnknown_02038C28; // todo: identify & document
-extern struct MusicPlayerInfo gMPlay_SE1;
-extern struct MusicPlayerInfo gMPlay_SE2;
+extern struct MusicPlayerInfo gMPlayInfo_SE1;
+extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern u8 gDecompressionBuffer[];
extern u16 gUnknown_020243FC;
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
@@ -153,7 +153,7 @@ extern u8 gUnknown_020241E9;
extern u16 gChosenMove;
extern const struct BattleMove gBattleMoves[];
-extern const u16 gUnknown_08C004E0[]; // battle textbox palette
+extern const u16 gBattleTextboxPalette[]; // battle textbox palette
extern const struct BgTemplate gUnknown_0831AA08[];
extern const struct WindowTemplate * const gUnknown_0831ABA0[];
extern const u8 gUnknown_0831ACE0[];
@@ -186,7 +186,7 @@ extern void sub_80356D0(void);
extern void GetFrontierTrainerName(u8* dst, u16 trainerId); // battle tower
extern void sub_8166188(void); // battle tower, sets link battle mons level but why?
extern void sub_8165B88(u8* dst, u16 trainerId); // battle tower, gets language
-extern void sub_81DB4DC(u8* dst, u8 arg2); //
+extern void PadNameString(u8* dst, u8 arg2); //
extern void sub_81B9150(void);
extern void sub_800AC34(void);
extern void sub_80B3AF8(u8 taskId); // cable club
@@ -416,7 +416,7 @@ static void CB2_InitBattleInternal(void)
gBattleTerrain = BattleSetup_GetTerrainId();
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
- gBattleTerrain = BATTLE_TERRAIN_INSIDE;
+ gBattleTerrain = BATTLE_TERRAIN_BUILDING;
sub_80356D0();
LoadBattleTextboxAndBackground();
@@ -755,7 +755,7 @@ static void CB2_HandleStartBattle(void)
ResetBlockReceivedFlags();
sub_8036EB8(2, playerMultiplayerId);
SetAllPlayersBerryData();
- taskId = CreateTask(task00_0800F6FC, 0);
+ taskId = CreateTask(sub_8035D74, 0);
gTasks[taskId].data[1] = 0x10E;
gTasks[taskId].data[2] = 0x5A;
gTasks[taskId].data[5] = 0;
@@ -957,7 +957,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
ResetBlockReceivedFlags();
sub_8036EB8(2, playerMultiplayerId);
SetAllPlayersBerryData();
- taskId = CreateTask(task00_0800F6FC, 0);
+ taskId = CreateTask(sub_8035D74, 0);
gTasks[taskId].data[1] = 0x10E;
gTasks[taskId].data[2] = 0x5A;
gTasks[taskId].data[5] = 0;
@@ -1141,7 +1141,7 @@ static void sub_80379F8(u8 arrayIdPlus)
gUnknown_02022FF8[i].gender = GetMonGender(&gPlayerParty[arrayIdPlus + i]);
StripExtCtrlCodes(gUnknown_02022FF8[i].nickname);
if (GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_LANGUAGE) != LANGUAGE_JAPANESE)
- sub_81DB4DC(gUnknown_02022FF8[i].nickname, 0);
+ PadNameString(gUnknown_02022FF8[i].nickname, CHAR_SPACE);
}
memcpy(gUnknown_02023058, gUnknown_02022FF8, sizeof(gUnknown_02022FF8));
}
@@ -1343,7 +1343,7 @@ static void CB2_HandleStartMultiBattle(void)
sub_8036EB8(4, playerMultiplayerId);
SetAllPlayersBerryData();
sub_8068AA4();
- var = CreateTask(task00_0800F6FC, 0);
+ var = CreateTask(sub_8035D74, 0);
gTasks[var].data[1] = 0x10E;
gTasks[var].data[2] = 0x5A;
gTasks[var].data[5] = 0;
@@ -1611,8 +1611,8 @@ void CB2_QuitRecordedBattle(void)
UpdatePaletteFade();
if (!gPaletteFade.active)
{
- m4aMPlayStop(&gMPlay_SE1);
- m4aMPlayStop(&gMPlay_SE2);
+ m4aMPlayStop(&gMPlayInfo_SE1);
+ m4aMPlayStop(&gMPlayInfo_SE2);
FreeRestoreBattleData();
FreeAllWindowBuffers();
SetMainCallback2(gMain.savedCallback);
@@ -1719,7 +1719,7 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
{
const struct TrainerMonNoItemDefaultMoves *partyData = gTrainers[trainerNum].party.NoItemDefaultMoves;
- for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++)
+ for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
nameHash += gSpeciesNames[partyData[i].species][j];
personalityValue += nameHash << 8;
@@ -1727,11 +1727,11 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
break;
}
- case PARTY_FLAG_CUSTOM_MOVES:
+ case F_TRAINER_PARTY_CUSTOM_MOVESET:
{
const struct TrainerMonNoItemCustomMoves *partyData = gTrainers[trainerNum].party.NoItemCustomMoves;
- for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++)
+ for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
nameHash += gSpeciesNames[partyData[i].species][j];
personalityValue += nameHash << 8;
@@ -1745,11 +1745,11 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
}
break;
}
- case PARTY_FLAG_HAS_ITEM:
+ case F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemDefaultMoves *partyData = gTrainers[trainerNum].party.ItemDefaultMoves;
- for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++)
+ for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
nameHash += gSpeciesNames[partyData[i].species][j];
personalityValue += nameHash << 8;
@@ -1759,11 +1759,11 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem);
break;
}
- case PARTY_FLAG_CUSTOM_MOVES | PARTY_FLAG_HAS_ITEM:
+ case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemCustomMoves *partyData = gTrainers[trainerNum].party.ItemCustomMoves;
- for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++)
+ for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
nameHash += gSpeciesNames[partyData[i].species][j];
personalityValue += nameHash << 8;
@@ -1979,7 +1979,7 @@ void sub_8038D64(void)
gBattle_BG3_Y = 0;
sub_80356D0();
- LoadCompressedPalette(gUnknown_08C004E0, 0, 64);
+ LoadCompressedPalette(gBattleTextboxPalette, 0, 64);
ApplyPlayerChosenFrameToBattleMenu();
ResetSpriteData();
ResetTasks();
@@ -1989,7 +1989,7 @@ void sub_8038D64(void)
gReservedSpritePaletteCount = 4;
SetVBlankCallback(VBlankCB_Battle);
- taskId = CreateTask(task00_0800F6FC, 0);
+ taskId = CreateTask(sub_8035D74, 0);
gTasks[taskId].data[1] = 0x10E;
gTasks[taskId].data[2] = 0x5A;
gTasks[taskId].data[5] = 1;
@@ -4739,9 +4739,9 @@ static void HandleEndTurn_BattleWon(void)
gBattlescriptCurrInstr = BattleScript_FrontierTrainerBattleWon;
if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_3FE)
- PlayBGM(BGM_KACHI3);
+ PlayBGM(MUS_KACHI3);
else
- PlayBGM(BGM_KACHI1);
+ PlayBGM(MUS_KACHI1);
}
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & BATTLE_TYPE_LINK))
{
@@ -4750,23 +4750,23 @@ static void HandleEndTurn_BattleWon(void)
switch (gTrainers[gTrainerBattleOpponent_A].trainerClass)
{
- case CLASS_ELITE_FOUR:
- case CLASS_CHAMPION:
- PlayBGM(BGM_KACHI5);
+ case TRAINER_CLASS_ELITE_FOUR:
+ case TRAINER_CLASS_CHAMPION:
+ PlayBGM(MUS_KACHI5);
break;
- case CLASS_TEAM_AQUA:
- case CLASS_TEAM_MAGMA:
- case CLASS_AQUA_ADMIN:
- case CLASS_AQUA_LEADER:
- case CLASS_MAGMA_ADMIN:
- case CLASS_MAGMA_LEADER:
- PlayBGM(BGM_KACHI4);
+ case TRAINER_CLASS_TEAM_AQUA:
+ case TRAINER_CLASS_TEAM_MAGMA:
+ case TRAINER_CLASS_AQUA_ADMIN:
+ case TRAINER_CLASS_AQUA_LEADER:
+ case TRAINER_CLASS_MAGMA_ADMIN:
+ case TRAINER_CLASS_MAGMA_LEADER:
+ PlayBGM(MUS_KACHI4);
break;
- case CLASS_LEADER:
- PlayBGM(BGM_KACHI3);
+ case TRAINER_CLASS_LEADER:
+ PlayBGM(MUS_KACHI3);
break;
default:
- PlayBGM(BGM_KACHI1);
+ PlayBGM(MUS_KACHI1);
break;
}
}
diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c
index 44be0a4d9..42cf0595f 100644
--- a/src/battle_ai_script_commands.c
+++ b/src/battle_ai_script_commands.c
@@ -9,6 +9,7 @@
#include "constants/battle_move_effects.h"
#include "constants/moves.h"
#include "util.h"
+#include "constants/battle_ai.h"
#define AIScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24)
#define AIScriptRead16(ptr) ((ptr)[0] | (ptr)[1] << 8)
@@ -26,14 +27,6 @@
#define AI_THINKING_STRUCT ((struct AI_ThinkingStruct *)(gBattleResources->ai))
#define BATTLE_HISTORY ((struct BattleHistory *)(gBattleResources->battleHistory))
-enum
-{
- AI_TARGET,
- AI_USER,
- AI_TARGET_PARTNER,
- AI_USER_PARTNER
-};
-
// AI states
enum
{
@@ -104,30 +97,30 @@ static void BattleAICmd_if_less_than(void);
static void BattleAICmd_if_more_than(void);
static void BattleAICmd_if_equal(void);
static void BattleAICmd_if_not_equal(void);
-static void BattleAICmd_if_less_than_32(void);
-static void BattleAICmd_if_more_than_32(void);
-static void BattleAICmd_if_equal_32(void);
-static void BattleAICmd_if_not_equal_32(void);
+static void BattleAICmd_if_less_than_ptr(void);
+static void BattleAICmd_if_more_than_ptr(void);
+static void BattleAICmd_if_equal_ptr(void);
+static void BattleAICmd_if_not_equal_ptr(void);
static void BattleAICmd_if_move(void);
static void BattleAICmd_if_not_move(void);
static void BattleAICmd_if_in_bytes(void);
static void BattleAICmd_if_not_in_bytes(void);
static void BattleAICmd_if_in_hwords(void);
static void BattleAICmd_if_not_in_hwords(void);
-static void BattleAICmd_if_user_can_damage(void);
-static void BattleAICmd_if_user_cant_damage(void);
+static void BattleAICmd_if_user_has_attacking_move(void);
+static void BattleAICmd_if_user_has_no_attacking_moves(void);
static void BattleAICmd_get_turn_count(void);
static void BattleAICmd_get_type(void);
-static void BattleAICmd_get_last_used_bank_move_power(void);
-static void BattleAICmd_is_most_powerful_move(void);
+static void BattleAICmd_get_considered_move_power(void);
+static void BattleAICmd_get_how_powerful_move_is(void);
static void BattleAICmd_get_last_used_bank_move(void);
-static void BattleAICmd_if_arg_equal(void);
-static void BattleAICmd_if_arg_not_equal(void);
-static void BattleAICmd_if_would_go_first(void);
-static void BattleAICmd_if_would_not_go_first(void);
+static void BattleAICmd_if_equal_(void);
+static void BattleAICmd_if_not_equal_(void);
+static void BattleAICmd_if_user_goes(void);
+static void BattleAICmd_if_user_doesnt_go(void);
static void BattleAICmd_nullsub_2A(void);
static void BattleAICmd_nullsub_2B(void);
-static void BattleAICmd_count_alive_pokemon(void);
+static void BattleAICmd_count_usable_party_mons(void);
static void BattleAICmd_get_considered_move(void);
static void BattleAICmd_get_considered_move_effect(void);
static void BattleAICmd_get_ability(void);
@@ -147,17 +140,17 @@ static void BattleAICmd_if_stat_level_not_equal(void);
static void BattleAICmd_if_can_faint(void);
static void BattleAICmd_if_cant_faint(void);
static void BattleAICmd_if_has_move(void);
-static void BattleAICmd_if_dont_have_move(void);
-static void BattleAICmd_if_move_effect(void);
-static void BattleAICmd_if_not_move_effect(void);
+static void BattleAICmd_if_doesnt_have_move(void);
+static void BattleAICmd_if_has_move_with_effect(void);
+static void BattleAICmd_if_doesnt_have_move_with_effect(void);
static void BattleAICmd_if_any_move_disabled_or_encored(void);
static void BattleAICmd_if_curr_move_disabled_or_encored(void);
static void BattleAICmd_flee(void);
-static void BattleAICmd_if_random_100(void);
+static void BattleAICmd_if_random_safari_flee(void);
static void BattleAICmd_watch(void);
static void BattleAICmd_get_hold_effect(void);
static void BattleAICmd_get_gender(void);
-static void BattleAICmd_is_first_turn(void);
+static void BattleAICmd_is_first_turn_for(void);
static void BattleAICmd_get_stockpile_count(void);
static void BattleAICmd_is_double_battle(void);
static void BattleAICmd_get_used_held_item(void);
@@ -172,7 +165,7 @@ static void BattleAICmd_nullsub_55(void);
static void BattleAICmd_nullsub_56(void);
static void BattleAICmd_nullsub_57(void);
static void BattleAICmd_call(void);
-static void BattleAICmd_jump(void);
+static void BattleAICmd_goto(void);
static void BattleAICmd_end(void);
static void BattleAICmd_if_level_cond(void);
static void BattleAICmd_if_target_taunted(void);
@@ -215,30 +208,30 @@ static const BattleAICmdFunc sBattleAICmdTable[] =
BattleAICmd_if_more_than, // 0x12
BattleAICmd_if_equal, // 0x13
BattleAICmd_if_not_equal, // 0x14
- BattleAICmd_if_less_than_32, // 0x15
- BattleAICmd_if_more_than_32, // 0x16
- BattleAICmd_if_equal_32, // 0x17
- BattleAICmd_if_not_equal_32, // 0x18
+ BattleAICmd_if_less_than_ptr, // 0x15
+ BattleAICmd_if_more_than_ptr, // 0x16
+ BattleAICmd_if_equal_ptr, // 0x17
+ BattleAICmd_if_not_equal_ptr, // 0x18
BattleAICmd_if_move, // 0x19
BattleAICmd_if_not_move, // 0x1A
BattleAICmd_if_in_bytes, // 0x1B
BattleAICmd_if_not_in_bytes, // 0x1C
BattleAICmd_if_in_hwords, // 0x1D
BattleAICmd_if_not_in_hwords, // 0x1E
- BattleAICmd_if_user_can_damage, // 0x1F
- BattleAICmd_if_user_cant_damage, // 0x20
+ BattleAICmd_if_user_has_attacking_move, // 0x1F
+ BattleAICmd_if_user_has_no_attacking_moves, // 0x20
BattleAICmd_get_turn_count, // 0x21
BattleAICmd_get_type, // 0x22
- BattleAICmd_get_last_used_bank_move_power, // 0x23
- BattleAICmd_is_most_powerful_move, // 0x24
+ BattleAICmd_get_considered_move_power, // 0x23
+ BattleAICmd_get_how_powerful_move_is, // 0x24
BattleAICmd_get_last_used_bank_move, // 0x25
- BattleAICmd_if_arg_equal, // 0x26
- BattleAICmd_if_arg_not_equal, // 0x27
- BattleAICmd_if_would_go_first, // 0x28
- BattleAICmd_if_would_not_go_first, // 0x29
+ BattleAICmd_if_equal_, // 0x26
+ BattleAICmd_if_not_equal_, // 0x27
+ BattleAICmd_if_user_goes, // 0x28
+ BattleAICmd_if_user_doesnt_go, // 0x29
BattleAICmd_nullsub_2A, // 0x2A
BattleAICmd_nullsub_2B, // 0x2B
- BattleAICmd_count_alive_pokemon, // 0x2C
+ BattleAICmd_count_usable_party_mons, // 0x2C
BattleAICmd_get_considered_move, // 0x2D
BattleAICmd_get_considered_move_effect, // 0x2E
BattleAICmd_get_ability, // 0x2F
@@ -258,17 +251,17 @@ static const BattleAICmdFunc sBattleAICmdTable[] =
BattleAICmd_if_can_faint, // 0x3D
BattleAICmd_if_cant_faint, // 0x3E
BattleAICmd_if_has_move, // 0x3F
- BattleAICmd_if_dont_have_move, // 0x40
- BattleAICmd_if_move_effect, // 0x41
- BattleAICmd_if_not_move_effect, // 0x42
+ BattleAICmd_if_doesnt_have_move, // 0x40
+ BattleAICmd_if_has_move_with_effect, // 0x41
+ BattleAICmd_if_doesnt_have_move_with_effect, // 0x42
BattleAICmd_if_any_move_disabled_or_encored, // 0x43
BattleAICmd_if_curr_move_disabled_or_encored, // 0x44
BattleAICmd_flee, // 0x45
- BattleAICmd_if_random_100, // 0x46
+ BattleAICmd_if_random_safari_flee, // 0x46
BattleAICmd_watch, // 0x47
BattleAICmd_get_hold_effect, // 0x48
BattleAICmd_get_gender, // 0x49
- BattleAICmd_is_first_turn, // 0x4A
+ BattleAICmd_is_first_turn_for, // 0x4A
BattleAICmd_get_stockpile_count, // 0x4B
BattleAICmd_is_double_battle, // 0x4C
BattleAICmd_get_used_held_item, // 0x4D
@@ -283,7 +276,7 @@ static const BattleAICmdFunc sBattleAICmdTable[] =
BattleAICmd_nullsub_56, // 0x56
BattleAICmd_nullsub_57, // 0x57
BattleAICmd_call, // 0x58
- BattleAICmd_jump, // 0x59
+ BattleAICmd_goto, // 0x59
BattleAICmd_end, // 0x5A
BattleAICmd_if_level_cond, // 0x5B
BattleAICmd_if_target_taunted, // 0x5C
@@ -374,32 +367,34 @@ void BattleAI_SetupAIData(u8 defaultScoreMoves)
// decide a random target bank in doubles
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
- gBankTarget = (Random() & 2) + (GetBankSide(gActiveBank) ^ 1);
+ gBankTarget = (Random() & BIT_MON) + (GetBankSide(gActiveBank) ^ BIT_SIDE);
if (gAbsentBankFlags & gBitTable[gBankTarget])
- gBankTarget ^= 2;
+ gBankTarget ^= BIT_MON;
}
// in singles there's only one choice
else
- gBankTarget = sBank_AI ^ 1;
+ {
+ gBankTarget = sBank_AI ^ BIT_SIDE;
+ }
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
AI_THINKING_STRUCT->aiFlags = GetAiScriptsInRecordedBattle();
else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
- AI_THINKING_STRUCT->aiFlags = 0x40000000;
+ AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_SAFARI;
else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER)
- AI_THINKING_STRUCT->aiFlags = 0x20000000;
+ AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_ROAMING;
else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE)
- AI_THINKING_STRUCT->aiFlags = 0x80000000;
+ AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_FIRST_BATTLE;
else if (gBattleTypeFlags & BATTLE_TYPE_FACTORY)
AI_THINKING_STRUCT->aiFlags = GetAiScriptsInBattleFactory();
else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_x4000000 | BATTLE_TYPE_SECRET_BASE))
- AI_THINKING_STRUCT->aiFlags = 7; // the smartest possible set
+ AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_TRY_TO_FAINT;
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags;
else
AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
- AI_THINKING_STRUCT->aiFlags |= 0x80; // act smart in doubles and don't attack your partner
+ AI_THINKING_STRUCT->aiFlags |= AI_SCRIPT_DOUBLE_BATTLE; // act smart in doubles and don't attack your partner
}
u8 BattleAI_ChooseMoveOrAction(void)
@@ -723,14 +718,14 @@ static void BattleAICmd_score(void)
static void BattleAICmd_if_hp_less_than(void)
{
- u16 index;
+ u16 bank;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) < gAIScriptPtr[2])
+ if ((u32)(100 * gBattleMons[bank].hp / gBattleMons[bank].maxHP) < gAIScriptPtr[2])
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
@@ -738,14 +733,14 @@ static void BattleAICmd_if_hp_less_than(void)
static void BattleAICmd_if_hp_more_than(void)
{
- u16 index;
+ u16 bank;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) > gAIScriptPtr[2])
+ if ((u32)(100 * gBattleMons[bank].hp / gBattleMons[bank].maxHP) > gAIScriptPtr[2])
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
@@ -753,14 +748,14 @@ static void BattleAICmd_if_hp_more_than(void)
static void BattleAICmd_if_hp_equal(void)
{
- u16 index;
+ u16 bank;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) == gAIScriptPtr[2])
+ if ((u32)(100 * gBattleMons[bank].hp / gBattleMons[bank].maxHP) == gAIScriptPtr[2])
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
@@ -768,14 +763,14 @@ static void BattleAICmd_if_hp_equal(void)
static void BattleAICmd_if_hp_not_equal(void)
{
- u16 index;
+ u16 bank;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) != gAIScriptPtr[2])
+ if ((u32)(100 * gBattleMons[bank].hp / gBattleMons[bank].maxHP) != gAIScriptPtr[2])
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
@@ -783,17 +778,17 @@ static void BattleAICmd_if_hp_not_equal(void)
static void BattleAICmd_if_status(void)
{
- u16 index;
- u32 arg;
+ u16 bank;
+ u32 status;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- arg = AIScriptRead32(gAIScriptPtr + 2);
+ status = AIScriptRead32(gAIScriptPtr + 2);
- if ((gBattleMons[index].status1 & arg) != 0)
+ if ((gBattleMons[bank].status1 & status) != 0)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
@@ -801,17 +796,17 @@ static void BattleAICmd_if_status(void)
static void BattleAICmd_if_not_status(void)
{
- u16 index;
- u32 arg;
+ u16 bank;
+ u32 status;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- arg = AIScriptRead32(gAIScriptPtr + 2);
+ status = AIScriptRead32(gAIScriptPtr + 2);
- if ((gBattleMons[index].status1 & arg) == 0)
+ if ((gBattleMons[bank].status1 & status) == 0)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
@@ -819,17 +814,17 @@ static void BattleAICmd_if_not_status(void)
static void BattleAICmd_if_status2(void)
{
- u16 index;
- u32 arg;
+ u16 bank;
+ u32 status;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- arg = AIScriptRead32(gAIScriptPtr + 2);
+ status = AIScriptRead32(gAIScriptPtr + 2);
- if ((gBattleMons[index].status2 & arg) != 0)
+ if ((gBattleMons[bank].status2 & status) != 0)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
@@ -837,17 +832,17 @@ static void BattleAICmd_if_status2(void)
static void BattleAICmd_if_not_status2(void)
{
- u16 index;
- u32 arg;
+ u16 bank;
+ u32 status;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- arg = AIScriptRead32(gAIScriptPtr + 2);
+ status = AIScriptRead32(gAIScriptPtr + 2);
- if ((gBattleMons[index].status2 & arg) == 0)
+ if ((gBattleMons[bank].status2 & status) == 0)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
@@ -855,17 +850,17 @@ static void BattleAICmd_if_not_status2(void)
static void BattleAICmd_if_status3(void)
{
- u16 index;
- u32 arg;
+ u16 bank;
+ u32 status;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- arg = AIScriptRead32(gAIScriptPtr + 2);
+ status = AIScriptRead32(gAIScriptPtr + 2);
- if ((gStatuses3[index] & arg) != 0)
+ if ((gStatuses3[bank] & status) != 0)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
@@ -873,17 +868,17 @@ static void BattleAICmd_if_status3(void)
static void BattleAICmd_if_not_status3(void)
{
- u16 index;
- u32 arg;
+ u16 bank;
+ u32 status;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- arg = AIScriptRead32(gAIScriptPtr + 2);
+ status = AIScriptRead32(gAIScriptPtr + 2);
- if ((gStatuses3[index] & arg) == 0)
+ if ((gStatuses3[bank] & status) == 0)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
@@ -891,18 +886,18 @@ static void BattleAICmd_if_not_status3(void)
static void BattleAICmd_if_side_affecting(void)
{
- u16 index;
- u32 arg1, arg2;
+ u16 bank;
+ u32 side, status;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- arg1 = GetBankIdentity(index) & 1;
- arg2 = AIScriptRead32(gAIScriptPtr + 2);
+ side = GET_BANK_SIDE(bank);
+ status = AIScriptRead32(gAIScriptPtr + 2);
- if ((gSideAffecting[arg1] & arg2) != 0)
+ if ((gSideAffecting[side] & status) != 0)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
@@ -910,18 +905,18 @@ static void BattleAICmd_if_side_affecting(void)
static void BattleAICmd_if_not_side_affecting(void)
{
- u16 index;
- u32 arg1, arg2;
+ u16 bank;
+ u32 side, status;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- arg1 = GetBankIdentity(index) & 1;
- arg2 = AIScriptRead32(gAIScriptPtr + 2);
+ side = GET_BANK_SIDE(bank);
+ status = AIScriptRead32(gAIScriptPtr + 2);
- if ((gSideAffecting[arg1] & arg2) == 0)
+ if ((gSideAffecting[side] & status) == 0)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
@@ -959,41 +954,41 @@ static void BattleAICmd_if_not_equal(void)
gAIScriptPtr += 6;
}
-static void BattleAICmd_if_less_than_32(void)
+static void BattleAICmd_if_less_than_ptr(void)
{
- const u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *value = AIScriptReadPtr(gAIScriptPtr + 1);
- if (AI_THINKING_STRUCT->funcResult < *temp)
+ if (AI_THINKING_STRUCT->funcResult < *value)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
else
gAIScriptPtr += 9;
}
-static void BattleAICmd_if_more_than_32(void)
+static void BattleAICmd_if_more_than_ptr(void)
{
- const u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *value = AIScriptReadPtr(gAIScriptPtr + 1);
- if (AI_THINKING_STRUCT->funcResult > *temp)
+ if (AI_THINKING_STRUCT->funcResult > *value)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
else
gAIScriptPtr += 9;
}
-static void BattleAICmd_if_equal_32(void)
+static void BattleAICmd_if_equal_ptr(void)
{
- const u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *value = AIScriptReadPtr(gAIScriptPtr + 1);
- if (AI_THINKING_STRUCT->funcResult == *temp)
+ if (AI_THINKING_STRUCT->funcResult == *value)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
else
gAIScriptPtr += 9;
}
-static void BattleAICmd_if_not_equal_32(void)
+static void BattleAICmd_if_not_equal_ptr(void)
{
- const u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *value = AIScriptReadPtr(gAIScriptPtr + 1);
- if (AI_THINKING_STRUCT->funcResult != *temp)
+ if (AI_THINKING_STRUCT->funcResult != *value)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
else
gAIScriptPtr += 9;
@@ -1083,7 +1078,7 @@ static void BattleAICmd_if_not_in_hwords(void)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
}
-static void BattleAICmd_if_user_can_damage(void)
+static void BattleAICmd_if_user_has_attacking_move(void)
{
s32 i;
@@ -1099,7 +1094,7 @@ static void BattleAICmd_if_user_can_damage(void)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
}
-static void BattleAICmd_if_user_cant_damage(void)
+static void BattleAICmd_if_user_has_no_attacking_moves(void)
{
s32 i;
@@ -1127,28 +1122,28 @@ static void BattleAICmd_get_type(void)
switch (typeVar)
{
- case 1: // player primary type
+ case AI_TYPE1_USER: // AI user primary type
AI_THINKING_STRUCT->funcResult = gBattleMons[sBank_AI].type1;
break;
- case 0: // enemy primary type
+ case AI_TYPE1_TARGET: // target primary type
AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type1;
break;
- case 3: // player secondary type
+ case AI_TYPE2_USER: // AI user secondary type
AI_THINKING_STRUCT->funcResult = gBattleMons[sBank_AI].type2;
break;
- case 2: // enemy secondary type
+ case AI_TYPE2_TARGET: // target secondary type
AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type2;
break;
- case 4: // type of move being pointed to
+ case AI_TYPE_MOVE: // type of move being pointed to
AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].type;
break;
}
gAIScriptPtr += 2;
}
-static u8 BattleAI_GetWantedBank(u8 index)
+static u8 BattleAI_GetWantedBank(u8 bank)
{
- switch (index)
+ switch (bank)
{
case AI_USER:
return sBank_AI;
@@ -1168,23 +1163,23 @@ static void BattleAICmd_is_of_type(void)
if(gBattleMons[bank].type1 == gAIScriptPtr[2] || gBattleMons[bank].type2 == gAIScriptPtr[2])
{
- AI_THINKING_STRUCT->funcResult = 1;
+ AI_THINKING_STRUCT->funcResult = TRUE;
}
else
{
- AI_THINKING_STRUCT->funcResult = 0;
+ AI_THINKING_STRUCT->funcResult = FALSE;
}
gAIScriptPtr += 3;
}
-static void BattleAICmd_get_last_used_bank_move_power(void)
+static void BattleAICmd_get_considered_move_power(void)
{
AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power;
gAIScriptPtr += 1;
}
-static void BattleAICmd_is_most_powerful_move(void)
+static void BattleAICmd_get_how_powerful_move_is(void)
{
s32 i, checkedMove;
s32 moveDmgs[4];
@@ -1236,13 +1231,13 @@ static void BattleAICmd_is_most_powerful_move(void)
}
if (checkedMove == 4)
- AI_THINKING_STRUCT->funcResult = 2; // is the most powerful
+ AI_THINKING_STRUCT->funcResult = MOVE_MOST_POWERFUL; // is the most powerful
else
- AI_THINKING_STRUCT->funcResult = 1; // not most powerful
+ AI_THINKING_STRUCT->funcResult = MOVE_NOT_MOST_POWERFUL; // not most powerful
}
else
{
- AI_THINKING_STRUCT->funcResult = 0; // highly discouraged in terms of power
+ AI_THINKING_STRUCT->funcResult = MOVE_POWER_DISCOURAGED; // highly discouraged in terms of power
}
gAIScriptPtr++;
@@ -1258,7 +1253,7 @@ static void BattleAICmd_get_last_used_bank_move(void)
gAIScriptPtr += 2;
}
-static void BattleAICmd_if_arg_equal(void)
+static void BattleAICmd_if_equal_(void) // same as if_equal
{
if (gAIScriptPtr[1] == AI_THINKING_STRUCT->funcResult)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
@@ -1266,7 +1261,7 @@ static void BattleAICmd_if_arg_equal(void)
gAIScriptPtr += 6;
}
-static void BattleAICmd_if_arg_not_equal(void)
+static void BattleAICmd_if_not_equal_(void) // same as if_not_equal
{
if (gAIScriptPtr[1] != AI_THINKING_STRUCT->funcResult)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
@@ -1274,7 +1269,7 @@ static void BattleAICmd_if_arg_not_equal(void)
gAIScriptPtr += 6;
}
-static void BattleAICmd_if_would_go_first(void)
+static void BattleAICmd_if_user_goes(void)
{
if (GetWhoStrikesFirst(sBank_AI, gBankTarget, TRUE) == gAIScriptPtr[1])
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
@@ -1282,7 +1277,7 @@ static void BattleAICmd_if_would_go_first(void)
gAIScriptPtr += 6;
}
-static void BattleAICmd_if_would_not_go_first(void)
+static void BattleAICmd_if_user_doesnt_go(void)
{
if (GetWhoStrikesFirst(sBank_AI, gBankTarget, TRUE) != gAIScriptPtr[1])
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
@@ -1298,9 +1293,9 @@ static void BattleAICmd_nullsub_2B(void)
{
}
-static void BattleAICmd_count_alive_pokemon(void)
+static void BattleAICmd_count_usable_party_mons(void)
{
- u8 index;
+ u8 bank;
u8 bankOnField1, bankOnField2;
struct Pokemon *party;
int i;
@@ -1308,29 +1303,29 @@ static void BattleAICmd_count_alive_pokemon(void)
AI_THINKING_STRUCT->funcResult = 0;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- if (GetBankSide(index) == SIDE_PLAYER)
+ if (GetBankSide(bank) == SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
- u32 status;
- bankOnField1 = gBattlePartyID[index];
- status = GetBankIdentity(index) ^ 2;
- bankOnField2 = gBattlePartyID[GetBankByIdentity(status)];
+ u32 identity;
+ bankOnField1 = gBattlePartyID[bank];
+ identity = GetBankIdentity(bank) ^ BIT_MON;
+ bankOnField2 = gBattlePartyID[GetBankByIdentity(identity)];
}
else // in singles there's only one bank by side
{
- bankOnField1 = gBattlePartyID[index];
- bankOnField2 = gBattlePartyID[index];
+ bankOnField1 = gBattlePartyID[bank];
+ bankOnField2 = gBattlePartyID[bank];
}
- for (i = 0; i < 6; i++)
+ for (i = 0; i < PARTY_SIZE; i++)
{
if (i != bankOnField1 && i != bankOnField2
&& GetMonData(&party[i], MON_DATA_HP) != 0
@@ -1358,60 +1353,60 @@ static void BattleAICmd_get_considered_move_effect(void)
static void BattleAICmd_get_ability(void)
{
- u8 index;
+ u8 bank;
if (gAIScriptPtr[1] == AI_USER)
- index = sBank_AI;
+ bank = sBank_AI;
else
- index = gBankTarget;
+ bank = gBankTarget;
- if(gActiveBank != index)
+ if (gActiveBank != bank)
{
- if(BATTLE_HISTORY->abilities[index] != 0)
+ if (BATTLE_HISTORY->abilities[bank] != 0)
{
- AI_THINKING_STRUCT->funcResult = BATTLE_HISTORY->abilities[index];
+ AI_THINKING_STRUCT->funcResult = BATTLE_HISTORY->abilities[bank];
gAIScriptPtr += 2;
return;
}
// abilities that prevent fleeing.
- if (gBattleMons[index].ability == ABILITY_SHADOW_TAG
- || gBattleMons[index].ability == ABILITY_MAGNET_PULL
- || gBattleMons[index].ability == ABILITY_ARENA_TRAP)
+ if (gBattleMons[bank].ability == ABILITY_SHADOW_TAG
+ || gBattleMons[bank].ability == ABILITY_MAGNET_PULL
+ || gBattleMons[bank].ability == ABILITY_ARENA_TRAP)
{
- AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability;
+ AI_THINKING_STRUCT->funcResult = gBattleMons[bank].ability;
gAIScriptPtr += 2;
return;
}
- if (gBaseStats[gBattleMons[index].species].ability1 != ABILITY_NONE)
+ if (gBaseStats[gBattleMons[bank].species].ability1 != ABILITY_NONE)
{
- if (gBaseStats[gBattleMons[index].species].ability2 != ABILITY_NONE)
+ if (gBaseStats[gBattleMons[bank].species].ability2 != ABILITY_NONE)
{
// AI has no knowledge of opponent, so it guesses which ability.
if (Random() & 1)
{
- AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1;
+ AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[bank].species].ability1;
}
else
{
- AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2;
+ AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[bank].species].ability2;
}
}
else
{
- AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1; // it's definitely ability 1.
+ AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[bank].species].ability1; // it's definitely ability 1.
}
}
else
{
- AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability.
+ AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[bank].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability.
}
}
else
{
// The AI knows its own ability.
- AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability;
+ AI_THINKING_STRUCT->funcResult = gBattleMons[bank].ability;
}
gAIScriptPtr += 2;
}
@@ -1493,7 +1488,7 @@ static void BattleAICmd_get_highest_type_effectiveness(void)
for (i = 0; i < 4; i++)
{
- gBattleMoveDamage = 40;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x1;
gCurrentMove = gBattleMons[sBank_AI].moves[i];
if (gCurrentMove)
@@ -1502,16 +1497,16 @@ static void BattleAICmd_get_highest_type_effectiveness(void)
// reduce by 1/3.
if (gBattleMoveDamage == 120)
- gBattleMoveDamage = 80;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x2;
if (gBattleMoveDamage == 240)
- gBattleMoveDamage = 160;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x4;
if (gBattleMoveDamage == 30)
- gBattleMoveDamage = 20;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x0_5;
if (gBattleMoveDamage == 15)
- gBattleMoveDamage = 10;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x0_25;
if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED)
- gBattleMoveDamage = 0;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x0;
if (AI_THINKING_STRUCT->funcResult < gBattleMoveDamage)
AI_THINKING_STRUCT->funcResult = gBattleMoveDamage;
@@ -1530,22 +1525,22 @@ static void BattleAICmd_if_type_effectiveness(void)
gBattleMoveFlags = 0;
gCritMultiplier = 1;
- gBattleMoveDamage = 40;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x1;
gCurrentMove = AI_THINKING_STRUCT->moveConsidered;
TypeCalc(gCurrentMove, sBank_AI, gBankTarget);
if (gBattleMoveDamage == 120)
- gBattleMoveDamage = 80;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x2;
if (gBattleMoveDamage == 240)
- gBattleMoveDamage = 160;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x4;
if (gBattleMoveDamage == 30)
- gBattleMoveDamage = 20;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x0_5;
if (gBattleMoveDamage == 15)
- gBattleMoveDamage = 10;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x0_25;
if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED)
- gBattleMoveDamage = 0;
+ gBattleMoveDamage = AI_EFFECTIVENESS_x0;
// store gBattleMoveDamage in a u8 variable because gAIScriptPtr[1] is a u8.
damageVar = gBattleMoveDamage;
@@ -1569,23 +1564,23 @@ static void BattleAICmd_if_status_in_party(void)
struct Pokemon *party;
int i;
u32 statusToCompareTo;
- u8 index;
+ u8 bank;
switch(gAIScriptPtr[1])
{
case AI_USER:
- index = sBank_AI;
+ bank = sBank_AI;
break;
default:
- index = gBankTarget;
+ bank = gBankTarget;
break;
}
- party = (GetBankSide(index) == 0) ? gPlayerParty : gEnemyParty;
+ party = (GetBankSide(bank) == SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
statusToCompareTo = AIScriptRead32(gAIScriptPtr + 2);
- for (i = 0; i < 6; i++)
+ for (i = 0; i < PARTY_SIZE; i++)
{
u16 species = GetMonData(&party[i], MON_DATA_SPECIES);
u16 hp = GetMonData(&party[i], MON_DATA_HP);
@@ -1606,23 +1601,23 @@ static void BattleAICmd_if_status_not_in_party(void)
struct Pokemon *party;
int i;
u32 statusToCompareTo;
- u8 index;
+ u8 bank;
switch(gAIScriptPtr[1])
{
case 1:
- index = sBank_AI;
+ bank = sBank_AI;
break;
default:
- index = gBankTarget;
+ bank = gBankTarget;
break;
}
- party = (GetBankSide(index) == 0) ? gPlayerParty : gEnemyParty;
+ party = (GetBankSide(bank) == SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
statusToCompareTo = AIScriptRead32(gAIScriptPtr + 2);
- for (i = 0; i < 6; i++)
+ for (i = 0; i < PARTY_SIZE; i++)
{
u16 species = GetMonData(&party[i], MON_DATA_SPECIES);
u16 hp = GetMonData(&party[i], MON_DATA_HP);
@@ -1640,13 +1635,13 @@ static void BattleAICmd_if_status_not_in_party(void)
static void BattleAICmd_get_weather(void)
{
if (gBattleWeather & WEATHER_RAIN_ANY)
- AI_THINKING_STRUCT->funcResult = 1;
+ AI_THINKING_STRUCT->funcResult = AI_WEATHER_RAIN;
if (gBattleWeather & WEATHER_SANDSTORM_ANY)
- AI_THINKING_STRUCT->funcResult = 2;
+ AI_THINKING_STRUCT->funcResult = AI_WEATHER_SANDSTORM;
if (gBattleWeather & WEATHER_SUN_ANY)
- AI_THINKING_STRUCT->funcResult = 0;
+ AI_THINKING_STRUCT->funcResult = AI_WEATHER_SUN;
if (gBattleWeather & WEATHER_HAIL_ANY)
- AI_THINKING_STRUCT->funcResult = 3;
+ AI_THINKING_STRUCT->funcResult = AI_WEATHER_HAIL;
gAIScriptPtr += 1;
}
@@ -1786,14 +1781,14 @@ static void BattleAICmd_if_cant_faint(void)
static void BattleAICmd_if_has_move(void)
{
int i;
- const u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2);
+ const u16 *movePtr = (u16 *)(gAIScriptPtr + 2);
- switch(gAIScriptPtr[1])
+ switch (gAIScriptPtr[1])
{
case AI_USER:
for (i = 0; i < 4; i++)
{
- if (gBattleMons[sBank_AI].moves[i] == *temp_ptr)
+ if (gBattleMons[sBank_AI].moves[i] == *movePtr)
break;
}
if (i == 4)
@@ -1807,7 +1802,7 @@ static void BattleAICmd_if_has_move(void)
return;
}
case AI_USER_PARTNER:
- if (gBattleMons[sBank_AI ^ 2].hp == 0)
+ if (gBattleMons[sBank_AI ^ BIT_MON].hp == 0)
{
gAIScriptPtr += 8;
return;
@@ -1816,7 +1811,7 @@ static void BattleAICmd_if_has_move(void)
{
for (i = 0; i < 4; i++)
{
- if (gBattleMons[sBank_AI ^ 2].moves[i] == *temp_ptr)
+ if (gBattleMons[sBank_AI ^ BIT_MON].moves[i] == *movePtr)
break;
}
}
@@ -1834,7 +1829,7 @@ static void BattleAICmd_if_has_move(void)
case AI_TARGET_PARTNER:
for (i = 0; i < 4; i++)
{
- if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] == *temp_ptr)
+ if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] == *movePtr)
break;
}
if (i == 4)
@@ -1850,10 +1845,10 @@ static void BattleAICmd_if_has_move(void)
}
}
-static void BattleAICmd_if_dont_have_move(void)
+static void BattleAICmd_if_doesnt_have_move(void)
{
int i;
- const u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2);
+ const u16 *movePtr = (u16 *)(gAIScriptPtr + 2);
switch(gAIScriptPtr[1])
{
@@ -1861,7 +1856,7 @@ static void BattleAICmd_if_dont_have_move(void)
case AI_USER_PARTNER: // UB: no separate check for user partner
for (i = 0; i < 4; i++)
{
- if (gBattleMons[sBank_AI].moves[i] == *temp_ptr)
+ if (gBattleMons[sBank_AI].moves[i] == *movePtr)
break;
}
if (i != 4)
@@ -1878,7 +1873,7 @@ static void BattleAICmd_if_dont_have_move(void)
case AI_TARGET_PARTNER:
for (i = 0; i < 4; i++)
{
- if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] == *temp_ptr)
+ if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] == *movePtr)
break;
}
if (i != 4)
@@ -1894,7 +1889,7 @@ static void BattleAICmd_if_dont_have_move(void)
}
}
-static void BattleAICmd_if_move_effect(void)
+static void BattleAICmd_if_has_move_with_effect(void)
{
int i;
@@ -1904,7 +1899,7 @@ static void BattleAICmd_if_move_effect(void)
case AI_USER_PARTNER:
for (i = 0; i < 4; i++)
{
- if(gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBank_AI].moves[i]].effect == gAIScriptPtr[2])
+ if (gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBank_AI].moves[i]].effect == gAIScriptPtr[2])
break;
}
if (i == 4)
@@ -1916,6 +1911,7 @@ static void BattleAICmd_if_move_effect(void)
case AI_TARGET_PARTNER:
for (i = 0; i < 4; i++)
{
+ // UB: checks sBank_AI instead of gBankTarget
if (gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[BATTLE_HISTORY->usedMoves[gBankTarget].moves[i]].effect == gAIScriptPtr[2])
break;
}
@@ -1927,7 +1923,7 @@ static void BattleAICmd_if_move_effect(void)
}
}
-static void BattleAICmd_if_not_move_effect(void)
+static void BattleAICmd_if_doesnt_have_move_with_effect(void)
{
int i;
@@ -2023,7 +2019,7 @@ static void BattleAICmd_flee(void)
AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_FLEE | AI_ACTION_DO_NOT_ATTACK);
}
-static void BattleAICmd_if_random_100(void)
+static void BattleAICmd_if_random_safari_flee(void)
{
u8 safariFleeRate = gBattleStruct->field_7B * 5; // safari flee rate, from 0-20
@@ -2041,7 +2037,6 @@ static void BattleAICmd_watch(void)
static void BattleAICmd_get_hold_effect(void)
{
u8 bank;
- u16 status;
if (gAIScriptPtr[1] == AI_USER)
bank = sBank_AI;
@@ -2049,9 +2044,7 @@ static void BattleAICmd_get_hold_effect(void)
bank = gBankTarget;
if (gActiveBank != bank)
- {
AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(BATTLE_HISTORY->itemEffects[bank]);
- }
else
AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(gBattleMons[bank].item);
@@ -2093,7 +2086,7 @@ static void BattleAICmd_get_gender(void)
gAIScriptPtr += 2;
}
-static void BattleAICmd_is_first_turn(void)
+static void BattleAICmd_is_first_turn_for(void)
{
u8 bank;
@@ -2212,7 +2205,7 @@ static void BattleAICmd_call(void)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
}
-static void BattleAICmd_jump(void)
+static void BattleAICmd_goto(void)
{
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
}
@@ -2272,7 +2265,7 @@ static void BattleAICmd_if_target_not_taunted(void)
static void BattleAICmd_if_target_is_ally(void)
{
- if((sBank_AI & 1) == (gBankTarget & 1))
+ if ((sBank_AI & BIT_SIDE) == (gBankTarget & BIT_SIDE))
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
else
gAIScriptPtr += 5;
@@ -2280,9 +2273,9 @@ static void BattleAICmd_if_target_is_ally(void)
static void BattleAICmd_if_flash_fired(void)
{
- u8 index = BattleAI_GetWantedBank(gAIScriptPtr[1]);
+ u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]);
- if(gBattleResources->flags->flags[index] & UNKNOWN_FLAG_FLASH_FIRE)
+ if (gBattleResources->flags->flags[bank] & UNKNOWN_FLAG_FLASH_FIRE)
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
diff --git a/src/battle_anim.c b/src/battle_anim.c
index 2eec0bed5..d991a702d 100644
--- a/src/battle_anim.c
+++ b/src/battle_anim.c
@@ -1,6 +1,7 @@
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "sprite.h"
#include "contest.h"
#include "m4a.h"
@@ -36,9 +37,9 @@ extern u16 gBattle_BG2_X;
extern u16 gBattle_BG2_Y;
extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
extern u8 gBankSpriteIds[BATTLE_BANKS_COUNT];
-extern struct MusicPlayerInfo gMPlay_BGM;
-extern struct MusicPlayerInfo gMPlay_SE1;
-extern struct MusicPlayerInfo gMPlay_SE2;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_SE1;
+extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern u8 gDecompressionBuffer[];
extern const u16 gUnknown_082C8D64[];
@@ -67,7 +68,7 @@ static void ScriptCmd_return(void);
static void ScriptCmd_setarg(void);
static void ScriptCmd_choosetwoturnanim(void);
static void ScriptCmd_jumpifmoveturn(void);
-static void ScriptCmd_jump(void);
+static void ScriptCmd_goto(void);
static void ScriptCmd_fadetobg(void);
static void ScriptCmd_restorebg(void);
static void ScriptCmd_waitbgfadeout(void);
@@ -156,7 +157,7 @@ static void (* const sScriptCmdTable[])(void) =
ScriptCmd_setarg,
ScriptCmd_choosetwoturnanim,
ScriptCmd_jumpifmoveturn,
- ScriptCmd_jump,
+ ScriptCmd_goto,
ScriptCmd_fadetobg,
ScriptCmd_restorebg,
ScriptCmd_waitbgfadeout,
@@ -271,7 +272,7 @@ void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMo
{
if (tableId == gUnknown_082C8D64[i])
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 128);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 128);
break;
}
}
@@ -513,8 +514,8 @@ static void ScriptCmd_end(void)
}
else
{
- m4aMPlayStop(&gMPlay_SE1);
- m4aMPlayStop(&gMPlay_SE2);
+ m4aMPlayStop(&gMPlayInfo_SE1);
+ m4aMPlayStop(&gMPlayInfo_SE2);
}
}
@@ -533,7 +534,7 @@ static void ScriptCmd_end(void)
if (!continuousAnim) // may have been used for debug?
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 256);
if (!IsContest())
{
sub_80A8278();
@@ -605,7 +606,7 @@ static void ScriptCmd_monbg(void)
sBattleAnimScriptPtr++;
animBank = sBattleAnimScriptPtr[0];
- if (animBank & ANIM_BANK_TARGET)
+ if (animBank & ANIM_TARGET)
bank = gAnimBankTarget;
else
bank = gAnimBankAttacker;
@@ -862,12 +863,12 @@ static void ScriptCmd_clearmonbg(void)
sBattleAnimScriptPtr++;
animBankId = sBattleAnimScriptPtr[0];
- if (animBankId == ANIM_BANK_ATTACKER)
- animBankId = ANIM_BANK_ATK_PARTNER;
- else if (animBankId == ANIM_BANK_TARGET)
- animBankId = ANIM_BANK_DEF_PARTNER;
+ if (animBankId == ANIM_ATTACKER)
+ animBankId = ANIM_ATK_PARTNER;
+ else if (animBankId == ANIM_TARGET)
+ animBankId = ANIM_DEF_PARTNER;
- if (animBankId == ANIM_BANK_ATTACKER || animBankId == ANIM_BANK_ATK_PARTNER)
+ if (animBankId == ANIM_ATTACKER || animBankId == ANIM_ATK_PARTNER)
bank = gAnimBankAttacker;
else
bank = gAnimBankTarget;
@@ -924,12 +925,12 @@ static void ScriptCmd_monbg_22(void)
animBankId = sBattleAnimScriptPtr[0];
- if (animBankId == ANIM_BANK_ATTACKER)
- animBankId = ANIM_BANK_ATK_PARTNER;
- else if (animBankId == ANIM_BANK_TARGET)
- animBankId = ANIM_BANK_DEF_PARTNER;
+ if (animBankId == ANIM_ATTACKER)
+ animBankId = ANIM_ATK_PARTNER;
+ else if (animBankId == ANIM_TARGET)
+ animBankId = ANIM_DEF_PARTNER;
- if (animBankId == ANIM_BANK_ATTACKER || animBankId == ANIM_BANK_ATK_PARTNER)
+ if (animBankId == ANIM_ATTACKER || animBankId == ANIM_ATK_PARTNER)
bank = gAnimBankAttacker;
else
bank = gAnimBankTarget;
@@ -969,12 +970,12 @@ static void ScriptCmd_clearmonbg_23(void)
sBattleAnimScriptPtr++;
animBankId = sBattleAnimScriptPtr[0];
- if (animBankId == ANIM_BANK_ATTACKER)
- animBankId = ANIM_BANK_ATK_PARTNER;
- else if (animBankId == ANIM_BANK_TARGET)
- animBankId = ANIM_BANK_DEF_PARTNER;
+ if (animBankId == ANIM_ATTACKER)
+ animBankId = ANIM_ATK_PARTNER;
+ else if (animBankId == ANIM_TARGET)
+ animBankId = ANIM_DEF_PARTNER;
- if (animBankId == ANIM_BANK_ATTACKER || animBankId == ANIM_BANK_ATK_PARTNER)
+ if (animBankId == ANIM_ATTACKER || animBankId == ANIM_ATK_PARTNER)
bank = gAnimBankAttacker;
else
bank = gAnimBankTarget;
@@ -1099,7 +1100,7 @@ static void ScriptCmd_jumpifmoveturn(void)
sBattleAnimScriptPtr += 4;
}
-static void ScriptCmd_jump(void)
+static void ScriptCmd_goto(void)
{
sBattleAnimScriptPtr++;
sBattleAnimScriptPtr = SCRIPT_READ_PTR(sBattleAnimScriptPtr);
@@ -1649,8 +1650,8 @@ static void ScriptCmd_waitsound(void)
{
if (++sSoundAnimFramesToWait > 90)
{
- m4aMPlayStop(&gMPlay_SE1);
- m4aMPlayStop(&gMPlay_SE2);
+ m4aMPlayStop(&gMPlayInfo_SE1);
+ m4aMPlayStop(&gMPlayInfo_SE2);
sSoundAnimFramesToWait = 0;
}
else
@@ -1699,7 +1700,7 @@ static void ScriptCmd_monbgprio_28(void)
wantedBank = sBattleAnimScriptPtr[1];
sBattleAnimScriptPtr += 2;
- if (wantedBank != ANIM_BANK_ATTACKER)
+ if (wantedBank != ANIM_ATTACKER)
bank = gAnimBankTarget;
else
bank = gAnimBankAttacker;
@@ -1732,7 +1733,7 @@ static void ScriptCmd_monbgprio_2A(void)
sBattleAnimScriptPtr += 2;
if (GetBankSide(gAnimBankAttacker) != GetBankSide(gAnimBankTarget))
{
- if (wantedBank != ANIM_BANK_ATTACKER)
+ if (wantedBank != ANIM_ATTACKER)
bank = gAnimBankTarget;
else
bank = gAnimBankAttacker;
@@ -1779,15 +1780,15 @@ static void ScriptCmd_doublebattle_2D(void)
if (!IsContest() && IsDoubleBattle()
&& GetBankSide(gAnimBankAttacker) == GetBankSide(gAnimBankTarget))
{
- if (wantedBank == ANIM_BANK_ATTACKER)
+ if (wantedBank == ANIM_ATTACKER)
{
r4 = sub_80A8364(gAnimBankAttacker);
- spriteId = GetAnimBankSpriteId(0);
+ spriteId = GetAnimBankSpriteId(ANIM_ATTACKER);
}
else
{
r4 = sub_80A8364(gAnimBankTarget);
- spriteId = GetAnimBankSpriteId(1);
+ spriteId = GetAnimBankSpriteId(ANIM_TARGET);
}
if (spriteId != 0xFF)
{
@@ -1814,15 +1815,15 @@ static void ScriptCmd_doublebattle_2E(void)
if (!IsContest() && IsDoubleBattle()
&& GetBankSide(gAnimBankAttacker) == GetBankSide(gAnimBankTarget))
{
- if (wantedBank == ANIM_BANK_ATTACKER)
+ if (wantedBank == ANIM_ATTACKER)
{
r4 = sub_80A8364(gAnimBankAttacker);
- spriteId = GetAnimBankSpriteId(0);
+ spriteId = GetAnimBankSpriteId(ANIM_ATTACKER);
}
else
{
r4 = sub_80A8364(gAnimBankTarget);
- spriteId = GetAnimBankSpriteId(1);
+ spriteId = GetAnimBankSpriteId(ANIM_TARGET);
}
if (spriteId != 0xFF && r4 == 2)
@@ -1832,7 +1833,7 @@ static void ScriptCmd_doublebattle_2E(void)
static void ScriptCmd_stopsound(void)
{
- m4aMPlayStop(&gMPlay_SE1);
- m4aMPlayStop(&gMPlay_SE2);
+ m4aMPlayStop(&gMPlayInfo_SE1);
+ m4aMPlayStop(&gMPlayInfo_SE2);
sBattleAnimScriptPtr++;
}
diff --git a/src/battle_bg.c b/src/battle_bg.c
new file mode 100644
index 000000000..5d5bbf0e9
--- /dev/null
+++ b/src/battle_bg.c
@@ -0,0 +1,754 @@
+#include "global.h"
+#include "battle.h"
+#include "sprite.h"
+#include "constants/trainers.h"
+#include "graphics.h"
+#include "decompress.h"
+#include "bg.h"
+#include "palette.h"
+#include "main.h"
+#include "gpu_regs.h"
+#include "link.h"
+#include "battle_message.h"
+#include "task.h"
+#include "trig.h"
+#include "sound.h"
+#include "constants/songs.h"
+#include "strings.h"
+#include "window.h"
+#include "text_window.h"
+#include "new_menu_helpers.h"
+
+struct BattleBackground
+{
+ const void *tileset;
+ const void *tilemap;
+ const void *entryTileset;
+ const void *entryTilemap;
+ const void *palette;
+};
+
+extern const struct SpriteTemplate gUnknown_0831A9D0;
+extern const struct SpriteTemplate gUnknown_0831A9E8;
+extern const struct CompressedSpriteSheet gUnknown_0831AA00;
+extern const struct BgTemplate gUnknown_0831AA08[4];
+extern const struct WindowTemplate *gUnknown_0831ABA0[];
+extern const struct BattleBackground gBattleTerrainTable[];
+
+extern u8 gBattleTerrain;
+extern u16 gTrainerBattleOpponent_A;
+extern u16 gBattle_BG1_X;
+extern u16 gBattle_BG1_Y;
+extern u16 gBattle_BG2_X;
+extern u16 gBattle_BG2_Y;
+extern u16 gPartnerTrainerId;
+
+extern u8 GetCurrentMapBattleScene(void);
+
+void sub_8035658(void)
+{
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, gUnknown_0831AA08, ARRAY_COUNT(gUnknown_0831AA08));
+
+ if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
+ {
+ gBattleScripting.field_24 = 1;
+ SetBgTilemapBuffer(1, gUnknown_02023060);
+ SetBgTilemapBuffer(2, gUnknown_02023060);
+ }
+ else
+ {
+ gBattleScripting.field_24 = 0;
+ }
+
+ InitWindows(gUnknown_0831ABA0[gBattleScripting.field_24]);
+ DeactivateAllTextPrinters();
+}
+
+void sub_80356D0(void)
+{
+ DisableInterrupts(INTR_FLAG_HBLANK);
+ EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
+ sub_8035658();
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON | DISPCNT_WIN0_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+}
+
+void ApplyPlayerChosenFrameToBattleMenu(void)
+{
+ sub_809882C(2, 0x12, 0x10);
+ sub_809882C(2, 0x22, 0x10);
+ LoadCompressedPalette(gUnknown_08D85600, 0x50, 0x20);
+
+ if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
+ {
+ sub_81978B0(0x70);
+ copy_textbox_border_tile_patterns_to_vram(0, 0x30, 0x70);
+ gPlttBufferUnfaded[0x76] = 0;
+ CpuCopy16(&gPlttBufferUnfaded[0x76], &gPlttBufferFaded[0x76], 2);
+ }
+}
+
+void DrawMainBattleBackground(void)
+{
+ if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_x2000000))
+ {
+ LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_Frontier, 0x20, 0x60);
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_GROUDON)
+ {
+ LZDecompressVram(gBattleTerrainTiles_Cave, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Cave, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_Groudon, 0x20, 0x60);
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE)
+ {
+ LZDecompressVram(gBattleTerrainTiles_Water, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Water, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_Kyogre, 0x20, 0x60);
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_RAYQUAZA)
+ {
+ LZDecompressVram(gBattleTerrainTiles_Rayquaza, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Rayquaza, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_Rayquaza, 0x20, 0x60);
+ }
+ else
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ {
+ u8 trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass;
+ if (trainerClass == TRAINER_CLASS_LEADER)
+ {
+ LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_BuildingLeader, 0x20, 0x60);
+ return;
+ }
+ else if (trainerClass == TRAINER_CLASS_CHAMPION)
+ {
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumWallace, 0x20, 0x60);
+ return;
+ }
+ }
+
+ switch (GetCurrentMapBattleScene())
+ {
+ default:
+ case MAP_BATTLE_SCENE_NORMAL:
+ LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tileset, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tilemap, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainTable[gBattleTerrain].palette, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_GYM:
+ LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_BuildingGym, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_MAGMA:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumMagma, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_AQUA:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumAqua, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_SIDNEY:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumSidney, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_PHOEBE:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumPhoebe, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_GLACIA:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumGlacia, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_DRAKE:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumDrake, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_FRONTIER:
+ LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000));
+ LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000));
+ LoadCompressedPalette(gBattleTerrainPalette_Frontier, 0x20, 0x60);
+ break;
+ }
+ }
+}
+
+void LoadBattleTextboxAndBackground(void)
+{
+ LZDecompressVram(gBattleTextboxTiles, (void*)(VRAM));
+ CopyToBgTilemapBuffer(0, gBattleTextboxTilemap, 0, 0);
+ CopyBgTilemapBufferToVram(0);
+ LoadCompressedPalette(gBattleTextboxPalette, 0, 0x40);
+ ApplyPlayerChosenFrameToBattleMenu();
+
+ DrawMainBattleBackground();
+}
+
+static void sub_8035AE4(u8 taskId, u8 bank, u8 bgId, u8 destX, u8 destY)
+{
+ s32 i;
+ u16 var = 0;
+ u16 src[6];
+
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ if (gTasks[taskId].data[5] != 0)
+ {
+ switch (bank)
+ {
+ case 0:
+ var = 0x3F & gTasks[taskId].data[3];
+ break;
+ case 1:
+ var = (0xFC0 & gTasks[taskId].data[4]) >> 6;
+ break;
+ case 2:
+ var = (0xFC0 & gTasks[taskId].data[3]) >> 6;
+ break;
+ case 3:
+ var = 0x3F & gTasks[taskId].data[4];
+ break;
+ }
+ }
+ else
+ {
+ switch (bank)
+ {
+ case 0:
+ var = 0x3F & gTasks[taskId].data[3];
+ break;
+ case 1:
+ var = 0x3F & gTasks[taskId].data[4];
+ break;
+ case 2:
+ var = (0xFC0 & gTasks[taskId].data[3]) >> 6;
+ break;
+ case 3:
+ var = (0xFC0 & gTasks[taskId].data[4]) >> 6;
+ break;
+ }
+ }
+
+ for (i = 0; i < 3; i++)
+ {
+ src[i] = ((var & (3 << (i * 2))) >> (i * 2)) + 0x6001;
+ }
+
+ CopyToBgTilemapBufferRect_ChangePalette(bgId, src, destX, destY, 3, 1, 0x11);
+ CopyBgTilemapBufferToVram(bgId);
+ }
+ else
+ {
+ if (bank == gBattleScripting.multiplayerId)
+ var = gTasks[taskId].data[3];
+ else
+ var = gTasks[taskId].data[4];
+
+ for (i = 0; i < 6; i++)
+ {
+ src[i] = ((var & (3 << (i * 2))) >> (i * 2)) + 0x6001;
+ }
+
+ CopyToBgTilemapBufferRect_ChangePalette(bgId, src, destX, destY, 6, 1, 0x11);
+ CopyBgTilemapBufferToVram(bgId);
+ }
+}
+
+static void sub_8035C4C(void)
+{
+ if (gBattleOutcome == BATTLE_DREW)
+ {
+ BattleHandleAddTextPrinter(gText_Draw, 0x15);
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ if (gBattleOutcome == BATTLE_WON)
+ {
+ switch (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18)
+ {
+ case 0:
+ BattleHandleAddTextPrinter(gText_Win, 0x16);
+ BattleHandleAddTextPrinter(gText_Loss, 0x17);
+ break;
+ case 1:
+ BattleHandleAddTextPrinter(gText_Win, 0x17);
+ BattleHandleAddTextPrinter(gText_Loss, 0x16);
+ break;
+ case 2:
+ BattleHandleAddTextPrinter(gText_Win, 0x16);
+ BattleHandleAddTextPrinter(gText_Loss, 0x17);
+ break;
+ case 3:
+ BattleHandleAddTextPrinter(gText_Win, 0x17);
+ BattleHandleAddTextPrinter(gText_Loss, 0x16);
+ break;
+ }
+ }
+ else
+ {
+ switch (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18)
+ {
+ case 0:
+ BattleHandleAddTextPrinter(gText_Win, 0x17);
+ BattleHandleAddTextPrinter(gText_Loss, 0x16);
+ break;
+ case 1:
+ BattleHandleAddTextPrinter(gText_Win, 0x16);
+ BattleHandleAddTextPrinter(gText_Loss, 0x17);
+ break;
+ case 2:
+ BattleHandleAddTextPrinter(gText_Win, 0x17);
+ BattleHandleAddTextPrinter(gText_Loss, 0x16);
+ break;
+ case 3:
+ BattleHandleAddTextPrinter(gText_Win, 0x16);
+ BattleHandleAddTextPrinter(gText_Loss, 0x17);
+ break;
+ }
+ }
+ }
+ else if (gBattleOutcome == BATTLE_WON)
+ {
+ if (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18 != 0)
+ {
+ BattleHandleAddTextPrinter(gText_Win, 0x17);
+ BattleHandleAddTextPrinter(gText_Loss, 0x16);
+ }
+ else
+ {
+ BattleHandleAddTextPrinter(gText_Win, 0x16);
+ BattleHandleAddTextPrinter(gText_Loss, 0x17);
+ }
+ }
+ else
+ {
+ if (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18 != 0)
+ {
+ BattleHandleAddTextPrinter(gText_Win, 0x16);
+ BattleHandleAddTextPrinter(gText_Loss, 0x17);
+ }
+ else
+ {
+ BattleHandleAddTextPrinter(gText_Win, 0x17);
+ BattleHandleAddTextPrinter(gText_Loss, 0x16);
+ }
+ }
+}
+
+void sub_8035D74(u8 taskId)
+{
+ struct LinkPlayer *linkPlayer;
+ u8 *name;
+ s32 i, palId;
+
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ for (i = 0; i < BATTLE_BANKS_COUNT; i++)
+ {
+ name = gLinkPlayers[i].name;
+ linkPlayer = &gLinkPlayers[i];
+
+ switch (linkPlayer->lp_field_18)
+ {
+ case 0:
+ BattleHandleAddTextPrinter(name, 0x11);
+ sub_8035AE4(taskId, linkPlayer->lp_field_18, 1, 2, 4);
+ break;
+ case 1:
+ BattleHandleAddTextPrinter(name, 0x12);
+ sub_8035AE4(taskId, linkPlayer->lp_field_18, 2, 2, 4);
+ break;
+ case 2:
+ BattleHandleAddTextPrinter(name, 0x13);
+ sub_8035AE4(taskId, linkPlayer->lp_field_18, 1, 2, 8);
+ break;
+ case 3:
+ BattleHandleAddTextPrinter(name, 0x14);
+ sub_8035AE4(taskId, linkPlayer->lp_field_18, 2, 2, 8);
+ break;
+ }
+ }
+ }
+ else
+ {
+ u8 playerId = gBattleScripting.multiplayerId;
+ u8 opponentId = playerId ^ BIT_SIDE;
+ u8 opponentId_copy = opponentId;
+
+ if (gLinkPlayers[playerId].lp_field_18 != 0)
+ opponentId = playerId, playerId = opponentId_copy;
+
+ name = gLinkPlayers[playerId].name;
+ BattleHandleAddTextPrinter(name, 0xF);
+
+ name = gLinkPlayers[opponentId].name;
+ BattleHandleAddTextPrinter(name, 0x10);
+
+ sub_8035AE4(taskId, playerId, 1, 2, 7);
+ sub_8035AE4(taskId, opponentId, 2, 2, 7);
+ }
+ gTasks[taskId].data[0]++;
+ break;
+ case 1:
+ palId = AllocSpritePalette(0x2710);
+ gPlttBufferUnfaded[palId * 16 + 0x10F] = gPlttBufferFaded[palId * 16 + 0x10F] = 0x7FFF;
+ gBattleStruct->field_7D = CreateSprite(&gUnknown_0831A9D0, 111, 80, 0);
+ gBattleStruct->field_7E = CreateSprite(&gUnknown_0831A9E8, 129, 80, 0);
+ gSprites[gBattleStruct->field_7D].invisible = 1;
+ gSprites[gBattleStruct->field_7E].invisible = 1;
+ gTasks[taskId].data[0]++;
+ break;
+ case 2:
+ if (gTasks[taskId].data[5] != 0)
+ {
+ gBattle_BG1_X = -(20) - (Sin2(gTasks[taskId].data[1]) / 32);
+ gBattle_BG2_X = -(140) - (Sin2(gTasks[taskId].data[2]) / 32);
+ gBattle_BG1_Y = -36;
+ gBattle_BG2_Y = -36;
+ }
+ else
+ {
+ gBattle_BG1_X = -(20) - (Sin2(gTasks[taskId].data[1]) / 32);
+ gBattle_BG1_Y = (Cos2(gTasks[taskId].data[1]) / 32) - 164;
+ gBattle_BG2_X = -(140) - (Sin2(gTasks[taskId].data[2]) / 32);
+ gBattle_BG2_Y = (Cos2(gTasks[taskId].data[2]) / 32) - 164;
+ }
+
+ if (gTasks[taskId].data[2] != 0)
+ {
+ gTasks[taskId].data[2] -= 2;
+ gTasks[taskId].data[1] += 2;
+ }
+ else
+ {
+ if (gTasks[taskId].data[5] != 0)
+ sub_8035C4C();
+
+ PlaySE(SE_W231);
+ DestroyTask(taskId);
+ gSprites[gBattleStruct->field_7D].invisible = 0;
+ gSprites[gBattleStruct->field_7E].invisible = 0;
+ gSprites[gBattleStruct->field_7E].oam.tileNum += 0x40;
+ gSprites[gBattleStruct->field_7D].data[0] = 0;
+ gSprites[gBattleStruct->field_7E].data[0] = 1;
+ gSprites[gBattleStruct->field_7D].data[1] = gSprites[gBattleStruct->field_7D].pos1.x;
+ gSprites[gBattleStruct->field_7E].data[1] = gSprites[gBattleStruct->field_7E].pos1.x;
+ gSprites[gBattleStruct->field_7D].data[2] = 0;
+ gSprites[gBattleStruct->field_7E].data[2] = 0;
+ }
+ break;
+ }
+}
+
+void LoadBattleEntryBackground(void)
+{
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ LZDecompressVram(gUnknown_08D778F0, (void*)(VRAM + 0x4000));
+ LZDecompressVram(gUnknown_08D77B0C, (void*)(VRAM + 0x10000));
+ LoadCompressedPalette(gUnknown_08D77AE4, 0x60, 0x20);
+ SetBgAttribute(1, BG_CTRL_ATTR_MAPBASEINDEX, 1);
+ SetGpuReg(REG_OFFSET_BG1CNT, 0x5C04);
+ CopyToBgTilemapBuffer(1, gUnknown_08D779D8, 0, 0);
+ CopyToBgTilemapBuffer(2, gUnknown_08D779D8, 0, 0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ SetGpuReg(REG_OFFSET_WININ, 0x36);
+ SetGpuReg(REG_OFFSET_WINOUT, 0x36);
+ gBattle_BG1_Y = 0xFF5C;
+ gBattle_BG2_Y = 0xFF5C;
+ LoadCompressedObjectPicUsingHeap(&gUnknown_0831AA00);
+ }
+ else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_EREADER_TRAINER))
+ {
+ if (!(gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) || gPartnerTrainerId == STEVEN_PARTNER_ID)
+ {
+ LZDecompressVram(gBattleTerrainAnimTiles_Building, (void*)(VRAM + 0x4000));
+ LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void*)(VRAM + 0xE000));
+ }
+ else
+ {
+ SetBgAttribute(1, BG_CTRL_ATTR_VISIBLE, 2);
+ SetBgAttribute(2, BG_CTRL_ATTR_VISIBLE, 2);
+ CopyToBgTilemapBuffer(1, gUnknown_08D857A8, 0, 0);
+ CopyToBgTilemapBuffer(2, gUnknown_08D85A1C, 0, 0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ }
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_GROUDON)
+ {
+ LZDecompressVram(gBattleTerrainAnimTiles_Cave, (void*)(VRAM + 0x4000));
+ LZDecompressVram(gBattleTerrainAnimTilemap_Cave, (void*)(VRAM + 0xE000));
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE)
+ {
+ LZDecompressVram(gBattleTerrainAnimTiles_Underwater, (void*)(VRAM + 0x4000));
+ LZDecompressVram(gBattleTerrainAnimTilemap_Underwater, (void*)(VRAM + 0xE000));
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_RAYQUAZA)
+ {
+ LZDecompressVram(gBattleTerrainAnimTiles_Rayquaza, (void*)(VRAM + 0x4000));
+ LZDecompressVram(gBattleTerrainAnimTilemap_Rayquaza, (void*)(VRAM + 0xE000));
+ }
+ else
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ {
+ u8 trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass;
+ if (trainerClass == TRAINER_CLASS_LEADER)
+ {
+ LZDecompressVram(gBattleTerrainAnimTiles_Building, (void*)(VRAM + 0x4000));
+ LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void*)(VRAM + 0xE000));
+ return;
+ }
+ else if (trainerClass == TRAINER_CLASS_CHAMPION)
+ {
+ LZDecompressVram(gBattleTerrainAnimTiles_Building, (void*)(VRAM + 0x4000));
+ LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void*)(VRAM + 0xE000));
+ return;
+ }
+ }
+
+ if (GetCurrentMapBattleScene() == MAP_BATTLE_SCENE_NORMAL)
+ {
+ LZDecompressVram(gBattleTerrainTable[gBattleTerrain].entryTileset, (void*)(VRAM + 0x4000));
+ LZDecompressVram(gBattleTerrainTable[gBattleTerrain].entryTilemap, (void*)(VRAM + 0xE000));
+ }
+ else
+ {
+ LZDecompressVram(gBattleTerrainAnimTiles_Building, (void*)(VRAM + 0x4000));
+ LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void*)(VRAM + 0xE000));
+ }
+ }
+}
+
+bool8 LoadChosenBattleElement(u8 caseId)
+{
+ bool8 ret = FALSE;
+
+ switch (caseId)
+ {
+ case 0:
+ LZDecompressVram(gBattleTextboxTiles, (void*)(VRAM));
+ break;
+ case 1:
+ CopyToBgTilemapBuffer(0, gBattleTextboxTilemap, 0, 0);
+ CopyBgTilemapBufferToVram(0);
+ break;
+ case 2:
+ LoadCompressedPalette(gBattleTextboxPalette, 0, 0x40);
+ break;
+ case 3:
+ if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_EREADER_TRAINER))
+ {
+ LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000));
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_GROUDON)
+ {
+ LZDecompressVram(gBattleTerrainTiles_Cave, (void*)(VRAM + 0x8000));
+ }
+ else
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ {
+ u8 trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass;
+ if (trainerClass == TRAINER_CLASS_LEADER)
+ {
+ LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000));
+ break;
+ }
+ else if (trainerClass == TRAINER_CLASS_CHAMPION)
+ {
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ break;
+ }
+ }
+
+ switch (GetCurrentMapBattleScene())
+ {
+ default:
+ case MAP_BATTLE_SCENE_NORMAL:
+ LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tileset, (void*)(VRAM + 0x8000));
+ break;
+ case MAP_BATTLE_SCENE_GYM:
+ LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000));
+ break;
+ case MAP_BATTLE_SCENE_MAGMA:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ break;
+ case MAP_BATTLE_SCENE_AQUA:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ break;
+ case MAP_BATTLE_SCENE_SIDNEY:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ break;
+ case MAP_BATTLE_SCENE_PHOEBE:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ break;
+ case MAP_BATTLE_SCENE_GLACIA:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ break;
+ case MAP_BATTLE_SCENE_DRAKE:
+ LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000));
+ break;
+ case MAP_BATTLE_SCENE_FRONTIER:
+ LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000));
+ break;
+ }
+ }
+ break;
+ case 4:
+ if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_EREADER_TRAINER))
+ {
+ LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000));
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON)
+ {
+ if (gGameVersion == VERSION_RUBY)
+ LZDecompressVram(gBattleTerrainTilemap_Cave, (void*)(VRAM + 0xD000));
+ else
+ LZDecompressVram(gBattleTerrainTilemap_Water, (void*)(VRAM + 0xD000));
+ }
+ else
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ {
+ u8 trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass;
+ if (trainerClass == TRAINER_CLASS_LEADER)
+ {
+ LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000));
+ break;
+ }
+ else if (trainerClass == TRAINER_CLASS_CHAMPION)
+ {
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ break;
+ }
+ }
+
+ switch (GetCurrentMapBattleScene())
+ {
+ default:
+ case MAP_BATTLE_SCENE_NORMAL:
+ LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tilemap, (void*)(VRAM + 0xD000));
+ break;
+ case MAP_BATTLE_SCENE_GYM:
+ LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000));
+ break;
+ case MAP_BATTLE_SCENE_MAGMA:
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ break;
+ case MAP_BATTLE_SCENE_AQUA:
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ break;
+ case MAP_BATTLE_SCENE_SIDNEY:
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ break;
+ case MAP_BATTLE_SCENE_PHOEBE:
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ break;
+ case MAP_BATTLE_SCENE_GLACIA:
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ break;
+ case MAP_BATTLE_SCENE_DRAKE:
+ LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000));
+ break;
+ case MAP_BATTLE_SCENE_FRONTIER:
+ LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000));
+ break;
+ }
+ }
+ break;
+ case 5:
+ if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_EREADER_TRAINER))
+ {
+ LoadCompressedPalette(gBattleTerrainPalette_Frontier, 0x20, 0x60);
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON)
+ {
+ if (gGameVersion == VERSION_RUBY)
+ LoadCompressedPalette(gBattleTerrainPalette_Groudon, 0x20, 0x60);
+ else
+ LoadCompressedPalette(gBattleTerrainPalette_Kyogre, 0x20, 0x60);
+ }
+ else
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ {
+ u8 trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass;
+ if (trainerClass == TRAINER_CLASS_LEADER)
+ {
+ LoadCompressedPalette(gBattleTerrainPalette_BuildingLeader, 0x20, 0x60);
+ break;
+ }
+ else if (trainerClass == TRAINER_CLASS_CHAMPION)
+ {
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumWallace, 0x20, 0x60);
+ break;
+ }
+ }
+
+ switch (GetCurrentMapBattleScene())
+ {
+ default:
+ case MAP_BATTLE_SCENE_NORMAL:
+ LoadCompressedPalette(gBattleTerrainTable[gBattleTerrain].palette, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_GYM:
+ LoadCompressedPalette(gBattleTerrainPalette_BuildingGym, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_MAGMA:
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumMagma, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_AQUA:
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumAqua, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_SIDNEY:
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumSidney, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_PHOEBE:
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumPhoebe, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_GLACIA:
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumGlacia, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_DRAKE:
+ LoadCompressedPalette(gBattleTerrainPalette_StadiumDrake, 0x20, 0x60);
+ break;
+ case MAP_BATTLE_SCENE_FRONTIER:
+ LoadCompressedPalette(gBattleTerrainPalette_Frontier, 0x20, 0x60);
+ break;
+ }
+ }
+ break;
+ case 6:
+ ApplyPlayerChosenFrameToBattleMenu();
+ break;
+ default:
+ ret = TRUE;
+ break;
+ }
+
+ return ret;
+}
diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c
index dd8582618..cb510bb5b 100644
--- a/src/battle_controller_link_opponent.c
+++ b/src/battle_controller_link_opponent.c
@@ -4,6 +4,7 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "battle_ai_script_commands.h"
#include "battle_link_817C95C.h"
#include "pokemon.h"
@@ -50,7 +51,7 @@ extern u8 gBankTarget;
extern u8 gAbsentBankFlags;
extern u8 gUnknown_020244B4[];
extern u32 gTransformedPersonalities[BATTLE_BANKS_COUNT];
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern struct UnusedControllerStruct gUnknown_02022D0C;
extern u16 gTrainerBattleOpponent_A;
extern u16 gTrainerBattleOpponent_B;
@@ -352,11 +353,11 @@ static void sub_8064734(void)
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
{
if (GetBankIdentity(gActiveBank) == IDENTITY_OPPONENT_MON1)
- m4aMPlayContinue(&gMPlay_BGM);
+ m4aMPlayContinue(&gMPlayInfo_BGM);
}
else
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
}
}
@@ -498,7 +499,7 @@ static void sub_8064DD0(void)
if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy
|| gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy_2)
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
LinkOpponentBufferExecCompleted();
}
}
diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c
index 9da468761..082b134b4 100644
--- a/src/battle_controller_link_partner.c
+++ b/src/battle_controller_link_partner.c
@@ -4,6 +4,7 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "battle_ai_script_commands.h"
#include "battle_link_817C95C.h"
#include "pokemon.h"
diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c
index 0862e72a7..30414d53a 100644
--- a/src/battle_controller_opponent.c
+++ b/src/battle_controller_opponent.c
@@ -4,6 +4,7 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "battle_link_817C95C.h"
#include "battle_ai_script_commands.h"
#include "pokemon.h"
@@ -37,7 +38,7 @@ extern u8 gBankSpriteIds[BATTLE_BANKS_COUNT];
extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern u8 gUnknown_03005D7C[BATTLE_BANKS_COUNT];
extern void (*gBattleBankFunc[BATTLE_BANKS_COUNT])(void);
extern void *gUnknown_020244D8;
@@ -349,10 +350,10 @@ static void sub_805F560(void)
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
{
if (GetBankIdentity(gActiveBank) == 1)
- m4aMPlayContinue(&gMPlay_BGM);
+ m4aMPlayContinue(&gMPlayInfo_BGM);
}
else
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x20 = 1;
sp = TRUE;
@@ -484,7 +485,7 @@ static void sub_805FC80(void)
{
if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy || gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy_2)
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
OpponentBufferExecCompleted();
}
}
diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c
index d10b8e88a..2434eb177 100644
--- a/src/battle_controller_player.c
+++ b/src/battle_controller_player.c
@@ -4,6 +4,7 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "battle_link_817C95C.h"
#include "pokemon.h"
#include "link.h"
@@ -42,7 +43,7 @@ extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern u8 gMultiUsePlayerCursor;
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern u16 gPartnerTrainerId;
extern struct SpriteTemplate gUnknown_0202499C;
extern u8 gBattleMonForms[BATTLE_BANKS_COUNT];
@@ -234,7 +235,7 @@ static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
static const u8 sTargetIdentities[] = {IDENTITY_PLAYER_MON1, IDENTITY_PLAYER_MON2, IDENTITY_OPPONENT_MON2, IDENTITY_OPPONENT_MON1};
// unknown unused data
-static const u8 gUnknown_0831C5FC[] = {0x48, 0x48, 0x20, 0x5a, 0x50, 0x50, 0x50, 0x58};
+static const u8 sUnknown_0831C5FC[] = {0x48, 0x48, 0x20, 0x5a, 0x50, 0x50, 0x50, 0x58};
void nullsub_21(void)
{
@@ -1053,9 +1054,9 @@ static void sub_8058B40(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x20)
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
- m4aMPlayContinue(&gMPlay_BGM);
+ m4aMPlayContinue(&gMPlayInfo_BGM);
else
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x20 = 1;
r9 = TRUE;
@@ -1118,7 +1119,7 @@ static void sub_8058FC0(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive
&& !IsCryPlayingOrClearCrySongs())
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
PlayerBufferExecCompleted();
}
@@ -1147,7 +1148,7 @@ void c3_0802FDF4(u8 taskId)
{
if (!IsCryPlayingOrClearCrySongs())
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
DestroyTask(taskId);
}
}
diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c
index eb57297da..6b5211ceb 100644
--- a/src/battle_controller_player_partner.c
+++ b/src/battle_controller_player_partner.c
@@ -4,6 +4,7 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "battle_ai_script_commands.h"
#include "pokemon.h"
#include "link.h"
@@ -198,7 +199,7 @@ static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
};
// unknown unused data
-static const u8 gUnknown_08617254[] =
+static const u8 sUnknown_08617254[] =
{
0x83, 0x4d, 0xf3, 0x5f, 0x6f, 0x4f, 0xeb, 0x3e,
0x67, 0x2e, 0x10, 0x46, 0x8c, 0x3d, 0x28, 0x35,
diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c
index 8e2f31879..6e29fa951 100644
--- a/src/battle_controller_recorded_opponent.c
+++ b/src/battle_controller_recorded_opponent.c
@@ -4,6 +4,7 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "battle_ai_script_commands.h"
#include "battle_link_817C95C.h"
#include "recorded_battle.h"
@@ -51,7 +52,7 @@ extern u8 gBankTarget;
extern u8 gAbsentBankFlags;
extern u8 gUnknown_020244B4[];
extern u32 gTransformedPersonalities[BATTLE_BANKS_COUNT];
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern struct UnusedControllerStruct gUnknown_02022D0C;
extern u16 gTrainerBattleOpponent_A;
extern u16 gTrainerBattleOpponent_B;
@@ -330,11 +331,11 @@ static void sub_818686C(void)
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
{
if (GetBankIdentity(gActiveBank) == IDENTITY_OPPONENT_MON1)
- m4aMPlayContinue(&gMPlay_BGM);
+ m4aMPlayContinue(&gMPlayInfo_BGM);
}
else
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
}
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x20 = 1;
@@ -483,7 +484,7 @@ static void sub_8186F14(void)
if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy
|| gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy_2)
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
RecordedOpponentBufferExecCompleted();
}
}
diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c
index f558fde87..f101d811f 100644
--- a/src/battle_controller_recorded_player.c
+++ b/src/battle_controller_recorded_player.c
@@ -4,6 +4,7 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "battle_ai_script_commands.h"
#include "recorded_battle.h"
#include "pokemon.h"
@@ -53,7 +54,7 @@ extern u8 gUnknown_020244B4[];
extern u32 gTransformedPersonalities[BATTLE_BANKS_COUNT];
extern u8 gBattleCommunication[];
extern u8 gUnknown_0203C7B4;
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern struct UnusedControllerStruct gUnknown_02022D0C;
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
@@ -353,11 +354,11 @@ static void sub_8189D40(void)
if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && (gBattleTypeFlags & BATTLE_TYPE_MULTI))
{
if (GetBankIdentity(gActiveBank) == IDENTITY_PLAYER_MON1)
- m4aMPlayContinue(&gMPlay_BGM);
+ m4aMPlayContinue(&gMPlayInfo_BGM);
}
else
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
}
}
diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c
index db4670523..682e8333d 100644
--- a/src/battle_controller_safari.c
+++ b/src/battle_controller_safari.c
@@ -4,6 +4,7 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "pokemon.h"
#include "link.h"
#include "util.h"
@@ -19,6 +20,7 @@
#include "reshow_battle_screen.h"
#include "pokeball.h"
#include "data2.h"
+#include "pokeblock.h"
extern u32 gBattleExecBuffer;
extern u8 gActiveBank;
@@ -291,13 +293,13 @@ static void CompleteOnSpecialAnimDone(void)
SafariBufferExecCompleted();
}
-static void OpenPokeblockCase(void)
+static void SafariOpenPokeblockCase(void)
{
if (!gPaletteFade.active)
{
gBattleBankFunc[gActiveBank] = CompleteWhenChosePokeblock;
FreeAllWindowBuffers();
- sub_81358F4();
+ OpenPokeblockCaseInBattle();
}
}
@@ -497,7 +499,7 @@ static void SafariHandleChooseItem(void)
s32 i;
BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
- gBattleBankFunc[gActiveBank] = OpenPokeblockCase;
+ gBattleBankFunc[gActiveBank] = SafariOpenPokeblockCase;
gBankInMenu = gActiveBank;
}
diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c
index 446027944..b0e1e1480 100644
--- a/src/battle_controller_wally.c
+++ b/src/battle_controller_wally.c
@@ -4,6 +4,7 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "battle_link_817C95C.h"
#include "pokemon.h"
#include "link.h"
@@ -41,7 +42,7 @@ extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern u8 gMultiUsePlayerCursor;
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern u16 gPartnerTrainerId;
extern struct SpriteTemplate gUnknown_0202499C;
extern u8 gBattleMonForms[BATTLE_BANKS_COUNT];
diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c
index 22be086f0..775578ca2 100644
--- a/src/battle_gfx_sfx_util.c
+++ b/src/battle_gfx_sfx_util.c
@@ -3,6 +3,7 @@
#include "battle_controllers.h"
#include "battle_ai_script_commands.h"
#include "battle_anim.h"
+#include "constants/battle_anim.h"
#include "battle_interface.h"
#include "main.h"
#include "malloc.h"
@@ -33,14 +34,14 @@ extern u8 gBankSpriteIds[BATTLE_BANKS_COUNT];
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
extern u8 gBattleMonForms[BATTLE_BANKS_COUNT];
extern u32 gTransformedPersonalities[BATTLE_BANKS_COUNT];
-extern struct MusicPlayerInfo gMPlay_SE1;
-extern struct MusicPlayerInfo gMPlay_SE2;
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_SE1;
+extern struct MusicPlayerInfo gMPlayInfo_SE2;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern const struct BattleMove gBattleMoves[];
extern const u8 gUnknown_0831C604[];
-extern const u8 * const gUnknown_082C9320[];
-extern const u8 * const gUnknown_082C937C[];
+extern const u8 * const gBattleAnims_VariousTable[];
+extern const u8 * const gBattleAnims_Special[];
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
extern const struct CompressedSpriteSheet gMonBackPicTable[];
extern const struct CompressedSpriteSheet gTrainerFrontPicTable[];
@@ -63,7 +64,7 @@ extern const u8 gUnknown_08C1F46C[];
extern const u8 gUnknown_08C1F5E8[];
extern const u8 gUnknown_08C1F76C[];
extern const u8 gUnknown_08C1F8E8[];
-extern const u8 gUnknown_08C0237C[];
+extern const u8 gBlankGfxCompressed[];
extern const u16 gBattleInterface_BallStatusBarPal[];
extern const u16 gBattleInterface_BallDisplayPal[];
@@ -110,10 +111,10 @@ static const struct CompressedSpriteSheet gUnknown_0832C100 =
static const struct CompressedSpriteSheet gUnknown_0832C108[BATTLE_BANKS_COUNT] =
{
- {gUnknown_08C0237C, 0x0100, 0xd704},
- {gUnknown_08C0237C, 0x0120, 0xd705},
- {gUnknown_08C0237C, 0x0100, 0xd706},
- {gUnknown_08C0237C, 0x0120, 0xd707}
+ {gBlankGfxCompressed, 0x0100, 0xd704},
+ {gBlankGfxCompressed, 0x0120, 0xd705},
+ {gBlankGfxCompressed, 0x0100, 0xd706},
+ {gBlankGfxCompressed, 0x0120, 0xd707}
};
static const struct SpritePalette gUnknown_0832C128[2] =
@@ -414,7 +415,7 @@ void InitAndLaunchChosenStatusAnimation(bool8 isStatus2, u32 status)
else if (status & STATUS2_NIGHTMARE)
LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_NIGHTMARE);
else if (status & STATUS2_WRAPPED)
- LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_WRAPPED);
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_WRAPPED); // this animation doesn't actually exist
else // no animation
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].statusAnimActive = 0;
}
@@ -448,7 +449,7 @@ bool8 TryHandleLaunchBattleTableAnimation(u8 activeBank, u8 atkBank, u8 defBank,
gAnimBankAttacker = atkBank;
gAnimBankTarget = defBank;
gBattleSpritesDataPtr->animationData->animArg = argument;
- LaunchBattleAnimation(gUnknown_082C9320, tableId, FALSE);
+ LaunchBattleAnimation(gBattleAnims_VariousTable, tableId, FALSE);
taskId = CreateTask(Task_ClearBitWhenBattleTableAnimDone, 10);
gTasks[taskId].tBank = activeBank;
gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].animFromTableActive = 1;
@@ -492,7 +493,7 @@ void InitAndLaunchSpecialAnimation(u8 activeBank, u8 atkBank, u8 defBank, u8 tab
gAnimBankAttacker = atkBank;
gAnimBankTarget = defBank;
- LaunchBattleAnimation(gUnknown_082C937C, tableId, FALSE);
+ LaunchBattleAnimation(gBattleAnims_Special, tableId, FALSE);
taskId = CreateTask(Task_ClearBitWhenSpecialAnimDone, 10);
gTasks[taskId].tBank = activeBank;
gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].specialAnimActive = 1;
@@ -526,8 +527,8 @@ bool8 mplay_80342A4(u8 bank)
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_8 < 30)
return TRUE;
- m4aMPlayStop(&gMPlay_SE1);
- m4aMPlayStop(&gMPlay_SE2);
+ m4aMPlayStop(&gMPlayInfo_SE1);
+ m4aMPlayStop(&gMPlayInfo_SE2);
}
if (zero == 0)
{
diff --git a/src/battle_interface.c b/src/battle_interface.c
index 95f1a1111..6a6bf00a2 100644
--- a/src/battle_interface.c
+++ b/src/battle_interface.c
@@ -177,7 +177,6 @@ extern const u16 gBattleInterface_BallDisplayPal[];
extern const u8 gHealthboxElementsGfxTable[][32];
// functions
-extern void AddTextPrinterParametrized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, struct TextColor *color, s8 speed, const u8 *str); // menu.h
extern void LoadBattleBarGfx(u8 arg0);
// this file's functions
diff --git a/src/battle_message.c b/src/battle_message.c
index ec1cfd626..e37a4c30c 100644
--- a/src/battle_message.c
+++ b/src/battle_message.c
@@ -12,6 +12,7 @@
#include "window.h"
#include "palette.h"
#include "battle_controllers.h"
+#include "battle_setup.h"
extern u16 gLastUsedItem;
extern u8 gLastUsedAbility;
@@ -54,8 +55,6 @@ extern void sub_81D5554(u8 *txtPtr, u16 trainerId); // pokenav
extern void GetEreaderTrainerName(u8 *txtPtr);
extern void sub_81A36D0(u8 arg0, u16 trainerId); // battle_frontier_2
extern void sub_81D572C(u8 arg0, u16 trainerId); // pokenav
-extern const u8* GetTrainer1LoseText(void); // battle_setup
-extern const u8* GetTrainer2LoseText(void); // battle_setup
extern void GetFrontierTrainerName(u8 *dst, u16 trainerId);
extern s32 GetStringCenterAlignXOffsetWithLetterSpacing(u8 fontId, const u8 *str, s32 totalWidth, s16 letterSpacing);
extern u8 GetTextSpeedInRecordedBattle(void);
@@ -485,8 +484,8 @@ const u8 gText_PkmnBrokeFree[] = _("Oh, no!\nThe POKéMON broke free!");
const u8 gText_ItAppearedCaught[] = _("Aww!\nIt appeared to be caught!");
const u8 gText_AarghAlmostHadIt[] = _("Aargh!\nAlmost had it!");
const u8 gText_ShootSoClose[] = _("Shoot!\nIt was so close, too!");
-const u8 gText_GotchaPkmnCaught[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{UNKNOWN_A}{PLAY_BGM BGM_KACHI22}\p");
-const u8 gText_GotchaPkmnCaught2[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{UNKNOWN_A}{PLAY_BGM BGM_KACHI22}{PAUSE 127}");
+const u8 gText_GotchaPkmnCaught[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{UNKNOWN_A}{PLAY_BGM MUS_KACHI22}\p");
+const u8 gText_GotchaPkmnCaught2[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{UNKNOWN_A}{PLAY_BGM MUS_KACHI22}{PAUSE 127}");
const u8 gText_GiveNicknameCaptured[] = _("Give a nickname to the\ncaptured {B_OPPONENT_MON1_NAME}?");
const u8 gText_PkmnSentToPC[] = _("{B_OPPONENT_MON1_NAME} was sent to\n{B_PC_CREATOR_NAME} PC.");
const u8 gText_Someones[] = _("someone’s");
@@ -1367,7 +1366,7 @@ static const u16 sUnknownMoveTable[] =
static const u8 sDummyWeirdStatusString[] = {EOS, EOS, EOS, EOS, EOS, EOS, EOS, EOS, 0, 0};
-static const u8 gUnknown_085CD42C[] =
+static const u8 sUnknown_085CD42C[] =
{
0xFF, 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x1, 0xF, 0x6, 0x0, 0x0, 0xFF, 0x1,
0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0xF, 0x6, 0x0, 0x0, 0xEE, 0x1, 0x0, 0x1, 0x0,
@@ -1392,7 +1391,7 @@ static const u8 gUnknown_085CD42C[] =
0x6, 0x0, 0x0, 0x0, 0x1, 0xFF, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x6, 0x0, 0x0
};
-static const u8 gUnknown_085CD54C[] =
+static const u8 sUnknown_085CD54C[] =
{
0xFF, 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x1, 0xF, 0x6, 0x0, 0x0, 0xFF, 0x1,
0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0xF, 0x6, 0x0, 0x0, 0xEE, 0x1, 0x0, 0x1, 0x0,
@@ -1419,7 +1418,7 @@ static const u8 gUnknown_085CD54C[] =
static const u8 * const gUnknown_085CD660[] =
{
- gUnknown_085CD42C, gUnknown_085CD54C
+ sUnknown_085CD42C, sUnknown_085CD54C
};
static const u8 sRecordedBattleTextSpeeds[] = {8, 4, 1, 0};
@@ -2068,7 +2067,7 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
}
else
{
- toCpy = GetTrainer1LoseText();
+ toCpy = GetTrainerALoseText();
}
break;
case B_TXT_TRAINER1_WIN_TEXT: // trainerA win text
@@ -2165,7 +2164,7 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
}
else
{
- toCpy = GetTrainer2LoseText();
+ toCpy = GetTrainerBLoseText();
}
break;
case B_TXT_TRAINER2_WIN_TEXT:
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index 88d583c1f..c7976fc2a 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -17,6 +17,8 @@
#include "battle_interface.h"
#include "constants/species.h"
#include "constants/songs.h"
+#include "constants/trainers.h"
+#include "constants/battle_anim.h"
#include "text.h"
#include "sound.h"
#include "pokedex.h"
@@ -110,7 +112,7 @@ extern u16 gBattle_BG1_Y;
extern u16 gBattle_BG2_X;
extern u16 gBattle_BG2_Y;
extern u16 gBattle_BG3_X;
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
struct TrainerMoney
{
@@ -6236,19 +6238,19 @@ static u32 GetTrainerMoneyToGive(u16 trainerId)
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
}
break;
- case PARTY_FLAG_CUSTOM_MOVES:
+ case F_TRAINER_PARTY_CUSTOM_MOVESET:
{
const struct TrainerMonNoItemCustomMoves *party = gTrainers[trainerId].party.NoItemCustomMoves;
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
}
break;
- case PARTY_FLAG_HAS_ITEM:
+ case F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemDefaultMoves *party = gTrainers[trainerId].party.ItemDefaultMoves;
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
}
break;
- case PARTY_FLAG_CUSTOM_MOVES | PARTY_FLAG_HAS_ITEM:
+ case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemCustomMoves *party = gTrainers[trainerId].party.ItemCustomMoves;
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
@@ -7101,10 +7103,10 @@ static void atk76_various(void)
}
break;
case 21:
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x55);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x55);
break;
case 22:
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
break;
case 23:
gBattleStruct->field_2A2 |= gBitTable[gActiveBank];
@@ -7120,7 +7122,7 @@ static void atk76_various(void)
gBattleOutcome = BATTLE_OPPONENT_TELEPORTED;
break;
case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC:
- EmitPlayFanfareOrBGM(0, BGM_KACHI1, TRUE);
+ EmitPlayFanfareOrBGM(0, MUS_KACHI1, TRUE);
MarkBufferBankForExecution(gActiveBank);
break;
}
@@ -10334,7 +10336,7 @@ static void atkE4_getsecretpowereffect(void)
case BATTLE_TERRAIN_POND:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_SPD_MINUS_1;
break;
- case BATTLE_TERRAIN_ROCK:
+ case BATTLE_TERRAIN_MOUNTAIN:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_CONFUSION;
break;
case BATTLE_TERRAIN_CAVE:
diff --git a/src/battle_setup.c b/src/battle_setup.c
new file mode 100644
index 000000000..6d7a97844
--- /dev/null
+++ b/src/battle_setup.c
@@ -0,0 +1,1881 @@
+#include "global.h"
+#include "constants/trainers.h"
+#include "battle.h"
+#include "battle_setup.h"
+#include "battle_transition.h"
+#include "main.h"
+#include "task.h"
+#include "pokemon_3.h"
+#include "safari_zone.h"
+#include "script.h"
+#include "constants/game_stat.h"
+#include "event_data.h"
+#include "constants/species.h"
+#include "constants/songs.h"
+#include "metatile_behavior.h"
+#include "constants/maps.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "random.h"
+#include "starter_choose.h"
+#include "script_pokemon_80F8.h"
+#include "constants/items.h"
+#include "palette.h"
+#include "window.h"
+#include "field_map_obj.h"
+#include "event_scripts.h"
+#include "trainer_see.h"
+#include "field_message_box.h"
+#include "sound.h"
+#include "strings.h"
+#include "secret_base.h"
+#include "string_util.h"
+
+enum
+{
+ TRAINER_PARAM_LOAD_VAL_8BIT,
+ TRAINER_PARAM_LOAD_VAL_16BIT,
+ TRAINER_PARAM_LOAD_VAL_32BIT,
+ TRAINER_PARAM_CLEAR_VAL_8BIT,
+ TRAINER_PARAM_CLEAR_VAL_16BIT,
+ TRAINER_PARAM_CLEAR_VAL_32BIT,
+ TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR,
+};
+
+struct TrainerBattleParameter
+{
+ void *varPtr;
+ u8 ptrType;
+};
+
+extern bool8 InBattlePyramid(void);
+extern bool8 InBattlePike(void);
+extern bool32 InTrainerHill(void);
+extern bool32 FieldPoisonEffectIsRunning(void);
+extern void overworld_free_bg_tilemaps(void);
+extern void prev_quest_postbuffer_cursor_backup_reset(void);
+extern void ResetPoisonStepCounter(void);
+extern void sub_81BE72C(void);
+extern void FreezeMapObjects(void);
+extern void sub_808BCF4(void);
+extern void sub_80EECC8(void);
+extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void);
+extern void c2_exit_to_overworld_2_switch(void);
+extern void Overworld_ClearSavedMusic(void);
+extern void CB2_WhiteOut(void);
+extern void sub_80AF6F0(void);
+extern void PlayBattleBGM(void);
+extern void sub_81DA57C(void);
+extern u8 GetSav1Weather(void);
+extern u8 Overworld_GetFlashLevel(void);
+extern u16 sub_81A9AA8(u8 localId);
+extern u16 sub_81D6180(u8 localId);
+extern bool8 GetBattlePyramidTrainerFlag(u8 mapObjId);
+extern bool8 GetTrainerHillTrainerFlag(u8 mapObjId);
+extern bool8 sub_81D5C18(void);
+extern void sub_816306C(u8 a0);
+extern void sub_8163048(u8 a0);
+extern void sub_81A9B04(void);
+extern void sub_81D639C(void);
+extern void sub_81D6384(void);
+extern void sub_81D61E8(void);
+extern void sub_80982B8(void);
+extern void sub_81A9EDC(u16 a0);
+extern void sub_81D572C(u8 a0, u16 arg1);
+extern void IncrementGameStat(u8 statId);
+extern u32 GetGameStat(u8 statId);
+
+extern u32 gBattleTypeFlags;
+extern u8 gBattleOutcome;
+extern void (*gFieldCallback)(void);
+
+// this file's functions
+static void DoBattlePikeWildBattle(void);
+static void DoSafariBattle(void);
+static void DoStandardWildBattle(void);
+static void CB2_EndWildBattle(void);
+static void CB2_EndScriptedWildBattle(void);
+static u8 GetWildBattleTransition(void);
+static u8 GetTrainerBattleTransition(void);
+static void sub_80B1218(void);
+static void sub_80B1234(void);
+static void CB2_GiveStarter(void);
+static void CB2_StartFirstBattle(void);
+static void CB2_EndFirstBattle(void);
+static void CB2_EndTrainerBattle(void);
+static bool32 IsPlayerDefeated(u32 battleOutcome);
+static u16 GetRematchTrainerId(u16 trainerId);
+static void RegisterTrainerInMatchCall(void);
+static void HandleRematchVarsOnBattleEnd(void);
+static const u8 *GetIntroSpeechOfApproachingTrainer(void);
+static const u8 *GetTrainerCantBattleSpeech(void);
+
+// ewram vars
+EWRAM_DATA static u16 sTrainerBattleMode = 0;
+EWRAM_DATA u16 gTrainerBattleOpponent_A = 0;
+EWRAM_DATA u16 gTrainerBattleOpponent_B = 0;
+EWRAM_DATA u16 gPartnerTrainerId = 0;
+EWRAM_DATA static u16 sTrainerMapObjectLocalId = 0;
+EWRAM_DATA static u8 *sTrainerAIntroSpeech = NULL;
+EWRAM_DATA static u8 *sTrainerBIntroSpeech = NULL;
+EWRAM_DATA static u8 *sTrainerADefeatSpeech = NULL;
+EWRAM_DATA static u8 *sTrainerBDefeatSpeech = NULL;
+EWRAM_DATA static u8 *sTrainerVictorySpeech = NULL;
+EWRAM_DATA static u8 *sTrainerCannotBattleSpeech = NULL;
+EWRAM_DATA static u8 *sTrainerBattleEndScript = NULL;
+EWRAM_DATA static u8 *sTrainerABattleScriptRetAddr = NULL;
+EWRAM_DATA static u8 *sTrainerBBattleScriptRetAddr = NULL;
+EWRAM_DATA static bool8 sShouldCheckTrainerBScript = FALSE;
+EWRAM_DATA static u8 sNoOfPossibleTrainerRetScripts = 0;
+
+// const rom data
+
+// The first transition is used if the enemy pokemon are lower level than our pokemon.
+// Otherwise, the second transition is used.
+static const u8 sBattleTransitionTable_Wild[][2] =
+{
+ {B_TRANSITION_SLICE, B_TRANSITION_WHITEFADE}, // Normal
+ {B_TRANSITION_CLOCKWISE_BLACKFADE, B_TRANSITION_GRID_SQUARES}, // Cave
+ {B_TRANSITION_BLUR, B_TRANSITION_GRID_SQUARES}, // Cave with flash used
+ {B_TRANSITION_WAVE, B_TRANSITION_RIPPLE}, // Water
+};
+
+static const u8 sBattleTransitionTable_Trainer[][2] =
+{
+ {B_TRANSITION_POKEBALLS_TRAIL, B_TRANSITION_SHARDS}, // Normal
+ {B_TRANSITION_SHUFFLE, B_TRANSITION_BIG_POKEBALL}, // Cave
+ {B_TRANSITION_BLUR, B_TRANSITION_GRID_SQUARES}, // Cave with flash used
+ {B_TRANSITION_SWIRL, B_TRANSITION_RIPPLE}, // Water
+};
+
+static const u8 sUnknown_0854FE98[] =
+{
+ B_TRANSITION_29, B_TRANSITION_30, B_TRANSITION_31, B_TRANSITION_32,
+ B_TRANSITION_34, B_TRANSITION_35, B_TRANSITION_36, B_TRANSITION_37,
+ B_TRANSITION_38, B_TRANSITION_39, B_TRANSITION_40, B_TRANSITION_41
+};
+
+static const u8 sUnknown_0854FEA4[] =
+{
+ B_TRANSITION_31, B_TRANSITION_32, B_TRANSITION_33
+};
+
+static const u8 sUnknown_0854FEA7[] =
+{
+ B_TRANSITION_29, B_TRANSITION_31, B_TRANSITION_32, B_TRANSITION_33
+};
+
+static const struct TrainerBattleParameter sOrdinaryBattleParams[] =
+{
+ {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT},
+ {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerMapObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerAIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerADefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerABattleScriptRetAddr, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR},
+};
+
+static const struct TrainerBattleParameter sContinueScriptBattleParams[] =
+{
+ {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT},
+ {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerMapObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerAIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerADefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerABattleScriptRetAddr, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR},
+};
+
+static const struct TrainerBattleParameter sDoubleBattleParams[] =
+{
+ {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT},
+ {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerMapObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerAIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerADefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerCannotBattleSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerABattleScriptRetAddr, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR},
+};
+
+static const struct TrainerBattleParameter sOrdinaryNoIntroBattleParams[] =
+{
+ {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT},
+ {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerMapObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerAIntroSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerADefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerABattleScriptRetAddr, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR},
+};
+
+static const struct TrainerBattleParameter sContinueScriptDoubleBattleParams[] =
+{
+ {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT},
+ {&gTrainerBattleOpponent_A, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerMapObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerAIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerADefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerCannotBattleSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerABattleScriptRetAddr, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR},
+};
+
+static const struct TrainerBattleParameter sTrainerBOrdinaryBattleParams[] =
+{
+ {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT},
+ {&gTrainerBattleOpponent_B, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerMapObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerBIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerBDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerBBattleScriptRetAddr, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR},
+};
+
+static const struct TrainerBattleParameter sTrainerBContinueScriptBattleParams[] =
+{
+ {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT},
+ {&gTrainerBattleOpponent_B, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerMapObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT},
+ {&sTrainerBIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerBDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT},
+ {&sTrainerBBattleScriptRetAddr, TRAINER_PARAM_LOAD_VAL_32BIT},
+ {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR},
+};
+
+const struct RematchTrainer gRematchTable[REMATCH_TABLE_ENTRIES] =
+{
+ {{0x0025, 0x0028, 0x0029, 0x002a, 0x002b}, 0x0000, 0x0021},
+ {{0x02e1, 0x032c, 0x032d, 0x032e, 0x032f}, 0x0000, 0x0014},
+ {{0x002c, 0x002f, 0x0030, 0x0031, 0x0032}, 0x0000, 0x001a},
+ {{0x0039, 0x003c, 0x003d, 0x003e, 0x003f}, 0x0000, 0x0018},
+ {{0x0040, 0x0043, 0x0044, 0x0045, 0x0046}, 0x0000, 0x0018},
+ {{0x02af, 0x02b0, 0x02b1, 0x02b2, 0x02b3}, 0x0000, 0x0027},
+ {{0x02ff, 0x033c, 0x033d, 0x033e, 0x033f}, 0x0000, 0x0024},
+ {{0x005e, 0x0065, 0x0066, 0x0067, 0x0068}, 0x0000, 0x001a},
+ {{0x004e, 0x0054, 0x0055, 0x0056, 0x0057}, 0x0000, 0x001a},
+ {{0x006c, 0x006e, 0x006f, 0x0070, 0x0071}, 0x0018, 0x0014},
+ {{0x0072, 0x0078, 0x0079, 0x007a, 0x007b}, 0x0000, 0x0013},
+ {{0x0090, 0x034c, 0x034d, 0x034e, 0x034f}, 0x0018, 0x0038},
+ {{0x007f, 0x0084, 0x0085, 0x0086, 0x0087}, 0x0000, 0x0024},
+ {{0x0088, 0x008b, 0x008c, 0x008d, 0x008e}, 0x0000, 0x0013},
+ {{0x008f, 0x0093, 0x0094, 0x0095, 0x0096}, 0x0000, 0x001d},
+ {{0x009b, 0x00af, 0x00b0, 0x00b1, 0x00b2}, 0x0000, 0x0016},
+ {{0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb}, 0x0000, 0x001e},
+ {{0x02a0, 0x0338, 0x0339, 0x033a, 0x033b}, 0x0000, 0x002a},
+ {{0x00c3, 0x0340, 0x0341, 0x0342, 0x0343}, 0x0000, 0x0026},
+ {{0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8}, 0x0000, 0x0021},
+ {{0x00ce, 0x00cf, 0x00d0, 0x00d1, 0x00d2}, 0x0000, 0x001d},
+ {{0x00d8, 0x00db, 0x00dc, 0x00dd, 0x00de}, 0x0018, 0x000d},
+ {{0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad}, 0x0018, 0x0001},
+ {{0x00e2, 0x00e4, 0x00e5, 0x00e6, 0x00e7}, 0x0000, 0x0023},
+ {{0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2}, 0x0000, 0x0026},
+ {{0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd}, 0x0000, 0x0026},
+ {{0x00fe, 0x0101, 0x0102, 0x0103, 0x0104}, 0x0000, 0x0024},
+ {{0x0118, 0x011a, 0x011b, 0x011c, 0x011d}, 0x0000, 0x001f},
+ {{0x0111, 0x0114, 0x0115, 0x0116, 0x0117}, 0x0000, 0x001f},
+ {{0x011f, 0x0120, 0x0121, 0x0122, 0x0123}, 0x0000, 0x0020},
+ {{0x012e, 0x012f, 0x0130, 0x0131, 0x0132}, 0x0000, 0x0019},
+ {{0x0125, 0x0127, 0x0128, 0x0129, 0x012a}, 0x0000, 0x0012},
+ {{0x0133, 0x0134, 0x0135, 0x0136, 0x0137}, 0x0000, 0x001e},
+ {{0x0139, 0x013a, 0x013b, 0x013c, 0x013d}, 0x0018, 0x000c},
+ {{0x013e, 0x0148, 0x0149, 0x014a, 0x014b}, 0x0000, 0x0011},
+ {{0x0153, 0x015a, 0x015b, 0x015c, 0x015d}, 0x0000, 0x0015},
+ {{0x0178, 0x017b, 0x017c, 0x017d, 0x017e}, 0x0000, 0x002b},
+ {{0x0171, 0x0172, 0x0173, 0x0174, 0x0175}, 0x0000, 0x0020},
+ {{0x0166, 0x0168, 0x0169, 0x016a, 0x016b}, 0x0000, 0x0019},
+ {{0x016c, 0x016d, 0x016e, 0x016f, 0x0170}, 0x0000, 0x0020},
+ {{0x0182, 0x0184, 0x0185, 0x0186, 0x0187}, 0x0000, 0x002b},
+ {{0x0161, 0x0162, 0x0163, 0x0164, 0x0165}, 0x0000, 0x0019},
+ {{0x0179, 0x0334, 0x0335, 0x0336, 0x0337}, 0x0000, 0x0029},
+ {{0x0188, 0x0189, 0x018a, 0x018b, 0x018c}, 0x0018, 0x0001},
+ {{0x0196, 0x0199, 0x019a, 0x019b, 0x019c}, 0x0000, 0x0023},
+ {{0x01a3, 0x01a5, 0x01a6, 0x01a7, 0x01a8}, 0x0000, 0x001c},
+ {{0x01ab, 0x01ae, 0x01af, 0x01b0, 0x01b1}, 0x0000, 0x001e},
+ {{0x01b2, 0x01b5, 0x01b6, 0x01b7, 0x01b8}, 0x0000, 0x001c},
+ {{0x01c1, 0x01d1, 0x01d2, 0x01d3, 0x01d4}, 0x0000, 0x0027},
+ {{0x01da, 0x01dd, 0x01de, 0x01df, 0x01e0}, 0x0018, 0x000d},
+ {{0x01e1, 0x01e2, 0x01e7, 0x01e8, 0x01e9}, 0x0000, 0x0012},
+ {{0x01ec, 0x01f1, 0x01f2, 0x01f3, 0x01f4}, 0x0000, 0x0028},
+ {{0x02e4, 0x0330, 0x0331, 0x0332, 0x0333}, 0x0000, 0x0017},
+ {{0x0200, 0x0203, 0x0204, 0x0205, 0x0206}, 0x0000, 0x0019},
+ {{0x0221, 0x0224, 0x0225, 0x0226, 0x0227}, 0x0000, 0x0020},
+ {{0x021a, 0x021d, 0x021e, 0x021f, 0x0220}, 0x0000, 0x0020},
+ {{0x0009, 0x0348, 0x0349, 0x034a, 0x034b}, 0x0018, 0x0011},
+ {{0x022f, 0x0232, 0x0233, 0x0234, 0x0235}, 0x0000, 0x0022},
+ {{0x0228, 0x022b, 0x022c, 0x022d, 0x022e}, 0x0000, 0x0022},
+ {{0x025c, 0x025f, 0x0260, 0x0261, 0x0262}, 0x0000, 0x0013},
+ {{0x026d, 0x026e, 0x026f, 0x0270, 0x0271}, 0x0018, 0x000b},
+ {{0x0273, 0x027c, 0x027d, 0x027e, 0x027f}, 0x0000, 0x001b},
+ {{0x0001, 0x0344, 0x0345, 0x0346, 0x0347}, 0x0018, 0x000c},
+ {{0x0282, 0x0283, 0x0284, 0x0285, 0x0286}, 0x0018, 0x003e},
+ {{0x0291, 0x0292, 0x0293, 0x0294, 0x0294}, 0x0018, 0x002b},
+ {{0x0109, 0x0302, 0x0303, 0x0304, 0x0305}, 0x0000, 0x0003},
+ {{0x010a, 0x0306, 0x0307, 0x0308, 0x0309}, 0x0000, 0x000b},
+ {{0x010b, 0x030a, 0x030b, 0x030c, 0x030d}, 0x0000, 0x0002},
+ {{0x010c, 0x030e, 0x030f, 0x0310, 0x0311}, 0x0000, 0x000c},
+ {{0x010d, 0x0312, 0x0313, 0x0314, 0x0315}, 0x0000, 0x0000},
+ {{0x010e, 0x0316, 0x0317, 0x0318, 0x0319}, 0x0000, 0x0004},
+ {{0x010f, 0x031a, 0x031b, 0x031c, 0x031d}, 0x0000, 0x0006},
+ {{0x0110, 0x031e, 0x031f, 0x0320, 0x0321}, 0x0000, 0x0007},
+ {{0x0105, 0x0105, 0x0105, 0x0105, 0x0105}, 0x0000, 0x0008},
+ {{0x0106, 0x0106, 0x0106, 0x0106, 0x0106}, 0x0000, 0x0008},
+ {{0x0107, 0x0107, 0x0107, 0x0107, 0x0107}, 0x0000, 0x0008},
+ {{0x0108, 0x0108, 0x0108, 0x0108, 0x0108}, 0x0000, 0x0008},
+ {{0x014f, 0x014f, 0x014f, 0x014f, 0x014f}, 0x0000, 0x0008},
+};
+
+static const u16 sBadgeFlags[8] =
+{
+ FLAG_BADGE01_GET, FLAG_BADGE02_GET, FLAG_BADGE03_GET, FLAG_BADGE04_GET,
+ FLAG_BADGE05_GET, FLAG_BADGE06_GET, FLAG_BADGE07_GET, FLAG_BADGE08_GET,
+};
+
+#define tState data[0]
+#define tTransition data[1]
+
+static void Task_BattleStart(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ switch (tState)
+ {
+ case 0:
+ if (!FieldPoisonEffectIsRunning()) // is poison not active?
+ {
+ BattleTransition_StartOnField(tTransition);
+ sub_81BE72C();
+ tState++; // go to case 1.
+ }
+ break;
+ case 1:
+ if (IsBattleTransitionDone() == TRUE)
+ {
+ overworld_free_bg_tilemaps();
+ SetMainCallback2(CB2_InitBattle);
+ prev_quest_postbuffer_cursor_backup_reset();
+ ResetPoisonStepCounter();
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+static void CreateBattleStartTask(u8 transition, u16 song)
+{
+ u8 taskId = CreateTask(Task_BattleStart, 1);
+
+ gTasks[taskId].tTransition = transition;
+ PlayMapChosenOrBattleBGM(song);
+}
+
+#undef tState
+#undef tTransition
+
+void BattleSetup_StartWildBattle(void)
+{
+ if (GetSafariZoneFlag())
+ DoSafariBattle();
+ else
+ DoStandardWildBattle();
+}
+
+void BattleSetup_StartBattlePikeWildBattle(void)
+{
+ DoBattlePikeWildBattle();
+}
+
+static void DoStandardWildBattle(void)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ sub_808BCF4();
+ gMain.savedCallback = CB2_EndWildBattle;
+ gBattleTypeFlags = 0;
+ if (InBattlePyramid())
+ {
+ VarSet(VAR_0x400E, 0);
+ gBattleTypeFlags |= BATTLE_TYPE_PYRAMID;
+ }
+ CreateBattleStartTask(GetWildBattleTransition(), 0);
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_WILD_BATTLES);
+ sub_80EECC8();
+ sub_80B1218();
+}
+
+void BattleSetup_StartRoamerBattle(void)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ sub_808BCF4();
+ gMain.savedCallback = CB2_EndWildBattle;
+ gBattleTypeFlags = BATTLE_TYPE_ROAMER;
+ CreateBattleStartTask(GetWildBattleTransition(), 0);
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_WILD_BATTLES);
+ sub_80EECC8();
+ sub_80B1218();
+}
+
+static void DoSafariBattle(void)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ sub_808BCF4();
+ gMain.savedCallback = CB2_EndSafariBattle;
+ gBattleTypeFlags = BATTLE_TYPE_SAFARI;
+ CreateBattleStartTask(GetWildBattleTransition(), 0);
+}
+
+static void DoBattlePikeWildBattle(void)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ sub_808BCF4();
+ gMain.savedCallback = CB2_EndWildBattle;
+ gBattleTypeFlags = BATTLE_TYPE_PIKE;
+ CreateBattleStartTask(GetWildBattleTransition(), 0);
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_WILD_BATTLES);
+ sub_80EECC8();
+ sub_80B1218();
+}
+
+static void DoTrainerBattle(void)
+{
+ CreateBattleStartTask(GetTrainerBattleTransition(), 0);
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_TRAINER_BATTLES);
+ sub_80B1234();
+}
+
+static void sub_80B0828(void)
+{
+ if (InBattlePyramid())
+ CreateBattleStartTask(sub_80B100C(10), 0);
+ else
+ CreateBattleStartTask(sub_80B100C(11), 0);
+
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_TRAINER_BATTLES);
+ sub_80B1234();
+}
+
+// Initiates battle where Wally catches Ralts
+void StartWallyTutorialBattle(void)
+{
+ CreateMaleMon(&gEnemyParty[0], SPECIES_RALTS, 5);
+ ScriptContext2_Enable();
+ gMain.savedCallback = c2_exit_to_overworld_1_continue_scripts_restart_music;
+ gBattleTypeFlags = BATTLE_TYPE_WALLY_TUTORIAL;
+ CreateBattleStartTask(B_TRANSITION_SLICE, 0);
+}
+
+void BattleSetup_StartScriptedWildBattle(void)
+{
+ ScriptContext2_Enable();
+ gMain.savedCallback = CB2_EndScriptedWildBattle;
+ gBattleTypeFlags = 0;
+ CreateBattleStartTask(GetWildBattleTransition(), 0);
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_WILD_BATTLES);
+ sub_80EECC8();
+ sub_80B1218();
+}
+
+void BattleSetup_StartLatiBattle(void)
+{
+ ScriptContext2_Enable();
+ gMain.savedCallback = CB2_EndScriptedWildBattle;
+ gBattleTypeFlags = BATTLE_TYPE_LEGENDARY;
+ CreateBattleStartTask(GetWildBattleTransition(), 0);
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_WILD_BATTLES);
+ sub_80EECC8();
+ sub_80B1218();
+}
+
+void BattleSetup_StartLegendaryBattle(void)
+{
+ ScriptContext2_Enable();
+ gMain.savedCallback = CB2_EndScriptedWildBattle;
+ gBattleTypeFlags = BATTLE_TYPE_LEGENDARY;
+
+ switch (GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL))
+ {
+ default:
+ case SPECIES_GROUDON:
+ gBattleTypeFlags |= BATTLE_TYPE_GROUDON;
+ CreateBattleStartTask(B_TRANSITION_GROUDON, MUS_BATTLE34);
+ break;
+ case SPECIES_KYOGRE:
+ gBattleTypeFlags |= BATTLE_TYPE_KYOGRE;
+ CreateBattleStartTask(B_TRANSITION_KYOGRE, MUS_BATTLE34);
+ break;
+ case SPECIES_RAYQUAZA:
+ gBattleTypeFlags |= BATTLE_TYPE_RAYQUAZA;
+ CreateBattleStartTask(B_TRANSITION_RAYQUAZA, MUS_VS_REKKU);
+ break;
+ case SPECIES_DEOXYS:
+ CreateBattleStartTask(B_TRANSITION_BLUR, MUS_RG_VS_DEO);
+ break;
+ case SPECIES_LUGIA:
+ case SPECIES_HO_OH:
+ CreateBattleStartTask(B_TRANSITION_BLUR, MUS_RG_VS_DEN);
+ break;
+ case SPECIES_MEW:
+ CreateBattleStartTask(B_TRANSITION_GRID_SQUARES, MUS_VS_MEW);
+ break;
+ }
+
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_WILD_BATTLES);
+ sub_80EECC8();
+ sub_80B1218();
+}
+
+void StartGroudonKyogreBattle(void)
+{
+ ScriptContext2_Enable();
+ gMain.savedCallback = CB2_EndScriptedWildBattle;
+ gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_KYOGRE_GROUDON;
+
+ if (gGameVersion == VERSION_RUBY)
+ CreateBattleStartTask(B_TRANSITION_SHARDS, MUS_BATTLE34); // GROUDON
+ else
+ CreateBattleStartTask(B_TRANSITION_RIPPLE, MUS_BATTLE34); // KYOGRE
+
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_WILD_BATTLES);
+ sub_80EECC8();
+ sub_80B1218();
+}
+
+void StartRegiBattle(void)
+{
+ u8 transitionId;
+ u16 species;
+
+ ScriptContext2_Enable();
+ gMain.savedCallback = CB2_EndScriptedWildBattle;
+ gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_REGI;
+
+ species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES);
+ switch (species)
+ {
+ case SPECIES_REGIROCK:
+ transitionId = B_TRANSITION_REGIROCK;
+ break;
+ case SPECIES_REGICE:
+ transitionId = B_TRANSITION_REGICE;
+ break;
+ case SPECIES_REGISTEEL:
+ transitionId = B_TRANSITION_REGISTEEL;
+ break;
+ default:
+ transitionId = B_TRANSITION_GRID_SQUARES;
+ break;
+ }
+ CreateBattleStartTask(transitionId, MUS_BATTLE36);
+
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_WILD_BATTLES);
+ sub_80EECC8();
+ sub_80B1218();
+}
+
+static void CB2_EndWildBattle(void)
+{
+ CpuFill16(0, (void*)(BG_PLTT), BG_PLTT_SIZE);
+ ResetOamRange(0, 128);
+
+ if (IsPlayerDefeated(gBattleOutcome) == TRUE && !InBattlePyramid() && !InBattlePike())
+ {
+ SetMainCallback2(CB2_WhiteOut);
+ }
+ else
+ {
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ gFieldCallback = sub_80AF6F0;
+ }
+}
+
+static void CB2_EndScriptedWildBattle(void)
+{
+ CpuFill16(0, (void*)(BG_PLTT), BG_PLTT_SIZE);
+ ResetOamRange(0, 128);
+
+ if (IsPlayerDefeated(gBattleOutcome) == TRUE)
+ {
+ if (InBattlePyramid())
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ else
+ SetMainCallback2(CB2_WhiteOut);
+ }
+ else
+ {
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ }
+}
+
+u8 BattleSetup_GetTerrainId(void)
+{
+ u16 tileBehavior;
+ s16 x, y;
+
+ PlayerGetDestCoords(&x, &y);
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+
+ if (MetatileBehavior_IsTallGrass(tileBehavior))
+ return BATTLE_TERRAIN_GRASS;
+ if (MetatileBehavior_IsLongGrass(tileBehavior))
+ return BATTLE_TERRAIN_LONG_GRASS;
+ if (MetatileBehavior_IsSandOrDeepSand(tileBehavior))
+ return BATTLE_TERRAIN_SAND;
+
+ switch (gMapHeader.mapType)
+ {
+ case MAP_TYPE_TOWN:
+ case MAP_TYPE_CITY:
+ case MAP_TYPE_ROUTE:
+ break;
+ case MAP_TYPE_UNDERGROUND:
+ if (MetatileBehavior_IsMB_0B(tileBehavior))
+ return BATTLE_TERRAIN_BUILDING;
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior))
+ return BATTLE_TERRAIN_POND;
+ return BATTLE_TERRAIN_CAVE;
+ case MAP_TYPE_INDOOR:
+ case MAP_TYPE_SECRET_BASE:
+ return BATTLE_TERRAIN_BUILDING;
+ case MAP_TYPE_UNDERWATER:
+ return BATTLE_TERRAIN_UNDERWATER;
+ case MAP_TYPE_6:
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior))
+ return BATTLE_TERRAIN_WATER;
+ return BATTLE_TERRAIN_PLAIN;
+ }
+ if (MetatileBehavior_IsDeepOrOceanWater(tileBehavior))
+ return BATTLE_TERRAIN_WATER;
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior))
+ return BATTLE_TERRAIN_POND;
+ if (MetatileBehavior_IsMountain(tileBehavior))
+ return BATTLE_TERRAIN_MOUNTAIN;
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ {
+ if (MetatileBehavior_GetBridgeSth(tileBehavior))
+ return BATTLE_TERRAIN_POND;
+ if (MetatileBehavior_IsBridge(tileBehavior) == TRUE)
+ return BATTLE_TERRAIN_WATER;
+ }
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE113) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE113))
+ return BATTLE_TERRAIN_SAND;
+ if (GetSav1Weather() == 8)
+ return BATTLE_TERRAIN_SAND;
+
+ return BATTLE_TERRAIN_PLAIN;
+}
+
+static u8 GetBattleTransitionTypeByMap(void)
+{
+ u16 tileBehavior;
+ s16 x, y;
+
+ PlayerGetDestCoords(&x, &y);
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (Overworld_GetFlashLevel())
+ return B_TRANSITION_SHUFFLE;
+ if (!MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior))
+ {
+ switch (gMapHeader.mapType)
+ {
+ case MAP_TYPE_UNDERGROUND:
+ return B_TRANSITION_SWIRL;
+ case MAP_TYPE_UNDERWATER:
+ return B_TRANSITION_BIG_POKEBALL;
+ default:
+ return B_TRANSITION_BLUR;
+ }
+ }
+ return B_TRANSITION_BIG_POKEBALL;
+}
+
+static u16 GetSumOfPlayerPartyLevel(u8 numMons)
+{
+ u8 sum = 0;
+ int i;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
+
+ if (species != SPECIES_EGG && species != SPECIES_NONE && GetMonData(&gPlayerParty[i], MON_DATA_HP) != 0)
+ {
+ sum += GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
+ if (--numMons == 0)
+ break;
+ }
+ }
+ return sum;
+}
+
+static u8 GetSumOfEnemyPartyLevel(u16 opponentId, u8 numMons)
+{
+ u8 i;
+ u8 sum;
+ u32 count = numMons;
+
+ if (gTrainers[opponentId].partySize < count)
+ count = gTrainers[opponentId].partySize;
+
+ sum = 0;
+
+ switch (gTrainers[opponentId].partyFlags)
+ {
+ case 0:
+ {
+ const struct TrainerMonNoItemDefaultMoves *party;
+ party = gTrainers[opponentId].party.NoItemDefaultMoves;
+ for (i = 0; i < count; i++)
+ sum += party[i].lvl;
+ }
+ break;
+ case F_TRAINER_PARTY_CUSTOM_MOVESET:
+ {
+ const struct TrainerMonNoItemCustomMoves *party;
+ party = gTrainers[opponentId].party.NoItemCustomMoves;
+ for (i = 0; i < count; i++)
+ sum += party[i].lvl;
+ }
+ break;
+ case F_TRAINER_PARTY_HELD_ITEM:
+ {
+ const struct TrainerMonItemDefaultMoves *party;
+ party = gTrainers[opponentId].party.ItemDefaultMoves;
+ for (i = 0; i < count; i++)
+ sum += party[i].lvl;
+ }
+ break;
+ case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
+ {
+ const struct TrainerMonItemCustomMoves *party;
+ party = gTrainers[opponentId].party.ItemCustomMoves;
+ for (i = 0; i < count; i++)
+ sum += party[i].lvl;
+ }
+ break;
+ }
+
+ return sum;
+}
+
+static u8 GetWildBattleTransition(void)
+{
+ u8 transitionType = GetBattleTransitionTypeByMap();
+ u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL);
+ u8 playerLevel = GetSumOfPlayerPartyLevel(1);
+
+ if (enemyLevel < playerLevel)
+ {
+ if (InBattlePyramid())
+ return B_TRANSITION_BLUR;
+ else
+ return sBattleTransitionTable_Wild[transitionType][0];
+ }
+ else
+ {
+ if (InBattlePyramid())
+ return B_TRANSITION_GRID_SQUARES;
+ else
+ return sBattleTransitionTable_Wild[transitionType][1];
+ }
+}
+
+static u8 GetTrainerBattleTransition(void)
+{
+ u8 minPartyCount;
+ u8 transitionType;
+ u8 enemyLevel;
+ u8 playerLevel;
+
+ if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
+ return B_TRANSITION_CHAMPION;
+
+ if (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_ELITE_FOUR)
+ {
+ if (gTrainerBattleOpponent_A == TRAINER_SIDNEY)
+ return B_TRANSITION_SYDNEY;
+ if (gTrainerBattleOpponent_A == TRAINER_PHOEBE)
+ return B_TRANSITION_PHOEBE;
+ if (gTrainerBattleOpponent_A == TRAINER_GLACIA)
+ return B_TRANSITION_GLACIA;
+ if (gTrainerBattleOpponent_A == TRAINER_DRAKE)
+ return B_TRANSITION_DRAKE;
+ return B_TRANSITION_CHAMPION;
+ }
+
+ if (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_CHAMPION)
+ return B_TRANSITION_CHAMPION;
+
+ if (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_TEAM_MAGMA
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_MAGMA_LEADER
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_MAGMA_ADMIN)
+ return B_TRANSITION_MAGMA;
+
+ if (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_TEAM_AQUA
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_AQUA_LEADER
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_AQUA_ADMIN)
+ return B_TRANSITION_AQUA;
+
+ if (gTrainers[gTrainerBattleOpponent_A].doubleBattle == TRUE)
+ minPartyCount = 2; // double battles always at least have 2 pokemon.
+ else
+ minPartyCount = 1;
+
+ transitionType = GetBattleTransitionTypeByMap();
+ enemyLevel = GetSumOfEnemyPartyLevel(gTrainerBattleOpponent_A, minPartyCount);
+ playerLevel = GetSumOfPlayerPartyLevel(minPartyCount);
+
+ if (enemyLevel < playerLevel)
+ return sBattleTransitionTable_Trainer[transitionType][0];
+ else
+ return sBattleTransitionTable_Trainer[transitionType][1];
+}
+
+u8 sub_80B100C(s32 arg0)
+{
+ u16 var;
+ u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL);
+ u8 playerLevel = GetSumOfPlayerPartyLevel(1);
+
+ if (enemyLevel < playerLevel)
+ {
+ switch (arg0)
+ {
+ case 11:
+ case 12:
+ case 13:
+ return B_TRANSITION_POKEBALLS_TRAIL;
+ case 10:
+ return sUnknown_0854FEA4[Random() % ARRAY_COUNT(sUnknown_0854FEA4)];
+ case 3:
+ return sUnknown_0854FEA7[Random() % ARRAY_COUNT(sUnknown_0854FEA7)];
+ }
+
+ if (VarGet(VAR_0x40CE) != 3)
+ return sUnknown_0854FE98[Random() % ARRAY_COUNT(sUnknown_0854FE98)];
+ }
+ else
+ {
+ switch (arg0)
+ {
+ case 11:
+ case 12:
+ case 13:
+ return B_TRANSITION_BIG_POKEBALL;
+ case 10:
+ return sUnknown_0854FEA4[Random() % ARRAY_COUNT(sUnknown_0854FEA4)];
+ case 3:
+ return sUnknown_0854FEA7[Random() % ARRAY_COUNT(sUnknown_0854FEA7)];
+ }
+
+ if (VarGet(VAR_0x40CE) != 3)
+ return sUnknown_0854FE98[Random() % ARRAY_COUNT(sUnknown_0854FE98)];
+ }
+
+ var = gSaveBlock2Ptr->field_CB4[gSaveBlock2Ptr->battlePyramidWildHeaderId * 2 + 0]
+ + gSaveBlock2Ptr->field_CB4[gSaveBlock2Ptr->battlePyramidWildHeaderId * 2 + 1];
+
+ return sUnknown_0854FE98[var % ARRAY_COUNT(sUnknown_0854FE98)];
+}
+
+void ChooseStarter(void)
+{
+ SetMainCallback2(CB2_ChooseStarter);
+ gMain.savedCallback = CB2_GiveStarter;
+}
+
+static void CB2_GiveStarter(void)
+{
+ u16 starterMon;
+
+ *GetVarPointer(VAR_FIRST_POKE) = gSpecialVar_Result;
+ starterMon = GetStarterPokemon(gSpecialVar_Result);
+ ScriptGiveMon(starterMon, 5, 0, 0, 0, 0);
+ ResetTasks();
+ PlayBattleBGM();
+ SetMainCallback2(CB2_StartFirstBattle);
+ BattleTransition_Start(B_TRANSITION_BLUR);
+}
+
+static void CB2_StartFirstBattle(void)
+{
+ UpdatePaletteFade();
+ RunTasks();
+
+ if (IsBattleTransitionDone() == TRUE)
+ {
+ gBattleTypeFlags = BATTLE_TYPE_FIRST_BATTLE;
+ gMain.savedCallback = CB2_EndFirstBattle;
+ FreeAllWindowBuffers();
+ SetMainCallback2(CB2_InitBattle);
+ prev_quest_postbuffer_cursor_backup_reset();
+ ResetPoisonStepCounter();
+ IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
+ IncrementGameStat(GAME_STAT_WILD_BATTLES);
+ sub_80EECC8();
+ sub_80B1218();
+ }
+}
+
+static void CB2_EndFirstBattle(void)
+{
+ Overworld_ClearSavedMusic();
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+}
+
+static void sub_80B1218(void)
+{
+ if (GetGameStat(GAME_STAT_WILD_BATTLES) % 60 == 0)
+ sub_81DA57C();
+}
+
+static void sub_80B1234(void)
+{
+ if (GetGameStat(GAME_STAT_TRAINER_BATTLES) % 20 == 0)
+ sub_81DA57C();
+}
+
+// why not just use the macros? maybe its because they didnt want to uncast const every time?
+static u32 TrainerBattleLoadArg32(const u8 *ptr)
+{
+ return T1_READ_32(ptr);
+}
+
+static u16 TrainerBattleLoadArg16(const u8 *ptr)
+{
+ return T1_READ_16(ptr);
+}
+
+static u8 TrainerBattleLoadArg8(const u8 *ptr)
+{
+ return T1_READ_8(ptr);
+}
+
+static u16 GetTrainerAFlag(void)
+{
+ return FLAG_TRAINER_FLAG_START + gTrainerBattleOpponent_A;
+}
+
+static u16 GetTrainerBFlag(void)
+{
+ return FLAG_TRAINER_FLAG_START + gTrainerBattleOpponent_B;
+}
+
+static bool32 IsPlayerDefeated(u32 battleOutcome)
+{
+ switch (battleOutcome)
+ {
+ case BATTLE_LOST:
+ case BATTLE_DREW:
+ return TRUE;
+ case BATTLE_WON:
+ case BATTLE_RAN:
+ case BATTLE_PLAYER_TELEPORTED:
+ case BATTLE_POKE_FLED:
+ case BATTLE_CAUGHT:
+ return FALSE;
+ default:
+ return FALSE;
+ }
+}
+
+void ResetTrainerOpponentIds(void)
+{
+ gTrainerBattleOpponent_A = 0;
+ gTrainerBattleOpponent_B = 0;
+}
+
+static void InitTrainerBattleVariables(void)
+{
+ sTrainerBattleMode = 0;
+ if (gApproachingTrainerId == 0)
+ {
+ sTrainerAIntroSpeech = NULL;
+ sTrainerADefeatSpeech = NULL;
+ sTrainerABattleScriptRetAddr = NULL;
+ }
+ else
+ {
+ sTrainerBIntroSpeech = NULL;
+ sTrainerBDefeatSpeech = NULL;
+ sTrainerBBattleScriptRetAddr = NULL;
+ }
+ sTrainerMapObjectLocalId = 0;
+ sTrainerVictorySpeech = NULL;
+ sTrainerCannotBattleSpeech = NULL;
+ sTrainerBattleEndScript = NULL;
+}
+
+static inline void SetU8(void *ptr, u8 value)
+{
+ *(u8*)(ptr) = value;
+}
+
+static inline void SetU16(void *ptr, u16 value)
+{
+ *(u16*)(ptr) = value;
+}
+
+static inline void SetU32(void *ptr, u32 value)
+{
+ *(u32*)(ptr) = value;
+}
+
+static inline void SetPtr(const void *ptr, const void* value)
+{
+ *(const void**)(ptr) = value;
+}
+
+static void TrainerBattleLoadArgs(const struct TrainerBattleParameter *specs, const u8 *data)
+{
+ while (1)
+ {
+ switch (specs->ptrType)
+ {
+ case TRAINER_PARAM_LOAD_VAL_8BIT:
+ SetU8(specs->varPtr, TrainerBattleLoadArg8(data));
+ data += 1;
+ break;
+ case TRAINER_PARAM_LOAD_VAL_16BIT:
+ SetU16(specs->varPtr, TrainerBattleLoadArg16(data));
+ data += 2;
+ break;
+ case TRAINER_PARAM_LOAD_VAL_32BIT:
+ SetU32(specs->varPtr, TrainerBattleLoadArg32(data));
+ data += 4;
+ break;
+ case TRAINER_PARAM_CLEAR_VAL_8BIT:
+ SetU8(specs->varPtr, 0);
+ break;
+ case TRAINER_PARAM_CLEAR_VAL_16BIT:
+ SetU16(specs->varPtr, 0);
+ break;
+ case TRAINER_PARAM_CLEAR_VAL_32BIT:
+ SetU32(specs->varPtr, 0);
+ break;
+ case TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR:
+ SetPtr(specs->varPtr, data);
+ return;
+ }
+ specs++;
+ }
+}
+
+void SetMapVarsToTrainer(void)
+{
+ if (sTrainerMapObjectLocalId != 0)
+ {
+ gSpecialVar_LastTalked = sTrainerMapObjectLocalId;
+ gSelectedMapObject = GetFieldObjectIdByLocalIdAndMap(sTrainerMapObjectLocalId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
+ }
+}
+
+const u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data)
+{
+ InitTrainerBattleVariables();
+ sTrainerBattleMode = TrainerBattleLoadArg8(data);
+
+ switch (sTrainerBattleMode)
+ {
+ case 3:
+ TrainerBattleLoadArgs(sOrdinaryNoIntroBattleParams, data);
+ return EventScript_2713C2;
+ case 4:
+ TrainerBattleLoadArgs(sDoubleBattleParams, data);
+ SetMapVarsToTrainer();
+ return EventScript_TryDoDoubleTrainerBattle;
+ case 2:
+ if (gApproachingTrainerId == 0)
+ {
+ TrainerBattleLoadArgs(sContinueScriptBattleParams, data);
+ SetMapVarsToTrainer();
+ }
+ else
+ {
+ TrainerBattleLoadArgs(sTrainerBContinueScriptBattleParams, data);
+ }
+ return EventScript_271362;
+ case 1:
+ TrainerBattleLoadArgs(sContinueScriptBattleParams, data);
+ SetMapVarsToTrainer();
+ return EventScript_271362;
+ case 6:
+ case 8:
+ TrainerBattleLoadArgs(sContinueScriptDoubleBattleParams, data);
+ SetMapVarsToTrainer();
+ return EventScript_TryDoDoubleTrainerBattle;
+ case 7:
+ TrainerBattleLoadArgs(sDoubleBattleParams, data);
+ SetMapVarsToTrainer();
+ gTrainerBattleOpponent_A = GetRematchTrainerId(gTrainerBattleOpponent_A);
+ return EventScript_TryDoDoubleRematchBattle;
+ case 5:
+ TrainerBattleLoadArgs(sOrdinaryBattleParams, data);
+ SetMapVarsToTrainer();
+ gTrainerBattleOpponent_A = GetRematchTrainerId(gTrainerBattleOpponent_A);
+ return EventScript_2713D1;
+ case 9:
+ if (gApproachingTrainerId == 0)
+ {
+ TrainerBattleLoadArgs(sOrdinaryBattleParams, data);
+ SetMapVarsToTrainer();
+ gTrainerBattleOpponent_A = sub_81A9AA8(gSpecialVar_LastTalked);
+ }
+ else
+ {
+ TrainerBattleLoadArgs(sTrainerBOrdinaryBattleParams, data);
+ gTrainerBattleOpponent_B = sub_81A9AA8(gSpecialVar_LastTalked);
+ }
+ return EventScript_271362;
+ case 10:
+ TrainerBattleLoadArgs(sOrdinaryBattleParams, data);
+ return NULL;
+ case 11:
+ TrainerBattleLoadArgs(sTrainerBOrdinaryBattleParams, data);
+ return NULL;
+ case 12:
+ if (gApproachingTrainerId == 0)
+ {
+ TrainerBattleLoadArgs(sOrdinaryBattleParams, data);
+ SetMapVarsToTrainer();
+ gTrainerBattleOpponent_A = sub_81D6180(gSpecialVar_LastTalked);
+ }
+ else
+ {
+ TrainerBattleLoadArgs(sTrainerBOrdinaryBattleParams, data);
+ gTrainerBattleOpponent_B = sub_81D6180(gSpecialVar_LastTalked);
+ }
+ return EventScript_271362;
+ default:
+ if (gApproachingTrainerId == 0)
+ {
+ TrainerBattleLoadArgs(sOrdinaryBattleParams, data);
+ SetMapVarsToTrainer();
+ }
+ else
+ {
+ TrainerBattleLoadArgs(sTrainerBOrdinaryBattleParams, data);
+ }
+ return EventScript_271362;
+ }
+}
+
+void ConfigureAndSetUpOneTrainerBattle(u8 trainerMapObjId, const u8 *trainerScript)
+{
+ gSelectedMapObject = trainerMapObjId;
+ gSpecialVar_LastTalked = gMapObjects[trainerMapObjId].localId;
+ BattleSetup_ConfigureTrainerBattle(trainerScript + 1);
+ ScriptContext1_SetupScript(EventScript_271354);
+ ScriptContext2_Enable();
+}
+
+void ConfigureTwoTrainersBattle(u8 trainerMapObjId, const u8 *trainerScript)
+{
+ gSelectedMapObject = trainerMapObjId;
+ gSpecialVar_LastTalked = gMapObjects[trainerMapObjId].localId;
+ BattleSetup_ConfigureTrainerBattle(trainerScript + 1);
+}
+
+void SetUpTwoTrainersBattle(void)
+{
+ ScriptContext1_SetupScript(EventScript_271354);
+ ScriptContext2_Enable();
+}
+
+bool32 GetTrainerFlagFromScriptPointer(const u8 *data)
+{
+ u32 flag = TrainerBattleLoadArg16(data + 2);
+ return FlagGet(FLAG_TRAINER_FLAG_START + flag);
+}
+
+void sub_80B16D8(void)
+{
+ struct MapObject *mapObject = &gMapObjects[gSelectedMapObject];
+
+ npc_set_running_behaviour_etc(mapObject, npc_running_behaviour_by_direction(mapObject->mapobj_unk_18));
+}
+
+u8 GetTrainerBattleMode(void)
+{
+ return sTrainerBattleMode;
+}
+
+bool8 GetTrainerFlag(void)
+{
+ if (InBattlePyramid())
+ return GetBattlePyramidTrainerFlag(gSelectedMapObject);
+ else if (InTrainerHill())
+ return GetTrainerHillTrainerFlag(gSelectedMapObject);
+ else
+ return FlagGet(GetTrainerAFlag());
+}
+
+static void SetBattledTrainersFlags(void)
+{
+ if (gTrainerBattleOpponent_B != 0)
+ FlagSet(GetTrainerBFlag());
+ FlagSet(GetTrainerAFlag());
+}
+
+static void SetBattledTrainerFlag(void)
+{
+ FlagSet(GetTrainerAFlag());
+}
+
+bool8 HasTrainerBeenFought(u16 trainerId)
+{
+ return FlagGet(FLAG_TRAINER_FLAG_START + trainerId);
+}
+
+void SetTrainerFlag(u16 trainerId)
+{
+ FlagSet(FLAG_TRAINER_FLAG_START + trainerId);
+}
+
+void ClearTrainerFlag(u16 trainerId)
+{
+ FlagClear(FLAG_TRAINER_FLAG_START + trainerId);
+}
+
+void BattleSetup_StartTrainerBattle(void)
+{
+ if (gNoOfApproachingTrainers == 2)
+ gBattleTypeFlags = (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_TRAINER);
+ else
+ gBattleTypeFlags = (BATTLE_TYPE_TRAINER);
+
+ if (InBattlePyramid())
+ {
+ VarSet(VAR_0x400E, 0);
+ gBattleTypeFlags |= BATTLE_TYPE_PYRAMID;
+
+ if (gNoOfApproachingTrainers == 2)
+ {
+ sub_816306C(1);
+ ZeroMonData(&gEnemyParty[1]);
+ ZeroMonData(&gEnemyParty[2]);
+ ZeroMonData(&gEnemyParty[4]);
+ ZeroMonData(&gEnemyParty[5]);
+ }
+ else
+ {
+ sub_8163048(1);
+ ZeroMonData(&gEnemyParty[1]);
+ ZeroMonData(&gEnemyParty[2]);
+ }
+
+ sub_81A9B04();
+ }
+ else if (sub_81D5C18())
+ {
+ gBattleTypeFlags |= BATTLE_TYPE_x4000000;
+
+ if (gNoOfApproachingTrainers == 2)
+ sub_81D639C();
+ else
+ sub_81D6384();
+
+ sub_81D61E8();
+ }
+
+ sNoOfPossibleTrainerRetScripts = gNoOfApproachingTrainers;
+ gNoOfApproachingTrainers = 0;
+ sShouldCheckTrainerBScript = FALSE;
+ gUnknown_03006080 = 0;
+ gMain.savedCallback = CB2_EndTrainerBattle;
+
+ if (InBattlePyramid() || sub_81D5C18())
+ sub_80B0828();
+ else
+ DoTrainerBattle();
+
+ ScriptContext1_Stop();
+}
+
+static void CB2_EndTrainerBattle(void)
+{
+ if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
+ {
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ }
+ else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
+ {
+ if (InBattlePyramid() || sub_81D5C18())
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ else
+ SetMainCallback2(CB2_WhiteOut);
+ }
+ else
+ {
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ if (!InBattlePyramid() && !sub_81D5C18())
+ {
+ RegisterTrainerInMatchCall();
+ SetBattledTrainersFlags();
+ }
+ }
+}
+
+static void CB2_EndRematchBattle(void)
+{
+ if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
+ {
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ }
+ else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
+ {
+ SetMainCallback2(CB2_WhiteOut);
+ }
+ else
+ {
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ RegisterTrainerInMatchCall();
+ SetBattledTrainersFlags();
+ HandleRematchVarsOnBattleEnd();
+ }
+}
+
+void BattleSetup_StartRematchBattle(void)
+{
+ gBattleTypeFlags = BATTLE_TYPE_TRAINER;
+ gMain.savedCallback = CB2_EndRematchBattle;
+ DoTrainerBattle();
+ ScriptContext1_Stop();
+}
+
+void ShowTrainerIntroSpeech(void)
+{
+ if (InBattlePyramid())
+ {
+ if (gNoOfApproachingTrainers == 0 || gNoOfApproachingTrainers == 1)
+ sub_81A9EDC(sub_81A9AA8(gSpecialVar_LastTalked));
+ else
+ sub_81A9EDC(sub_81A9AA8(gMapObjects[gApproachingTrainers[gApproachingTrainerId].mapObjectId].localId));
+
+ sub_80982B8();
+ }
+ else if (sub_81D5C18())
+ {
+ if (gNoOfApproachingTrainers == 0 || gNoOfApproachingTrainers == 1)
+ sub_81D572C(2, sub_81D6180(gSpecialVar_LastTalked));
+ else
+ sub_81D572C(2, sub_81D6180(gMapObjects[gApproachingTrainers[gApproachingTrainerId].mapObjectId].localId));
+
+ sub_80982B8();
+ }
+ else
+ {
+ ShowFieldMessage(GetIntroSpeechOfApproachingTrainer());
+ }
+}
+
+const u8 *BattleSetup_GetScriptAddrAfterBattle(void)
+{
+ if (sTrainerBattleEndScript != NULL)
+ return sTrainerBattleEndScript;
+ else
+ return EventScript_TestSignpostMsg;
+}
+
+const u8 *BattleSetup_GetTrainerPostBattleScript(void)
+{
+ if (sShouldCheckTrainerBScript)
+ {
+ sShouldCheckTrainerBScript = FALSE;
+ if (sTrainerBBattleScriptRetAddr != NULL)
+ {
+ gUnknown_03006080 = 1;
+ return sTrainerBBattleScriptRetAddr;
+ }
+ }
+ else
+ {
+ if (sTrainerABattleScriptRetAddr != NULL)
+ {
+ gUnknown_03006080 = 0;
+ return sTrainerABattleScriptRetAddr;
+ }
+ }
+
+ return EventScript_TryGetTrainerScript;
+}
+
+void ShowTrainerCantBattleSpeech(void)
+{
+ ShowFieldMessage(GetTrainerCantBattleSpeech());
+}
+
+void SetUpTrainerEncounterMusic(void)
+{
+ u16 trainerId;
+ u16 music;
+
+ if (gApproachingTrainerId == 0)
+ trainerId = gTrainerBattleOpponent_A;
+ else
+ trainerId = gTrainerBattleOpponent_B;
+
+ if (sTrainerBattleMode != TRAINER_BATTLE_CONTINUE_SCRIPT_NO_MUSIC
+ && sTrainerBattleMode != TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE_NO_MUSIC)
+ {
+ switch (GetTrainerEncounterMusicId(trainerId))
+ {
+ case TRAINER_ENCOUNTER_MUSIC_MALE:
+ music = MUS_BOYEYE;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_FEMALE:
+ music = MUS_GIRLEYE;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_GIRL:
+ music = MUS_SYOUJOEYE;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_INTENSE:
+ music = MUS_HAGESHII;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_COOL:
+ music = MUS_KAKKOII;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_AQUA:
+ music = MUS_AQA_0;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_MAGMA:
+ music = MUS_MGM0;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_SWIMMER:
+ music = MUS_SWIMEYE;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_TWINS:
+ music = MUS_HUTAGO;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR:
+ music = MUS_SITENNOU;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_HIKER:
+ music = MUS_YAMA_EYE;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_INTERVIEWER:
+ music = MUS_INTER_V;
+ break;
+ case TRAINER_ENCOUNTER_MUSIC_RICH:
+ music = MUS_TEST;
+ break;
+ default:
+ music = MUS_AYASII;
+ }
+ PlayNewMapMusic(music);
+ }
+}
+
+static const u8 *ReturnEmptyStringIfNull(const u8 *string)
+{
+ if (string == NULL)
+ return gText_EmptyString2;
+ else
+ return string;
+}
+
+static const u8 *GetIntroSpeechOfApproachingTrainer(void)
+{
+ if (gApproachingTrainerId == 0)
+ return ReturnEmptyStringIfNull(sTrainerAIntroSpeech);
+ else
+ return ReturnEmptyStringIfNull(sTrainerBIntroSpeech);
+}
+
+const u8 *GetTrainerALoseText(void)
+{
+ const u8 *string;
+
+ if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
+ string = GetSecretBaseTrainerLoseText();
+ else
+ string = sTrainerADefeatSpeech;
+
+ StringExpandPlaceholders(gStringVar4, ReturnEmptyStringIfNull(string));
+ return gStringVar4;
+}
+
+const u8 *GetTrainerBLoseText(void)
+{
+ StringExpandPlaceholders(gStringVar4, ReturnEmptyStringIfNull(sTrainerBDefeatSpeech));
+ return gStringVar4;
+}
+
+const u8 *GetTrainerWonSpeech(void)
+{
+ return ReturnEmptyStringIfNull(sTrainerVictorySpeech);
+}
+
+static const u8 *GetTrainerCantBattleSpeech(void)
+{
+ return ReturnEmptyStringIfNull(sTrainerCannotBattleSpeech);
+}
+
+static s32 FirstBattleTrainerIdToRematchTableId(const struct RematchTrainer *table, u16 trainerId)
+{
+ s32 i;
+
+ for (i = 0; i < REMATCH_TABLE_ENTRIES; i++)
+ {
+ if (table[i].trainerIds[0] == trainerId)
+ return i;
+ }
+
+ return -1;
+}
+
+static s32 TrainerIdToRematchTableId(const struct RematchTrainer *table, u16 trainerId)
+{
+ s32 i, j;
+
+ for (i = 0; i < REMATCH_TABLE_ENTRIES; i++)
+ {
+ for (j = 0; j < REMATCHES_COUNT; j++)
+ {
+ if (table[i].trainerIds[j] == 0)
+ break;
+ if (table[i].trainerIds[j] == trainerId)
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static bool32 sub_80B1D94(s32 rematchTableId)
+{
+ if (rematchTableId >= REMATCH_ELITE_FOUR_ENTRIES)
+ return TRUE;
+ else if (rematchTableId == REMATCH_WALLY_ENTRY)
+ return (FlagGet(FLAG_0x07E) == FALSE);
+ else
+ return FALSE;
+}
+
+static void SetRematchIdForTrainer(const struct RematchTrainer *table, u32 tableId)
+{
+ s32 i;
+
+ for (i = 1; i < REMATCHES_COUNT; i++)
+ {
+ u16 trainerId = table[tableId].trainerIds[i];
+
+ if (trainerId == 0)
+ break;
+ if (!HasTrainerBeenFought(trainerId))
+ break;
+ }
+
+ gSaveBlock1Ptr->trainerRematches[tableId] = i;
+}
+
+static bool32 UpdateRandomTrainerRematches(const struct RematchTrainer *table, u16 mapGroup, u16 mapNum)
+{
+ s32 i;
+ bool32 ret = FALSE;
+
+ for (i = 0; i <= REMATCH_WALLY_ENTRY; i++)
+ {
+ if (table[i].mapGroup == mapGroup && table[i].mapNum == mapNum && !sub_80B1D94(i))
+ {
+ if (gSaveBlock1Ptr->trainerRematches[i] != 0)
+ {
+ // Trainer already wants a rematch. Don't bother updating it
+ ret = TRUE;
+ }
+ else if (FlagGet(FLAG_MATCH_CALL_REGISTERED + i)
+ && (Random() % 100) <= 30) // 31% chance of getting a rematch
+ {
+ SetRematchIdForTrainer(table, i);
+ ret = TRUE;
+ }
+ }
+ }
+
+ return ret;
+}
+
+void UpdateRematchIfDefeated(s32 rematchTableId)
+{
+ if (HasTrainerBeenFought(gRematchTable[rematchTableId].trainerIds[0]) == TRUE)
+ SetRematchIdForTrainer(gRematchTable, rematchTableId);
+}
+
+static bool32 DoesSomeoneWantRematchIn_(const struct RematchTrainer *table, u16 mapGroup, u16 mapNum)
+{
+ s32 i;
+
+ for (i = 0; i < REMATCH_TABLE_ENTRIES; i++)
+ {
+ if (table[i].mapGroup == mapGroup && table[i].mapNum == mapNum && gSaveBlock1Ptr->trainerRematches[i] != 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool32 IsRematchTrainerIn_(const struct RematchTrainer *table, u16 mapGroup, u16 mapNum)
+{
+ s32 i;
+
+ for (i = 0; i < REMATCH_TABLE_ENTRIES; i++)
+ {
+ if (table[i].mapGroup == mapGroup && table[i].mapNum == mapNum)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 IsFirstTrainerIdReadyForRematch(const struct RematchTrainer *table, u16 firstBattleTrainerId)
+{
+ s32 tableId = FirstBattleTrainerIdToRematchTableId(table, firstBattleTrainerId);
+
+ if (tableId == -1)
+ return FALSE;
+ if (tableId >= 100)
+ return FALSE;
+ if (gSaveBlock1Ptr->trainerRematches[tableId] == 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bool8 IsTrainerReadyForRematch_(const struct RematchTrainer *table, u16 trainerId)
+{
+ s32 tableId = TrainerIdToRematchTableId(table, trainerId);
+
+ if (tableId == -1)
+ return FALSE;
+ if (tableId >= 100)
+ return FALSE;
+ if (gSaveBlock1Ptr->trainerRematches[tableId] == 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static u16 GetRematchTrainerIdFromTable(const struct RematchTrainer *table, u16 firstBattleTrainerId)
+{
+ const struct RematchTrainer *trainerEntry;
+ s32 i;
+ s32 tableId = FirstBattleTrainerIdToRematchTableId(table, firstBattleTrainerId);
+
+ if (tableId == -1)
+ return FALSE;
+
+ trainerEntry = &table[tableId];
+ for (i = 1; i < REMATCHES_COUNT; i++)
+ {
+ if (trainerEntry->trainerIds[i] == 0) // previous entry was this trainer's last one
+ return trainerEntry->trainerIds[i - 1];
+ if (!HasTrainerBeenFought(trainerEntry->trainerIds[i]))
+ return trainerEntry->trainerIds[i];
+ }
+
+ return trainerEntry->trainerIds[REMATCHES_COUNT - 1]; // already beaten at max stage
+}
+
+static u16 GetLastBeatenRematchTrainerIdFromTable(const struct RematchTrainer *table, u16 firstBattleTrainerId)
+{
+ const struct RematchTrainer *trainerEntry;
+ s32 i;
+ s32 tableId = FirstBattleTrainerIdToRematchTableId(table, firstBattleTrainerId);
+
+ if (tableId == -1)
+ return FALSE;
+
+ trainerEntry = &table[tableId];
+ for (i = 1; i < REMATCHES_COUNT; i++)
+ {
+ if (trainerEntry->trainerIds[i] == 0) // previous entry was this trainer's last one
+ return trainerEntry->trainerIds[i - 1];
+ if (!HasTrainerBeenFought(trainerEntry->trainerIds[i]))
+ return trainerEntry->trainerIds[i - 1];
+ }
+
+ return trainerEntry->trainerIds[REMATCHES_COUNT - 1]; // already beaten at max stage
+}
+
+static void ClearTrainerWantRematchState(const struct RematchTrainer *table, u16 firstBattleTrainerId)
+{
+ s32 tableId = TrainerIdToRematchTableId(table, firstBattleTrainerId);
+
+ if (tableId != -1)
+ gSaveBlock1Ptr->trainerRematches[tableId] = 0;
+}
+
+static u32 GetTrainerMatchCallFlag(u32 trainerId)
+{
+ s32 i;
+
+ for (i = 0; i < REMATCH_TABLE_ENTRIES; i++)
+ {
+ if (gRematchTable[i].trainerIds[0] == trainerId)
+ return FLAG_MATCH_CALL_REGISTERED + i;
+ }
+
+ return 0xFFFF;
+}
+
+static void RegisterTrainerInMatchCall(void)
+{
+ if (FlagGet(FLAG_HAS_MATCH_CALL))
+ {
+ u32 matchCallFlagId = GetTrainerMatchCallFlag(gTrainerBattleOpponent_A);
+ if (matchCallFlagId != 0xFFFF)
+ FlagSet(matchCallFlagId);
+ }
+}
+
+static bool8 WasSecondRematchWon(const struct RematchTrainer *table, u16 firstBattleTrainerId)
+{
+ s32 tableId = FirstBattleTrainerIdToRematchTableId(table, firstBattleTrainerId);
+
+ if (tableId == -1)
+ return FALSE;
+ if (!HasTrainerBeenFought(table[tableId].trainerIds[1]))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bool32 HasAtLeastFiveBadges(void)
+{
+ s32 i, count;
+
+ for (count = 0, i = 0; i < ARRAY_COUNT(sBadgeFlags); i++)
+ {
+ if (FlagGet(sBadgeFlags[i]) == TRUE)
+ {
+ if (++count >= 5)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+#define STEP_COUNTER_MAX 255
+
+void IncrementRematchStepCounter(void)
+{
+ if (HasAtLeastFiveBadges())
+ {
+ if (gSaveBlock1Ptr->trainerRematchStepCounter >= STEP_COUNTER_MAX)
+ gSaveBlock1Ptr->trainerRematchStepCounter = STEP_COUNTER_MAX;
+ else
+ gSaveBlock1Ptr->trainerRematchStepCounter++;
+ }
+}
+
+static bool32 IsRematchStepCounterMaxed(void)
+{
+ if (HasAtLeastFiveBadges() && gSaveBlock1Ptr->trainerRematchStepCounter >= STEP_COUNTER_MAX)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void TryUpdateRandomTrainerRematches(u16 mapGroup, u16 mapNum)
+{
+ if (IsRematchStepCounterMaxed() && UpdateRandomTrainerRematches(gRematchTable, mapGroup, mapNum) == TRUE)
+ gSaveBlock1Ptr->trainerRematchStepCounter = 0;
+}
+
+bool32 DoesSomeoneWantRematchIn(u16 mapGroup, u16 mapNum)
+{
+ return DoesSomeoneWantRematchIn_(gRematchTable, mapGroup, mapNum);
+}
+
+bool32 IsRematchTrainerIn(u16 mapGroup, u16 mapNum)
+{
+ return IsRematchTrainerIn_(gRematchTable, mapGroup, mapNum);
+}
+
+static u16 GetRematchTrainerId(u16 trainerId)
+{
+ return GetRematchTrainerIdFromTable(gRematchTable, trainerId);
+}
+
+u16 GetLastBeatenRematchTrainerId(u16 trainerId)
+{
+ return GetLastBeatenRematchTrainerIdFromTable(gRematchTable, trainerId);
+}
+
+bool8 ShouldTryRematchBattle(void)
+{
+ if (IsFirstTrainerIdReadyForRematch(gRematchTable, gTrainerBattleOpponent_A))
+ return TRUE;
+
+ return WasSecondRematchWon(gRematchTable, gTrainerBattleOpponent_A);
+}
+
+bool8 IsTrainerReadyForRematch(void)
+{
+ return IsTrainerReadyForRematch_(gRematchTable, gTrainerBattleOpponent_A);
+}
+
+static void HandleRematchVarsOnBattleEnd(void)
+{
+ ClearTrainerWantRematchState(gRematchTable, gTrainerBattleOpponent_A);
+ SetBattledTrainersFlags();
+}
+
+void ShouldTryGetTrainerScript(void)
+{
+ if (sNoOfPossibleTrainerRetScripts > 1)
+ {
+ sNoOfPossibleTrainerRetScripts = 0;
+ sShouldCheckTrainerBScript = TRUE;
+ gSpecialVar_Result = TRUE;
+ }
+ else
+ {
+ sShouldCheckTrainerBScript = FALSE;
+ gSpecialVar_Result = FALSE;
+ }
+}
+
+u16 CountBattledRematchTeams(u16 trainerId)
+{
+ s32 i;
+
+ if (HasTrainerBeenFought(gRematchTable[trainerId].trainerIds[0]) != TRUE)
+ return 0;
+
+ for (i = 1; i < REMATCHES_COUNT; i++)
+ {
+ if (gRematchTable[trainerId].trainerIds[i] == 0)
+ break;
+ if (!HasTrainerBeenFought(gRematchTable[trainerId].trainerIds[i]))
+ break;
+ }
+
+ return i;
+}
diff --git a/src/battle_transition.c b/src/battle_transition.c
new file mode 100644
index 000000000..ca2134837
--- /dev/null
+++ b/src/battle_transition.c
@@ -0,0 +1,4346 @@
+#include "global.h"
+#include "battle_transition.h"
+#include "unk_transition.h"
+#include "main.h"
+#include "overworld.h"
+#include "task.h"
+#include "palette.h"
+#include "trig.h"
+#include "field_effect.h"
+#include "field_camera.h"
+#include "random.h"
+#include "sprite.h"
+#include "sound.h"
+#include "constants/songs.h"
+#include "constants/trainers.h"
+#include "field_camera.h"
+#include "unknown_task.h"
+#include "malloc.h"
+#include "gpu_regs.h"
+#include "decompress.h"
+#include "bg.h"
+#include "blend_palette.h"
+
+struct TransitionData
+{
+ vu8 VBlank_DMA;
+ u16 WININ;
+ u16 WINOUT;
+ u16 WIN0H;
+ u16 WIN0V;
+ u16 field_A; // unused
+ u16 field_C; // unused
+ u16 BLDCNT;
+ u16 BLDALPHA;
+ u16 BLDY;
+ s16 field_14;
+ s16 field_16;
+ s16 BG0HOFS_1;
+ s16 BG0HOFS_2;
+ s16 BG0VOFS; // used but not set
+ s16 field_1E; // unused
+ s16 field_20;
+ s16 field_22; // unused
+ s16 data[11];
+};
+
+struct StructRectangularSpiral
+{
+ u8 field_0;
+ s16 field_2;
+ u8 field_4;
+ s16 field_6;
+ u8 field_8;
+};
+
+typedef bool8 (*TransitionStateFunc)(struct Task *task);
+typedef bool8 (*TransitionSpriteCallback)(struct Sprite *sprite);
+
+extern u16 gUnknown_020393A8[];
+extern u16 gUnknown_02038C28[][0x3C0];
+extern u16 gBattle_BG0_X;
+extern u16 gBattle_BG0_Y;
+
+extern const struct OamData gFieldObjectBaseOam_32x32;
+
+extern void c2_exit_to_overworld_2_switch(void);
+extern void sub_80AC3D0(void);
+extern void dp12_8087EA4(void);
+
+// this file's functions
+static void LaunchBattleTransitionTask(u8 transitionId);
+static void Task_BattleTransitionMain(u8 taskId);
+static void Phase1Task_TransitionAll(u8 taskId);
+static void Phase2Task_Blur(u8 taskId);
+static void Phase2Task_Swirl(u8 taskId);
+static void Phase2Task_Shuffle(u8 taskId);
+static void Phase2Task_BigPokeball(u8 taskId);
+static void Phase2Task_PokeballsTrail(u8 taskId);
+static void Phase2Task_Clockwise_BlackFade(u8 taskId);
+static void Phase2Task_Ripple(u8 taskId);
+static void Phase2Task_Wave(u8 taskId);
+static void Phase2Task_Slice(u8 taskId);
+static void Phase2Task_WhiteFade(u8 taskId);
+static void Phase2Task_GridSquares(u8 taskId);
+static void Phase2Task_Shards(u8 taskId);
+static void Phase2Task_Sydney(u8 taskId);
+static void Phase2Task_Phoebe(u8 taskId);
+static void Phase2Task_Glacia(u8 taskId);
+static void Phase2Task_Drake(u8 taskId);
+static void Phase2Task_Champion(u8 taskId);
+static void Phase2Task_Aqua(u8 taskId);
+static void Phase2Task_Magma(u8 taskId);
+static void Phase2Task_Regice(u8 taskId);
+static void Phase2Task_Registeel(u8 taskId);
+static void Phase2Task_Regirock(u8 taskId);
+static void Phase2Task_Kyogre(u8 taskId);
+static void Phase2Task_Groudon(u8 taskId);
+static void Phase2Task_Rayquaza(u8 taskId);
+static void Phase2Task_ShredSplit(u8 taskId);
+static void Phase2Task_Blackhole1(u8 taskId);
+static void Phase2Task_Blackhole2(u8 taskId);
+static void Phase2Task_RectangularSpiral(u8 taskId);
+static void Phase2Task_29(u8 taskId);
+static void Phase2Task_30(u8 taskId);
+static void Phase2Task_31(u8 taskId);
+static void Phase2Task_32(u8 taskId);
+static void Phase2Task_33(u8 taskId);
+static void VBlankCB_BattleTransition(void);
+static void VBlankCB_Phase2_Swirl(void);
+static void HBlankCB_Phase2_Swirl(void);
+static void VBlankCB_Phase2_Shuffle(void);
+static void HBlankCB_Phase2_Shuffle(void);
+static void VBlankCB0_Phase2_BigPokeball(void);
+static void VBlankCB1_Phase2_BigPokeball(void);
+static void VBlankCB_Phase2_Clockwise_BlackFade(void);
+static void VBlankCB_Phase2_Ripple(void);
+static void HBlankCB_Phase2_Ripple(void);
+static void VBlankCB_Phase2_30(void);
+static void HBlankCB_Phase2_30(void);
+static void VBlankCB_Phase2_Wave(void);
+static void VBlankCB_Phase2_Slice(void);
+static void HBlankCB_Phase2_Slice(void);
+static void VBlankCB0_Phase2_WhiteFade(void);
+static void VBlankCB1_Phase2_WhiteFade(void);
+static void HBlankCB_Phase2_WhiteFade(void);
+static void VBlankCB_Phase2_Shards(void);
+static void VBlankCB_Phase2_Rayquaza(void);
+static bool8 Phase2_Blur_Func1(struct Task *task);
+static bool8 Phase2_Blur_Func2(struct Task *task);
+static bool8 Phase2_Blur_Func3(struct Task *task);
+static bool8 Phase2_Swirl_Func1(struct Task *task);
+static bool8 Phase2_Swirl_Func2(struct Task *task);
+static bool8 Phase2_Shuffle_Func1(struct Task *task);
+static bool8 Phase2_Shuffle_Func2(struct Task *task);
+static bool8 Phase2_Aqua_Func1(struct Task *task);
+static bool8 Phase2_Aqua_Func2(struct Task *task);
+static bool8 Phase2_Magma_Func1(struct Task *task);
+static bool8 Phase2_Magma_Func2(struct Task *task);
+static bool8 Phase2_FramesCountdown(struct Task *task);
+static bool8 Phase2_Regi_Func1(struct Task *task);
+static bool8 Phase2_Regice_Func2(struct Task *task);
+static bool8 Phase2_Registeel_Func2(struct Task *task);
+static bool8 Phase2_Regirock_Func2(struct Task *task);
+static bool8 Phase2_WeatherTrio_Func1(struct Task *task);
+static bool8 Phase2_WaitPaletteFade(struct Task *task);
+static bool8 Phase2_Kyogre_Func3(struct Task *task);
+static bool8 Phase2_Kyogre_Func4(struct Task *task);
+static bool8 Phase2_Kyogre_Func5(struct Task *task);
+static bool8 Phase2_Groudon_Func3(struct Task *task);
+static bool8 Phase2_Groudon_Func4(struct Task *task);
+static bool8 Phase2_Groudon_Func5(struct Task *task);
+static bool8 Phase2_WeatherDuo_Func6(struct Task *task);
+static bool8 Phase2_WeatherDuo_Func7(struct Task *task);
+static bool8 Phase2_BigPokeball_Func1(struct Task *task);
+static bool8 Phase2_BigPokeball_Func2(struct Task *task);
+static bool8 Phase2_BigPokeball_Func3(struct Task *task);
+static bool8 Phase2_BigPokeball_Func4(struct Task *task);
+static bool8 Phase2_BigPokeball_Func5(struct Task *task);
+static bool8 Phase2_BigPokeball_Func6(struct Task *task);
+static bool8 Phase2_PokeballsTrail_Func1(struct Task *task);
+static bool8 Phase2_PokeballsTrail_Func2(struct Task *task);
+static bool8 Phase2_PokeballsTrail_Func3(struct Task *task);
+static bool8 Phase2_Clockwise_BlackFade_Func1(struct Task *task);
+static bool8 Phase2_Clockwise_BlackFade_Func2(struct Task *task);
+static bool8 Phase2_Clockwise_BlackFade_Func3(struct Task *task);
+static bool8 Phase2_Clockwise_BlackFade_Func4(struct Task *task);
+static bool8 Phase2_Clockwise_BlackFade_Func5(struct Task *task);
+static bool8 Phase2_Clockwise_BlackFade_Func6(struct Task *task);
+static bool8 Phase2_Clockwise_BlackFade_Func7(struct Task *task);
+static bool8 Phase2_Ripple_Func1(struct Task *task);
+static bool8 Phase2_Ripple_Func2(struct Task *task);
+static bool8 Phase2_Wave_Func1(struct Task *task);
+static bool8 Phase2_Wave_Func2(struct Task *task);
+static bool8 Phase2_Wave_Func3(struct Task *task);
+static bool8 Phase2_Slice_Func1(struct Task *task);
+static bool8 Phase2_Slice_Func2(struct Task *task);
+static bool8 Phase2_Slice_Func3(struct Task *task);
+static bool8 Phase2_WhiteFade_Func1(struct Task *task);
+static bool8 Phase2_WhiteFade_Func2(struct Task *task);
+static bool8 Phase2_WhiteFade_Func3(struct Task *task);
+static bool8 Phase2_WhiteFade_Func4(struct Task *task);
+static bool8 Phase2_WhiteFade_Func5(struct Task *task);
+static bool8 Phase2_GridSquares_Func1(struct Task *task);
+static bool8 Phase2_GridSquares_Func2(struct Task *task);
+static bool8 Phase2_GridSquares_Func3(struct Task *task);
+static bool8 Phase2_Shards_Func1(struct Task *task);
+static bool8 Phase2_Shards_Func2(struct Task *task);
+static bool8 Phase2_Shards_Func3(struct Task *task);
+static bool8 Phase2_Shards_Func4(struct Task *task);
+static bool8 Phase2_Shards_Func5(struct Task *task);
+static bool8 Phase2_ShredSplit_Func1(struct Task *task);
+static bool8 Phase2_ShredSplit_Func2(struct Task *task);
+static bool8 Phase2_ShredSplit_Func3(struct Task *task);
+static bool8 Phase2_ShredSplit_Func4(struct Task *task);
+static bool8 Phase2_Blackhole_Func1(struct Task *task);
+static bool8 Phase2_Blackhole1_Func2(struct Task *task);
+static bool8 Phase2_Blackhole1_Func3(struct Task *task);
+static bool8 Phase2_Blackhole2_Func2(struct Task *task);
+static bool8 Phase2_RectangularSpiral_Func1(struct Task *task);
+static bool8 Phase2_RectangularSpiral_Func2(struct Task *task);
+static bool8 Phase2_RectangularSpiral_Func3(struct Task *task);
+static bool8 Phase2_29_Func1(struct Task *task);
+static bool8 Phase2_29_Func2(struct Task *task);
+static bool8 Phase2_30_Func1(struct Task *task);
+static bool8 Phase2_30_Func2(struct Task *task);
+static bool8 Phase2_30_Func3(struct Task *task);
+static bool8 Phase2_30_Func4(struct Task *task);
+static bool8 Phase2_Rayquaza_Func3(struct Task *task);
+static bool8 Phase2_Rayquaza_Func4(struct Task *task);
+static bool8 Phase2_Rayquaza_Func5(struct Task *task);
+static bool8 Phase2_Rayquaza_Func6(struct Task *task);
+static bool8 Phase2_Rayquaza_Func7(struct Task *task);
+static bool8 Phase2_Rayquaza_Func8(struct Task *task);
+static bool8 Phase2_Rayquaza_Func9(struct Task *task);
+static bool8 Phase2_31_Func1(struct Task *task);
+static bool8 Phase2_31_Func2(struct Task *task);
+static bool8 Phase2_31_Func3(struct Task *task);
+static bool8 Phase2_31_33_Func5(struct Task *task);
+static bool8 Phase2_33_Func1(struct Task *task);
+static bool8 Phase2_33_Func2(struct Task *task);
+static bool8 Phase2_33_Func3(struct Task *task);
+static bool8 Phase2_33_Func4(struct Task *task);
+static bool8 Phase2_32_Func1(struct Task *task);
+static bool8 Phase2_32_Func2(struct Task *task);
+static bool8 Phase2_32_Func3(struct Task *task);
+static bool8 Phase2_32_Func4(struct Task *task);
+static bool8 Phase2_32_Func5(struct Task *task);
+static bool8 Phase2_Mugshot_Func1(struct Task *task);
+static bool8 Phase2_Mugshot_Func2(struct Task *task);
+static bool8 Phase2_Mugshot_Func3(struct Task *task);
+static bool8 Phase2_Mugshot_Func4(struct Task *task);
+static bool8 Phase2_Mugshot_Func5(struct Task *task);
+static bool8 Phase2_Mugshot_Func6(struct Task *task);
+static bool8 Phase2_Mugshot_Func7(struct Task *task);
+static bool8 Phase2_Mugshot_Func8(struct Task *task);
+static bool8 Phase2_Mugshot_Func9(struct Task *task);
+static bool8 Phase2_Mugshot_Func10(struct Task *task);
+static void Phase2Task_MugShotTransition(u8 taskId);
+static void Mugshots_CreateOpponentPlayerSprites(struct Task *task);
+static void VBlankCB0_Phase2_Mugshots(void);
+static void VBlankCB1_Phase2_Mugshots(void);
+static void HBlankCB_Phase2_Mugshots(void);
+static bool8 Transition_Phase1(struct Task *task);
+static bool8 Transition_WaitForPhase1(struct Task *task);
+static bool8 Transition_Phase2(struct Task *task);
+static bool8 Transition_WaitForPhase2(struct Task *task);
+static void sub_8149F08(void);
+static void sub_8149F84(void);
+static void CreatePhase1Task(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4);
+static void sub_814A014(u16 *a0, s16 a1, s16 a2, s16 a3);
+static void sub_8149F98(s16 *array, s16 sinAdd, s16 index, s16 indexIncrementer, s16 amplitude, s16 arrSize);
+static void sub_8149F40(u16 **a0);
+static void sub_814A1AC(s16 *a0, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6);
+static bool8 sub_814A228(s16 *a0, bool8 a1, bool8 a2);
+static void sub_8148484(s16 spriteId, s16 value);
+static void sub_814849C(s16 spriteId);
+static s16 sub_81484B8(s16 spriteId);
+static bool8 Phase1_TransitionAll_Func1(struct Task *task);
+static bool8 Phase1_TransitionAll_Func2(struct Task *task);
+static bool8 IsPhase1Done(void);
+static bool16 sub_8149048(const s16 * const *arg0, struct StructRectangularSpiral *arg1);
+static void sub_814713C(struct Sprite *sprite);
+static void sub_8148380(struct Sprite *sprite);
+static void sub_8149864(struct Sprite *sprite);
+static bool8 sub_81483A8(struct Sprite *sprite);
+static bool8 sub_81483AC(struct Sprite *sprite);
+static bool8 sub_81483F8(struct Sprite *sprite);
+static bool8 sub_814842C(struct Sprite *sprite);
+static bool8 sub_8148458(struct Sprite *sprite);
+
+// iwram bss vars
+IWRAM_DATA static s16 sUnusedRectangularSpiralVar;
+IWRAM_DATA static u8 sTestingTransitionId;
+IWRAM_DATA static u8 sTestingTransitionState;
+IWRAM_DATA static struct StructRectangularSpiral sRectangularSpiralTransition[4];
+
+// ewram vars
+EWRAM_DATA static struct TransitionData *sTransitionStructPtr = NULL;
+
+// const rom data
+static const u32 sBigPokeball_Tileset[] = INCBIN_U32("graphics/battle_transitions/big_pokeball.4bpp");
+static const u32 sPokeballTrail_Tileset[] = INCBIN_U32("graphics/battle_transitions/pokeball_trail.4bpp");
+static const u8 sSpriteImage_85B98F0[] = INCBIN_U8("graphics/battle_transitions/pokeball.4bpp");
+static const u32 sUnknown_085B9AF0[] = INCBIN_U32("graphics/battle_transitions/elite_four_bg.4bpp");
+static const u8 sSpriteImage_85B9CD0[] = INCBIN_U8("graphics/battle_transitions/unused_brendan.4bpp");
+static const u8 sSpriteImage_85BA4D0[] = INCBIN_U8("graphics/battle_transitions/unused_lass.4bpp");
+static const u32 sShrinkingBoxTileset[] = INCBIN_U32("graphics/battle_transitions/shrinking_box.4bpp");
+static const u32 sEvilTeam_Palette[] = INCBIN_U32("graphics/battle_transitions/evil_team.gbapal");
+static const u32 sTeamAqua_Tileset[] = INCBIN_U32("graphics/battle_transitions/team_aqua.4bpp.lz");
+static const u32 sTeamAqua_Tilemap[] = INCBIN_U32("graphics/battle_transitions/team_aqua.bin.lz");
+static const u32 sTeamMagma_Tileset[] = INCBIN_U32("graphics/battle_transitions/team_magma.4bpp.lz");
+static const u32 sTeamMagma_Tilemap[] = INCBIN_U32("graphics/battle_transitions/team_magma.bin.lz");
+static const u32 gUnknown_085BBC14[] = INCBIN_U32("graphics/battle_transitions/85BBC14.4bpp");
+static const u32 gUnknown_085BC2B4[] = INCBIN_U32("graphics/battle_transitions/85BC2B4.gbapal");
+static const u32 gUnknown_085BC2D4[] = INCBIN_U32("graphics/battle_transitions/85BC2D4.gbapal");
+static const u32 gUnknown_085BC2F4[] = INCBIN_U32("graphics/battle_transitions/85BC2F4.gbapal");
+static const u32 gUnknown_085BC314[] = INCBIN_U32("graphics/battle_transitions/85BC314.bin");
+static const u32 gUnknown_085BCB14[] = INCBIN_U32("graphics/battle_transitions/85BCB14.bin");
+static const u32 gUnknown_085BD314[] = INCBIN_U32("graphics/battle_transitions/85BD314.bin");
+static const u16 gUnknown_085BDB14[] = INCBIN_U16("graphics/battle_transitions/85BDB14.gbapal");
+static const u32 gUnknown_085BDB34[] = INCBIN_U32("graphics/battle_transitions/kyogre.4bpp.lz");
+static const u32 gUnknown_085BE1E8[] = INCBIN_U32("graphics/battle_transitions/kyogre.bin.lz");
+static const u32 gUnknown_085BE51C[] = INCBIN_U32("graphics/battle_transitions/groudon.4bpp.lz");
+static const u32 gUnknown_085BEA88[] = INCBIN_U32("graphics/battle_transitions/groudon.bin.lz");
+static const u16 gUnknown_085BEDA0[] = INCBIN_U16("graphics/battle_transitions/kyogre_pt1.gbapal");
+static const u16 gUnknown_085BEEE0[] = INCBIN_U16("graphics/battle_transitions/kyogre_pt2.gbapal");
+static const u16 gUnknown_085BF0A0[] = INCBIN_U16("graphics/battle_transitions/groudon_pt1.gbapal");
+static const u16 gUnknown_085BF2A0[] = INCBIN_U16("graphics/battle_transitions/groudon_pt2.gbapal");
+static const u16 gUnknown_085BF4A0[] = INCBIN_U16("graphics/battle_transitions/rayquaza.gbapal");
+static const u32 gUnknown_085BF6A0[] = INCBIN_U32("graphics/battle_transitions/rayquaza.4bpp");
+static const u32 gUnknown_085C6BE0[] = INCBIN_U32("graphics/battle_transitions/rayquaza.bin");
+static const u32 gUnknown_085C7BE0[] = INCBIN_U32("graphics/battle_transitions/frontier_brain.gbapal");
+static const u32 gUnknown_085C7C00[] = INCBIN_U32("graphics/battle_transitions/frontier_brain.4bpp.lz");
+static const u32 gUnknown_085C828C[] = INCBIN_U32("graphics/battle_transitions/frontier_brain.bin.lz");
+static const u32 gUnknown_085C8578[] = INCBIN_U32("graphics/battle_transitions/frontier_squares_blanktiles.gbapal");
+static const u32 gUnknown_085C8598[] = INCBIN_U32("graphics/battle_transitions/frontier_square_1.4bpp.lz");
+static const u32 gUnknown_085C86F4[] = INCBIN_U32("graphics/battle_transitions/frontier_square_2.4bpp.lz");
+static const u32 gUnknown_085C87F4[] = INCBIN_U32("graphics/battle_transitions/frontier_square_3.4bpp.lz");
+static const u32 gUnknown_085C88A4[] = INCBIN_U32("graphics/battle_transitions/frontier_square_4.4bpp.lz");
+static const u32 gUnknown_085C8928[] = INCBIN_U32("graphics/battle_transitions/frontier_squares.bin");
+
+static const TaskFunc sPhase1_Tasks[B_TRANSITION_COUNT] =
+{
+ [0 ... B_TRANSITION_COUNT - 1] = &Phase1Task_TransitionAll
+};
+
+static const TaskFunc sPhase2_Tasks[B_TRANSITION_COUNT] =
+{
+ Phase2Task_Blur, // 0
+ Phase2Task_Swirl, // 1
+ Phase2Task_Shuffle, // 2
+ Phase2Task_BigPokeball, // 3
+ Phase2Task_PokeballsTrail, // 4
+ Phase2Task_Clockwise_BlackFade, // 5
+ Phase2Task_Ripple, // 6
+ Phase2Task_Wave, // 7
+ Phase2Task_Slice, // 8
+ Phase2Task_WhiteFade, // 9
+ Phase2Task_GridSquares, // 10
+ Phase2Task_Shards, // 11
+ Phase2Task_Sydney, // 12
+ Phase2Task_Phoebe, // 13
+ Phase2Task_Glacia, // 14
+ Phase2Task_Drake, // 15
+ Phase2Task_Champion, // 16
+ Phase2Task_Aqua, // 17
+ Phase2Task_Magma, // 18
+ Phase2Task_Regice, // 19
+ Phase2Task_Registeel, // 20
+ Phase2Task_Regirock, // 21
+ Phase2Task_Kyogre, // 22
+ Phase2Task_Groudon, // 23
+ Phase2Task_Rayquaza, // 24
+ Phase2Task_ShredSplit, // 25
+ Phase2Task_Blackhole1, // 26
+ Phase2Task_Blackhole2, // 27
+ Phase2Task_RectangularSpiral, // 28
+ Phase2Task_29, // 29
+ Phase2Task_30, // 30
+ Phase2Task_31, // 31
+ Phase2Task_32, // 32
+ Phase2Task_33, // 33
+ Phase2Task_34, // 34
+ Phase2Task_35, // 35
+ Phase2Task_36, // 36
+ Phase2Task_37, // 37
+ Phase2Task_38, // 38
+ Phase2Task_39, // 39
+ Phase2Task_40, // 40
+ Phase2Task_41, // 41
+};
+
+static const TransitionStateFunc sMainTransitionPhases[] =
+{
+ &Transition_Phase1,
+ &Transition_WaitForPhase1,
+ &Transition_Phase2,
+ &Transition_WaitForPhase2
+};
+
+static const TransitionStateFunc sPhase2_Blur_Funcs[] =
+{
+ Phase2_Blur_Func1,
+ Phase2_Blur_Func2,
+ Phase2_Blur_Func3
+};
+
+static const TransitionStateFunc sPhase2_Swirl_Funcs[] =
+{
+ Phase2_Swirl_Func1,
+ Phase2_Swirl_Func2,
+};
+
+static const TransitionStateFunc sPhase2_Shuffle_Funcs[] =
+{
+ Phase2_Shuffle_Func1,
+ Phase2_Shuffle_Func2,
+};
+
+static const TransitionStateFunc sPhase2_Aqua_Funcs[] =
+{
+ Phase2_Aqua_Func1,
+ Phase2_Aqua_Func2,
+ Phase2_BigPokeball_Func3,
+ Phase2_BigPokeball_Func4,
+ Phase2_BigPokeball_Func5,
+ Phase2_FramesCountdown,
+ Phase2_BigPokeball_Func6
+};
+
+static const TransitionStateFunc sPhase2_Magma_Funcs[] =
+{
+ Phase2_Magma_Func1,
+ Phase2_Magma_Func2,
+ Phase2_BigPokeball_Func3,
+ Phase2_BigPokeball_Func4,
+ Phase2_BigPokeball_Func5,
+ Phase2_FramesCountdown,
+ Phase2_BigPokeball_Func6
+};
+
+static const TransitionStateFunc sPhase2_BigPokeball_Funcs[] =
+{
+ Phase2_BigPokeball_Func1,
+ Phase2_BigPokeball_Func2,
+ Phase2_BigPokeball_Func3,
+ Phase2_BigPokeball_Func4,
+ Phase2_BigPokeball_Func5,
+ Phase2_BigPokeball_Func6
+};
+
+static const TransitionStateFunc sPhase2_Regice_Funcs[] =
+{
+ Phase2_Regi_Func1,
+ Phase2_Regice_Func2,
+ Phase2_BigPokeball_Func3,
+ Phase2_BigPokeball_Func4,
+ Phase2_BigPokeball_Func5,
+ Phase2_BigPokeball_Func6
+};
+
+static const TransitionStateFunc sPhase2_Registeel_Funcs[] =
+{
+ Phase2_Regi_Func1,
+ Phase2_Registeel_Func2,
+ Phase2_BigPokeball_Func3,
+ Phase2_BigPokeball_Func4,
+ Phase2_BigPokeball_Func5,
+ Phase2_BigPokeball_Func6
+};
+
+static const TransitionStateFunc sPhase2_Regirock_Funcs[] =
+{
+ Phase2_Regi_Func1,
+ Phase2_Regirock_Func2,
+ Phase2_BigPokeball_Func3,
+ Phase2_BigPokeball_Func4,
+ Phase2_BigPokeball_Func5,
+ Phase2_BigPokeball_Func6
+};
+
+static const TransitionStateFunc sPhase2_Kyogre_Funcs[] =
+{
+ Phase2_WeatherTrio_Func1,
+ Phase2_WaitPaletteFade,
+ Phase2_Kyogre_Func3,
+ Phase2_Kyogre_Func4,
+ Phase2_Kyogre_Func5,
+ Phase2_FramesCountdown,
+ Phase2_WeatherDuo_Func6,
+ Phase2_WeatherDuo_Func7
+};
+
+static const TransitionStateFunc sPhase2_PokeballsTrail_Funcs[] =
+{
+ Phase2_PokeballsTrail_Func1,
+ Phase2_PokeballsTrail_Func2,
+ Phase2_PokeballsTrail_Func3
+};
+
+static const s16 sUnknown_085C8B88[2] = {-16, 256};
+static const s16 sUnknown_085C8B8C[5] = {0, 32, 64, 18, 48};
+static const s16 sUnknown_085C8B96[2] = {8, -8};
+
+static const TransitionStateFunc sPhase2_Clockwise_BlackFade_Funcs[] =
+{
+ Phase2_Clockwise_BlackFade_Func1,
+ Phase2_Clockwise_BlackFade_Func2,
+ Phase2_Clockwise_BlackFade_Func3,
+ Phase2_Clockwise_BlackFade_Func4,
+ Phase2_Clockwise_BlackFade_Func5,
+ Phase2_Clockwise_BlackFade_Func6,
+ Phase2_Clockwise_BlackFade_Func7
+};
+
+static const TransitionStateFunc sPhase2_Ripple_Funcs[] =
+{
+ Phase2_Ripple_Func1,
+ Phase2_Ripple_Func2
+};
+
+static const TransitionStateFunc sPhase2_Wave_Funcs[] =
+{
+ Phase2_Wave_Func1,
+ Phase2_Wave_Func2,
+ Phase2_Wave_Func3
+};
+
+static const TransitionStateFunc sPhase2_Mugshot_Funcs[] =
+{
+ Phase2_Mugshot_Func1,
+ Phase2_Mugshot_Func2,
+ Phase2_Mugshot_Func3,
+ Phase2_Mugshot_Func4,
+ Phase2_Mugshot_Func5,
+ Phase2_Mugshot_Func6,
+ Phase2_Mugshot_Func7,
+ Phase2_Mugshot_Func8,
+ Phase2_Mugshot_Func9,
+ Phase2_Mugshot_Func10
+};
+
+static const u8 sMugshotsTrainerPicIDsTable[MUGSHOTS_COUNT] =
+{
+ TRAINER_PIC_ELITE_FOUR_SIDNEY,
+ TRAINER_PIC_ELITE_FOUR_PHOEBE,
+ TRAINER_PIC_ELITE_FOUR_GLACIA,
+ TRAINER_PIC_ELITE_FOUR_DRAKE,
+ TRAINER_PIC_CHAMPION_WALLACE
+};
+static const s16 sMugshotsOpponentRotationScales[MUGSHOTS_COUNT][2] =
+{
+ {0x200, 0x200},
+ {0x200, 0x200},
+ {0x1B0, 0x1B0},
+ {0x1A0, 0x1A0},
+ {0x188, 0x188},
+};
+static const s16 sMugshotsOpponentCoords[MUGSHOTS_COUNT][2] =
+{
+ {0, 0},
+ {0, 0},
+ {-4, 4},
+ {0, 5},
+ {-8, 7},
+};
+
+static const TransitionSpriteCallback sUnknown_085C8C24[] =
+{
+ sub_81483A8,
+ sub_81483AC,
+ sub_81483F8,
+ sub_814842C,
+ sub_81483A8,
+ sub_8148458,
+ sub_81483A8
+};
+
+static const s16 sUnknown_085C8C40[2] = {12, -12};
+static const s16 sUnknown_085C8C44[2] = {-1, 1};
+
+static const TransitionStateFunc sPhase2_Slice_Funcs[] =
+{
+ Phase2_Slice_Func1,
+ Phase2_Slice_Func2,
+ Phase2_Slice_Func3
+};
+
+static const TransitionStateFunc sPhase2_ShredSplit_Funcs[] =
+{
+ Phase2_ShredSplit_Func1,
+ Phase2_ShredSplit_Func2,
+ Phase2_ShredSplit_Func3,
+ Phase2_ShredSplit_Func4
+};
+
+static const u8 gUnknown_085C8C64[] = {39, 119};
+static const s16 gUnknown_085C8C66[] = {1, -1};
+
+static const TransitionStateFunc sPhase2_Blackhole1_Funcs[] =
+{
+ Phase2_Blackhole_Func1,
+ Phase2_Blackhole1_Func2,
+ Phase2_Blackhole1_Func3
+};
+
+static const TransitionStateFunc sPhase2_Blackhole2_Funcs[] =
+{
+ Phase2_Blackhole_Func1,
+ Phase2_Blackhole2_Func2
+};
+
+static const s16 gUnknown_085C8C80[] = {-6, 4};
+
+static const TransitionStateFunc sPhase2_RectangularSpiral_Funcs[] =
+{
+ Phase2_RectangularSpiral_Func1,
+ Phase2_RectangularSpiral_Func2,
+ Phase2_RectangularSpiral_Func3
+};
+
+static const s16 gUnknown_085C8C90[] = {1, 27, 275, -1};
+static const s16 gUnknown_085C8C98[] = {2, 486, -1};
+static const s16 gUnknown_085C8C9E[] = {3, 262, -1};
+static const s16 gUnknown_085C8CA4[] = {4, 507, -2};
+static const s16 gUnknown_085C8CAA[] = {1, 213, -1};
+static const s16 gUnknown_085C8CB0[] = {2, 548, -2};
+static const s16 gUnknown_085C8CB6[] = {3, 196, -1};
+static const s16 gUnknown_085C8CBC[] = {4, 573, 309, -1};
+static const s16 gUnknown_085C8CC4[] = {1, 474, -1};
+static const s16 gUnknown_085C8CCA[] = {2, 295, 32, -1};
+static const s16 gUnknown_085C8CD2[] = {3, 58, -1};
+static const s16 gUnknown_085C8CD8[] = {4, 455, -1};
+static const s16 gUnknown_085C8CDE[] = {1, 540, -1};
+static const s16 gUnknown_085C8CE4[] = {2, 229, -1};
+static const s16 gUnknown_085C8CEA[] = {3, 244, 28, -1};
+static const s16 gUnknown_085C8CF2[] = {4, 517, -1};
+
+static const s16 *const gUnknown_085C8CF8[] =
+{
+ gUnknown_085C8C90,
+ gUnknown_085C8CA4,
+ gUnknown_085C8C98,
+ gUnknown_085C8C9E,
+ gUnknown_085C8CEA,
+ gUnknown_085C8CE4,
+ gUnknown_085C8CF2,
+ gUnknown_085C8CDE
+};
+
+static const s16 *const gUnknown_085C8D18[] =
+{
+ gUnknown_085C8CBC,
+ gUnknown_085C8CB0,
+ gUnknown_085C8CB6,
+ gUnknown_085C8CAA,
+ gUnknown_085C8CCA,
+ gUnknown_085C8CD8,
+ gUnknown_085C8CC4,
+ gUnknown_085C8CD2
+};
+
+static const s16 *const *const gUnknown_085C8D38[] =
+{
+ gUnknown_085C8CF8,
+ gUnknown_085C8D18
+};
+
+static const TransitionStateFunc sPhase2_Groudon_Funcs[] =
+{
+ Phase2_WeatherTrio_Func1,
+ Phase2_WaitPaletteFade,
+ Phase2_Groudon_Func3,
+ Phase2_Groudon_Func4,
+ Phase2_Groudon_Func5,
+ Phase2_FramesCountdown,
+ Phase2_WeatherDuo_Func6,
+ Phase2_WeatherDuo_Func7
+};
+
+static const TransitionStateFunc sPhase2_Rayquaza_Funcs[] =
+{
+ Phase2_WeatherTrio_Func1,
+ Phase2_WaitPaletteFade,
+ Phase2_Rayquaza_Func3,
+ Phase2_Rayquaza_Func4,
+ Phase2_Rayquaza_Func5,
+ Phase2_Rayquaza_Func6,
+ Phase2_Rayquaza_Func7,
+ Phase2_Rayquaza_Func8,
+ Phase2_Rayquaza_Func9,
+ Phase2_Blackhole1_Func2,
+ Phase2_Blackhole1_Func3
+};
+
+static const TransitionStateFunc sPhase2_WhiteFade_Funcs[] =
+{
+ Phase2_WhiteFade_Func1,
+ Phase2_WhiteFade_Func2,
+ Phase2_WhiteFade_Func3,
+ Phase2_WhiteFade_Func4,
+ Phase2_WhiteFade_Func5
+};
+
+static const s16 sUnknown_085C8DA0[] = {0, 20, 15, 40, 10, 25, 35, 5};
+
+static const TransitionStateFunc sPhase2_GridSquares_Funcs[] =
+{
+ Phase2_GridSquares_Func1,
+ Phase2_GridSquares_Func2,
+ Phase2_GridSquares_Func3
+};
+
+static const TransitionStateFunc sPhase2_Shards_Funcs[] =
+{
+ Phase2_Shards_Func1,
+ Phase2_Shards_Func2,
+ Phase2_Shards_Func3,
+ Phase2_Shards_Func4,
+ Phase2_Shards_Func5
+};
+
+static const s16 sUnknown_085C8DD0[][5] =
+{
+ {56, 0, 0, 160, 0},
+ {104, 160, 240, 88, 1},
+ {240, 72, 56, 0, 1},
+ {0, 32, 144, 160, 0},
+ {144, 160, 184, 0, 1},
+ {56, 0, 168, 160, 0},
+ {168, 160, 48, 0, 1},
+};
+
+static const s16 sUnknown_085C8E16[] = {8, 4, 2, 1, 1, 1, 0};
+
+static const TransitionStateFunc sPhase1_TransitionAll_Funcs[] =
+{
+ Phase1_TransitionAll_Func1,
+ Phase1_TransitionAll_Func2
+};
+
+static const struct SpriteFrameImage sSpriteImageTable_85C8E2C[] =
+{
+ sSpriteImage_85B98F0, 0x200
+};
+
+static const union AnimCmd sSpriteAnim_85C8E34[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_85C8E3C[] =
+{
+ sSpriteAnim_85C8E34
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_85C8E40[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, -4, 1),
+ AFFINEANIMCMD_JUMP(0)
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_85C8E50[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, 4, 1),
+ AFFINEANIMCMD_JUMP(0)
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85C8E60[] =
+{
+ sSpriteAffineAnim_85C8E40,
+ sSpriteAffineAnim_85C8E50
+};
+
+static const struct SpriteTemplate gUnknown_085C8E68 =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = 4105,
+ .oam = &gFieldObjectBaseOam_32x32,
+ .anims = sSpriteAnimTable_85C8E3C,
+ .images = sSpriteImageTable_85C8E2C,
+ .affineAnims = sSpriteAffineAnimTable_85C8E60,
+ .callback = sub_814713C
+};
+
+static const struct OamData gOamData_85C8E80 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct SpriteFrameImage sSpriteImageTable_85C8E88[] =
+{
+ sSpriteImage_85B9CD0, 0x800
+};
+
+static const struct SpriteFrameImage sSpriteImageTable_85C8E90[] =
+{
+ sSpriteImage_85BA4D0, 0x800
+};
+
+static const union AnimCmd sSpriteAnim_85C8E98[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_85C8EA0[] =
+{
+ sSpriteAnim_85C8E98
+};
+
+static const struct SpriteTemplate sSpriteTemplate_85C8EA4 =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = 4106,
+ .oam = &gOamData_85C8E80,
+ .anims = sSpriteAnimTable_85C8EA0,
+ .images = sSpriteImageTable_85C8E88,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_8148380
+};
+
+static const struct SpriteTemplate sSpriteTemplate_85C8EBC =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = 4106,
+ .oam = &gOamData_85C8E80,
+ .anims = sSpriteAnimTable_85C8EA0,
+ .images = sSpriteImageTable_85C8E90,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_8148380
+};
+
+static const u16 gFieldEffectObjectPalette10[] = INCBIN_U16("graphics/map_objects/palettes/field_effect_object_palette_10.gbapal");
+
+const struct SpritePalette gFieldEffectObjectPaletteInfo10 =
+{
+ gFieldEffectObjectPalette10, 0x1009
+};
+
+static const u16 sMugshotPal_Sydney[] = INCBIN_U16("graphics/battle_transitions/sidney_bg.gbapal");
+static const u16 sMugshotPal_Phoebe[] = INCBIN_U16("graphics/battle_transitions/phoebe_bg.gbapal");
+static const u16 sMugshotPal_Glacia[] = INCBIN_U16("graphics/battle_transitions/glacia_bg.gbapal");
+static const u16 sMugshotPal_Drake[] = INCBIN_U16("graphics/battle_transitions/drake_bg.gbapal");
+static const u16 sMugshotPal_Champion[] = INCBIN_U16("graphics/battle_transitions/wallace_bg.gbapal");
+static const u16 sMugshotPal_Brendan[] = INCBIN_U16("graphics/battle_transitions/brendan_bg.gbapal");
+static const u16 sMugshotPal_May[] = INCBIN_U16("graphics/battle_transitions/may_bg.gbapal");
+
+static const u16 *const sOpponentMugshotsPals[MUGSHOTS_COUNT] =
+{
+ sMugshotPal_Sydney,
+ sMugshotPal_Phoebe,
+ sMugshotPal_Glacia,
+ sMugshotPal_Drake,
+ sMugshotPal_Champion
+};
+
+static const u16 *const sPlayerMugshotsPals[2] =
+{
+ sMugshotPal_Brendan,
+ sMugshotPal_May
+};
+
+static const u16 sUnusedTrainerPalette[] = INCBIN_U16("graphics/battle_transitions/unused_trainer.gbapal");
+static const struct SpritePalette sSpritePalette_UnusedTrainer =
+{
+ sUnusedTrainerPalette, 0x100A
+};
+
+static const u16 sBigPokeball_Tilemap[] = INCBIN_U16("graphics/battle_transitions/big_pokeball_map.bin");
+static const u16 sMugshotsTilemap[] = INCBIN_U16("graphics/battle_transitions/elite_four_bg_map.bin");
+
+static const TransitionStateFunc sPhase2_29_Funcs[] =
+{
+ Phase2_29_Func1,
+ Phase2_29_Func2,
+ Phase2_BigPokeball_Func3,
+ Phase2_BigPokeball_Func4,
+ Phase2_BigPokeball_Func5,
+ Phase2_BigPokeball_Func6
+};
+
+static const TransitionStateFunc sPhase2_30_Funcs[] =
+{
+ Phase2_30_Func1,
+ Phase2_30_Func2,
+ Phase2_30_Func3,
+ Phase2_30_Func4
+};
+
+static const TransitionStateFunc sPhase2_31_Funcs[] =
+{
+ Phase2_31_Func1,
+ Phase2_31_Func2,
+ Phase2_31_Func3,
+ Phase2_31_33_Func5
+};
+
+static const TransitionStateFunc sPhase2_33_Funcs[] =
+{
+ Phase2_33_Func1,
+ Phase2_33_Func2,
+ Phase2_33_Func3,
+ Phase2_33_Func4,
+ Phase2_31_33_Func5
+};
+
+static const TransitionStateFunc sPhase2_32_Funcs[] =
+{
+ Phase2_32_Func1,
+ Phase2_32_Func2,
+ Phase2_32_Func3,
+ Phase2_32_Func4,
+ Phase2_32_Func5
+};
+
+static const u8 gUnknown_085C9A30[] = {0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x1b, 0x14, 0x0d, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x07, 0x0e, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x13, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x10, 0x11, 0x12};
+static const u8 gUnknown_085C9A53[] = {0x00, 0x10, 0x29, 0x16, 0x2c, 0x02, 0x2b, 0x15, 0x2e, 0x1b, 0x09, 0x30, 0x26, 0x05, 0x39, 0x3b, 0x0c, 0x3f, 0x23, 0x1c, 0x0a, 0x35, 0x07, 0x31, 0x27, 0x17, 0x37, 0x01, 0x3e, 0x11, 0x3d, 0x1e, 0x06, 0x22, 0x0f, 0x33, 0x20, 0x3a, 0x0d, 0x2d, 0x25, 0x34, 0x0b, 0x18, 0x3c, 0x13, 0x38, 0x21, 0x1d, 0x32, 0x28, 0x36, 0x0e, 0x03, 0x2f, 0x14, 0x12, 0x19, 0x04, 0x24, 0x1a, 0x2a, 0x1f, 0x08, 0x00};
+
+// code
+static void CB2_TestBattleTransition(void)
+{
+ switch (sTestingTransitionState)
+ {
+ case 0:
+ LaunchBattleTransitionTask(sTestingTransitionId);
+ sTestingTransitionState++;
+ break;
+ case 1:
+ if (IsBattleTransitionDone())
+ {
+ sTestingTransitionState = 0;
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ }
+ break;
+ }
+
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+void TestBattleTransition(u8 transitionId)
+{
+ sTestingTransitionId = transitionId;
+ SetMainCallback2(CB2_TestBattleTransition);
+}
+
+void BattleTransition_StartOnField(u8 transitionId)
+{
+ gMain.callback2 = CB2_OverworldBasic;
+ LaunchBattleTransitionTask(transitionId);
+}
+
+void BattleTransition_Start(u8 transitionId)
+{
+ LaunchBattleTransitionTask(transitionId);
+}
+
+// in all tasks data[0] is reserved for the state
+#define tState data[0]
+
+// main task that launches sub-tasks for phase1 and phase2
+#define tTransitionId data[1]
+#define tTransitionDone data[15]
+
+bool8 IsBattleTransitionDone(void)
+{
+ u8 taskId = FindTaskIdByFunc(Task_BattleTransitionMain);
+ if (gTasks[taskId].tTransitionDone)
+ {
+ DestroyTask(taskId);
+ FREE_AND_SET_NULL(sTransitionStructPtr);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static void LaunchBattleTransitionTask(u8 transitionId)
+{
+ u8 taskId = CreateTask(Task_BattleTransitionMain, 2);
+ gTasks[taskId].tTransitionId = transitionId;
+ sTransitionStructPtr = AllocZeroed(sizeof(*sTransitionStructPtr));
+}
+
+static void Task_BattleTransitionMain(u8 taskId)
+{
+ while (sMainTransitionPhases[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Transition_Phase1(struct Task *task)
+{
+ sub_80AC3D0();
+ CpuCopy32(gPlttBufferFaded, gPlttBufferUnfaded, 0x400);
+ if (sPhase1_Tasks[task->tTransitionId] != NULL)
+ {
+ CreateTask(sPhase1_Tasks[task->tTransitionId], 4);
+ task->tState++;
+ return FALSE;
+ }
+ else
+ {
+ task->tState = 2;
+ return TRUE;
+ }
+}
+
+static bool8 Transition_WaitForPhase1(struct Task *task)
+{
+ if (FindTaskIdByFunc(sPhase1_Tasks[task->tTransitionId]) == 0xFF)
+ {
+ task->tState++;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static bool8 Transition_Phase2(struct Task *task)
+{
+ CreateTask(sPhase2_Tasks[task->tTransitionId], 0);
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Transition_WaitForPhase2(struct Task *task)
+{
+ task->tTransitionDone = FALSE;
+ if (FindTaskIdByFunc(sPhase2_Tasks[task->tTransitionId]) == 0xFF)
+ task->tTransitionDone = TRUE;
+ return FALSE;
+}
+
+#undef tTransitionId
+#undef tTransitionDone
+
+static void Phase1Task_TransitionAll(u8 taskId)
+{
+ if (gTasks[taskId].tState == 0)
+ {
+ gTasks[taskId].tState++;
+ CreatePhase1Task(0, 0, 3, 2, 2); // creates a sub-task for this sub-task
+ }
+ else if (IsPhase1Done())
+ {
+ DestroyTask(taskId);
+ }
+}
+
+// sub-task for phase2
+#define tData1 data[1]
+#define tData2 data[2]
+#define tData3 data[3]
+#define tData4 data[4]
+#define tData5 data[5]
+#define tData6 data[6]
+#define tFuncState data[7]
+#define tFrames data[8]
+#define tOpponentSpriteId data[13]
+#define tPlayerSpriteId data[14]
+#define tMugshotId data[15]
+
+static void Phase2Task_Blur(u8 taskId)
+{
+ while (sPhase2_Blur_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Blur_Func1(struct Task *task)
+{
+ SetGpuReg(REG_OFFSET_MOSAIC, 0);
+ SetGpuRegBits(REG_OFFSET_BG1CNT, BGCNT_MOSAIC);
+ SetGpuRegBits(REG_OFFSET_BG2CNT, BGCNT_MOSAIC);
+ SetGpuRegBits(REG_OFFSET_BG3CNT, BGCNT_MOSAIC);
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_Blur_Func2(struct Task *task)
+{
+ if (task->tData1 != 0)
+ {
+ task->tData1--;
+ }
+ else
+ {
+ task->tData1 = 4;
+ if (++task->tData2 == 10)
+ BeginNormalPaletteFade(-1, -1, 0, 0x10, 0);
+ SetGpuReg(REG_OFFSET_MOSAIC, (task->tData2 & 15) * 17);
+ if (task->tData2 > 14)
+ task->tState++;
+ }
+ return FALSE;
+}
+
+static bool8 Phase2_Blur_Func3(struct Task *task)
+{
+ if (!gPaletteFade.active)
+ {
+ u8 taskId = FindTaskIdByFunc(Phase2Task_Blur);
+ DestroyTask(taskId);
+ }
+ return FALSE;
+}
+
+static void Phase2Task_Swirl(u8 taskId)
+{
+ while (sPhase2_Swirl_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Swirl_Func1(struct Task *task)
+{
+ sub_8149F08();
+ dp12_8087EA4();
+ BeginNormalPaletteFade(-1, 4, 0, 0x10, 0);
+ sub_8149F98(gUnknown_020393A8, sTransitionStructPtr->field_14, 0, 2, 0, 160);
+
+ SetVBlankCallback(VBlankCB_Phase2_Swirl);
+ SetHBlankCallback(HBlankCB_Phase2_Swirl);
+
+ EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_HBLANK);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Swirl_Func2(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ task->tData1 += 4;
+ task->tData2 += 8;
+
+ sub_8149F98(gUnknown_02038C28[0], sTransitionStructPtr->field_14, task->tData1, 2, task->tData2, 160);
+
+ if (!gPaletteFade.active)
+ {
+ u8 taskId = FindTaskIdByFunc(Phase2Task_Swirl);
+ DestroyTask(taskId);
+ }
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static void VBlankCB_Phase2_Swirl(void)
+{
+ VBlankCB_BattleTransition();
+ if (sTransitionStructPtr->VBlank_DMA)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+}
+
+static void HBlankCB_Phase2_Swirl(void)
+{
+ u16 var = gUnknown_02038C28[1][REG_VCOUNT];
+ REG_BG1HOFS = var;
+ REG_BG2HOFS = var;
+ REG_BG3HOFS = var;
+}
+
+static void Phase2Task_Shuffle(u8 taskId)
+{
+ while (sPhase2_Shuffle_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Shuffle_Func1(struct Task *task)
+{
+ sub_8149F08();
+ dp12_8087EA4();
+
+ BeginNormalPaletteFade(-1, 4, 0, 0x10, 0);
+ memset(gUnknown_020393A8, sTransitionStructPtr->field_16, 0x140);
+
+ SetVBlankCallback(VBlankCB_Phase2_Shuffle);
+ SetHBlankCallback(HBlankCB_Phase2_Shuffle);
+
+ EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_HBLANK);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Shuffle_Func2(struct Task *task)
+{
+ u8 i;
+ u16 r3, r4;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ r4 = task->tData1;
+ r3 = task->tData2 >> 8;
+ task->tData1 += 4224;
+ task->tData2 += 384;
+
+ for (i = 0; i < 160; i++, r4 += 4224)
+ {
+ u16 var = r4 / 256;
+ gUnknown_02038C28[0][i] = sTransitionStructPtr->field_16 + Sin(var, r3);
+ }
+
+ if (!gPaletteFade.active)
+ DestroyTask(FindTaskIdByFunc(Phase2Task_Shuffle));
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static void VBlankCB_Phase2_Shuffle(void)
+{
+ VBlankCB_BattleTransition();
+ if (sTransitionStructPtr->VBlank_DMA)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+}
+
+static void HBlankCB_Phase2_Shuffle(void)
+{
+ u16 var = gUnknown_02038C28[1][REG_VCOUNT];
+ REG_BG1VOFS = var;
+ REG_BG2VOFS = var;
+ REG_BG3VOFS = var;
+}
+
+static void Phase2Task_BigPokeball(u8 taskId)
+{
+ while (sPhase2_BigPokeball_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_Aqua(u8 taskId)
+{
+ while (sPhase2_Aqua_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_Magma(u8 taskId)
+{
+ while (sPhase2_Magma_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_Regice(u8 taskId)
+{
+ while (sPhase2_Regice_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_Registeel(u8 taskId)
+{
+ while (sPhase2_Registeel_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_Regirock(u8 taskId)
+{
+ while (sPhase2_Regirock_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_Kyogre(u8 taskId)
+{
+ while (sPhase2_Kyogre_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void sub_814669C(struct Task *task)
+{
+ s32 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ task->tData1 = 16;
+ task->tData2 = 0;
+ task->tData4 = 0;
+ task->tData5 = 0x4000;
+ sTransitionStructPtr->WININ = 63;
+ sTransitionStructPtr->WINOUT = 0;
+ sTransitionStructPtr->WIN0H = 240;
+ sTransitionStructPtr->WIN0V = 160;
+ sTransitionStructPtr->BLDCNT = 0x3F41;
+ sTransitionStructPtr->BLDALPHA = (task->tData1 << 8) | (task->tData2);
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_02038C28[1][i] = 240;
+ }
+
+ SetVBlankCallback(VBlankCB0_Phase2_BigPokeball);
+}
+
+static bool8 Phase2_Aqua_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ task->tFrames = 60;
+ sub_814669C(task);
+ sub_8149F58(&dst1, &dst2);
+ CpuFill16(0, dst1, 0x800);
+ LZ77UnCompVram(sTeamAqua_Tileset, dst2);
+ LoadPalette(sEvilTeam_Palette, 0xF0, 0x20);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Magma_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ task->tFrames = 60;
+ sub_814669C(task);
+ sub_8149F58(&dst1, &dst2);
+ CpuFill16(0, dst1, 0x800);
+ LZ77UnCompVram(sTeamMagma_Tileset, dst2);
+ LoadPalette(sEvilTeam_Palette, 0xF0, 0x20);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Regi_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ task->tFrames = 60;
+ sub_814669C(task);
+ sub_8149F58(&dst1, &dst2);
+ CpuFill16(0, dst1, 0x800);
+ CpuCopy16(gUnknown_085BBC14, dst2, 0x2000);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_BigPokeball_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_814669C(task);
+ sub_8149F58(&dst1, &dst2);
+ CpuFill16(0, dst1, 0x800);
+ CpuCopy16(sBigPokeball_Tileset, dst2, 0x580);
+ LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_BigPokeball_Func2(struct Task *task)
+{
+ s16 i, j;
+ u16 *dst1, *dst2;
+ const u16 *BigPokeballMap;
+
+ sub_8149F58(&dst1, &dst2);
+ BigPokeballMap = sBigPokeball_Tilemap;
+ for (i = 0; i < 20; i++)
+ {
+ for (j = 0; j < 30; j++, BigPokeballMap++)
+ {
+ dst1[i * 32 + j] = *BigPokeballMap | 0xF000;
+ }
+ }
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 132, task->tData5, 160);
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_Aqua_Func2(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LZ77UnCompVram(sTeamAqua_Tilemap, dst1);
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 132, task->tData5, 160);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Magma_Func2(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LZ77UnCompVram(sTeamMagma_Tilemap, dst1);
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 132, task->tData5, 160);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Regice_Func2(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LoadPalette(gUnknown_085BC2B4, 0xF0, 0x20);
+ CpuCopy16(gUnknown_085BC314, dst1, 0x500);
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 132, task->tData5, 160);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Registeel_Func2(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LoadPalette(gUnknown_085BC2D4, 0xF0, 0x20);
+ CpuCopy16(gUnknown_085BCB14, dst1, 0x500);
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 132, task->tData5, 160);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Regirock_Func2(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LoadPalette(gUnknown_085BC2F4, 0xF0, 0x20);
+ CpuCopy16(gUnknown_085BD314, dst1, 0x500);
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 132, task->tData5, 160);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Kyogre_Func3(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ CpuFill16(0, dst1, 0x800);
+ LZ77UnCompVram(gUnknown_085BDB34, dst2);
+ LZ77UnCompVram(gUnknown_085BE1E8, dst1);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Kyogre_Func4(struct Task *task)
+{
+ if (task->tData1 % 3 == 0)
+ {
+ u16 var = task->tData1 % 30;
+ var /= 3;
+ LoadPalette(gUnknown_085BEDA0 + (var * 16), 0xF0, 0x20);
+ }
+ if (++task->tData1 > 58)
+ {
+ task->tState++;
+ task->tData1 = 0;
+ }
+
+ return FALSE;
+}
+
+static bool8 Phase2_Kyogre_Func5(struct Task *task)
+{
+ if (task->tData1 % 5 == 0)
+ {
+ s16 var = task->tData1 / 5;
+ LoadPalette(gUnknown_085BEEE0 + (var * 16), 0xF0, 0x20);
+ }
+ if (++task->tData1 > 68)
+ {
+ task->tState++;
+ task->tData1 = 0;
+ task->tFrames = 30;
+ }
+
+ return FALSE;
+}
+
+static bool8 Phase2_WeatherDuo_Func6(struct Task *task)
+{
+ BeginNormalPaletteFade(0xFFFF8000, 1, 0, 0x10, 0);
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_WeatherDuo_Func7(struct Task *task)
+{
+ if (!gPaletteFade.active)
+ {
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(task->func));
+ }
+ return FALSE;
+}
+
+static bool8 Phase2_BigPokeball_Func3(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ if (task->tData3 == 0 || --task->tData3 == 0)
+ {
+ task->tData2++;
+ task->tData3 = 2;
+ }
+ sTransitionStructPtr->BLDALPHA = (task->tData1 << 8) | task->tData2;
+ if (task->tData2 > 15)
+ task->tState++;
+ task->tData4 += 8;
+ task->tData5 -= 256;
+
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 132, task->tData5 >> 8, 160);
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_BigPokeball_Func4(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ if (task->tData3 == 0 || --task->tData3 == 0)
+ {
+ task->tData1--;
+ task->tData3 = 2;
+ }
+ sTransitionStructPtr->BLDALPHA = (task->tData1 << 8) | task->tData2;
+ if (task->tData1 == 0)
+ task->tState++;
+ task->tData4 += 8;
+ task->tData5 -= 256;
+
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 132, task->tData5 >> 8, 160);
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_BigPokeball_Func5(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ task->tData4 += 8;
+ task->tData5 -= 256;
+
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 132, task->tData5 >> 8, 160);
+
+ if (task->tData5 <= 0)
+ {
+ task->tState++;
+ task->tData1 = 160;
+ task->tData2 = 256;
+ task->tData3 = 0;
+ }
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_FramesCountdown(struct Task *task)
+{
+ if (--task->tFrames == 0)
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_WeatherTrio_Func1(struct Task *task)
+{
+ BeginNormalPaletteFade(0x0000FFFF, 1, 0, 0x10, 0);
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_WaitPaletteFade(struct Task *task)
+{
+ if (!gPaletteFade.active)
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_BigPokeball_Func6(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ if (task->tData2 < 1024)
+ task->tData2 += 128;
+ if (task->tData1 != 0)
+ {
+ task->tData1 -= (task->tData2 >> 8);
+ if (task->tData1 < 0)
+ task->tData1 = 0;
+ }
+ sub_814A014(gUnknown_02038C28[0], 120, 80, task->tData1);
+ if (task->tData1 == 0)
+ {
+ SetVBlankCallback(NULL);
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(task->func));
+ }
+ else
+ {
+ if (task->tData3 == 0)
+ {
+ task->tData3++;
+ SetVBlankCallback(VBlankCB1_Phase2_BigPokeball);
+ }
+
+ sTransitionStructPtr->VBlank_DMA++;
+ }
+
+ return FALSE;
+}
+
+static void Transition_BigPokeball_Vblank(void)
+{
+ DmaStop(0);
+ VBlankCB_BattleTransition();
+ if (sTransitionStructPtr->VBlank_DMA)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+ REG_WININ = sTransitionStructPtr->WININ;
+ REG_WINOUT = sTransitionStructPtr->WINOUT;
+ REG_WIN0V = sTransitionStructPtr->WIN0V;
+ REG_BLDCNT = sTransitionStructPtr->BLDCNT;
+ REG_BLDALPHA = sTransitionStructPtr->BLDALPHA;
+}
+
+static void VBlankCB0_Phase2_BigPokeball(void)
+{
+ Transition_BigPokeball_Vblank();
+ DmaSet(0, gUnknown_020393A8, &REG_BG0HOFS, 0xA2400001);
+}
+
+static void VBlankCB1_Phase2_BigPokeball(void)
+{
+ Transition_BigPokeball_Vblank();
+ DmaSet(0, gUnknown_020393A8, &REG_WIN0H, 0xA2400001);
+}
+
+static void Phase2Task_PokeballsTrail(u8 taskId)
+{
+ while (sPhase2_PokeballsTrail_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_PokeballsTrail_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ CpuSet(sPokeballTrail_Tileset, dst2, 0x20);
+ CpuFill32(0, dst1, 0x800);
+ LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_PokeballsTrail_Func2(struct Task *task)
+{
+ s16 i;
+ s16 rand;
+ s16 arr0[ARRAY_COUNT(sUnknown_085C8B88)];
+ s16 arr1[ARRAY_COUNT(sUnknown_085C8B8C)];
+
+ memcpy(arr0, sUnknown_085C8B88, sizeof(sUnknown_085C8B88));
+ memcpy(arr1, sUnknown_085C8B8C, sizeof(sUnknown_085C8B8C));
+ rand = Random() & 1;
+ for (i = 0; i <= 4; i++, rand ^= 1)
+ {
+ gFieldEffectArguments[0] = arr0[rand]; // x
+ gFieldEffectArguments[1] = (i * 32) + 16; // y
+ gFieldEffectArguments[2] = rand;
+ gFieldEffectArguments[3] = arr1[i];
+ FieldEffectStart(FLDEFF_POKEBALL);
+ }
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_PokeballsTrail_Func3(struct Task *task)
+{
+ if (!FieldEffectActiveListContains(FLDEFF_POKEBALL))
+ {
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(Phase2Task_PokeballsTrail));
+ }
+ return FALSE;
+}
+
+bool8 FldEff_Pokeball(void)
+{
+ u8 spriteId = CreateSpriteAtEnd(&gUnknown_085C8E68, gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
+ gSprites[spriteId].oam.priority = 0;
+ gSprites[spriteId].oam.affineMode = 1;
+ gSprites[spriteId].data[0] = gFieldEffectArguments[2];
+ gSprites[spriteId].data[1] = gFieldEffectArguments[3];
+ gSprites[spriteId].data[2] = -1;
+ InitSpriteAffineAnim(&gSprites[spriteId]);
+ StartSpriteAffineAnim(&gSprites[spriteId], gFieldEffectArguments[2]);
+ return FALSE;
+}
+
+#define SOME_VRAM_STORE(ptr, posY, posX, toStore) \
+{ \
+ u32 index = (posY) * 32 + posX; \
+ ptr[index] = toStore; \
+}
+
+static void sub_814713C(struct Sprite *sprite)
+{
+ s16 arr0[ARRAY_COUNT(sUnknown_085C8B96)];
+
+ memcpy(arr0, sUnknown_085C8B96, sizeof(sUnknown_085C8B96));
+ if (sprite->data[1] != 0)
+ {
+ sprite->data[1]--;
+ }
+ else
+ {
+ if (sprite->pos1.x >= 0 && sprite->pos1.x <= 240)
+ {
+ s16 posX = sprite->pos1.x >> 3;
+ s16 posY = sprite->pos1.y >> 3;
+
+ if (posX != sprite->data[2])
+ {
+ u32 var;
+ u16 *ptr;
+
+ sprite->data[2] = posX;
+ var = (((REG_BG0CNT >> 8) & 0x1F) << 11); // r2
+ ptr = (u16 *)(VRAM + var);
+
+ SOME_VRAM_STORE(ptr, posY - 2, posX, 0xF001);
+ SOME_VRAM_STORE(ptr, posY - 1, posX, 0xF001);
+ SOME_VRAM_STORE(ptr, posY - 0, posX, 0xF001);
+ SOME_VRAM_STORE(ptr, posY + 1, posX, 0xF001);
+ }
+ }
+ sprite->pos1.x += arr0[sprite->data[0]];
+ if (sprite->pos1.x < -15 || sprite->pos1.x > 255)
+ FieldEffectStop(sprite, FLDEFF_POKEBALL);
+ }
+}
+
+static void Phase2Task_Clockwise_BlackFade(u8 taskId)
+{
+ while (sPhase2_Clockwise_BlackFade_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Clockwise_BlackFade_Func1(struct Task *task)
+{
+ u16 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ sTransitionStructPtr->WININ = 0;
+ sTransitionStructPtr->WINOUT = 63;
+ sTransitionStructPtr->WIN0H = -3855;
+ sTransitionStructPtr->WIN0V = 160;
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_020393A8[i] = 0xF3F4;
+ }
+
+ SetVBlankCallback(VBlankCB_Phase2_Clockwise_BlackFade);
+ sTransitionStructPtr->data[4] = 120;
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_Clockwise_BlackFade_Func2(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ sub_814A1AC(sTransitionStructPtr->data, 120, 80, sTransitionStructPtr->data[4], -1, 1, 1);
+ do
+ {
+ gUnknown_02038C28[0][sTransitionStructPtr->data[3]] = (sTransitionStructPtr->data[2] + 1) | 0x7800;
+ } while (!sub_814A228(sTransitionStructPtr->data, 1, 1));
+
+ sTransitionStructPtr->data[4] += 16;
+ if (sTransitionStructPtr->data[4] >= 240)
+ {
+ sTransitionStructPtr->data[5] = 0;
+ task->tState++;
+ }
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Clockwise_BlackFade_Func3(struct Task *task)
+{
+ s16 r1, r3;
+ vu8 var = 0;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ sub_814A1AC(sTransitionStructPtr->data, 120, 80, 240, sTransitionStructPtr->data[5], 1, 1);
+
+ while (1)
+ {
+ r1 = 120, r3 = sTransitionStructPtr->data[2] + 1;
+ if (sTransitionStructPtr->data[5] >= 80)
+ r1 = sTransitionStructPtr->data[2], r3 = 240;
+ gUnknown_02038C28[0][sTransitionStructPtr->data[3]] = (r3) | (r1 << 8);
+ if (var != 0)
+ break;
+ var = sub_814A228(sTransitionStructPtr->data, 1, 1);
+ }
+
+ sTransitionStructPtr->data[5] += 8;
+ if (sTransitionStructPtr->data[5] >= 160)
+ {
+ sTransitionStructPtr->data[4] = 240;
+ task->tState++;
+ }
+ else
+ {
+ while (sTransitionStructPtr->data[3] < sTransitionStructPtr->data[5])
+ {
+ gUnknown_02038C28[0][++sTransitionStructPtr->data[3]] = (r3) | (r1 << 8);
+ }
+ }
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Clockwise_BlackFade_Func4(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ sub_814A1AC(sTransitionStructPtr->data, 120, 80, sTransitionStructPtr->data[4], 160, 1, 1);
+ do
+ {
+ gUnknown_02038C28[0][sTransitionStructPtr->data[3]] = (sTransitionStructPtr->data[2] << 8) | 0xF0;
+ } while (!sub_814A228(sTransitionStructPtr->data, 1, 1));
+
+ sTransitionStructPtr->data[4] -= 16;
+ if (sTransitionStructPtr->data[4] <= 0)
+ {
+ sTransitionStructPtr->data[5] = 160;
+ task->tState++;
+ }
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Clockwise_BlackFade_Func5(struct Task *task)
+{
+ s16 r1, r2, var4;
+ vu8 var = 0;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ sub_814A1AC(sTransitionStructPtr->data, 120, 80, 0, sTransitionStructPtr->data[5], 1, 1);
+
+ while (1)
+ {
+ r1 = (gUnknown_02038C28[0][sTransitionStructPtr->data[3]]) & 0xFF;
+ r2 = sTransitionStructPtr->data[2];
+ if (sTransitionStructPtr->data[5] <= 80)
+ r2 = 120, r1 = sTransitionStructPtr->data[2];
+ var4 = (r1) | (r2 << 8);
+ gUnknown_02038C28[0][sTransitionStructPtr->data[3]] = var4;
+ if (var != 0)
+ break;
+ var = sub_814A228(sTransitionStructPtr->data, 1, 1);
+ }
+
+ sTransitionStructPtr->data[5] -= 8;
+ if (sTransitionStructPtr->data[5] <= 0)
+ {
+ sTransitionStructPtr->data[4] = 0;
+ task->tState++;
+ }
+ else
+ {
+ while (sTransitionStructPtr->data[3] > sTransitionStructPtr->data[5])
+ {
+ gUnknown_02038C28[0][--sTransitionStructPtr->data[3]] = (r1) | (r2 << 8);
+ }
+ }
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Clockwise_BlackFade_Func6(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ sub_814A1AC(sTransitionStructPtr->data, 120, 80, sTransitionStructPtr->data[4], 0, 1, 1);
+ do
+ {
+ s16 r2, r3;
+
+ r2 = 120, r3 = sTransitionStructPtr->data[2];
+ if (sTransitionStructPtr->data[2] >= 120)
+ r2 = 0, r3 = 240;
+ gUnknown_02038C28[0][sTransitionStructPtr->data[3]] = (r3) | (r2 << 8);
+
+ } while (!sub_814A228(sTransitionStructPtr->data, 1, 1));
+
+ sTransitionStructPtr->data[4] += 16;
+ if (sTransitionStructPtr->data[2] > 120)
+ task->tState++;
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Clockwise_BlackFade_Func7(struct Task *task)
+{
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(Phase2Task_Clockwise_BlackFade));
+ return FALSE;
+}
+
+static void VBlankCB_Phase2_Clockwise_BlackFade(void)
+{
+ DmaStop(0);
+ VBlankCB_BattleTransition();
+ if (sTransitionStructPtr->VBlank_DMA != 0)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+ REG_WININ = sTransitionStructPtr->WININ;
+ REG_WINOUT = sTransitionStructPtr->WINOUT;
+ REG_WIN0V = sTransitionStructPtr->WIN0V;
+ REG_WIN0H = gUnknown_02038C28[1][0];
+ DmaSet(0, gUnknown_02038C28[1], &REG_WIN0H, 0xA2400001);
+}
+
+static void Phase2Task_Ripple(u8 taskId)
+{
+ while (sPhase2_Ripple_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Ripple_Func1(struct Task *task)
+{
+ u8 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_020393A8[i] = sTransitionStructPtr->field_16;
+ }
+
+ SetVBlankCallback(VBlankCB_Phase2_Ripple);
+ SetHBlankCallback(HBlankCB_Phase2_Ripple);
+
+ EnableInterrupts(INTR_FLAG_HBLANK);
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_Ripple_Func2(struct Task *task)
+{
+ u8 i;
+ s16 r3;
+ u16 r4, r8;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ r3 = task->tData2 >> 8;
+ r4 = task->tData1;
+ r8 = 384;
+ task->tData1 += 0x400;
+ if (task->tData2 <= 0x1FFF)
+ task->tData2 += 0x180;
+
+ for (i = 0; i < 160; i++, r4 += r8)
+ {
+ // todo: fix the asm
+ s16 var = r4 >> 8;
+ asm("");
+ gUnknown_02038C28[0][i] = sTransitionStructPtr->field_16 + Sin(var, r3);
+ }
+
+ if (++task->tData3 == 81)
+ {
+ task->tData4++;
+ BeginNormalPaletteFade(-1, -2, 0, 0x10, 0);
+ }
+
+ if (task->tData4 != 0 && !gPaletteFade.active)
+ DestroyTask(FindTaskIdByFunc(Phase2Task_Ripple));
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static void VBlankCB_Phase2_Ripple(void)
+{
+ VBlankCB_BattleTransition();
+ if (sTransitionStructPtr->VBlank_DMA)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+}
+
+static void HBlankCB_Phase2_Ripple(void)
+{
+ u16 var = gUnknown_02038C28[1][REG_VCOUNT];
+ REG_BG1VOFS = var;
+ REG_BG2VOFS = var;
+ REG_BG3VOFS = var;
+}
+
+static void Phase2Task_Wave(u8 taskId)
+{
+ while (sPhase2_Wave_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Wave_Func1(struct Task *task)
+{
+ u8 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ sTransitionStructPtr->WININ = 63;
+ sTransitionStructPtr->WINOUT = 0;
+ sTransitionStructPtr->WIN0H = 240;
+ sTransitionStructPtr->WIN0V = 160;
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_02038C28[1][i] = 242;
+ }
+
+ SetVBlankCallback(VBlankCB_Phase2_Wave);
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_Wave_Func2(struct Task *task)
+{
+ u8 i, r5;
+ u16* toStore;
+ bool8 nextFunc;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ toStore = gUnknown_02038C28[0];
+ r5 = task->tData2;
+ task->tData2 += 16;
+ task->tData1 += 8;
+
+ for (i = 0, nextFunc = TRUE; i < 160; i++, r5 += 4, toStore++)
+ {
+ s16 value = task->tData1 + Sin(r5, 40);
+ if (value < 0)
+ value = 0;
+ if (value > 240)
+ value = 240;
+ *toStore = (value << 8) | (0xF1);
+ if (value < 240)
+ nextFunc = FALSE;
+ }
+ if (nextFunc)
+ task->tState++;
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Wave_Func3(struct Task *task)
+{
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(Phase2Task_Wave));
+ return FALSE;
+}
+
+static void VBlankCB_Phase2_Wave(void)
+{
+ DmaStop(0);
+ VBlankCB_BattleTransition();
+ if (sTransitionStructPtr->VBlank_DMA != 0)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+ REG_WININ = sTransitionStructPtr->WININ;
+ REG_WINOUT = sTransitionStructPtr->WINOUT;
+ REG_WIN0V = sTransitionStructPtr->WIN0V;
+ DmaSet(0, gUnknown_02038C28[1], &REG_WIN0H, 0xA2400001);
+}
+
+static void Phase2Task_Sydney(u8 taskId)
+{
+ gTasks[taskId].tMugshotId = MUGSHOT_SYDNEY;
+ Phase2Task_MugShotTransition(taskId);
+}
+
+static void Phase2Task_Phoebe(u8 taskId)
+{
+ gTasks[taskId].tMugshotId = MUGSHOT_PHOEBE;
+ Phase2Task_MugShotTransition(taskId);
+}
+
+static void Phase2Task_Glacia(u8 taskId)
+{
+ gTasks[taskId].tMugshotId = MUGSHOT_GLACIA;
+ Phase2Task_MugShotTransition(taskId);
+}
+
+static void Phase2Task_Drake(u8 taskId)
+{
+ gTasks[taskId].tMugshotId = MUGSHOT_DRAKE;
+ Phase2Task_MugShotTransition(taskId);
+}
+
+static void Phase2Task_Champion(u8 taskId)
+{
+ gTasks[taskId].tMugshotId = MUGSHOT_CHAMPION;
+ Phase2Task_MugShotTransition(taskId);
+}
+
+static void Phase2Task_MugShotTransition(u8 taskId)
+{
+ while (sPhase2_Mugshot_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Mugshot_Func1(struct Task *task)
+{
+ u8 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+ Mugshots_CreateOpponentPlayerSprites(task);
+
+ task->tData1 = 0;
+ task->tData2 = 1;
+ task->tData3 = 239;
+ sTransitionStructPtr->WININ = 63;
+ sTransitionStructPtr->WINOUT = 62;
+ sTransitionStructPtr->WIN0V = 160;
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_02038C28[1][i] = 0xF0F1;
+ }
+
+ SetVBlankCallback(VBlankCB0_Phase2_Mugshots);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Mugshot_Func2(struct Task *task)
+{
+ s16 i, j;
+ u16 *dst1, *dst2;
+ const u16 *MugshotsMap;
+
+ MugshotsMap = sMugshotsTilemap;
+ sub_8149F58(&dst1, &dst2);
+ CpuSet(sUnknown_085B9AF0, dst2, 0xF0);
+ LoadPalette(sOpponentMugshotsPals[task->tMugshotId], 0xF0, 0x20);
+ LoadPalette(sPlayerMugshotsPals[gSaveBlock2Ptr->playerGender], 0xFA, 0xC);
+
+ for (i = 0; i < 20; i++)
+ {
+ for (j = 0; j < 32; j++, MugshotsMap++)
+ {
+ dst1[i * 32 + j] = *MugshotsMap | 0xF000;
+ }
+ }
+
+ EnableInterrupts(INTR_FLAG_HBLANK);
+
+ SetHBlankCallback(HBlankCB_Phase2_Mugshots);
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Mugshot_Func3(struct Task *task)
+{
+ u8 i, r5;
+ u16* toStore;
+ s16 value;
+ s32 mergedValue;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ toStore = gUnknown_02038C28[0];
+ r5 = task->tData1;
+ task->tData1 += 0x10;
+
+ for (i = 0; i < 80; i++, toStore++, r5 += 0x10)
+ {
+ value = task->tData2 + Sin(r5, 0x10);
+ if (value < 0)
+ value = 1;
+ if (value > 0xF0)
+ value = 0xF0;
+ *toStore = value;
+ }
+ for (; i < 160; i++, toStore++, r5 += 0x10)
+ {
+ value = task->tData3 - Sin(r5, 0x10);
+ if (value < 0)
+ value = 0;
+ if (value > 0xEF)
+ value = 0xEF;
+ *toStore = (value << 8) | (0xF0);
+ }
+
+ task->tData2 += 8;
+ task->tData3 -= 8;
+ if (task->tData2 > 0xF0)
+ task->tData2 = 0xF0;
+ if (task->tData3 < 0)
+ task->tData3 = 0;
+ mergedValue = *(s32*)(&task->tData2);
+ if (mergedValue == 0xF0)
+ task->tState++;
+
+ sTransitionStructPtr->BG0HOFS_1 -= 8;
+ sTransitionStructPtr->BG0HOFS_2 += 8;
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Mugshot_Func4(struct Task *task)
+{
+ u8 i;
+ u16* toStore;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ for (i = 0, toStore = gUnknown_02038C28[0]; i < 160; i++, toStore++)
+ {
+ *toStore = 0xF0;
+ }
+
+ task->tState++;
+ task->tData1 = 0;
+ task->tData2 = 0;
+ task->tData3 = 0;
+ sTransitionStructPtr->BG0HOFS_1 -= 8;
+ sTransitionStructPtr->BG0HOFS_2 += 8;
+
+ sub_8148484(task->tOpponentSpriteId, 0);
+ sub_8148484(task->tPlayerSpriteId, 1);
+ sub_814849C(task->tOpponentSpriteId);
+
+ PlaySE(SE_BT_START);
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Mugshot_Func5(struct Task *task)
+{
+ sTransitionStructPtr->BG0HOFS_1 -= 8;
+ sTransitionStructPtr->BG0HOFS_2 += 8;
+ if (sub_81484B8(task->tOpponentSpriteId))
+ {
+ task->tState++;
+ sub_814849C(task->tPlayerSpriteId);
+ }
+ return FALSE;
+}
+
+static bool8 Phase2_Mugshot_Func6(struct Task *task)
+{
+ sTransitionStructPtr->BG0HOFS_1 -= 8;
+ sTransitionStructPtr->BG0HOFS_2 += 8;
+ if (sub_81484B8(task->tPlayerSpriteId))
+ {
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ SetVBlankCallback(NULL);
+ DmaStop(0);
+ memset(gUnknown_02038C28[0], 0, 0x140);
+ memset(gUnknown_02038C28[1], 0, 0x140);
+ SetGpuReg(REG_OFFSET_WIN0H, 0xF0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ task->tState++;
+ task->tData3 = 0;
+ task->tData4 = 0;
+ sTransitionStructPtr->BLDCNT = 0xBF;
+ SetVBlankCallback(VBlankCB1_Phase2_Mugshots);
+ }
+ return FALSE;
+}
+
+static bool8 Phase2_Mugshot_Func7(struct Task *task)
+{
+ bool32 r6;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ r6 = TRUE;
+ sTransitionStructPtr->BG0HOFS_1 -= 8;
+ sTransitionStructPtr->BG0HOFS_2 += 8;
+
+ if (task->tData4 < 0x50)
+ task->tData4 += 2;
+ if (task->tData4 > 0x50)
+ task->tData4 = 0x50;
+
+ if (++task->tData3 & 1)
+ {
+ s16 i;
+ for (i = 0, r6 = FALSE; i <= task->tData4; i++)
+ {
+ s16 index1 = 0x50 - i;
+ s16 index2 = 0x50 + i;
+ if (gUnknown_02038C28[0][index1] <= 15)
+ {
+ r6 = TRUE;
+ gUnknown_02038C28[0][index1]++;
+ }
+ if (gUnknown_02038C28[0][index2] <= 15)
+ {
+ r6 = TRUE;
+ gUnknown_02038C28[0][index2]++;
+ }
+ }
+ }
+
+ if (task->tData4 == 0x50 && !r6)
+ task->tState++;
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Mugshot_Func8(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ BlendPalettes(-1, 0x10, 0x7FFF);
+ sTransitionStructPtr->BLDCNT = 0xFF;
+ task->tData3 = 0;
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_Mugshot_Func9(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ task->tData3++;
+ memset(gUnknown_02038C28[0], task->tData3, 0x140);
+ if (task->tData3 > 15)
+ task->tState++;
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Mugshot_Func10(struct Task *task)
+{
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(task->func));
+ return FALSE;
+}
+
+static void VBlankCB0_Phase2_Mugshots(void)
+{
+ DmaStop(0);
+ VBlankCB_BattleTransition();
+ if (sTransitionStructPtr->VBlank_DMA != 0)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+ REG_BG0VOFS = sTransitionStructPtr->BG0VOFS;
+ REG_WININ = sTransitionStructPtr->WININ;
+ REG_WINOUT = sTransitionStructPtr->WINOUT;
+ REG_WIN0V = sTransitionStructPtr->WIN0V;
+ DmaSet(0, gUnknown_02038C28[1], &REG_WIN0H, 0xA2400001);
+}
+
+static void VBlankCB1_Phase2_Mugshots(void)
+{
+ DmaStop(0);
+ VBlankCB_BattleTransition();
+ if (sTransitionStructPtr->VBlank_DMA != 0)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+ REG_BLDCNT = sTransitionStructPtr->BLDCNT;
+ DmaSet(0, gUnknown_02038C28[1], &REG_BLDY, 0xA2400001);
+}
+
+static void HBlankCB_Phase2_Mugshots(void)
+{
+ if (REG_VCOUNT < 80)
+ REG_BG0HOFS = sTransitionStructPtr->BG0HOFS_1;
+ else
+ REG_BG0HOFS = sTransitionStructPtr->BG0HOFS_2;
+}
+
+static void Mugshots_CreateOpponentPlayerSprites(struct Task *task)
+{
+ struct Sprite *opponentSprite, *playerSprite;
+
+ s16 mugshotId = task->tMugshotId;
+ task->tOpponentSpriteId = CreateTrainerSprite(sMugshotsTrainerPicIDsTable[mugshotId],
+ sMugshotsOpponentCoords[mugshotId][0] - 32,
+ sMugshotsOpponentCoords[mugshotId][1] + 42,
+ 0, gDecompressionBuffer);
+ task->tPlayerSpriteId = CreateTrainerSprite(PlayerGenderToFrontTrainerPicId(gSaveBlock2Ptr->playerGender), 272, 106, 0, gDecompressionBuffer);
+
+ opponentSprite = &gSprites[task->tOpponentSpriteId];
+ playerSprite = &gSprites[task->tPlayerSpriteId];
+
+ opponentSprite->callback = sub_8148380;
+ playerSprite->callback = sub_8148380;
+
+ opponentSprite->oam.affineMode = 3;
+ playerSprite->oam.affineMode = 3;
+
+ opponentSprite->oam.matrixNum = AllocOamMatrix();
+ playerSprite->oam.matrixNum = AllocOamMatrix();
+
+ opponentSprite->oam.shape = 1;
+ playerSprite->oam.shape = 1;
+
+ opponentSprite->oam.size = 3;
+ playerSprite->oam.size = 3;
+
+ CalcCenterToCornerVec(opponentSprite, 1, 3, 3);
+ CalcCenterToCornerVec(playerSprite, 1, 3, 3);
+
+ SetOamMatrixRotationScaling(opponentSprite->oam.matrixNum, sMugshotsOpponentRotationScales[mugshotId][0], sMugshotsOpponentRotationScales[mugshotId][1], 0);
+ SetOamMatrixRotationScaling(playerSprite->oam.matrixNum, -512, 512, 0);
+}
+
+static void sub_8148380(struct Sprite *sprite)
+{
+ while (sUnknown_085C8C24[sprite->data[0]](sprite));
+}
+
+static bool8 sub_81483A8(struct Sprite *sprite)
+{
+ return FALSE;
+}
+
+static bool8 sub_81483AC(struct Sprite *sprite)
+{
+ s16 arr0[2];
+ s16 arr1[2];
+
+ memcpy(arr0, sUnknown_085C8C40, sizeof(sUnknown_085C8C40));
+ memcpy(arr1, sUnknown_085C8C44, sizeof(sUnknown_085C8C44));
+
+ sprite->data[0]++;
+ sprite->data[1] = arr0[sprite->data[7]];
+ sprite->data[2] = arr1[sprite->data[7]];
+ return TRUE;
+}
+
+static bool8 sub_81483F8(struct Sprite *sprite)
+{
+ sprite->pos1.x += sprite->data[1];
+ if (sprite->data[7] && sprite->pos1.x < 133)
+ sprite->data[0]++;
+ else if (!sprite->data[7] && sprite->pos1.x > 103)
+ sprite->data[0]++;
+ return FALSE;
+}
+
+static bool8 sub_814842C(struct Sprite *sprite)
+{
+ sprite->data[1] += sprite->data[2];
+ sprite->pos1.x += sprite->data[1];
+ if (sprite->data[1] == 0)
+ {
+ sprite->data[0]++;
+ sprite->data[2] = -sprite->data[2];
+ sprite->data[6] = 1;
+ }
+ return FALSE;
+}
+
+static bool8 sub_8148458(struct Sprite *sprite)
+{
+ sprite->data[1] += sprite->data[2];
+ sprite->pos1.x += sprite->data[1];
+ if (sprite->pos1.x < -31 || sprite->pos1.x > 271)
+ sprite->data[0]++;
+ return FALSE;
+}
+
+static void sub_8148484(s16 spriteId, s16 value)
+{
+ gSprites[spriteId].data[7] = value;
+}
+
+static void sub_814849C(s16 spriteId)
+{
+ gSprites[spriteId].data[0]++;
+}
+
+static s16 sub_81484B8(s16 spriteId)
+{
+ return gSprites[spriteId].data[6];
+}
+
+static void Phase2Task_Slice(u8 taskId)
+{
+ while (sPhase2_Slice_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Slice_Func1(struct Task *task)
+{
+ u16 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ task->tData2 = 256;
+ task->tData3 = 1;
+ sTransitionStructPtr->WININ = 63;
+ sTransitionStructPtr->WINOUT = 0;
+ sTransitionStructPtr->WIN0V = 160;
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_02038C28[1][i] = sTransitionStructPtr->field_14;
+ gUnknown_02038C28[1][160 + i] = 0xF0;
+ }
+
+ EnableInterrupts(INTR_FLAG_HBLANK);
+ SetGpuRegBits(REG_OFFSET_DISPSTAT, DISPSTAT_HBLANK_INTR);
+
+ SetVBlankCallback(VBlankCB_Phase2_Slice);
+ SetHBlankCallback(HBlankCB_Phase2_Slice);
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_Slice_Func2(struct Task *task)
+{
+ u16 i;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ task->tData1 += (task->tData2 >> 8);
+ if (task->tData1 > 0xF0)
+ task->tData1 = 0xF0;
+ if (task->tData2 <= 0xFFF)
+ task->tData2 += task->tData3;
+ if (task->tData3 < 128)
+ task->tData3 <<= 1; // multiplying by two
+
+ for (i = 0; i < 160; i++)
+ {
+ u16 *storeLoc1 = &gUnknown_02038C28[0][i];
+ u16 *storeLoc2 = &gUnknown_02038C28[0][i + 160];
+ if (i & 1)
+ {
+ *storeLoc1 = sTransitionStructPtr->field_14 + task->tData1;
+ *storeLoc2 = 0xF0 - task->tData1;
+ }
+ else
+ {
+ *storeLoc1 = sTransitionStructPtr->field_14 - task->tData1;
+ *storeLoc2 = (task->tData1 << 8) | (0xF1);
+ }
+ }
+
+ if (task->tData1 > 0xEF)
+ task->tState++;
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Slice_Func3(struct Task *task)
+{
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(Phase2Task_Slice));
+ return FALSE;
+}
+
+static void VBlankCB_Phase2_Slice(void)
+{
+ DmaStop(0);
+ VBlankCB_BattleTransition();
+ REG_WININ = sTransitionStructPtr->WININ;
+ REG_WINOUT = sTransitionStructPtr->WINOUT;
+ REG_WIN0V = sTransitionStructPtr->WIN0V;
+ if (sTransitionStructPtr->VBlank_DMA)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 640);
+ DmaSet(0, &gUnknown_02038C28[1][160], &REG_WIN0H, 0xA2400001);
+}
+
+static void HBlankCB_Phase2_Slice(void)
+{
+ if (REG_VCOUNT < 160)
+ {
+ u16 var = gUnknown_02038C28[1][REG_VCOUNT];
+ REG_BG1HOFS = var;
+ REG_BG2HOFS = var;
+ REG_BG3HOFS = var;
+ }
+}
+
+static void Phase2Task_ShredSplit(u8 taskId)
+{
+ while (sPhase2_ShredSplit_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_ShredSplit_Func1(struct Task *task)
+{
+ u16 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ sTransitionStructPtr->WININ = 63;
+ sTransitionStructPtr->WINOUT = 0;
+ sTransitionStructPtr->WIN0V = 160;
+
+ for (i = 0; i < 0xA0; i++)
+ {
+ gUnknown_02038C28[1][i] = sTransitionStructPtr->field_14;
+ gUnknown_02038C28[1][0xA0 + i] = 0xF0;
+ gUnknown_02038C28[0][i] = sTransitionStructPtr->field_14;
+ gUnknown_02038C28[0][0xA0 + i] = 0xF0;
+ gUnknown_02038C28[0][0x140 + i] = 0;
+ gUnknown_02038C28[0][0x1E0 + i] = 0x100;
+ gUnknown_02038C28[0][0x280 + i] = 1;
+ }
+
+ task->tData4 = 0;
+ task->tData5 = 0;
+ task->tData6 = 7;
+
+ EnableInterrupts(INTR_FLAG_HBLANK);
+
+ SetVBlankCallback(VBlankCB_Phase2_Slice);
+ SetHBlankCallback(HBlankCB_Phase2_Slice);
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_ShredSplit_Func2(struct Task *task)
+{
+ u16 i, j, k;
+ u8 arr1[ARRAY_COUNT(gUnknown_085C8C64)];
+ s16 arr2[ARRAY_COUNT(gUnknown_085C8C66)];
+ u8 var;
+ u16 *ptr4, *ptr3, *ptr1, *ptr2;
+ s16 unkVar;
+
+ memcpy(arr1, gUnknown_085C8C64, sizeof(arr1));
+ memcpy(arr2, gUnknown_085C8C66, sizeof(arr2));
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ var = 0;
+
+ for (i = 0; i <= task->tData5; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ for (k = 0; k < 2; k++)
+ {
+ unkVar = (arr1[j]) + (arr2[k] * -(i) * 2);
+ if (unkVar >= 0 && (unkVar != 79 || j != 1))
+ {
+ ptr4 = &gUnknown_02038C28[0][unkVar + 320];
+ ptr3 = &gUnknown_02038C28[0][unkVar + 480];
+ ptr1 = &gUnknown_02038C28[0][unkVar + 640];
+ if (*ptr4 > 0xEF)
+ {
+ *ptr4 = 0xF0;
+ var++;
+ }
+ else
+ {
+ *ptr4 += (*ptr3 >> 8);
+ if (*ptr1 <= 0x7F)
+ *ptr1 *= 2;
+ if (*ptr3 <= 0xFFF)
+ *ptr3 += *ptr1;
+ }
+ ptr2 = &gUnknown_02038C28[0][unkVar];
+ ptr3 = &gUnknown_02038C28[0][unkVar + 160];
+ *ptr2 = sTransitionStructPtr->field_14 + *ptr4;
+ *ptr3 = 0xF0 - *ptr4;
+
+ if (i == 0)
+ break;
+ }
+ }
+ }
+
+ for (j = 0; j < 2; j++)
+ {
+ for (k = 0; k < 2; k++)
+ {
+ unkVar = (arr1[j] + 1) + (arr2[k] * -(i) * 2);
+ if (unkVar <= 160 && (unkVar != 80 || j != 1))
+ {
+ ptr4 = &gUnknown_02038C28[0][unkVar + 320];
+ ptr3 = &gUnknown_02038C28[0][unkVar + 480];
+ ptr1 = &gUnknown_02038C28[0][unkVar + 640];
+ if (*ptr4 > 0xEF)
+ {
+ *ptr4 = 0xF0;
+ var++;
+ }
+ else
+ {
+ *ptr4 += (*ptr3 >> 8);
+ if (*ptr1 <= 0x7F)
+ *ptr1 *= 2;
+ if (*ptr3 <= 0xFFF)
+ *ptr3 += *ptr1;
+ }
+ ptr2 = &gUnknown_02038C28[0][unkVar];
+ ptr3 = &gUnknown_02038C28[0][unkVar + 160];
+ *ptr2 = sTransitionStructPtr->field_14 - *ptr4;
+ *ptr3 = (*ptr4 << 8) | (0xF1);
+
+ if (i == 0)
+ break;
+ }
+ }
+ }
+ }
+
+ if (--task->tData4 < 0)
+ task->tData4 = 0;
+ if (task->tData4 <= 0 && task->tData5 + 1 <= 20)
+ task->tData4 = task->tData6, task->tData5++;
+ if (var > 0x9F)
+ task->tState++;
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_ShredSplit_Func3(struct Task *task)
+{
+ u16 i;
+ bool32 done = TRUE;
+ u16 checkVar2 = 0xFF10;
+
+ for (i = 0; i < 0xA0; i++)
+ {
+ if (gUnknown_02038C28[1][i] != 0xF0 && gUnknown_02038C28[1][i] != checkVar2)
+ done = FALSE; // a break statement should be put here
+ }
+
+ if (done == TRUE)
+ task->tState++;
+
+ return FALSE;
+}
+
+static bool8 Phase2_ShredSplit_Func4(struct Task *task)
+{
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(Phase2Task_ShredSplit));
+ return FALSE;
+}
+
+static void Phase2Task_Blackhole1(u8 taskId)
+{
+ while (sPhase2_Blackhole1_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_Blackhole2(u8 taskId)
+{
+ while (sPhase2_Blackhole2_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Blackhole_Func1(struct Task *task)
+{
+ s32 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ sTransitionStructPtr->WININ = 0;
+ sTransitionStructPtr->WINOUT = 63;
+ sTransitionStructPtr->WIN0H = 240;
+ sTransitionStructPtr->WIN0V = 160;
+
+ for (i = 0; i < 0xA0; i++)
+ {
+ gUnknown_02038C28[1][i] = 0;
+ }
+
+ SetVBlankCallback(VBlankCB1_Phase2_BigPokeball);
+
+ task->tState++;
+ task->tData1 = 1;
+ task->tData2 = 0x100;
+ task->tFuncState = 0;
+
+ return FALSE;
+}
+
+static bool8 Phase2_Blackhole1_Func3(struct Task *task)
+{
+ if (task->tFuncState == 1)
+ {
+ DmaStop(0);
+ SetVBlankCallback(NULL);
+ DestroyTask(FindTaskIdByFunc(task->func));
+ }
+ else
+ {
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ if (task->tData2 < 0x400)
+ task->tData2 += 0x80;
+ if (task->tData1 < 0xA0)
+ task->tData1 += (task->tData2 >> 8);
+ if (task->tData1 > 0xA0)
+ task->tData1 = 0xA0;
+ sub_814A014(gUnknown_02038C28[0], 0x78, 0x50, task->tData1);
+ if (task->tData1 == 0xA0)
+ {
+ task->tFuncState = 1;
+ sub_8149F84();
+ }
+ else
+ {
+ sTransitionStructPtr->VBlank_DMA++;
+ }
+ }
+
+ return FALSE;
+}
+
+static bool8 Phase2_Blackhole1_Func2(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ if (task->tFuncState == 0)
+ {
+ task->tFuncState++;
+ task->tData1 = 0x30;
+ task->tData6 = 0;
+ }
+ task->tData1 += gUnknown_085C8C80[task->tData6];
+ task->tData6 = (task->tData6 + 1) % 2;
+ sub_814A014(gUnknown_02038C28[0], 0x78, 0x50, task->tData1);
+ if (task->tData1 < 9)
+ {
+ task->tState++;
+ task->tFuncState = 0;
+ }
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Blackhole2_Func2(struct Task *task)
+{
+ u16 index; // should be s16 I think
+ s16 amplitude;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+ if (task->tFuncState == 0)
+ {
+ task->tFuncState++;
+ task->tData5 = 2;
+ task->tData6 = 2;
+ }
+ if (task->tData1 > 0xA0)
+ task->tData1 = 0xA0;
+
+ sub_814A014(gUnknown_02038C28[0], 0x78, 0x50, task->tData1);
+ if (task->tData1 == 0xA0)
+ {
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(task->func));
+ }
+
+ index = task->tData5;
+ if ((task->tData5 & 0xFF) <= 128)
+ {
+ amplitude = task->tData6;
+ task->tData5 += 8;
+ }
+ else
+ {
+ amplitude = task->tData6 - 1;
+ task->tData5 += 16;
+ }
+ task->tData1 += Sin(index & 0xFF, amplitude);
+
+ if (task->tData1 <= 0)
+ task->tData1 = 1;
+ if (task->tData5 > 0xFE)
+ task->tData5 >>= 8, task->tData6++;
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static void Phase2Task_RectangularSpiral(u8 taskId)
+{
+ while (sPhase2_RectangularSpiral_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_RectangularSpiral_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ CpuCopy16(sShrinkingBoxTileset, dst2, 0x20);
+ CpuCopy16(sShrinkingBoxTileset + 0x70, dst2 + 0x20, 0x20);
+ CpuFill16(0xF000, dst1, 0x800);
+ LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20);
+
+ task->tData3 = 1;
+ task->tState++;
+
+ sRectangularSpiralTransition[0].field_0 = 0;
+ sRectangularSpiralTransition[0].field_2 = -1;
+ sRectangularSpiralTransition[0].field_4 = 1;
+ sRectangularSpiralTransition[0].field_6 = 308;
+ sRectangularSpiralTransition[0].field_8 = 0;
+
+ sRectangularSpiralTransition[1].field_0 = 0;
+ sRectangularSpiralTransition[1].field_2 = -1;
+ sRectangularSpiralTransition[1].field_4 = 1;
+ sRectangularSpiralTransition[1].field_6 = 308;
+ sRectangularSpiralTransition[1].field_8 = 0;
+
+ sRectangularSpiralTransition[2].field_0 = 0;
+ sRectangularSpiralTransition[2].field_2 = -3;
+ sRectangularSpiralTransition[2].field_4 = 1;
+ sRectangularSpiralTransition[2].field_6 = 307;
+ sRectangularSpiralTransition[2].field_8 = 0;
+
+ sRectangularSpiralTransition[3].field_0 = 0;
+ sRectangularSpiralTransition[3].field_2 = -3;
+ sRectangularSpiralTransition[3].field_4 = 1;
+ sRectangularSpiralTransition[3].field_6 = 307;
+ sRectangularSpiralTransition[3].field_8 = 0;
+
+ return FALSE;
+}
+
+static bool8 Phase2_RectangularSpiral_Func2(struct Task *task)
+{
+ u16 *dst1, *dst2;
+ u8 i;
+ u16 j;
+ bool32 done = TRUE;
+
+ sub_8149F58(&dst1, &dst2);
+
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < ARRAY_COUNT(sRectangularSpiralTransition); j++)
+ {
+ s16 var = 0, var2 = 0;
+ s32 var3 = 0;
+
+ if (sub_8149048(gUnknown_085C8D38[j / 2], &sRectangularSpiralTransition[j]))
+ {
+ u32 one;
+ done = FALSE;
+ var = sRectangularSpiralTransition[j].field_2;
+ one = 1;
+ if ((j & 1) == one)
+ var = 0x27D - var;
+
+ var2 = var % 32;
+ var3 = var / 32 * 32;
+
+ dst1[var3 + var2] = 0xF002;
+ }
+ }
+ }
+
+ if (done == TRUE)
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_RectangularSpiral_Func3(struct Task *task)
+{
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(task->func));
+ return FALSE;
+}
+
+static bool16 sub_8149048(const s16 * const *arg0, struct StructRectangularSpiral *arg1)
+{
+ const s16 *array = arg0[arg1->field_0];
+ if (array[arg1->field_4] == -1)
+ return FALSE;
+
+ // ??
+ sUnusedRectangularSpiralVar = array[0];
+ sUnusedRectangularSpiralVar = array[1];
+ sUnusedRectangularSpiralVar = array[2];
+ sUnusedRectangularSpiralVar = array[3];
+
+ switch (array[0])
+ {
+ case 1:
+ arg1->field_2 += 0x1;
+ break;
+ case 2:
+ arg1->field_2 -= 0x1;
+ break;
+ case 3:
+ arg1->field_2 -= 0x20;
+ break;
+ case 4:
+ arg1->field_2 += 0x20;
+ break;
+ }
+
+ if (arg1->field_2 > 0x27F || array[arg1->field_4] == -1)
+ return FALSE;
+
+ if (arg1->field_8 == 0 && array[arg1->field_4] == -2)
+ {
+ arg1->field_8 = 1;
+ arg1->field_4 = 1;
+ arg1->field_2 = arg1->field_6;
+ arg1->field_0 = 4;
+ }
+
+ if (arg1->field_2 == array[arg1->field_4])
+ {
+ (arg1->field_0)++;
+ if (arg1->field_8 == 1)
+ {
+ if (arg1->field_0 > 7)
+ {
+ (arg1->field_4)++;
+ (arg1->field_0) = 4;
+ }
+ }
+ else
+ {
+ if (arg1->field_0 > 3)
+ {
+ (arg1->field_4)++;
+ (arg1->field_0) = 0;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static void Phase2Task_Groudon(u8 taskId)
+{
+ while (sPhase2_Groudon_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Groudon_Func3(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ CpuFill16(0, dst1, 0x800);
+ LZ77UnCompVram(gUnknown_085BE51C, dst2);
+ LZ77UnCompVram(gUnknown_085BEA88, dst1);
+
+ task->tState++;
+ task->tData1 = 0;
+ return FALSE;
+}
+
+static bool8 Phase2_Groudon_Func4(struct Task *task)
+{
+ if (task->tData1 % 3 == 0)
+ {
+ u16 var = (task->tData1 % 30) / 3;
+ LoadPalette(gUnknown_085BF0A0 + (var * 16), 0xF0, 0x20);
+ }
+ if (++task->tData1 > 58)
+ {
+ task->tState++;
+ task->tData1 = 0;
+ }
+
+ return FALSE;
+}
+
+static bool8 Phase2_Groudon_Func5(struct Task *task)
+{
+ if (task->tData1 % 5 == 0)
+ {
+ s16 var = task->tData1 / 5;
+ LoadPalette(gUnknown_085BF2A0 + (var * 16), 0xF0, 0x20);
+ }
+ if (++task->tData1 > 68)
+ {
+ task->tState++;
+ task->tData1 = 0;
+ task->tFrames = 30;
+ }
+
+ return FALSE;
+}
+
+static void Phase2Task_Rayquaza(u8 taskId)
+{
+ while (sPhase2_Rayquaza_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Rayquaza_Func3(struct Task *task)
+{
+ u16 *dst1, *dst2;
+ u16 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ SetGpuReg(REG_OFFSET_BG0CNT, 0x9A08);
+ sub_8149F58(&dst1, &dst2);
+ CpuFill16(0, dst1, 0x800);
+ CpuCopy16(gUnknown_085BF6A0, dst2, 0x2000);
+
+ sTransitionStructPtr->field_20 = 0;
+ task->tState++;
+ LoadPalette(gUnknown_085BF4A0 + 0x50, 0xF0, 0x20);
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_02038C28[0][i] = 0;
+ gUnknown_02038C28[1][i] = 0x100;
+ }
+
+ SetVBlankCallback(VBlankCB_Phase2_Rayquaza);
+ return FALSE;
+}
+
+static bool8 Phase2_Rayquaza_Func4(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ CpuCopy16(gUnknown_085C6BE0, dst1, 0x1000);
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Rayquaza_Func5(struct Task *task)
+{
+ if ((task->tData1 % 4) == 0)
+ {
+ u16 value = task->tData1 / 4;
+ const u16 *palPtr = &gUnknown_085BF4A0[(value + 5) * 16];
+ LoadPalette(palPtr, 0xF0, 0x20);
+ }
+ if (++task->tData1 > 40)
+ {
+ task->tState++;
+ task->tData1 = 0;
+ }
+
+ return FALSE;
+}
+
+static bool8 Phase2_Rayquaza_Func6(struct Task *task)
+{
+ if (++task->tData1 > 20)
+ {
+ task->tState++;
+ task->tData1 = 0;
+ BeginNormalPaletteFade(0xFFFF8000, 2, 0, 0x10, 0);
+ }
+
+ return FALSE;
+}
+
+static bool8 Phase2_Rayquaza_Func7(struct Task *task)
+{
+ if (!gPaletteFade.active)
+ {
+ sTransitionStructPtr->field_20 = 1;
+ task->tState++;
+ }
+
+ return FALSE;
+}
+
+static bool8 Phase2_Rayquaza_Func8(struct Task *task)
+{
+ BlendPalettes(0x00007FFF, 8, 0);
+ BlendPalettes(0xFFFF8000, 0, 0);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_Rayquaza_Func9(struct Task *task)
+{
+ if ((task->tData1 % 3) == 0)
+ {
+ u16 value = task->tData1 / 3;
+ const u16 *palPtr = &gUnknown_085BF4A0[(value + 0) * 16];
+ LoadPalette(palPtr, 0xF0, 0x20);
+ }
+ if (++task->tData1 >= 40)
+ {
+ u16 i;
+
+ sTransitionStructPtr->WININ = 0;
+ sTransitionStructPtr->WINOUT = 63;
+ sTransitionStructPtr->WIN0H = 240;
+ sTransitionStructPtr->WIN0V = 160;
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_02038C28[1][i] = 0;
+ }
+
+ SetVBlankCallback(VBlankCB1_Phase2_BigPokeball);
+ task->tState++;
+ task->tData2 = 0x100;
+ task->tFuncState = 0;
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG0_ON);
+ }
+
+ return FALSE;
+}
+
+static void VBlankCB_Phase2_Rayquaza(void)
+{
+ void *dmaSrc;
+
+ DmaStop(0);
+ VBlankCB_BattleTransition();
+
+ if (sTransitionStructPtr->field_20 == 0)
+ dmaSrc = gUnknown_02038C28[0];
+ else if (sTransitionStructPtr->field_20 == 1)
+ dmaSrc = gUnknown_02038C28[1];
+ else
+ dmaSrc = gUnknown_02038C28[0];
+
+ DmaSet(0, dmaSrc, &REG_BG0VOFS, 0xA2400001);
+}
+
+static void Phase2Task_WhiteFade(u8 taskId)
+{
+ while (sPhase2_WhiteFade_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_WhiteFade_Func1(struct Task *task)
+{
+ u16 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ sTransitionStructPtr->BLDCNT = 0xBF;
+ sTransitionStructPtr->BLDY = 0;
+ sTransitionStructPtr->WININ = 0x1E;
+ sTransitionStructPtr->WINOUT = 0x3F;
+ sTransitionStructPtr->WIN0V = 0xA0;
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_02038C28[1][i] = 0;
+ gUnknown_02038C28[1][i + 160] = 0xF0;
+ }
+
+ EnableInterrupts(INTR_FLAG_HBLANK);
+ SetHBlankCallback(HBlankCB_Phase2_WhiteFade);
+ SetVBlankCallback(VBlankCB0_Phase2_WhiteFade);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_WhiteFade_Func2(struct Task *task)
+{
+ s16 i, posY;
+ s16 arr1[ARRAY_COUNT(sUnknown_085C8DA0)];
+ struct Sprite *sprite;
+
+ memcpy(arr1, sUnknown_085C8DA0, sizeof(sUnknown_085C8DA0));
+ for (i = 0, posY = 0; i < 8; i++, posY += 0x14)
+ {
+ sprite = &gSprites[CreateInvisibleSprite(sub_8149864)];
+ sprite->pos1.x = 0xF0;
+ sprite->pos1.y = posY;
+ sprite->data[5] = arr1[i];
+ }
+ sprite->data[6]++;
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_WhiteFade_Func3(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = 0;
+ if (sTransitionStructPtr->field_20 > 7)
+ {
+ BlendPalettes(-1, 0x10, 0x7FFF);
+ task->tState++;
+ }
+ return FALSE;
+}
+
+static bool8 Phase2_WhiteFade_Func4(struct Task *task)
+{
+ sTransitionStructPtr->VBlank_DMA = 0;
+
+ DmaStop(0);
+ SetVBlankCallback(0);
+ SetHBlankCallback(0);
+
+ sTransitionStructPtr->WIN0H = 0xF0;
+ sTransitionStructPtr->BLDY = 0;
+ sTransitionStructPtr->BLDCNT = 0xFF;
+ sTransitionStructPtr->WININ = 0x3F;
+
+ SetVBlankCallback(VBlankCB1_Phase2_WhiteFade);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_WhiteFade_Func5(struct Task *task)
+{
+ if (++sTransitionStructPtr->BLDY > 16)
+ {
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(Phase2Task_WhiteFade));
+ }
+ return FALSE;
+}
+
+static void VBlankCB0_Phase2_WhiteFade(void)
+{
+ DmaStop(0);
+ VBlankCB_BattleTransition();
+ REG_BLDCNT = sTransitionStructPtr->BLDCNT;
+ REG_WININ = sTransitionStructPtr->WININ;
+ REG_WINOUT = sTransitionStructPtr->WINOUT;
+ REG_WIN0V = sTransitionStructPtr->WIN0V;
+ if (sTransitionStructPtr->VBlank_DMA)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 640);
+ DmaSet(0, &gUnknown_02038C28[1][160], &REG_WIN0H, 0xA2400001);
+}
+
+static void VBlankCB1_Phase2_WhiteFade(void)
+{
+ VBlankCB_BattleTransition();
+ REG_BLDY = sTransitionStructPtr->BLDY;
+ REG_BLDCNT = sTransitionStructPtr->BLDCNT;
+ REG_WININ = sTransitionStructPtr->WININ;
+ REG_WINOUT = sTransitionStructPtr->WINOUT;
+ REG_WIN0H = sTransitionStructPtr->WIN0H;
+ REG_WIN0V = sTransitionStructPtr->WIN0V;
+}
+
+static void HBlankCB_Phase2_WhiteFade(void)
+{
+ REG_BLDY = gUnknown_02038C28[1][REG_VCOUNT];
+}
+
+static void sub_8149864(struct Sprite *sprite)
+{
+ if (sprite->data[5])
+ {
+ sprite->data[5]--;
+ if (sprite->data[6])
+ sTransitionStructPtr->VBlank_DMA = 1;
+ }
+ else
+ {
+ u16 i;
+ u16* ptr1 = &gUnknown_02038C28[0][sprite->pos1.y];
+ u16* ptr2 = &gUnknown_02038C28[0][sprite->pos1.y + 160];
+ for (i = 0; i < 20; i++)
+ {
+ ptr1[i] = sprite->data[0] >> 8;
+ ptr2[i] = (u8)(sprite->pos1.x);
+ }
+ if (sprite->pos1.x == 0 && sprite->data[0] == 0x1000)
+ sprite->data[1] = 1;
+
+ sprite->pos1.x -= 16;
+ sprite->data[0] += 0x80;
+
+ if (sprite->pos1.x < 0)
+ sprite->pos1.x = 0;
+ if (sprite->data[0] > 0x1000)
+ sprite->data[0] = 0x1000;
+
+ if (sprite->data[6])
+ sTransitionStructPtr->VBlank_DMA = 1;
+
+ if (sprite->data[1])
+ {
+ if (sprite->data[6] == 0 || (sTransitionStructPtr->field_20 > 6 && sprite->data[2]++ > 7))
+ {
+ sTransitionStructPtr->field_20++;
+ DestroySprite(sprite);
+ }
+ }
+ }
+}
+
+static void Phase2Task_GridSquares(u8 taskId)
+{
+ while (sPhase2_GridSquares_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_GridSquares_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ CpuSet(sShrinkingBoxTileset, dst2, 0x10);
+ CpuFill16(0xF000, dst1, 0x800);
+ LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_GridSquares_Func2(struct Task *task)
+{
+ u16* dst1;
+
+ if (task->tData1 == 0)
+ {
+ sub_8149F40(&dst1);
+ task->tData1 = 3;
+ task->tData2++;
+ CpuSet(sShrinkingBoxTileset + (task->tData2 * 8), dst1, 0x10);
+ if (task->tData2 > 0xD)
+ {
+ task->tState++;
+ task->tData1 = 16;
+ }
+ }
+
+ task->tData1--;
+ return FALSE;
+}
+
+static bool8 Phase2_GridSquares_Func3(struct Task *task)
+{
+ if (--task->tData1 == 0)
+ {
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(Phase2Task_GridSquares));
+ }
+ return FALSE;
+}
+
+static void Phase2Task_Shards(u8 taskId)
+{
+ while (sPhase2_Shards_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_Shards_Func1(struct Task *task)
+{
+ u16 i;
+
+ sub_8149F08();
+ dp12_8087EA4();
+
+ sTransitionStructPtr->WININ = 0x3F;
+ sTransitionStructPtr->WINOUT = 0;
+ sTransitionStructPtr->WIN0V = 0xA0;
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_02038C28[0][i] = 0xF0;
+ }
+
+ CpuSet(gUnknown_02038C28[0], gUnknown_02038C28[1], 0xA0);
+ SetVBlankCallback(VBlankCB_Phase2_Shards);
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_Shards_Func2(struct Task *task)
+{
+ sub_814A1AC(sTransitionStructPtr->data,
+ sUnknown_085C8DD0[task->tData1][0],
+ sUnknown_085C8DD0[task->tData1][1],
+ sUnknown_085C8DD0[task->tData1][2],
+ sUnknown_085C8DD0[task->tData1][3],
+ 1, 1);
+ task->tData2 = sUnknown_085C8DD0[task->tData1][4];
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_Shards_Func3(struct Task *task)
+{
+ s16 i;
+ bool8 nextFunc;
+
+ sTransitionStructPtr->VBlank_DMA = 0;
+
+ for (i = 0, nextFunc = FALSE; i < 16; i++)
+ {
+ s16 r3 = gUnknown_02038C28[0][sTransitionStructPtr->data[3]] >> 8;
+ s16 r4 = gUnknown_02038C28[0][sTransitionStructPtr->data[3]] & 0xFF;
+ if (task->tData2 == 0)
+ {
+ if (r3 < sTransitionStructPtr->data[2])
+ r3 = sTransitionStructPtr->data[2];
+ if (r3 > r4)
+ r3 = r4;
+ }
+ else
+ {
+ if (r4 > sTransitionStructPtr->data[2])
+ r4 = sTransitionStructPtr->data[2];
+ if (r4 <= r3)
+ r4 = r3;
+ }
+ gUnknown_02038C28[0][sTransitionStructPtr->data[3]] = (r4) | (r3 << 8);
+ if (nextFunc)
+ {
+ task->tState++;
+ break;
+ }
+ else
+ nextFunc = sub_814A228(sTransitionStructPtr->data, 1, 1);
+ }
+
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static bool8 Phase2_Shards_Func4(struct Task *task)
+{
+ if (++task->tData1 < 7)
+ {
+ task->tState++;
+ task->tData3 = sUnknown_085C8E16[task->tData1 - 1];
+ return TRUE;
+ }
+ else
+ {
+ DmaStop(0);
+ sub_8149F84();
+ DestroyTask(FindTaskIdByFunc(Phase2Task_Shards));
+ return FALSE;
+ }
+}
+
+static bool8 Phase2_Shards_Func5(struct Task *task)
+{
+ if (--task->tData3 == 0)
+ {
+ task->tState = 1;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void VBlankCB_Phase2_Shards(void)
+{
+ DmaStop(0);
+ VBlankCB_BattleTransition();
+ if (sTransitionStructPtr->VBlank_DMA)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+ REG_WININ = sTransitionStructPtr->WININ;
+ REG_WINOUT = sTransitionStructPtr->WINOUT;
+ REG_WIN0V = sTransitionStructPtr->WIN0V;
+ REG_WIN0H = gUnknown_02038C28[1][0];
+ DmaSet(0, gUnknown_02038C28[1], &REG_WIN0H, 0xA2400001);
+}
+
+// sub-task for phase2
+#undef tData1
+#undef tData2
+#undef tData3
+#undef tData4
+#undef tData5
+#undef tData6
+#undef tFuncState
+#undef tFrames
+#undef tOpponentSpriteId
+#undef tPlayerSpriteId
+#undef tMugshotId
+
+// sub-task for sub-task phase
+#define tData1 data[1]
+#define tData2 data[2]
+#define tData3 data[3]
+#define tData4 data[4]
+#define tData5 data[5]
+#define tData6 data[6]
+#define tData7 data[7]
+
+static void CreatePhase1Task(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4)
+{
+ u8 taskId = CreateTask(TransitionPhase1_Task_RunFuncs, 3);
+ gTasks[taskId].tData1 = a0;
+ gTasks[taskId].tData2 = a1;
+ gTasks[taskId].tData3 = a2;
+ gTasks[taskId].tData4 = a3;
+ gTasks[taskId].tData5 = a4;
+ gTasks[taskId].tData6 = a0;
+}
+
+static bool8 IsPhase1Done(void)
+{
+ if (FindTaskIdByFunc(TransitionPhase1_Task_RunFuncs) == 0xFF)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void TransitionPhase1_Task_RunFuncs(u8 taskId)
+{
+ while (sPhase1_TransitionAll_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase1_TransitionAll_Func1(struct Task *task)
+{
+ if (task->tData6 == 0 || --task->tData6 == 0)
+ {
+ task->tData6 = task->tData1;
+ task->tData7 += task->tData4;
+ if (task->tData7 > 16)
+ task->tData7 = 16;
+ BlendPalettes(-1, task->tData7, 0x2D6B);
+ }
+ if (task->tData7 > 15)
+ {
+ task->tState++;
+ task->tData6 = task->tData2;
+ }
+ return FALSE;
+}
+
+static bool8 Phase1_TransitionAll_Func2(struct Task *task)
+{
+ if (task->tData6 == 0 || --task->tData6 == 0)
+ {
+ task->tData6 = task->tData2;
+ task->tData7 -= task->tData5;
+ if (task->tData7 < 0)
+ task->tData7 = 0;
+ BlendPalettes(-1, task->tData7, 0x2D6B);
+ }
+ if (task->tData7 == 0)
+ {
+ if (--task->tData3 == 0)
+ DestroyTask(FindTaskIdByFunc(TransitionPhase1_Task_RunFuncs));
+ else
+ {
+ task->tData6 = task->tData1;
+ task->tState = 0;
+ }
+ }
+ return FALSE;
+}
+
+#undef tData1
+#undef tData2
+#undef tData3
+#undef tData4
+#undef tData5
+#undef tData6
+#undef tData7
+
+static void sub_8149F08(void)
+{
+ memset(sTransitionStructPtr, 0, sizeof(*sTransitionStructPtr));
+ sub_8089C08(&sTransitionStructPtr->field_14, &sTransitionStructPtr->field_16);
+}
+
+static void VBlankCB_BattleTransition(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void sub_8149F40(u16 **a0)
+{
+ u16 reg, *vram;
+
+ reg = REG_BG0CNT >> 2;
+ reg <<= 0xE;
+ vram = (u16*)(VRAM + reg);
+
+ *a0 = vram;
+}
+
+void sub_8149F58(u16 **a0, u16 **a1)
+{
+ u16 reg0, reg1, *vram0, *vram1;
+
+ reg0 = REG_BG0CNT >> 8;
+ reg1 = REG_BG0CNT >> 2;
+
+ reg0 <<= 0xB;
+ reg1 <<= 0xE;
+
+ vram0 = (u16*)(VRAM + reg0);
+ *a0 = vram0;
+
+ vram1 = (u16*)(VRAM + reg1);
+ *a1 = vram1;
+}
+
+static void sub_8149F84(void)
+{
+ BlendPalettes(-1, 0x10, 0);
+}
+
+static void sub_8149F98(s16 *array, s16 sinAdd, s16 index, s16 indexIncrementer, s16 amplitude, s16 arrSize)
+{
+ u8 i;
+ for (i = 0; arrSize > 0; arrSize--, i++, index += indexIncrementer)
+ {
+ array[i] = sinAdd + Sin(0xFF & index, amplitude);
+ }
+}
+
+static void sub_814A014(u16 *array, s16 a1, s16 a2, s16 a3)
+{
+ s16 i;
+
+ memset(array, 0xA, 160 * sizeof(s16));
+ for (i = 0; i < 64; i++)
+ {
+ s16 sinResult, cosResult;
+ s16 toStoreOrr, r2, r3, toStore, r7, r8;
+
+ sinResult = Sin(i, a3);
+ cosResult = Cos(i, a3);
+
+ toStoreOrr = a1 - sinResult;
+ toStore = a1 + sinResult;
+ r7 = a2 - cosResult;
+ r8 = a2 + cosResult;
+
+ if (toStoreOrr < 0)
+ toStoreOrr = 0;
+ if (toStore > 0xF0)
+ toStore = 0xF0;
+ if (r7 < 0)
+ r7 = 0;
+ if (r8 > 0x9F)
+ r8 = 0x9F;
+
+ toStore |= (toStoreOrr << 8);
+ array[r7] = toStore;
+ array[r8] = toStore;
+
+ cosResult = Cos(i + 1, a3);
+ r3 = a2 - cosResult;
+ r2 = a2 + cosResult;
+
+ if (r3 < 0)
+ r3 = 0;
+ if (r2 > 0x9F)
+ r2 = 0x9F;
+
+ while (r7 > r3)
+ array[--r7] = toStore;
+ while (r7 < r3)
+ array[++r7] = toStore;
+
+ while (r8 > r2)
+ array[--r8] = toStore;
+ while (r8 < r2)
+ array[++r8] = toStore;
+ }
+}
+
+static void sub_814A1AC(s16 *data, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6)
+{
+ data[0] = a1;
+ data[1] = a2;
+ data[2] = a1;
+ data[3] = a2;
+ data[4] = a3;
+ data[5] = a4;
+ data[6] = a5;
+ data[7] = a6;
+ data[8] = a3 - a1;
+ if (data[8] < 0)
+ {
+ data[8] = -data[8];
+ data[6] = -a5;
+ }
+ data[9] = a4 - a2;
+ if (data[9] < 0)
+ {
+ data[9] = -data[9];
+ data[7] = -a6;
+ }
+ data[10] = 0;
+}
+
+static bool8 sub_814A228(s16 *data, bool8 a1, bool8 a2)
+{
+ u8 var;
+ if (data[8] > data[9])
+ {
+ data[2] += data[6];
+ data[10] += data[9];
+ if (data[10] > data[8])
+ {
+ data[3] += data[7];
+ data[10] -= data[8];
+ }
+ }
+ else
+ {
+ data[3] += data[7];
+ data[10] += data[8];
+ if (data[10] > data[9])
+ {
+ data[2] += data[6];
+ data[10] -= data[9];
+ }
+ }
+ var = 0;
+ if ((data[6] > 0 && data[2] >= data[4]) || (data[6] < 0 && data[2] <= data[4]))
+ {
+ var++;
+ if (a1)
+ data[2] = data[4];
+ }
+ if ((data[7] > 0 && data[3] >= data[5]) || (data[7] < 0 && data[3] <= data[5]))
+ {
+ var++;
+ if (a2)
+ data[3] = data[5];
+ }
+
+ if (var == 2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// sub-task for phase2 of a couple of new transitions
+#define tData1 data[1]
+#define tData2 data[2]
+#define tData3 data[3]
+#define tData4 data[4]
+#define tData5 data[5]
+#define tData6 data[6]
+#define tData7 data[7]
+
+static bool8 Phase2_29_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_814669C(task);
+ sub_8149F58(&dst1, &dst2);
+ CpuFill16(0, dst1, 0x800);
+ LZ77UnCompVram(gUnknown_085C7C00, dst2);
+ LoadPalette(gUnknown_085C7BE0, 0xF0, 0x20);
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_29_Func2(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LZ77UnCompVram(gUnknown_085C828C, dst1);
+ sub_8149F98(gUnknown_02038C28[0], 0, task->tData4, 0x84, task->tData5, 160);
+
+ task->tState++;
+ return TRUE;
+}
+
+static void Phase2Task_29(u8 taskId)
+{
+ while (sPhase2_29_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_30(u8 taskId)
+{
+ while (sPhase2_30_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_30_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F08();
+ dp12_8087EA4();
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON);
+ task->tData2 = 0x2000;
+ task->tData1 = 0x7FFF;
+ task->tData5 = 0;
+ task->tData6 = 16;
+ task->tData7 = 2560;
+ sTransitionStructPtr->BLDCNT = 0x3F41;
+ sTransitionStructPtr->BLDALPHA = (task->tData6 << 8) | (task->tData5);
+ REG_BLDCNT = sTransitionStructPtr->BLDCNT;
+ REG_BLDALPHA = sTransitionStructPtr->BLDALPHA;
+ sub_8149F58(&dst1, &dst2);
+ CpuFill16(0, dst1, 0x800);
+ LZ77UnCompVram(gUnknown_085C7C00, dst2);
+ LoadPalette(gUnknown_085C7BE0, 0xF0, 0x20);
+ sTransitionStructPtr->field_16 = 0;
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_30_Func2(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LZ77UnCompVram(gUnknown_085C828C, dst1);
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_30_Func3(struct Task *task)
+{
+ u8 i;
+
+ for (i = 0; i < 160; i++)
+ {
+ gUnknown_02038C28[1][i] = sTransitionStructPtr->field_16;
+ }
+
+ SetVBlankCallback(VBlankCB_Phase2_30);
+ SetHBlankCallback(HBlankCB_Phase2_30);
+ EnableInterrupts(INTR_FLAG_HBLANK);
+
+ task->tState++;
+ return TRUE;
+}
+
+static bool8 Phase2_30_Func4(struct Task *task)
+{
+ u8 i;
+ u16 var6, amplitude, var8;
+
+ sTransitionStructPtr->VBlank_DMA = FALSE;
+
+ amplitude = task->tData2 >> 8;
+ var6 = task->tData1;
+ var8 = 384;
+
+ task->tData1 = var6 - task->tData7;
+
+ if (task->tData3 >= 70)
+ {
+ if (task->tData2 - 384 >= 0)
+ task->tData2 -= 384;
+ else
+ task->tData2 = 0;
+ }
+
+ if (task->tData3 >= 0 && task->tData3 % 3 == 0)
+ {
+ if (task->tData5 < 16)
+ task->tData5++;
+ else if (task->tData6 > 0)
+ task->tData6--;
+
+ sTransitionStructPtr->BLDALPHA = (task->tData6 << 8) | (task->tData5);
+ }
+
+ for (i = 0; i < 160; i++, var6 += var8)
+ {
+ s16 index = var6 / 256;
+ asm("");
+ gUnknown_02038C28[0][i] = sTransitionStructPtr->field_16 + Sin(index, amplitude);
+ }
+
+ if (++task->tData3 == 101)
+ {
+ task->tData4++;
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ }
+
+ if (task->tData4 != 0 && !gPaletteFade.active)
+ DestroyTask(FindTaskIdByFunc(Phase2Task_30));
+
+ task->tData7 -= 17;
+ sTransitionStructPtr->VBlank_DMA++;
+ return FALSE;
+}
+
+static void VBlankCB_Phase2_30(void)
+{
+ VBlankCB_BattleTransition();
+ REG_BLDCNT = sTransitionStructPtr->BLDCNT;
+ REG_BLDALPHA = sTransitionStructPtr->BLDALPHA;
+
+ if (sTransitionStructPtr->VBlank_DMA)
+ DmaCopy16(3, gUnknown_02038C28[0], gUnknown_02038C28[1], 320);
+}
+
+static void HBlankCB_Phase2_30(void)
+{
+ u16 var = gUnknown_02038C28[1][REG_VCOUNT];
+ REG_BG0VOFS = var;
+}
+
+static void Phase2Task_31(u8 taskId)
+{
+ while (sPhase2_31_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_33(u8 taskId)
+{
+ while (sPhase2_33_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static void Phase2Task_32(u8 taskId)
+{
+ while (sPhase2_32_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
+}
+
+static bool8 Phase2_31_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LZ77UnCompVram(gUnknown_085C8598, dst2);
+
+ FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x20, 0x20);
+ FillBgTilemapBufferRect(0, 1, 0, 0, 1, 0x20, 0xF);
+ FillBgTilemapBufferRect(0, 1, 0x1D, 0, 1, 0x20, 0xF);
+ CopyBgTilemapBufferToVram(0);
+ LoadPalette(gUnknown_085C8578, 0xF0, 0x20);
+
+ task->tData2 = 1;
+ task->tData3 = 0;
+ task->tData4 = 0;
+ task->tData7 = 10;
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_31_Func2(struct Task *task)
+{
+ CopyRectToBgTilemapBufferRect(0, gUnknown_085C8928, 0, 0, 4, 4, task->tData2, task->tData3, 4, 4, 0xF, 0, 0);
+ CopyBgTilemapBufferToVram(0);
+
+ task->tData2 += 4;
+ if (++task->tData4 == 7)
+ {
+ task->tData2 = 1;
+ task->tData3 += 4;
+ task->tData4 = 0;
+ if (task->tData3 > 19)
+ task->tState++;
+ }
+
+ return FALSE;
+}
+
+static bool8 Phase2_31_Func3(struct Task *task)
+{
+ u8 i;
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ if (task->tData6++ >= task->tData7)
+ {
+ switch (task->tData5)
+ {
+ case 0:
+ for (i = 250; i < 255; i++)
+ {
+ gPlttBufferUnfaded[i] = 0;
+ gPlttBufferFaded[i] = 0;
+ }
+ break;
+ case 1:
+ BlendPalettes(0xFFFF7FFF, 0x10, 0);
+ LZ77UnCompVram(gUnknown_085C86F4, dst2);
+ break;
+ case 2:
+ LZ77UnCompVram(gUnknown_085C87F4, dst2);
+ break;
+ case 3:
+ LZ77UnCompVram(gUnknown_085C88A4, dst2);
+ break;
+ default:
+ FillBgTilemapBufferRect_Palette0(0, 1, 0, 0, 0x20, 0x20);
+ CopyBgTilemapBufferToVram(0);
+ task->tState++;
+ return FALSE;
+ }
+
+ task->tData6 = 0;
+ task->tData5++;
+ }
+
+ return FALSE;
+}
+
+static bool8 Phase2_33_Func1(struct Task *task)
+{
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LZ77UnCompVram(gUnknown_085C8598, dst2);
+
+ FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x20, 0x20);
+ FillBgTilemapBufferRect(0, 1, 0, 0, 1, 0x20, 0xF);
+ FillBgTilemapBufferRect(0, 1, 0x1D, 0, 1, 0x20, 0xF);
+ CopyBgTilemapBufferToVram(0);
+ LoadPalette(gUnknown_085C8578, 0xE0, 0x20);
+ LoadPalette(gUnknown_085C8578, 0xF0, 0x20);
+ BlendPalette(0xE0, 0x10, 8, 0);
+
+ task->tData2 = 34;
+ task->tData3 = 0;
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_33_Func2(struct Task *task)
+{
+ u8 var = gUnknown_085C9A30[task->tData2];
+ u8 varMod = var % 7;
+ u8 varDiv = var / 7;
+ CopyRectToBgTilemapBufferRect(0, &gUnknown_085C8928, 0, 0, 4, 4, 4 * varMod + 1, 4 * varDiv, 4, 4, 0xF, 0, 0);
+ CopyBgTilemapBufferToVram(0);
+
+ if (--task->tData2 < 0)
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_33_Func3(struct Task *task)
+{
+ BlendPalette(0xE0, 0x10, 3, 0);
+ BlendPalettes(0xFFFF3FFF, 0x10, 0);
+
+ task->tData2 = 0;
+ task->tData3 = 0;
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_33_Func4(struct Task *task)
+{
+ if ((task->tData3 ^= 1))
+ {
+ CopyRectToBgTilemapBufferRect(
+ 0,
+ gUnknown_085C8928,
+ 0,
+ 0,
+ 4,
+ 4,
+ 4 * (gUnknown_085C9A30[task->tData2] % 7) + 1,
+ 4 * (gUnknown_085C9A30[task->tData2] / 7),
+ 4,
+ 4,
+ 0xE,
+ 0,
+ 0);
+ }
+ else
+ {
+ if (task->tData2 > 0)
+ {
+ FillBgTilemapBufferRect(
+ 0,
+ 1,
+ 4 * (gUnknown_085C9A30[task->tData2 - 1] % 7) + 1,
+ 4 * (gUnknown_085C9A30[task->tData2 - 1] / 7),
+ 4,
+ 4,
+ 0xF);
+ }
+
+ task->tData2++;
+ }
+
+ if (task->tData2 > 34)
+ task->tState++;
+
+ CopyBgTilemapBufferToVram(0);
+ return FALSE;
+}
+
+static bool8 Phase2_31_33_Func5(struct Task *task)
+{
+ FillBgTilemapBufferRect_Palette0(0, 1, 0, 0, 0x20, 0x20);
+ CopyBgTilemapBufferToVram(0);
+ BlendPalettes(0xFFFFFFFF, 0x10, 0);
+ DestroyTask(FindTaskIdByFunc(task->func));
+ return FALSE;
+}
+
+// sub task for phase2 32
+#define tSub32_X_delta data[0]
+#define tSub32_Y_delta data[1]
+#define tSub32_Bool data[2]
+
+static void sub_814ABE4(u8 taskId)
+{
+ if (!(gTasks[taskId].tSub32_Bool ^= 1))
+ {
+ SetGpuReg(REG_OFFSET_BG0VOFS, gBattle_BG0_X);
+ SetGpuReg(REG_OFFSET_BG0HOFS, gBattle_BG0_Y);
+ gBattle_BG0_X += gTasks[taskId].tSub32_X_delta;
+ gBattle_BG0_Y += gTasks[taskId].tSub32_Y_delta;
+ }
+}
+
+static bool8 Phase2_32_Func1(struct Task *task)
+{
+ u8 taskId = 0;
+ u16 *dst1, *dst2;
+
+ sub_8149F58(&dst1, &dst2);
+ LZ77UnCompVram(gUnknown_085C8598, dst2);
+ FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x20, 0x20);
+ CopyBgTilemapBufferToVram(0);
+ LoadPalette(gUnknown_085C8578, 0xF0, 0x20);
+
+ gBattle_BG0_X = 0;
+ gBattle_BG0_Y = 0;
+ SetGpuReg(REG_OFFSET_BG0VOFS, gBattle_BG0_X);
+ SetGpuReg(REG_OFFSET_BG0HOFS, gBattle_BG0_Y);
+
+ task->tData2 = 0;
+ taskId = CreateTask(sub_814ABE4, 1);
+ switch (Random() % 4)
+ {
+ case 0:
+ gTasks[taskId].tSub32_X_delta = 1;
+ gTasks[taskId].tSub32_Y_delta = 1;
+ break;
+ case 1:
+ gTasks[taskId].tSub32_X_delta = -1;
+ gTasks[taskId].tSub32_Y_delta = -1;
+ break;
+ case 2:
+ gTasks[taskId].tSub32_X_delta = 1;
+ gTasks[taskId].tSub32_Y_delta = -1;
+ break;
+ default:
+ gTasks[taskId].tSub32_X_delta = -1;
+ gTasks[taskId].tSub32_Y_delta = 1;
+ break;
+ }
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_32_Func2(struct Task *task)
+{
+ u8 var = gUnknown_085C9A53[task->tData2];
+ u8 varDiv = var / 8;
+ u8 varAnd = var & 7;
+
+ CopyRectToBgTilemapBufferRect(
+ 0,
+ &gUnknown_085C8928,
+ 0,
+ 0,
+ 4,
+ 4,
+ 4 * varDiv + 1,
+ 4 * varAnd,
+ 4,
+ 4,
+ 0xF,
+ 0,
+ 0);
+ CopyBgTilemapBufferToVram(0);
+
+ if (++task->tData2 > 63)
+ task->tState++;
+ return 0;
+}
+
+static bool8 Phase2_32_Func3(struct Task *task)
+{
+ BlendPalettes(0xFFFF7FFF, 0x10, 0);
+
+ task->tData2 = 0;
+
+ task->tState++;
+ return FALSE;
+}
+
+static bool8 Phase2_32_Func4(struct Task *task)
+{
+ u8 var = gUnknown_085C9A53[task->tData2];
+ u8 varDiv = var / 8;
+ u8 varAnd = var & 7;
+
+ FillBgTilemapBufferRect(0, 1, 4 * varDiv + 1, 4 * varAnd, 4, 4, 0xF);
+ CopyBgTilemapBufferToVram(0);
+
+ if (++task->tData2 > 63)
+ {
+ DestroyTask(FindTaskIdByFunc(sub_814ABE4));
+ task->tState++;
+ }
+
+ return FALSE;
+}
+
+#undef tSub32_X_delta
+#undef tSub32_Y_delta
+#undef tSub32_Bool
+
+static bool8 Phase2_32_Func5(struct Task *task)
+{
+ gBattle_BG0_X = 0;
+ gBattle_BG0_Y = 0;
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, gBattle_BG0_Y);
+
+ FillBgTilemapBufferRect_Palette0(0, 1, 0, 0, 0x20, 0x20);
+ CopyBgTilemapBufferToVram(0);
+ BlendPalettes(0xFFFFFFFF, 0x10, 0);
+
+ DestroyTask(FindTaskIdByFunc(task->func));
+ task->tState++; // UB: changing value of a destroyed task
+ return FALSE;
+}
+
+#undef tData1
+#undef tData2
+#undef tData3
+#undef tData4
+#undef tData5
+#undef tData6
+#undef tData7
diff --git a/src/battle_util.c b/src/battle_util.c
index 1a624641d..2ce37cfbd 100644
--- a/src/battle_util.c
+++ b/src/battle_util.c
@@ -3,6 +3,7 @@
#include "constants/abilities.h"
#include "constants/moves.h"
#include "constants/hold_effects.h"
+#include "constants/battle_anim.h"
#include "pokemon.h"
#include "constants/species.h"
#include "item.h"
diff --git a/src/berry_blender.c b/src/berry_blender.c
index 7200f3465..b61bb8e9b 100644
--- a/src/berry_blender.c
+++ b/src/berry_blender.c
@@ -127,15 +127,13 @@ struct BerryBlenderData
struct BlenderGameBlock gameBlock;
};
-extern struct MusicPlayerInfo gMPlay_SE2;
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_SE2;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern u16 gSpecialVar_ItemId;
extern u8 gInGameOpponentsNo;
extern u8 gUnknown_020322D5;
extern u8 gResultsWindowId;
-extern const u8 * const gPokeblockNames[];
-
// graphics
extern const u8 gBerryBlenderArrowTiles[];
extern const u8 gBerryBlenderStartTiles[];
@@ -803,7 +801,7 @@ static const struct WindowTemplate sBlenderRecordWindowTemplate = {0, 6, 4, 0x12
static void Blender_ControlHitPitch(void)
{
- m4aMPlayPitchControl(&gMPlay_SE2, 0xFFFF, 2 * (sBerryBlenderData->field_4C - 128));
+ m4aMPlayPitchControl(&gMPlayInfo_SE2, 0xFFFF, 2 * (sBerryBlenderData->field_4C - 128));
}
static void VBlankCB0_BerryBlender(void)
@@ -1305,11 +1303,11 @@ static void sub_8080018(void)
sBerryBlenderData->field_4C = 128;
sBerryBlenderData->gameFrameTime = 0;
SetMainCallback2(sub_8081898);
- if (GetCurrentMapMusic() != BGM_CYCLING)
+ if (GetCurrentMapMusic() != MUS_CYCLING)
{
sBerryBlenderData->field_154 = GetCurrentMapMusic();
}
- PlayBGM(BGM_CYCLING);
+ PlayBGM(MUS_CYCLING);
break;
}
@@ -1604,10 +1602,10 @@ static void sub_80808D4(void)
sBerryBlenderData->field_120[i] = CreateTask(sUnknown_083399EC[i], 10 + i);
}
- if (GetCurrentMapMusic() != BGM_CYCLING)
+ if (GetCurrentMapMusic() != MUS_CYCLING)
sBerryBlenderData->field_154 = GetCurrentMapMusic();
- PlayBGM(BGM_CYCLING);
+ PlayBGM(MUS_CYCLING);
PlaySE(SE_MOTER);
Blender_ControlHitPitch();
break;
@@ -1940,9 +1938,9 @@ static void sub_80814F4(void)
if (gRecvCmds[i][2] == 0x2345 || gRecvCmds[2][i] == 0x4523 || gRecvCmds[2][i] == 0x5432) // could be a bug, 2 and i are reversed
{
if (sBerryBlenderData->field_4C > 1500)
- m4aMPlayTempoControl(&gMPlay_BGM, ((sBerryBlenderData->field_4C - 750) / 20) + 256);
+ m4aMPlayTempoControl(&gMPlayInfo_BGM, ((sBerryBlenderData->field_4C - 750) / 20) + 256);
else
- m4aMPlayTempoControl(&gMPlay_BGM, 0x100);
+ m4aMPlayTempoControl(&gMPlayInfo_BGM, 0x100);
}
}
}
@@ -2337,7 +2335,7 @@ static void CB2_HandleBlenderEndGame(void)
switch (sBerryBlenderData->gameEndState)
{
case 1:
- m4aMPlayTempoControl(&gMPlay_BGM, 256);
+ m4aMPlayTempoControl(&gMPlayInfo_BGM, 256);
for (i = 0; i < gSpecialVar_0x8004; i++)
{
DestroyTask(sBerryBlenderData->field_120[i]);
@@ -2357,7 +2355,7 @@ static void CB2_HandleBlenderEndGame(void)
sBerryBlenderData->gameEndState = 5;
sBerryBlenderData->mainState = 0;
- m4aMPlayStop(&gMPlay_SE2);
+ m4aMPlayStop(&gMPlayInfo_SE2);
}
Blender_ControlHitPitch();
break;
@@ -3522,7 +3520,7 @@ static void sub_8083F3C(u8 taskId)
{
if (gTasks[taskId].data[0] == 0)
{
- PlayFanfare(BGM_FANFA1);
+ PlayFanfare(MUS_FANFA1);
gTasks[taskId].data[0]++;
}
if (IsFanfareTaskInactive())
diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c
index bba39c3eb..3b2bfb5f7 100644
--- a/src/berry_fix_program.c
+++ b/src/berry_fix_program.c
@@ -35,9 +35,9 @@ static void berry_fix_bg_hide(void);
// .rodata
-static const u8 gUnknown_08617E78[] = _("Berry Program Update");
-static const u8 gUnknown_08617E8D[] = _("Ruby/Sapphire");
-static const u8 gUnknown_08617E9B[] = _("Emerald");
+static const u8 sUnknown_08617E78[] = _("Berry Program Update");
+static const u8 sUnknown_08617E8D[] = _("Ruby/Sapphire");
+static const u8 sUnknown_08617E9B[] = _("Emerald");
static const u8 Unknown_08617EA3[] = _("The Berry Program on your POKéMON\nRuby/Sapphire Game Pak will be updated.\n{COLOR RED}{SHADOW LIGHT_RED}Press the A Button.");
static const u8 Unknown_08617F07[] = _("Please ensure the connection of your\nGame Boy Advance system matches this.\n{COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button.\nNO: Turn off the power and try again.");
@@ -62,15 +62,15 @@ static const struct WindowTemplate gUnknown_08618110[] = {
{-1}
};
-static const u16 gUnknown_08618138[] = {
+static const u16 sUnknown_08618138[] = {
0x7fff, 0x7fff, 0x318c, 0x675a,
0x043c, 0x3aff, 0x0664, 0x4bd2,
0x6546, 0x7b14, 0x7fff, 0x318c,
0x675a, 0x0000, 0x0000, 0x0000
};
-static const u8 gUnknown_08618158[] = {10, 11, 12};
-static const u8 gUnknown_0861815B[] = { 0, 10, 13};
+static const u8 sUnknown_08618158[] = {10, 11, 12};
+static const u8 sUnknown_0861815B[] = { 0, 10, 13};
static const u8 *const gUnknown_08618160[] = {
Unknown_08617F07,
@@ -81,50 +81,50 @@ static const u8 *const gUnknown_08618160[] = {
Unknown_08617EA3
};
-extern const u8 gUnknown_08DD87C0[];
-extern const u8 gUnknown_08DD8EE0[];
-extern const u8 gUnknown_08DD8780[];
-extern const u8 gUnknown_08DD90E0[];
-extern const u8 gUnknown_08DD9718[];
-extern const u8 gUnknown_08DD9080[];
-extern const u8 gUnknown_08DD98B4[];
-extern const u8 gUnknown_08DD9E58[];
-extern const u8 gUnknown_08DD9874[];
-extern const u8 gUnknown_08DDA02C[];
-extern const u8 gUnknown_08DDA63C[];
-extern const u8 gUnknown_08DD9FEC[];
-extern const u8 gUnknown_08DDA840[];
-extern const u8 gUnknown_08DDAE40[];
-extern const u8 gUnknown_08DDA800[];
-extern const u8 gUnknown_08DDB020[];
-extern const u8 gUnknown_08DDB2C4[];
-extern const u8 gUnknown_08DDAFE0[];
+extern const u8 gBerryFixGameboy_Gfx[];
+extern const u8 gBerryFixGameboy_Tilemap[];
+extern const u8 gBerryFixGameboy_Pal[];
+extern const u8 gBerryFixGameboyLogo_Gfx[];
+extern const u8 gBerryFixGameboyLogo_Tilemap[];
+extern const u8 gBerryFixGameboyLogo_Pal[];
+extern const u8 gBerryFixGbaTransfer_Gfx[];
+extern const u8 gBerryFixGbaTransfer_Tilemap[];
+extern const u8 gBerryFixGbaTransfer_Pal[];
+extern const u8 gBerryFixGbaTransferHighlight_Gfx[];
+extern const u8 gBerryFixGbaTransferHighlight_Tilemap[];
+extern const u8 gBerryFixGbaTransferHighlight_Pal[];
+extern const u8 gBerryFixGbaTransferError_Gfx[];
+extern const u8 gBerryFixGbaTransferError_Tilemap[];
+extern const u8 gBerryFixGbaTransferError_Pal[];
+extern const u8 gBerryFixWindow_Gfx[];
+extern const u8 gBerryFixWindow_Tilemap[];
+extern const u8 gBerryFixWindow_Pal[];
static const u8 *const gUnknown_08618178[][3] = {
{
- gUnknown_08DD87C0,
- gUnknown_08DD8EE0,
- gUnknown_08DD8780
+ gBerryFixGameboy_Gfx,
+ gBerryFixGameboy_Tilemap,
+ gBerryFixGameboy_Pal
}, {
- gUnknown_08DD90E0,
- gUnknown_08DD9718,
- gUnknown_08DD9080
+ gBerryFixGameboyLogo_Gfx,
+ gBerryFixGameboyLogo_Tilemap,
+ gBerryFixGameboyLogo_Pal
}, {
- gUnknown_08DD98B4,
- gUnknown_08DD9E58,
- gUnknown_08DD9874
+ gBerryFixGbaTransfer_Gfx,
+ gBerryFixGbaTransfer_Tilemap,
+ gBerryFixGbaTransfer_Pal
}, {
- gUnknown_08DDA02C,
- gUnknown_08DDA63C,
- gUnknown_08DD9FEC
+ gBerryFixGbaTransferHighlight_Gfx,
+ gBerryFixGbaTransferHighlight_Tilemap,
+ gBerryFixGbaTransferHighlight_Pal
}, {
- gUnknown_08DDA840,
- gUnknown_08DDAE40,
- gUnknown_08DDA800
+ gBerryFixGbaTransferError_Gfx,
+ gBerryFixGbaTransferError_Tilemap,
+ gBerryFixGbaTransferError_Pal
}, {
- gUnknown_08DDB020,
- gUnknown_08DDB2C4,
- gUnknown_08DDAFE0
+ gBerryFixWindow_Gfx,
+ gBerryFixWindow_Tilemap,
+ gBerryFixWindow_Pal
},
};
@@ -243,21 +243,21 @@ static void berry_fix_gpu_set(void)
InitWindows(gUnknown_08618110);
DeactivateAllTextPrinters();
- DmaCopy32(3, gUnknown_08618138, BG_PLTT + 0x1E0, 0x20);
+ DmaCopy32(3, sUnknown_08618138, BG_PLTT + 0x1E0, 0x20);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP);
FillWindowPixelBuffer(2, 0);
FillWindowPixelBuffer(3, 0);
FillWindowPixelBuffer(0, 0xAA);
// This block is a meme among memes
- width = (0x78 - GetStringWidth(0, gUnknown_08617E9B, 0)) / 2;
- box_print(2, 0, width, 3, gUnknown_0861815B, -1, gUnknown_08617E9B);
- width = (s32)(0x78 - GetStringWidth(0, gUnknown_08617E9B, 0)) / 2 + 0x78;
- box_print(2, 0, width, 3, gUnknown_0861815B, -1, gUnknown_08617E8D);
- width = (0x70 - GetStringWidth(0, gUnknown_08617E8D, 0)) / 2;
- box_print(3, 0, width, 0, gUnknown_0861815B, -1, gUnknown_08617E8D);
- width = (0xd0 - GetStringWidth(1, gUnknown_08617E78, 0)) / 2;
- box_print(0, 1, width, 2, gUnknown_08618158, -1, gUnknown_08617E78);
+ width = (0x78 - GetStringWidth(0, sUnknown_08617E9B, 0)) / 2;
+ box_print(2, 0, width, 3, sUnknown_0861815B, -1, sUnknown_08617E9B);
+ width = (s32)(0x78 - GetStringWidth(0, sUnknown_08617E9B, 0)) / 2 + 0x78;
+ box_print(2, 0, width, 3, sUnknown_0861815B, -1, sUnknown_08617E8D);
+ width = (0x70 - GetStringWidth(0, sUnknown_08617E8D, 0)) / 2;
+ box_print(3, 0, width, 0, sUnknown_0861815B, -1, sUnknown_08617E8D);
+ width = (0xd0 - GetStringWidth(1, sUnknown_08617E78, 0)) / 2;
+ box_print(0, 1, width, 2, sUnknown_08618158, -1, sUnknown_08617E78);
CopyWindowToVram(2, 2);
CopyWindowToVram(3, 2);
@@ -346,7 +346,7 @@ __attribute__((naked)) static void berry_fix_gpu_set(void)
"\tldr r0, =gUnknown_08618110\n"
"\tbl InitWindows\n"
"\tbl DeactivateAllTextPrinters\n"
- "\tldr r0, =gUnknown_08618138\n"
+ "\tldr r0, =sUnknown_08618138\n"
"\tstr r0, [r4]\n"
"\tldr r0, =0x050001e0\n"
"\tstr r0, [r4, 0x4]\n"
@@ -365,7 +365,7 @@ __attribute__((naked)) static void berry_fix_gpu_set(void)
"\tmovs r0, 0\n"
"\tmovs r1, 0xAA\n"
"\tbl FillWindowPixelBuffer\n"
- "\tldr r5, =gUnknown_08617E9B\n"
+ "\tldr r5, =sUnknown_08617E9B\n"
"\tmovs r0, 0\n"
"\tadds r1, r5, 0\n"
"\tmovs r2, 0\n"
@@ -378,7 +378,7 @@ __attribute__((naked)) static void berry_fix_gpu_set(void)
"\tasrs r0, 1\n"
"\tlsls r2, r0, 24\n"
"\tlsrs r2, 24\n"
- "\tldr r6, =gUnknown_0861815B\n"
+ "\tldr r6, =sUnknown_0861815B\n"
"\tstr r6, [sp]\n"
"\tmovs r0, 0x1\n"
"\tnegs r0, r0\n"
@@ -389,7 +389,7 @@ __attribute__((naked)) static void berry_fix_gpu_set(void)
"\tmovs r1, 0\n"
"\tmovs r3, 0x3\n"
"\tbl box_print\n"
- "\tldr r5, =gUnknown_08617E8D\n"
+ "\tldr r5, =sUnknown_08617E8D\n"
"\tmovs r0, 0\n"
"\tadds r1, r5, 0\n"
"\tmovs r2, 0\n"
@@ -431,7 +431,7 @@ __attribute__((naked)) static void berry_fix_gpu_set(void)
"\tmovs r1, 0\n"
"\tmovs r3, 0\n"
"\tbl box_print\n"
- "\tldr r4, =gUnknown_08617E78\n"
+ "\tldr r4, =sUnknown_08617E78\n"
"\tmovs r0, 0x1\n"
"\tadds r1, r4, 0\n"
"\tmovs r2, 0\n"
@@ -444,7 +444,7 @@ __attribute__((naked)) static void berry_fix_gpu_set(void)
"\tasrs r0, 1\n"
"\tlsls r2, r0, 24\n"
"\tlsrs r2, 24\n"
- "\tldr r0, =gUnknown_08618158\n"
+ "\tldr r0, =sUnknown_08618158\n"
"\tstr r0, [sp]\n"
"\tmov r0, r8\n"
"\tstr r0, [sp, 0x4]\n"
@@ -496,7 +496,7 @@ static void berry_fix_text_print(int scene)
{
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32);
FillWindowPixelBuffer(1, 0xAA);
- box_print(1, 1, 0, 0, gUnknown_08618158, -1, gUnknown_08618160[scene]);
+ box_print(1, 1, 0, 0, sUnknown_08618158, -1, gUnknown_08618160[scene]);
PutWindowTilemap(1);
CopyWindowToVram(1, 2);
switch (scene)
diff --git a/src/bg.c b/src/bg.c
index 74e3ea830..b699a0b1f 100644
--- a/src/bg.c
+++ b/src/bg.c
@@ -1007,7 +1007,7 @@ void CopyToBgTilemapBufferRect_ChangePalette(u8 bg, void *src, u8 destX, u8 dest
}
// Skipping for now, it probably uses structs passed by value
/*
-void CopyRectToBgTilemapBufferRect(u8 bg, void* src, u8 srcX, u8 srcY, u8 srcWidth, u8 srcHeight, u8 destX, u8 destY, u8 rectWidth, u8 rectHeight, u8 palette1, u16 tileOffset, u16 palette2)
+void CopyRectToBgTilemapBufferRect(u8 bg, const void* src, u8 srcX, u8 srcY, u8 srcWidth, u8 srcHeight, u8 destX, u8 destY, u8 rectWidth, u8 rectHeight, u8 palette1, u16 tileOffset, u16 palette2)
{
u16 attribute;
u16 mode;
@@ -1049,7 +1049,7 @@ void CopyRectToBgTilemapBufferRect(u8 bg, void* src, u8 srcX, u8 srcY, u8 srcWid
}
}*/
__attribute__((naked))
-void CopyRectToBgTilemapBufferRect(u8 bg, void* src, u8 srcX, u8 srcY, u8 srcWidth, u8 srcHeight, u8 destX, u8 destY, u8 rectWidth, u8 rectHeight, u8 palette1, u16 tileOffset, u16 palette2)
+void CopyRectToBgTilemapBufferRect(u8 bg, const void* src, u8 srcX, u8 srcY, u8 srcWidth, u8 srcHeight, u8 destX, u8 destY, u8 rectWidth, u8 rectHeight, u8 palette1, u16 tileOffset, u16 palette2)
{
asm("push {r4-r7,lr}\n\
mov r7, r10\n\
diff --git a/src/bike.c b/src/bike.c
new file mode 100644
index 000000000..64af7c711
--- /dev/null
+++ b/src/bike.c
@@ -0,0 +1,1078 @@
+#include "global.h"
+#include "bike.h"
+#include "field_map_obj.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "constants/flags.h"
+#include "global.fieldmap.h"
+#include "metatile_behavior.h"
+#include "overworld.h"
+#include "constants/songs.h"
+#include "sound.h"
+
+extern bool8 gBikeCyclingChallenge;
+extern u8 gBikeCollisions;
+extern bool8 gUnknown_02037348;
+
+extern u8 sub_8093514(u8 direction);
+extern u8 sub_808B980(u8 direction);
+extern u8 sub_808B9BC(u8 direction);
+extern u8 sub_808B9A4(u8 direction);
+extern u8 sub_808C1B4(u8 direction);
+extern u8 npc_use_some_d2s(u8 direction);
+extern void Overworld_ClearSavedMusic(void);
+extern void Overworld_PlaySpecialMapMusic(void);
+
+// this file's functions
+static void MovePlayerOnMachBike(u8, u16, u16);
+static u8 GetMachBikeTransition(u8 *);
+static void MachBikeTransition_FaceDirection(u8);
+static void MachBikeTransition_TurnDirection(u8);
+static void MachBikeTransition_TrySpeedUp(u8);
+static void MachBikeTransition_TrySlowDown(u8);
+static void MovePlayerOnAcroBike(u8, u16, u16);
+static u8 CheckMovementInputAcroBike(u8 *, u16, u16);
+static u8 AcroBikeHandleInputNormal(u8 *, u16, u16);
+static u8 AcroBikeHandleInputTurning(u8 *, u16, u16);
+static u8 AcroBikeHandleInputWheelieStanding(u8 *, u16, u16);
+static u8 AcroBikeHandleInputBunnyHop(u8 *, u16, u16);
+static u8 AcroBikeHandleInputWheelieMoving(u8 *, u16, u16);
+static u8 AcroBikeHandleInputSidewaysJump(u8 *, u16, u16);
+static u8 AcroBikeHandleInputTurnJump(u8 *, u16, u16);
+static void AcroBikeTransition_FaceDirection(u8);
+static void AcroBikeTransition_TurnDirection(u8);
+static void AcroBikeTransition_Moving(u8);
+static void AcroBikeTransition_NormalToWheelie(u8);
+static void AcroBikeTransition_WheelieToNormal(u8);
+static void AcroBikeTransition_WheelieIdle(u8);
+static void AcroBikeTransition_WheelieHoppingStanding(u8);
+static void AcroBikeTransition_WheelieHoppingMoving(u8);
+static void AcroBikeTransition_SideJump(u8);
+static void AcroBikeTransition_TurnJump(u8);
+static void AcroBikeTransition_WheelieMoving(u8);
+static void AcroBikeTransition_WheelieRisingMoving(u8);
+static void AcroBikeTransition_WheelieLoweringMoving(u8);
+static void AcroBike_TryHistoryUpdate(u16, u16);
+static u8 AcroBike_GetJumpDirection(void);
+static void Bike_UpdateDirTimerHistory(u8);
+static void Bike_UpdateABStartSelectHistory(u8);
+static u8 Bike_DPadToDirection(u16);
+static u8 get_some_collision(u8);
+static u8 Bike_CheckCollisionTryAdvanceCollisionCount(struct MapObject *, s16, s16, u8, u8);
+static bool8 IsRunningDisallowedByMetatile(u8);
+static void Bike_TryAdvanceCyclingRoadCollisions();
+static u8 CanBikeFaceDirOnMetatile(u8, u8);
+static bool8 WillPlayerCollideWithCollision(u8, u8);
+static void Bike_SetBikeStill(void);
+
+// const rom data
+
+/*
+ A bike transition is a type of callback for the bike that actually
+ modifies the bicycle's direction or momentum or otherwise movement.
+ Alternatively, a bike may also have input handlers which process the
+ bike transition to call: the acro bike has input handlers while the mach
+ bike does not. This is because the Acro needs to know the button inputs
+ for its complex tricks and actions.
+*/
+
+static void (*const sMachBikeTransitions[])(u8) =
+{
+ MachBikeTransition_FaceDirection, // Face vs Turn: Face has no anim while Turn does. Turn checks for collision because if you turn right as opposed to face right, if there is a wall there, turn will make a bonk sound effect while face will not.
+ MachBikeTransition_TurnDirection,
+ MachBikeTransition_TrySpeedUp,
+ MachBikeTransition_TrySlowDown,
+};
+
+// bikeFrameCounter is input which is represented by sMachBikeSpeeds in order: 0 is normal speed (1 speed), 1 is fast speed (2 speed), 2 is fastest speed (4 speed)
+static void (*const sMachBikeSpeedCallbacks[])(u8) =
+{
+ PlayerGoSpeed1, // normal speed (1 speed)
+ PlayerGoSpeed2, // fast speed (2 speed)
+ PlayerGoSpeed4, // fastest speed (4 speed)
+};
+
+static void (*const sAcroBikeTransitions[])(u8) =
+{
+ AcroBikeTransition_FaceDirection,
+ AcroBikeTransition_TurnDirection,
+ AcroBikeTransition_Moving,
+ AcroBikeTransition_NormalToWheelie,
+ AcroBikeTransition_WheelieToNormal,
+ AcroBikeTransition_WheelieIdle,
+ AcroBikeTransition_WheelieHoppingStanding,
+ AcroBikeTransition_WheelieHoppingMoving,
+ AcroBikeTransition_SideJump,
+ AcroBikeTransition_TurnJump,
+ AcroBikeTransition_WheelieMoving,
+ AcroBikeTransition_WheelieRisingMoving,
+ AcroBikeTransition_WheelieLoweringMoving,
+};
+
+static u8 (*const sAcroBikeInputHandlers[])(u8 *, u16, u16) =
+{
+ AcroBikeHandleInputNormal,
+ AcroBikeHandleInputTurning,
+ AcroBikeHandleInputWheelieStanding,
+ AcroBikeHandleInputBunnyHop,
+ AcroBikeHandleInputWheelieMoving,
+ AcroBikeHandleInputSidewaysJump,
+ AcroBikeHandleInputTurnJump,
+};
+
+// used with bikeFrameCounter from mach bike
+static const u16 sMachBikeSpeeds[] = {SPEED_NORMAL, SPEED_FAST, SPEED_FASTEST};
+
+// this is a list of timers to compare against later, terminated with 0. the only timer being compared against is 4 frames in this list.
+static const u8 sAcroBikeJumpTimerList[] = {4, 0};
+
+// this is a list of history inputs to do in order to do the check to retrieve a jump direction for acro bike. it seems to be an extensible list, so its possible that Game Freak may have intended for the Acro Bike to have more complex tricks at some point. The final list only has the acro jump.
+static const struct BikeHistoryInputInfo sAcroBikeTricksList[] =
+{
+ // the 0xF is a mask performed with each byte of the array in order to perform the check on only the last entry of the history list, otherwise the check wouldn't work as there can be 0xF0 as opposed to 0x0F.
+ {DIR_SOUTH, B_BUTTON, 0xF, 0xF, sAcroBikeJumpTimerList, sAcroBikeJumpTimerList, DIR_SOUTH},
+ {DIR_NORTH, B_BUTTON, 0xF, 0xF, sAcroBikeJumpTimerList, sAcroBikeJumpTimerList, DIR_NORTH},
+ {DIR_WEST, B_BUTTON, 0xF, 0xF, sAcroBikeJumpTimerList, sAcroBikeJumpTimerList, DIR_WEST},
+ {DIR_EAST, B_BUTTON, 0xF, 0xF, sAcroBikeJumpTimerList, sAcroBikeJumpTimerList, DIR_EAST},
+};
+
+// code
+void MovePlayerOnBike(u8 direction, u16 newKeys, u16 heldKeys)
+{
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE)
+ MovePlayerOnMachBike(direction, newKeys, heldKeys);
+ else
+ MovePlayerOnAcroBike(direction, newKeys, heldKeys);
+}
+
+static void MovePlayerOnMachBike(u8 direction, u16 newKeys, u16 heldKeys)
+{
+ sMachBikeTransitions[GetMachBikeTransition(&direction)](direction);
+}
+
+// dirTraveling is a variable that is 0 when the player is standing still.
+static u8 GetMachBikeTransition(u8 *dirTraveling)
+{
+ // if the dir updated before this function, get the relevent new direction to check later.
+ u8 direction = player_get_direction_upper_nybble();
+
+ // is the player standing still?
+ if (*dirTraveling == 0)
+ {
+ *dirTraveling = direction; // update the direction, since below we either faced a direction or we started moving.
+ if (gPlayerAvatar.bikeSpeed == SPEED_STANDING)
+ {
+ gPlayerAvatar.runningState = NOT_MOVING;
+ return MACH_TRANS_FACE_DIRECTION;
+ }
+ gPlayerAvatar.runningState = MOVING;
+ return MACH_TRANS_START_MOVING;
+ }
+
+ // we need to check if the last traveled direction changed from the new direction as well as ensuring that we dont update the state while the player is moving: see the else check.
+ if (*dirTraveling != direction && gPlayerAvatar.runningState != MOVING)
+ {
+ if (gPlayerAvatar.bikeSpeed != SPEED_STANDING)
+ {
+ *dirTraveling = direction; // implement the new direction
+ gPlayerAvatar.runningState = MOVING;
+ return MACH_TRANS_START_MOVING;
+ }
+ // if you didnt start moving but your dir was different, do a turn direction instead.
+ gPlayerAvatar.runningState = TURN_DIRECTION;
+ return MACH_TRANS_TURN_DIRECTION;
+ }
+ else // the player is either going in the current direction and hasnt changed or their state is currently moving.
+ {
+ gPlayerAvatar.runningState = MOVING;
+ return MACH_TRANS_KEEP_MOVING;
+ }
+}
+
+// the difference between face direction and turn direction is that one changes direction while the other does the animation of turning as well as changing direction.
+static void MachBikeTransition_FaceDirection(u8 direction)
+{
+ PlayerFaceDirection(direction);
+ Bike_SetBikeStill();
+}
+
+static void MachBikeTransition_TurnDirection(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E))
+ {
+ PlayerTurnInPlace(direction);
+ Bike_SetBikeStill();
+ }
+ else
+ {
+ MachBikeTransition_FaceDirection(playerMapObj->mapobj_unk_18);
+ }
+}
+
+static void MachBikeTransition_TrySpeedUp(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ u8 collision;
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == FALSE)
+ {
+ // we cannot go forward, so either slow down or, if we are stopped, idle face direction.
+ if (gPlayerAvatar.bikeSpeed)
+ MachBikeTransition_TrySlowDown(playerMapObj->placeholder18);
+ else
+ MachBikeTransition_FaceDirection(playerMapObj->placeholder18);
+ }
+ else
+ {
+ collision = get_some_collision(direction);
+ if (collision > 0 && collision < 12)
+ {
+ // we hit a solid object, but check to see if its a ledge and then jump.
+ if (collision == COLLISION_LEDGE_JUMP)
+ {
+ PlayerJumpLedge(direction);
+ }
+ else
+ {
+ // we hit a solid object that is not a ledge, so perform the collision.
+ Bike_SetBikeStill();
+ if (collision == 4 && IsPlayerCollidingWithFarawayIslandMew(direction))
+ PlayerOnBikeCollideWithFarawayIslandMew(direction);
+ else if (collision < 5 || collision > 8)
+ PlayerOnBikeCollide(direction);
+ }
+ }
+ else
+ {
+ // we did not hit anything that can slow us down, so perform the advancement callback depending on the bikeFrameCounter and try to increase the mach bike's speed.
+ sMachBikeSpeedCallbacks[gPlayerAvatar.bikeFrameCounter](direction);
+ gPlayerAvatar.bikeSpeed = gPlayerAvatar.bikeFrameCounter + (gPlayerAvatar.bikeFrameCounter >> 1); // same as dividing by 2, but compiler is insistent on >> 1
+ if (gPlayerAvatar.bikeFrameCounter < 2) // do not go faster than the last element in the mach bike array
+ gPlayerAvatar.bikeFrameCounter++;
+ }
+ }
+}
+
+static void MachBikeTransition_TrySlowDown(u8 direction)
+{
+ u8 collision;
+
+ if (gPlayerAvatar.bikeSpeed != SPEED_STANDING)
+ gPlayerAvatar.bikeFrameCounter = --gPlayerAvatar.bikeSpeed;
+
+ collision = get_some_collision(direction);
+
+ if (collision > 0 && collision < 12)
+ {
+ if (collision == COLLISION_LEDGE_JUMP)
+ {
+ PlayerJumpLedge(direction);
+ }
+ else
+ {
+ Bike_SetBikeStill();
+ if (collision == 4 && IsPlayerCollidingWithFarawayIslandMew(direction))
+ PlayerOnBikeCollideWithFarawayIslandMew(direction);
+ else if (collision < 5 || collision > 8)
+ PlayerOnBikeCollide(direction);
+ }
+ }
+ else
+ {
+ sMachBikeSpeedCallbacks[gPlayerAvatar.bikeFrameCounter](direction);
+ }
+}
+
+// the acro bike requires the input handler to be executed before the transition can.
+static void MovePlayerOnAcroBike(u8 newDirection, u16 newKeys, u16 heldKeys)
+{
+ sAcroBikeTransitions[CheckMovementInputAcroBike(&newDirection, newKeys, heldKeys)](newDirection);
+}
+
+static u8 CheckMovementInputAcroBike(u8 *newDirection, u16 newKeys, u16 heldKeys)
+{
+ return sAcroBikeInputHandlers[gPlayerAvatar.acroBikeState](newDirection, newKeys, heldKeys);
+}
+
+static u8 AcroBikeHandleInputNormal(u8 *newDirection, u16 newKeys, u16 heldKeys)
+{
+ u8 direction = player_get_direction_upper_nybble();
+
+ gPlayerAvatar.bikeFrameCounter = 0;
+ if (*newDirection == DIR_NONE)
+ {
+ if (newKeys & B_BUTTON)
+ {
+ //We're standing still with the B button held.
+ //Do a wheelie.
+ *newDirection = direction;
+ gPlayerAvatar.runningState = NOT_MOVING;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ return ACRO_TRANS_NORMAL_TO_WHEELIE;
+ }
+ else
+ {
+ *newDirection = direction;
+ gPlayerAvatar.runningState = NOT_MOVING;
+ return ACRO_TRANS_FACE_DIRECTION;
+ }
+ }
+ if (*newDirection == direction && (heldKeys & B_BUTTON) && gPlayerAvatar.bikeSpeed == SPEED_STANDING)
+ {
+ gPlayerAvatar.bikeSpeed++;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_MOVING;
+ return ACRO_TRANS_WHEELIE_RISING_MOVING;
+ }
+ if (*newDirection != direction && gPlayerAvatar.runningState != MOVING)
+ {
+ gPlayerAvatar.acroBikeState = ACRO_STATE_TURNING;
+ gPlayerAvatar.newDirBackup = *newDirection;
+ gPlayerAvatar.runningState = NOT_MOVING;
+ return CheckMovementInputAcroBike(newDirection, newKeys, heldKeys);
+ }
+ gPlayerAvatar.runningState = MOVING;
+ return ACRO_TRANS_MOVING;
+}
+
+static u8 AcroBikeHandleInputTurning(u8 *newDirection, u16 newKeys, u16 heldKeys)
+{
+ u8 direction;
+
+ *newDirection = gPlayerAvatar.newDirBackup;
+ gPlayerAvatar.bikeFrameCounter++;
+
+ // Wait 6 frames before actually changing direction
+ if (gPlayerAvatar.bikeFrameCounter > 6) // ... because it takes 6 frames to advance 1 tile.
+ {
+ gPlayerAvatar.runningState = TURN_DIRECTION;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ Bike_SetBikeStill();
+ return ACRO_TRANS_TURN_DIRECTION;
+ }
+ direction = player_get_direction_upper_nybble();
+ if (*newDirection == AcroBike_GetJumpDirection())
+ {
+ Bike_SetBikeStill(); // Bike_SetBikeStill sets speed to standing, but the next line immediately overrides it. could have just reset acroBikeState to 0 here instead of wasting a jump.
+ gPlayerAvatar.bikeSpeed = SPEED_NORMAL;
+ if (*newDirection == GetOppositeDirection(direction))
+ {
+ // do a turn jump.
+ // no need to update runningState, didnt move.
+ gPlayerAvatar.acroBikeState = ACRO_STATE_TURN_JUMP;
+ return ACRO_TRANS_TURN_JUMP;
+ }
+ else
+ {
+ // do a sideways jump.
+ gPlayerAvatar.runningState = MOVING; // we need to move, set state to moving.
+ gPlayerAvatar.acroBikeState = ACRO_STATE_SIDE_JUMP;
+ return ACRO_TRANS_SIDE_JUMP;
+ }
+ }
+ *newDirection = direction;
+ return ACRO_TRANS_FACE_DIRECTION;
+}
+
+static u8 AcroBikeHandleInputWheelieStanding(u8 *newDirection, u16 newKeys, u16 heldKeys)
+{
+ u8 direction;
+ struct MapObject *playerMapObj;
+
+ direction = player_get_direction_upper_nybble();
+ playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ gPlayerAvatar.runningState = NOT_MOVING;
+
+ if (heldKeys & B_BUTTON)
+ gPlayerAvatar.bikeFrameCounter++;
+ else
+ {
+ // B button was released.
+ gPlayerAvatar.bikeFrameCounter = 0;
+ if (!MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ {
+ // Go back to normal on flat ground
+ *newDirection = direction;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ Bike_SetBikeStill();
+ return ACRO_TRANS_WHEELIE_TO_NORMAL;
+ }
+ }
+ if (gPlayerAvatar.bikeFrameCounter >= 40)
+ {
+ *newDirection = direction;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_BUNNY_HOP;
+ Bike_SetBikeStill();
+ return ACRO_TRANS_WHEELIE_HOPPING_STANDING;
+ }
+ if (*newDirection == direction)
+ {
+ gPlayerAvatar.runningState = MOVING;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_MOVING;
+ Bike_SetBikeStill();
+ return ACRO_TRANS_WHEELIE_MOVING;
+ }
+ if (*newDirection == 0)
+ {
+ *newDirection = direction;
+ return ACRO_TRANS_WHEELIE_IDLE;
+ }
+ gPlayerAvatar.runningState = TURN_DIRECTION;
+ return ACRO_TRANS_WHEELIE_IDLE;
+}
+
+static u8 AcroBikeHandleInputBunnyHop(u8 *newDirection, u16 newKeys, u16 heldKeys)
+{
+ u8 direction;
+ struct MapObject *playerMapObj;
+
+ direction = player_get_direction_upper_nybble();
+ playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!(heldKeys & B_BUTTON))
+ {
+ // B button was released
+ Bike_SetBikeStill();
+ if (MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ {
+ // even though B was released, dont undo the wheelie on the bumpy slope.
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ return CheckMovementInputAcroBike(newDirection, newKeys, heldKeys);
+ }
+ else
+ {
+ // .. otherwise, go back to normal on flat ground
+ *newDirection = direction;
+ gPlayerAvatar.runningState = NOT_MOVING;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ return ACRO_TRANS_WHEELIE_TO_NORMAL;
+ }
+ }
+
+ // B Button is still held
+
+ if (*newDirection == DIR_NONE)
+ {
+ // we did not move, so keep hopping in place without moving.
+ *newDirection = direction;
+ gPlayerAvatar.runningState = NOT_MOVING;
+ return ACRO_TRANS_WHEELIE_HOPPING_STANDING;
+ }
+ if (*newDirection != direction && gPlayerAvatar.runningState != MOVING)
+ {
+ // we changed direction, so turn but do not move hop.
+ gPlayerAvatar.runningState = TURN_DIRECTION;
+ return ACRO_TRANS_WHEELIE_HOPPING_STANDING;
+ }
+ // otherwise, we started moving while hopping
+ gPlayerAvatar.runningState = MOVING;
+ return ACRO_TRANS_WHEELIE_HOPPING_MOVING;
+}
+
+static u8 AcroBikeHandleInputWheelieMoving(u8 *newDirection, u16 newKeys, u16 heldKeys)
+{
+ u8 direction;
+ struct MapObject *playerMapObj;
+
+ direction = player_get_direction_lower_nybble();
+ playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!(heldKeys & B_BUTTON))
+ {
+ // we were moving on a wheelie, but we let go while moving. reset bike still status
+ Bike_SetBikeStill();
+ if (!MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ {
+ // we let go of B and arent on a bumpy slope, set state to normal because now we need to handle this
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ if (*newDirection == DIR_NONE)
+ {
+ // we stopped moving but are turning, still try to lower the wheelie in place.
+ *newDirection = direction;
+ gPlayerAvatar.runningState = NOT_MOVING;
+ return ACRO_TRANS_WHEELIE_TO_NORMAL;
+ }
+ if (*newDirection != direction && gPlayerAvatar.runningState != MOVING)
+ {
+ // we did not turn while lowering wheelie, so do so without turning.
+ gPlayerAvatar.runningState = NOT_MOVING;
+ return ACRO_TRANS_WHEELIE_TO_NORMAL;
+ }
+ // if we are moving while lowering wheelie, put the acro into a lowering state while moving.
+ gPlayerAvatar.runningState = MOVING;
+ return ACRO_TRANS_WHEELIE_LOWERING_MOVING;
+ }
+ // please do not undo the wheelie on a bumpy slope
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ return CheckMovementInputAcroBike(newDirection, newKeys, heldKeys);
+ }
+ // we are still holding B.
+ if (*newDirection == DIR_NONE)
+ {
+ // idle the wheelie in place because we're holding B without moving.
+ *newDirection = direction;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ gPlayerAvatar.runningState = NOT_MOVING;
+ Bike_SetBikeStill();
+ return ACRO_TRANS_WHEELIE_IDLE;
+ }
+ if (direction != *newDirection && gPlayerAvatar.runningState != MOVING)
+ {
+ gPlayerAvatar.runningState = NOT_MOVING;
+ return ACRO_TRANS_WHEELIE_IDLE;
+ }
+ gPlayerAvatar.runningState = MOVING;
+ return ACRO_TRANS_WHEELIE_MOVING;
+}
+
+static u8 AcroBikeHandleInputSidewaysJump(u8 *ptr, u16 newKeys, u16 heldKeys)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ playerMapObj->mapobj_bit_9 = 0;
+ FieldObjectSetDirection(playerMapObj, playerMapObj->mapobj_unk_18);
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ return CheckMovementInputAcroBike(ptr, newKeys, heldKeys);
+}
+
+static u8 AcroBikeHandleInputTurnJump(u8 *ptr, u16 newKeys, u16 heldKeys)
+{
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ return CheckMovementInputAcroBike(ptr, newKeys, heldKeys);
+}
+
+static void AcroBikeTransition_FaceDirection(u8 direction)
+{
+ PlayerFaceDirection(direction);
+}
+
+static void AcroBikeTransition_TurnDirection(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ PlayerFaceDirection(direction);
+}
+
+static void AcroBikeTransition_Moving(u8 direction)
+{
+ u8 collision;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ AcroBikeTransition_FaceDirection(playerMapObj->placeholder18);
+ return;
+ }
+ collision = get_some_collision(direction);
+ if (collision > 0 && collision < 12)
+ {
+ if (collision == COLLISION_LEDGE_JUMP)
+ PlayerJumpLedge(direction);
+ else if (collision == 4 && IsPlayerCollidingWithFarawayIslandMew(direction))
+ PlayerOnBikeCollideWithFarawayIslandMew(direction);
+ else if (collision < 5 || collision > 8)
+ PlayerOnBikeCollide(direction);
+ }
+ else
+ {
+ PlayerGoSpeed3(direction);
+ }
+}
+
+static void AcroBikeTransition_NormalToWheelie(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ PlayerStartWheelie(direction);
+}
+
+static void AcroBikeTransition_WheelieToNormal(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ PlayerEndWheelie(direction);
+}
+
+static void AcroBikeTransition_WheelieIdle(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ PlayerIdleWheelie(direction);
+}
+
+static void AcroBikeTransition_WheelieHoppingStanding(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ PlayerStandingHoppingWheelie(direction);
+}
+
+static void AcroBikeTransition_WheelieHoppingMoving(u8 direction)
+{
+ u8 collision;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ AcroBikeTransition_WheelieHoppingStanding(playerMapObj->placeholder18);
+ return;
+ }
+ collision = get_some_collision(direction);
+ // TODO: Try to get rid of this goto
+ if (collision == 0 || collision == 9)
+ {
+ goto derp;
+ }
+ else if (collision == 6)
+ {
+ PlayerLedgeHoppingWheelie(direction);
+ }
+ else if (collision < 5 || collision > 8)
+ {
+ if (collision <= 11)
+ {
+ AcroBikeTransition_WheelieHoppingStanding(direction);
+ }
+ else
+ {
+ derp:
+ PlayerMovingHoppingWheelie(direction);
+ }
+ }
+}
+
+static void AcroBikeTransition_SideJump(u8 direction)
+{
+ u8 collision;
+ struct MapObject *playerMapObj;
+
+ collision = get_some_collision(direction);
+ if (collision != 0)
+ {
+ if (collision == 7)
+ return;
+ if (collision < 10)
+ {
+ AcroBikeTransition_TurnDirection(direction);
+ return;
+ }
+ if (WillPlayerCollideWithCollision(collision, direction) == FALSE)
+ {
+ AcroBikeTransition_TurnDirection(direction);
+ return;
+ }
+ }
+ playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ PlaySE(SE_JITE_PYOKO);
+ playerMapObj->mapobj_bit_9 = 1;
+ PlayerSetAnimId(sub_8093514(direction), 2);
+}
+
+static void AcroBikeTransition_TurnJump(u8 direction)
+{
+ PlayerAcroTurnJump(direction);
+}
+
+static void AcroBikeTransition_WheelieMoving(u8 direction)
+{
+ u8 collision;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ PlayerIdleWheelie(playerMapObj->placeholder18);
+ return;
+ }
+ collision = get_some_collision(direction);
+ if (collision > 0 && collision < 12)
+ {
+ if (collision == 6)
+ {
+ PlayerLedgeHoppingWheelie(direction);
+ }
+ else if (collision == 9)
+ {
+ PlayerIdleWheelie(direction);
+ }
+ else if (collision <= 4)
+ {
+ if (MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ PlayerIdleWheelie(direction);
+ else
+ sub_808B980(direction); //hit wall?
+ }
+ return;
+ }
+ sub_808B9BC(direction);
+ gPlayerAvatar.runningState = MOVING;
+}
+
+static void AcroBikeTransition_WheelieRisingMoving(u8 direction)
+{
+ u8 collision;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ PlayerStartWheelie(playerMapObj->placeholder18);
+ return;
+ }
+ collision = get_some_collision(direction);
+ if (collision > 0 && collision < 12)
+ {
+ if (collision == 6)
+ {
+ PlayerLedgeHoppingWheelie(direction);
+ }
+ else if (collision == 9)
+ {
+ PlayerIdleWheelie(direction);
+ }
+ else if (collision <= 4)
+ {
+ if (MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ PlayerIdleWheelie(direction);
+ else
+ sub_808B980(direction); //hit wall?
+ }
+ return;
+ }
+ sub_808B9A4(direction);
+ gPlayerAvatar.runningState = MOVING;
+}
+
+static void AcroBikeTransition_WheelieLoweringMoving(u8 direction)
+{
+ u8 collision;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ PlayerEndWheelie(playerMapObj->placeholder18);
+ return;
+ }
+ collision = get_some_collision(direction);
+ if (collision > 0 && collision < 12)
+ {
+ if (collision == 6)
+ PlayerJumpLedge(direction);
+ else if (collision < 5 || collision > 8)
+ PlayerEndWheelie(direction);
+ return;
+ }
+ npc_use_some_d2s(direction);
+}
+
+void Bike_TryAcroBikeHistoryUpdate(u16 newKeys, u16 heldKeys)
+{
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE)
+ AcroBike_TryHistoryUpdate(newKeys, heldKeys);
+}
+
+static void AcroBike_TryHistoryUpdate(u16 newKeys, u16 heldKeys) // newKeys is unused
+{
+ u8 direction = Bike_DPadToDirection(heldKeys);
+
+ if (direction == (gPlayerAvatar.directionHistory & 0xF))
+ {
+ // increment the timer for direction history since last input.
+ if (gPlayerAvatar.dirTimerHistory[0] < 0xFF)
+ gPlayerAvatar.dirTimerHistory[0]++;
+ }
+ else
+ {
+ Bike_UpdateDirTimerHistory(direction);
+ gPlayerAvatar.bikeSpeed = SPEED_STANDING;
+ }
+
+ direction = heldKeys & (A_BUTTON | B_BUTTON | SELECT_BUTTON | START_BUTTON); // directions is reused for some reason.
+ if (direction == (gPlayerAvatar.abStartSelectHistory & 0xF))
+ {
+ if (gPlayerAvatar.abStartSelectTimerHistory[0] < 0xFF)
+ gPlayerAvatar.abStartSelectTimerHistory[0]++;
+ }
+ else
+ {
+ Bike_UpdateABStartSelectHistory(direction);
+ gPlayerAvatar.bikeSpeed = SPEED_STANDING;
+ }
+}
+
+static bool8 HasPlayerInputTakenLongerThanList(const u8 *dirTimerList, const u8 *abStartSelectTimerList)
+{
+ u8 i;
+
+ for (i = 0; dirTimerList[i] != 0; i++)
+ {
+ if (gPlayerAvatar.dirTimerHistory[i] > dirTimerList[i])
+ return FALSE;
+ }
+ for (i = 0; abStartSelectTimerList[i] != 0; i++)
+ {
+ if (gPlayerAvatar.abStartSelectTimerHistory[i] > abStartSelectTimerList[i])
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static u8 AcroBike_GetJumpDirection(void)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_COUNT(sAcroBikeTricksList); i++)
+ {
+ const struct BikeHistoryInputInfo *historyInputInfo = &sAcroBikeTricksList[i];
+ u32 dirHistory = gPlayerAvatar.directionHistory;
+ u32 abStartSelectHistory = gPlayerAvatar.abStartSelectHistory;
+
+ dirHistory &= historyInputInfo->dirHistoryMask;
+ abStartSelectHistory &= historyInputInfo->abStartSelectHistoryMask;
+ if (dirHistory == historyInputInfo->dirHistoryMatch && abStartSelectHistory == historyInputInfo->abStartSelectHistoryMatch && HasPlayerInputTakenLongerThanList(historyInputInfo->dirTimerHistoryList, historyInputInfo->abStartSelectHistoryList))
+ return historyInputInfo->direction;
+ }
+ return 0;
+}
+
+static void Bike_UpdateDirTimerHistory(u8 dir)
+{
+ u8 i;
+
+ gPlayerAvatar.directionHistory = (gPlayerAvatar.directionHistory << 4) | (dir & 0xF);
+
+ for (i = 7; i != 0; i--)
+ gPlayerAvatar.dirTimerHistory[i] = gPlayerAvatar.dirTimerHistory[i - 1];
+ gPlayerAvatar.dirTimerHistory[0] = 1;
+}
+
+static void Bike_UpdateABStartSelectHistory(u8 input)
+{
+ u8 i;
+
+ gPlayerAvatar.abStartSelectHistory = (gPlayerAvatar.abStartSelectHistory << 4) | (input & 0xF);
+
+ for (i = 7; i != 0; i--)
+ gPlayerAvatar.abStartSelectTimerHistory[i] = gPlayerAvatar.abStartSelectTimerHistory[i - 1];
+ gPlayerAvatar.abStartSelectTimerHistory[0] = 1;
+}
+
+static u8 Bike_DPadToDirection(u16 heldKeys)
+{
+ if (heldKeys & DPAD_UP)
+ return DIR_NORTH;
+ if (heldKeys & DPAD_DOWN)
+ return DIR_SOUTH;
+ if (heldKeys & DPAD_LEFT)
+ return DIR_WEST;
+ if (heldKeys & DPAD_RIGHT)
+ return DIR_EAST;
+ return DIR_NONE;
+}
+
+static u8 get_some_collision(u8 direction)
+{
+ s16 x;
+ s16 y;
+ u8 metatitleBehavior;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ x = playerMapObj->coords2.x;
+ y = playerMapObj->coords2.y;
+ MoveCoords(direction, &x, &y);
+ metatitleBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ return Bike_CheckCollisionTryAdvanceCollisionCount(playerMapObj, x, y, direction, metatitleBehavior);
+}
+
+static u8 Bike_CheckCollisionTryAdvanceCollisionCount(struct MapObject *mapObject, s16 x, s16 y, u8 direction, u8 metatitleBehavior)
+{
+ u8 collision = CheckForFieldObjectCollision(mapObject, x, y, direction, metatitleBehavior);
+
+ if (collision > 4)
+ return collision;
+
+ if (collision == 0 && IsRunningDisallowedByMetatile(metatitleBehavior))
+ collision = 2;
+
+ if (collision)
+ Bike_TryAdvanceCyclingRoadCollisions();
+
+ return collision;
+}
+
+bool8 RS_IsRunningDisallowed(u8 tile)
+{
+ if (IsRunningDisallowedByMetatile(tile) != FALSE || gMapHeader.mapType == MAP_TYPE_INDOOR)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 IsRunningDisallowedByMetatile(u8 tile)
+{
+ if (MetatileBehavior_IsRunningDisallowed(tile))
+ return TRUE;
+ if (MetatileBehavior_IsFortreeBridge(tile) && (PlayerGetZCoord() & 1) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+static void Bike_TryAdvanceCyclingRoadCollisions(void)
+{
+ if (gBikeCyclingChallenge != FALSE && gBikeCollisions < 100)
+ gBikeCollisions++;
+}
+
+static bool8 CanBikeFaceDirOnMetatile(u8 direction, u8 tile)
+{
+ if (direction == DIR_EAST || direction == DIR_WEST)
+ {
+ // Bike cannot face east or west on a vertical rail
+ if (MetatileBehavior_IsIsolatedVerticalRail(tile)
+ || MetatileBehavior_IsVerticalRail(tile))
+ return FALSE;
+ }
+ else
+ {
+ // Bike cannot face north or south on a horizontal rail
+ if (MetatileBehavior_IsIsolatedHorizontalRail(tile)
+ || MetatileBehavior_IsHorizontalRail(tile))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static bool8 WillPlayerCollideWithCollision(u8 newTileCollision, u8 direction)
+{
+ if (direction == DIR_NORTH || direction == DIR_SOUTH)
+ {
+ if (newTileCollision == 10 || newTileCollision == 12)
+ return FALSE;
+ }
+ else if (newTileCollision == 11 || newTileCollision == 13)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+bool8 IsBikingDisallowedByPlayer(void)
+{
+ s16 x, y;
+ u8 tileBehavior;
+
+ if (!(gPlayerAvatar.flags & (PLAYER_AVATAR_FLAG_SURFING | PLAYER_AVATAR_FLAG_4)))
+ {
+ PlayerGetDestCoords(&x, &y);
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (!IsRunningDisallowedByMetatile(tileBehavior))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 player_should_look_direction_be_enforced_upon_movement(void)
+{
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE) != FALSE && MetatileBehavior_IsBumpySlope(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E) != FALSE)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void GetOnOffBike(u8 transitionFlags)
+{
+ gUnknown_02037348 = FALSE;
+
+ if (gPlayerAvatar.flags & (PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ {
+ SetPlayerAvatarTransitionFlags(PLAYER_AVATAR_FLAG_ON_FOOT);
+ Overworld_ClearSavedMusic();
+ Overworld_PlaySpecialMapMusic();
+ }
+ else
+ {
+ SetPlayerAvatarTransitionFlags(transitionFlags);
+ Overworld_SetSavedMusic(MUS_CYCLING);
+ Overworld_ChangeMusicTo(MUS_CYCLING);
+ }
+}
+
+void BikeClearState(int newDirHistory, int newAbStartHistory)
+{
+ u8 i;
+
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ gPlayerAvatar.newDirBackup = DIR_NONE;
+ gPlayerAvatar.bikeFrameCounter = 0;
+ gPlayerAvatar.bikeSpeed = SPEED_STANDING;
+ gPlayerAvatar.directionHistory = newDirHistory;
+ gPlayerAvatar.abStartSelectHistory = newAbStartHistory;
+
+ for (i = 0; i < 8; i++)
+ gPlayerAvatar.dirTimerHistory[i] = 0;
+
+ for (i = 0; i < 8; i++)
+ gPlayerAvatar.abStartSelectTimerHistory[i] = 0;
+}
+
+void Bike_UpdateBikeCounterSpeed(u8 counter)
+{
+ gPlayerAvatar.bikeFrameCounter = counter;
+ gPlayerAvatar.bikeSpeed = gPlayerAvatar.bikeFrameCounter + (gPlayerAvatar.bikeFrameCounter >> 1); // lazy way of multiplying by 1.5.
+}
+
+static void Bike_SetBikeStill(void)
+{
+ gPlayerAvatar.bikeFrameCounter = 0;
+ gPlayerAvatar.bikeSpeed = SPEED_STANDING;
+}
+
+s16 GetPlayerSpeed(void)
+{
+ // because the player pressed a direction, it won't ever return a speed of 0 since this function returns the player's current speed.
+ s16 machSpeeds[3];
+
+ memcpy(machSpeeds, sMachBikeSpeeds, sizeof(machSpeeds));
+
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE)
+ return machSpeeds[gPlayerAvatar.bikeFrameCounter];
+ else if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE)
+ return SPEED_FASTER;
+ else if (gPlayerAvatar.flags & (PLAYER_AVATAR_FLAG_SURFING | PLAYER_AVATAR_FLAG_DASH))
+ return SPEED_FAST;
+ else
+ return SPEED_NORMAL;
+}
+
+void Bike_HandleBumpySlopeJump(void)
+{
+ s16 x, y;
+ u8 tileBehavior;
+
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE)
+ {
+ PlayerGetDestCoords(&x, &y);
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (MetatileBehavior_IsBumpySlope(tileBehavior))
+ {
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ sub_808C1B4(player_get_direction_upper_nybble());
+ }
+ }
+}
+
+bool32 IsRunningDisallowed(u8 metatile)
+{
+ if (!(gMapHeader.flags & 4) || IsRunningDisallowedByMetatile(metatile) == TRUE)
+ return TRUE;
+ else
+ return FALSE;
+}
diff --git a/src/daycare.c b/src/daycare.c
index ce9952531..59ee562bd 100644
--- a/src/daycare.c
+++ b/src/daycare.c
@@ -40,7 +40,7 @@ extern const u8 gDaycareText_PlayOther[];
extern u8 GetCursorSelectionMonId(void);
extern u16 ItemIdToBattleMoveId(u16);
-extern s32 ListMenuHandleInput(u8);
+extern s32 ListMenuHandleInputGetItemId(u8);
extern void sub_81AE6C8(u8, u16*, u16*);
extern void sub_819746C(u8, bool8);
extern void sub_81973FC(u8, bool8);
@@ -75,7 +75,7 @@ static const struct ListMenuItem sLevelMenuItems[] =
static const struct ListMenuTemplate sDaycareListMenuLevelTemplate =
{
.items = sLevelMenuItems,
- .unk_04 = sub_81AF078,
+ .moveCursorFunc = sub_81AF078,
.unk_08 = DaycarePrintMonInfo,
.totalItems = 3,
.maxShowed = 3,
@@ -90,7 +90,8 @@ static const struct ListMenuTemplate sDaycareListMenuLevelTemplate =
.unk_16_0 = TRUE,
.spaceBetweenItems = 0,
.unk_16_7 = FALSE,
- .unk_17_0 = 1
+ .unk_17_0 = 1,
+ .cursorKind = 0
};
static const u8 *const sCompatibilityMessages[] =
@@ -1256,7 +1257,7 @@ static void DaycarePrintMonInfo(u8 windowId, s32 daycareSlotId, u8 y)
static void Task_HandleDaycareLevelMenuInput(u8 taskId)
{
- u32 var = ListMenuHandleInput(gTasks[taskId].tMenuListTaskId);
+ u32 var = ListMenuHandleInputGetItemId(gTasks[taskId].tMenuListTaskId);
if (gMain.newKeys & A_BUTTON)
{
diff --git a/src/decoration.c b/src/decoration.c
index 987e628c5..c539091c8 100644
--- a/src/decoration.c
+++ b/src/decoration.c
@@ -25,7 +25,7 @@
#include "sound.h"
#include "event_scripts.h"
#include "event_data.h"
-#include "region_map.h"
+#include "constants/region_map_sections.h"
#include "player_pc.h"
#include "strings.h"
#include "tv.h"
@@ -792,17 +792,17 @@ void sub_8127330(u8 taskId)
for (i = 0; i < sDecorPCBuffer->unk_520 - 1; i ++)
{
sub_8127454(sDecorPCBuffer->names[i], gCurDecorInventoryItems[i]);
- sDecorPCBuffer->items[i].unk_00 = sDecorPCBuffer->names[i];
- sDecorPCBuffer->items[i].unk_04 = i;
+ sDecorPCBuffer->items[i].name = sDecorPCBuffer->names[i];
+ sDecorPCBuffer->items[i].id = i;
}
StringCopy(sDecorPCBuffer->names[i], gText_Cancel);
- sDecorPCBuffer->items[i].unk_00 = sDecorPCBuffer->names[i];
- sDecorPCBuffer->items[i].unk_04 = -2;
- gUnknown_03006310 = gUnknown_085A6BD0;
- gUnknown_03006310.unk_10 = sDecorMenuWindowIndices[1];
- gUnknown_03006310.totalItems = sDecorPCBuffer->unk_520;
- gUnknown_03006310.items = sDecorPCBuffer->items;
- gUnknown_03006310.maxShowed = sDecorPCBuffer->unk_521;
+ sDecorPCBuffer->items[i].name = sDecorPCBuffer->names[i];
+ sDecorPCBuffer->items[i].id = -2;
+ gMultiuseListMenuTemplate = gUnknown_085A6BD0;
+ gMultiuseListMenuTemplate.unk_10 = sDecorMenuWindowIndices[1];
+ gMultiuseListMenuTemplate.totalItems = sDecorPCBuffer->unk_520;
+ gMultiuseListMenuTemplate.items = sDecorPCBuffer->items;
+ gMultiuseListMenuTemplate.maxShowed = sDecorPCBuffer->unk_521;
}
void sub_8127454(u8 *dest, u16 decorId)
@@ -871,7 +871,7 @@ void sub_812759C(u8 taskId)
sub_81272C8();
sub_81272F8();
sub_8127330(taskId);
- data[13] = ListMenuInit(&gUnknown_03006310, sSecretBasePCSelectDecorPageNo, sSecretBasePCSelectDecorLineNo);
+ data[13] = ListMenuInit(&gMultiuseListMenuTemplate, sSecretBasePCSelectDecorPageNo, sSecretBasePCSelectDecorLineNo);
sub_8127500();
}
@@ -889,8 +889,8 @@ void sub_812764C(u8 taskId)
data = gTasks[taskId].data;
if (!gPaletteFade.active)
{
- input = ListMenuHandleInput(data[13]);
- get_coro_args_x18_x1A(data[13], &sSecretBasePCSelectDecorPageNo, &sSecretBasePCSelectDecorLineNo);
+ input = ListMenuHandleInputGetItemId(data[13]);
+ sub_81AE860(data[13], &sSecretBasePCSelectDecorPageNo, &sSecretBasePCSelectDecorLineNo);
switch (input)
{
case -1:
diff --git a/src/dma3_manager.c b/src/dma3_manager.c
index bb015c5cf..3832c3663 100644
--- a/src/dma3_manager.c
+++ b/src/dma3_manager.c
@@ -1,13 +1,24 @@
#include "global.h"
#include "dma3.h"
-IWRAM_DATA struct {
- /* 0x00 */ const u8 *src;
- /* 0x04 */ u8 *dest;
- /* 0x08 */ u16 size;
- /* 0x0A */ u16 mode;
- /* 0x0C */ u32 value;
-} gDma3Requests[128];
+// Maximum amount of data we will transfer in one operation
+#define MAX_DMA_BLOCK_SIZE 0x1000
+
+#define MAX_DMA_REQUESTS 128
+
+#define DMA_REQUEST_COPY32 1
+#define DMA_REQUEST_FILL32 2
+#define DMA_REQUEST_COPY16 3
+#define DMA_REQUEST_FILL16 4
+
+IWRAM_DATA struct
+{
+ const u8 *src;
+ u8 *dest;
+ u16 size;
+ u16 mode;
+ u32 value;
+} gDma3Requests[MAX_DMA_REQUESTS];
static bool8 gDma3ManagerLocked;
static u8 gDma3RequestCursor;
@@ -19,88 +30,103 @@ void ClearDma3Requests(void)
gDma3ManagerLocked = TRUE;
gDma3RequestCursor = 0;
- for(i = 0; i < (u8)ARRAY_COUNT(gDma3Requests); i++)
+ for (i = 0; i < MAX_DMA_REQUESTS; i++)
{
gDma3Requests[i].size = 0;
- gDma3Requests[i].src = 0;
- gDma3Requests[i].dest = 0;
+ gDma3Requests[i].src = NULL;
+ gDma3Requests[i].dest = NULL;
}
gDma3ManagerLocked = FALSE;
}
-#ifdef NONMATCHING
+#define Dma3CopyLarge_(src, dest, size, bit) \
+{ \
+ const void *_src = src; \
+ void *_dest = dest; \
+ u32 _size = size; \
+ while (1) \
+ { \
+ if (_size <= MAX_DMA_BLOCK_SIZE) \
+ { \
+ DmaCopy##bit(3, _src, _dest, _size); \
+ break; \
+ } \
+ DmaCopy##bit(3, _src, _dest, MAX_DMA_BLOCK_SIZE); \
+ _src += MAX_DMA_BLOCK_SIZE; \
+ _dest += MAX_DMA_BLOCK_SIZE; \
+ _size -= MAX_DMA_BLOCK_SIZE; \
+ } \
+}
+
+#define Dma3CopyLarge16_(src, dest, size) Dma3CopyLarge_(src, dest, size, 16)
+#define Dma3CopyLarge32_(src, dest, size) Dma3CopyLarge_(src, dest, size, 32)
+
+#define Dma3FillLarge_(value, dest, size, bit) \
+{ \
+ void *_dest = dest; \
+ u32 _size = size; \
+ while (1) \
+ { \
+ if (_size <= MAX_DMA_BLOCK_SIZE) \
+ { \
+ DmaFill##bit(3, value, _dest, _size); \
+ break; \
+ } \
+ DmaFill##bit(3, value, _dest, MAX_DMA_BLOCK_SIZE); \
+ _dest += MAX_DMA_BLOCK_SIZE; \
+ _size -= MAX_DMA_BLOCK_SIZE; \
+ } \
+}
+
+#define Dma3FillLarge16_(value, dest, size) Dma3FillLarge_(value, dest, size, 16)
+#define Dma3FillLarge32_(value, dest, size) Dma3FillLarge_(value, dest, size, 32)
+
+
void ProcessDma3Requests(void)
{
- // NOTE: the fillerA member of the DMA struct is actually u32 value;
- u16 total_size;
+ u16 bytesTransferred;
if (gDma3ManagerLocked)
return;
- total_size = 0;
+ bytesTransferred = 0;
// as long as there are DMA requests to process (unless size or vblank is an issue), do not exit
- while (gDma3Requests[gDma3RequestCursor].size)
+ while (gDma3Requests[gDma3RequestCursor].size != 0)
{
- total_size += gDma3Requests[gDma3RequestCursor].size;
+ bytesTransferred += gDma3Requests[gDma3RequestCursor].size;
- if (total_size > 0xA000)
- return; // don't do too much at once
-
- if (REG_VCOUNT > 224)
- return;// we're about to leave vblank, stop
+ if (bytesTransferred > 40 * 1024)
+ return; // don't transfer more than 40 KiB
+ if (*(u8 *)REG_ADDR_VCOUNT > 224)
+ return; // we're about to leave vblank, stop
switch (gDma3Requests[gDma3RequestCursor].mode)
{
- case 1: // regular 32-bit copy
- // _08000C8C
- if(gDma3Requests[gDma3RequestCursor].size <= 0x1000)
- {
- DmaCopy32(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
- break;
- }
- while (gDma3Requests[gDma3RequestCursor].size > 0x1000)
- {
- DmaCopy32(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, 0x1000);
- gDma3Requests[gDma3RequestCursor].src += 0x1000;
- gDma3Requests[gDma3RequestCursor].dest += 0x1000;
- gDma3Requests[gDma3RequestCursor].size -= 0x1000;
- }
- DmaCopy32(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
+ case DMA_REQUEST_COPY32: // regular 32-bit copy
+ Dma3CopyLarge32_(gDma3Requests[gDma3RequestCursor].src,
+ gDma3Requests[gDma3RequestCursor].dest,
+ gDma3Requests[gDma3RequestCursor].size);
break;
- case 2: // repeat a single 32-bit value across RAM
- // _08000CD0
- while (gDma3Requests[gDma3RequestCursor].size > 0x1000)
- {
- DmaFill32(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, 0x1000);
- gDma3Requests[gDma3RequestCursor].dest += 0x1000;
- gDma3Requests[gDma3RequestCursor].size -= 0x1000;
- }
- DmaFill32(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
+ case DMA_REQUEST_FILL32: // repeat a single 32-bit value across RAM
+ Dma3FillLarge32_(gDma3Requests[gDma3RequestCursor].value,
+ gDma3Requests[gDma3RequestCursor].dest,
+ gDma3Requests[gDma3RequestCursor].size);
break;
- case 3: // regular 16-bit copy
- // _08000D3C
- while (gDma3Requests[gDma3RequestCursor].size > 0x1000)
- {
- DmaCopy16(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, 0x1000);
- gDma3Requests[gDma3RequestCursor].src += 0x1000;
- gDma3Requests[gDma3RequestCursor].dest += 0x1000;
- gDma3Requests[gDma3RequestCursor].size -= 0x1000;
- }
- DmaCopy16(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
+ case DMA_REQUEST_COPY16: // regular 16-bit copy
+ Dma3CopyLarge16_(gDma3Requests[gDma3RequestCursor].src,
+ gDma3Requests[gDma3RequestCursor].dest,
+ gDma3Requests[gDma3RequestCursor].size);
break;
- case 4: // repeat a single 16-bit value across RAM
- // _08000D88
- while (gDma3Requests[gDma3RequestCursor].size > 0x1000)
- {
- DmaFill16(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, 0x1000);
- gDma3Requests[gDma3RequestCursor].dest += 0x1000;
- gDma3Requests[gDma3RequestCursor].size -= 0x1000;
- }
- DmaFill16(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
+ case DMA_REQUEST_FILL16: // repeat a single 16-bit value across RAM
+ Dma3FillLarge16_(gDma3Requests[gDma3RequestCursor].value,
+ gDma3Requests[gDma3RequestCursor].dest,
+ gDma3Requests[gDma3RequestCursor].size);
break;
}
+
+ // Free the request
gDma3Requests[gDma3RequestCursor].src = NULL;
gDma3Requests[gDma3RequestCursor].dest = NULL;
gDma3Requests[gDma3RequestCursor].size = 0;
@@ -108,375 +134,54 @@ void ProcessDma3Requests(void)
gDma3Requests[gDma3RequestCursor].value = 0;
gDma3RequestCursor++;
- if (gDma3RequestCursor >= 128) // loop back to the first DMA request
+ if (gDma3RequestCursor >= MAX_DMA_REQUESTS) // loop back to the first DMA request
gDma3RequestCursor = 0;
}
}
-#else
-__attribute__((naked))
-void ProcessDma3Requests(void)
-{
- asm(".syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r10\n\
- mov r6, r9\n\
- mov r5, r8\n\
- push {r5-r7}\n\
- sub sp, 0xC\n\
- ldr r0, =gDma3ManagerLocked\n\
- ldrb r0, [r0]\n\
- cmp r0, 0\n\
- beq _08000C06\n\
- b _08000E46\n\
-_08000C06:\n\
- movs r0, 0\n\
- str r0, [sp, 0x8]\n\
- ldr r1, =gDma3Requests\n\
- ldr r2, =gDma3RequestCursor\n\
- ldrb r0, [r2]\n\
- lsls r0, 4\n\
- adds r0, r1\n\
- ldrh r0, [r0, 0x8]\n\
- mov r12, r2\n\
- cmp r0, 0\n\
- bne _08000C1E\n\
- b _08000E46\n\
-_08000C1E:\n\
- mov r8, r1\n\
- adds r1, 0x4\n\
- mov r10, r1\n\
- movs r6, 0x80\n\
- lsls r6, 5\n\
- ldr r7, =0x040000D4 @REG_DMA3\n\
- movs r2, 0\n\
- mov r9, r2\n\
-_08000C2E:\n\
- mov r3, r12 @ gDma3RequestCursor\n\
- ldrb r0, [r3]\n\
- lsls r5, r0, 4\n\
- mov r0, r8 @ gDma3Requests\n\
- adds r1, r5, r0 @ gDma3Requests[gDma3RequestCursor]\n\
- ldrh r0, [r1, 0x8] @ gDma3Requests[gDma3RequestCursor].size\n\
- ldr r2, [sp, 0x8]\n\
- adds r0, r2, r0\n\
- lsls r0, 16\n\
- lsrs r0, 16\n\
- str r0, [sp, 0x8]\n\
- movs r0, 0xA0\n\
- lsls r0, 8\n\
- ldr r3, [sp, 0x8]\n\
- cmp r3, r0\n\
- bls _08000C50\n\
- b _08000E46\n\
-_08000C50:\n\
- ldr r0, =0x04000006 @REG_VCOUNT\n\
- ldrb r0, [r0]\n\
- cmp r0, 0xE0\n\
- bls _08000C5A\n\
- b _08000E46\n\
-_08000C5A:\n\
- ldrh r0, [r1, 0xA]\n\
- cmp r0, 0x2\n\
- beq _08000CD0\n\
- cmp r0, 0x2\n\
- bgt _08000C80\n\
- cmp r0, 0x1\n\
- beq _08000C8C\n\
- b _08000DF0\n\
- .pool\n\
-_08000C80:\n\
- cmp r0, 0x3\n\
- beq _08000D3C\n\
- cmp r0, 0x4\n\
- bne _08000C8A\n\
- b _08000D88\n\
-_08000C8A:\n\
- b _08000DF0\n\
-_08000C8C:\n\
- ldr r3, [r1]\n\
- mov r2, r10\n\
- adds r0, r5, r2\n\
- ldr r2, [r0]\n\
- ldrh r1, [r1, 0x8]\n\
- cmp r1, r6\n\
- bhi _08000CA6\n\
- str r3, [r7]\n\
- str r2, [r7, 0x4]\n\
- lsrs r0, r1, 2\n\
- movs r1, 0x84\n\
- lsls r1, 24\n\
- b _08000DAA\n\
-_08000CA6:\n\
- ldr r4, =0x040000D4 @REG_DMA3\n\
- str r3, [r4]\n\
- str r2, [r4, 0x4]\n\
- ldr r0, =0x84000400\n\
- str r0, [r4, 0x8]\n\
- ldr r0, [r4, 0x8]\n\
- adds r3, r6\n\
- adds r2, r6\n\
- subs r1, r6\n\
- cmp r1, r6\n\
- bhi _08000CA6\n\
- str r3, [r4]\n\
- str r2, [r4, 0x4]\n\
- lsrs r0, r1, 2\n\
- movs r1, 0x84\n\
- lsls r1, 24\n\
- b _08000D76\n\
- .pool\n\
-_08000CD0:\n\
- mov r3, r10\n\
- adds r0, r5, r3\n\
- ldr r4, [r0]\n\
- ldrh r1, [r1, 0x8]\n\
- cmp r1, r6\n\
- bhi _08000CF4\n\
- mov r0, r8\n\
- adds r0, 0xC\n\
- adds r0, r5, r0\n\
- ldr r0, [r0]\n\
- str r0, [sp]\n\
- mov r5, sp\n\
- str r5, [r7]\n\
- str r4, [r7, 0x4]\n\
- lsrs r0, r1, 2\n\
- movs r1, 0x85\n\
- lsls r1, 24\n\
- b _08000DAA\n\
-_08000CF4:\n\
- mov r2, r12\n\
- ldrb r0, [r2]\n\
- lsls r0, 4\n\
- mov r5, r8\n\
- adds r5, 0xC\n\
- adds r0, r5\n\
- ldr r0, [r0]\n\
- str r0, [sp]\n\
- ldr r3, =0x040000D4 @REG_DMA3\n\
- mov r0, sp\n\
- str r0, [r3]\n\
- str r4, [r3, 0x4]\n\
- ldr r0, =0x85000400\n\
- str r0, [r3, 0x8]\n\
- ldr r0, [r3, 0x8]\n\
- adds r4, r6\n\
- subs r1, r6\n\
- cmp r1, r6\n\
- bhi _08000CF4\n\
- ldrb r0, [r2]\n\
- lsls r0, 4\n\
- adds r0, r5\n\
- ldr r0, [r0]\n\
- str r0, [sp]\n\
- mov r2, sp\n\
- str r2, [r3]\n\
- str r4, [r3, 0x4]\n\
- lsrs r0, r1, 2\n\
- movs r1, 0x85\n\
- lsls r1, 24\n\
- b _08000DEA\n\
- .pool\n\
-_08000D3C:\n\
- ldr r3, [r1]\n\
- mov r2, r10\n\
- adds r0, r5, r2\n\
- ldr r2, [r0]\n\
- ldrh r1, [r1, 0x8]\n\
- cmp r1, r6\n\
- bhi _08000D56\n\
- str r3, [r7]\n\
- str r2, [r7, 0x4]\n\
- lsrs r0, r1, 1\n\
- movs r1, 0x80\n\
- lsls r1, 24\n\
- b _08000DAA\n\
-_08000D56:\n\
- ldr r4, =0x040000D4 @REG_DMA3\n\
- str r3, [r4]\n\
- str r2, [r4, 0x4]\n\
- ldr r0, =0x80000800\n\
- str r0, [r4, 0x8]\n\
- ldr r0, [r4, 0x8]\n\
- adds r3, r6\n\
- adds r2, r6\n\
- subs r1, r6\n\
- cmp r1, r6\n\
- bhi _08000D56\n\
- str r3, [r4]\n\
- str r2, [r4, 0x4]\n\
- lsrs r0, r1, 1\n\
- movs r1, 0x80\n\
- lsls r1, 24\n\
-_08000D76:\n\
- orrs r0, r1\n\
- str r0, [r4, 0x8]\n\
- ldr r0, [r4, 0x8]\n\
- b _08000DF0\n\
- .pool\n\
-_08000D88:\n\
- mov r3, r10\n\
- adds r0, r5, r3\n\
- ldr r2, [r0]\n\
- ldrh r4, [r1, 0x8]\n\
- add r1, sp, 0x4\n\
- cmp r4, r6\n\
- bhi _08000DB2\n\
- mov r0, r8\n\
- adds r0, 0xC\n\
- adds r0, r5, r0\n\
- ldr r0, [r0]\n\
- strh r0, [r1]\n\
- str r1, [r7]\n\
- str r2, [r7, 0x4]\n\
- lsrs r0, r4, 1\n\
- movs r1, 0x81\n\
- lsls r1, 24\n\
-_08000DAA:\n\
- orrs r0, r1\n\
- str r0, [r7, 0x8]\n\
- ldr r0, [r7, 0x8]\n\
- b _08000DF0\n\
-_08000DB2:\n\
- mov r5, r12\n\
- ldrb r0, [r5]\n\
- lsls r0, 4\n\
- ldr r3, =gDma3Requests + 0x0C\n\
- adds r0, r3\n\
- ldr r0, [r0]\n\
- strh r0, [r1]\n\
- ldr r3, =0x040000D4 @REG_DMA3\n\
- str r1, [r3]\n\
- str r2, [r3, 0x4]\n\
- ldr r0, =0x81000800\n\
- str r0, [r3, 0x8]\n\
- ldr r0, [r3, 0x8]\n\
- adds r2, r6\n\
- subs r4, r6\n\
- cmp r4, r6\n\
- bhi _08000DB2\n\
- ldrb r0, [r5]\n\
- lsls r0, 4\n\
- ldr r5, =gDma3Requests + 0x0C\n\
- adds r0, r5\n\
- ldr r0, [r0]\n\
- strh r0, [r1]\n\
- str r1, [r3]\n\
- str r2, [r3, 0x4]\n\
- lsrs r0, r4, 1\n\
- movs r1, 0x81\n\
- lsls r1, 24\n\
-_08000DEA:\n\
- orrs r0, r1\n\
- str r0, [r3, 0x8]\n\
- ldr r0, [r3, 0x8]\n\
-_08000DF0:\n\
- ldr r1, =gDma3Requests\n\
- mov r3, r12\n\
- ldrb r0, [r3]\n\
- lsls r0, 4\n\
- adds r0, r1\n\
- mov r2, r9\n\
- str r2, [r0]\n\
- ldrb r0, [r3]\n\
- lsls r0, 4\n\
- add r0, r10\n\
- str r2, [r0]\n\
- ldrb r0, [r3]\n\
- lsls r0, 4\n\
- adds r0, r1\n\
- movs r4, 0\n\
- strh r2, [r0, 0x8]\n\
- ldrb r0, [r3]\n\
- lsls r0, 4\n\
- adds r0, r1\n\
- mov r5, r9\n\
- strh r5, [r0, 0xA]\n\
- ldrb r0, [r3]\n\
- lsls r0, 4\n\
- adds r1, 0xC\n\
- adds r0, r1\n\
- mov r1, r9\n\
- str r1, [r0]\n\
- ldrb r0, [r3]\n\
- adds r0, 0x1\n\
- strb r0, [r3]\n\
- lsls r0, 24\n\
- cmp r0, 0\n\
- bge _08000E34\n\
- strb r4, [r3]\n\
-_08000E34:\n\
- mov r2, r12\n\
- ldrb r0, [r2]\n\
- lsls r0, 4\n\
- ldr r3, =gDma3Requests\n\
- adds r0, r3\n\
- ldrh r0, [r0, 0x8]\n\
- cmp r0, 0\n\
- beq _08000E46\n\
- b _08000C2E\n\
-_08000E46:\n\
- add sp, 0xC\n\
- pop {r3-r5}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- mov r10, r5\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0\n\
- .pool\n\
- .syntax divided");
-}
-#endif
-int RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode)
+s16 RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode)
{
int cursor;
- int var = 0;
-
- gDma3ManagerLocked = 1;
+ int i = 0;
+ gDma3ManagerLocked = TRUE;
cursor = gDma3RequestCursor;
- while(1)
+
+ while (i < MAX_DMA_REQUESTS)
{
- if(!gDma3Requests[cursor].size) // an empty copy was found and the current cursor will be returned.
+ if (gDma3Requests[cursor].size == 0) // an empty request was found.
{
gDma3Requests[cursor].src = src;
gDma3Requests[cursor].dest = dest;
gDma3Requests[cursor].size = size;
- if(mode == 1)
- gDma3Requests[cursor].mode = mode;
+ if (mode == 1)
+ gDma3Requests[cursor].mode = DMA_REQUEST_COPY32;
else
- gDma3Requests[cursor].mode = 3;
+ gDma3Requests[cursor].mode = DMA_REQUEST_COPY16;
gDma3ManagerLocked = FALSE;
- return (s16)cursor;
+ return cursor;
}
- if(++cursor >= 0x80) // loop back to start.
- {
+ if (++cursor >= MAX_DMA_REQUESTS) // loop back to start.
cursor = 0;
- }
- if(++var >= 0x80) // max checks were made. all resulted in failure.
- {
- break;
- }
+ i++;
}
gDma3ManagerLocked = FALSE;
- return -1;
+ return -1; // no free DMA request was found
}
-int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
+s16 RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
{
int cursor;
- int var = 0;
+ int i = 0;
cursor = gDma3RequestCursor;
- gDma3ManagerLocked = 1;
+ gDma3ManagerLocked = TRUE;
- while(1)
+ while (i < MAX_DMA_REQUESTS)
{
- if(!gDma3Requests[cursor].size)
+ if (gDma3Requests[cursor].size == 0) // an empty request was found.
{
gDma3Requests[cursor].dest = dest;
gDma3Requests[cursor].size = size;
@@ -484,41 +189,39 @@ int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
gDma3Requests[cursor].value = value;
if(mode == 1)
- gDma3Requests[cursor].mode = 2;
+ gDma3Requests[cursor].mode = DMA_REQUEST_FILL32;
else
- gDma3Requests[cursor].mode = 4;
+ gDma3Requests[cursor].mode = DMA_REQUEST_FILL16;
gDma3ManagerLocked = FALSE;
- return (s16)cursor;
+ return cursor;
}
- if(++cursor >= 0x80) // loop back to start.
- {
+ if (++cursor >= MAX_DMA_REQUESTS) // loop back to start.
cursor = 0;
- }
- if(++var >= 0x80) // max checks were made. all resulted in failure.
- {
- break;
- }
+ i++;
}
gDma3ManagerLocked = FALSE;
- return -1;
+ return -1; // no free DMA request was found
}
int CheckForSpaceForDma3Request(s16 index)
{
- int current = 0;
+ int i = 0;
- if (index == -1)
+ if (index == -1) // check if all requests are free
{
- for (; current < 0x80; current ++)
- if (gDma3Requests[current].size)
+ while (i < MAX_DMA_REQUESTS)
+ {
+ if (gDma3Requests[i].size != 0)
return -1;
-
+ i++;
+ }
+ return 0;
+ }
+ else // check the specified request
+ {
+ if (gDma3Requests[index].size != 0)
+ return -1;
return 0;
}
-
- if (gDma3Requests[index].size)
- return -1;
-
- return 0;
}
diff --git a/src/egg_hatch.c b/src/egg_hatch.c
index 3235f6144..ed1e7f4cc 100644
--- a/src/egg_hatch.c
+++ b/src/egg_hatch.c
@@ -48,11 +48,11 @@ extern struct SpriteTemplate gUnknown_0202499C;
extern void (*gFieldCallback)(void);
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
-extern const u8 gUnknown_08C00000[];
-extern const u8 gUnknown_08C00524[];
-extern const u8 gUnknown_08C004E0[];
-extern const u16 gUnknown_08DD7300[]; // palette, gameboy advance
-extern const u32 gUnknown_08DD7360[]; // tileset gameboy advance
+extern const u8 gBattleTextboxTiles[];
+extern const u8 gBattleTextboxTilemap[];
+extern const u8 gBattleTextboxPalette[];
+extern const u16 gTradeGba2_Pal[]; // palette, gameboy advance
+extern const u32 gTradeGba_Gfx[]; // tileset gameboy advance
extern const u32 gUnknown_08331F60[]; // tilemap gameboy circle
extern const u8 gText_HatchedFromEgg[];
extern const u8 gText_NickHatchPrompt[];
@@ -85,7 +85,7 @@ static void CreateRandomEggShardSprite(void);
static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex);
// IWRAM bss
-static IWRAM_DATA struct EggHatchData* sEggHatchData;
+static IWRAM_DATA struct EggHatchData *sEggHatchData;
// rom data
static const u16 sEggPalette[] = INCBIN_U16("graphics/pokemon/palettes/egg_palette.gbapal");
@@ -516,9 +516,9 @@ static void CB2_EggHatch_0(void)
gMain.state++;
break;
case 2:
- copy_decompressed_tile_data_to_vram_autofree(0, gUnknown_08C00000, 0, 0, 0);
- CopyToBgTilemapBuffer(0, gUnknown_08C00524, 0, 0);
- LoadCompressedPalette(gUnknown_08C004E0, 0, 0x20);
+ copy_decompressed_tile_data_to_vram_autofree(0, gBattleTextboxTiles, 0, 0, 0);
+ CopyToBgTilemapBuffer(0, gBattleTextboxTilemap, 0, 0);
+ LoadCompressedPalette(gBattleTextboxPalette, 0, 0x20);
gMain.state++;
break;
case 3:
@@ -542,8 +542,8 @@ static void CB2_EggHatch_0(void)
break;
case 7:
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
- LoadPalette(gUnknown_08DD7300, 0x10, 0xA0);
- LoadBgTiles(1, gUnknown_08DD7360, 0x1420, 0);
+ LoadPalette(gTradeGba2_Pal, 0x10, 0xA0);
+ LoadBgTiles(1, gTradeGba_Gfx, 0x1420, 0);
CopyToBgTilemapBuffer(1, gUnknown_08331F60, 0x1000, 0);
CopyBgTilemapBufferToVram(1);
gMain.state++;
diff --git a/src/evolution_scene.c b/src/evolution_scene.c
index 3bbdaca13..536eb6979 100644
--- a/src/evolution_scene.c
+++ b/src/evolution_scene.c
@@ -60,16 +60,8 @@ extern u8 gBattleCommunication[];
extern const struct WindowTemplate gUnknown_0833900C;
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
-extern const u8 gUnknown_085B58C9[][4];
-extern const u16 gUnknown_085B5884[];
-extern const u8 gUnknown_085B58D9[];
-extern const u16 gUnknown_085B51E4[];
-extern const u32 gUnknown_085B4134[];
-extern const u32 gUnknown_085B482C[];
-extern const u32 gUnknown_085B4D10[];
// strings
-extern const u8 gText_ShedinjaJapaneseName2[];
extern const u8 gText_PkmnIsEvolving[];
extern const u8 gText_CongratsPkmnEvolved[];
extern const u8 gText_BattleYesNoChoice[];
@@ -83,7 +75,7 @@ extern void sub_806A068(u16, u8);
extern void sub_807F19C(void);
extern void sub_807B140(void);
extern void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies);
-extern void sub_8085784(void);
+extern void Overworld_PlaySpecialMapMusic(void);
extern void sub_81BFA38(struct Pokemon *party, u8 monId, u8 partyCount, void *CB2_ptr, u16 move);
extern u8 sub_81C1B94(void);
extern void sub_807F1A8(u8 arg0, const u8 *arg1, u8 arg2);
@@ -105,6 +97,80 @@ static void InitMovingBackgroundTask(bool8 isLink);
static void sub_813FEE8(u8 taskId);
static void sub_8140174(void);
+// const data
+static const u16 sUnknown_085B4114[] = INCBIN_U16("graphics/evolution_scene/unknown_5B4114.gbapal");
+static const u32 sUnknown_085B4134[] = INCBIN_U32("graphics/evolution_scene/bg.4bpp.lz");
+static const u32 sUnknown_085B482C[] = INCBIN_U32("graphics/evolution_scene/bg.bin.lz");
+static const u32 sUnknown_085B4D10[] = INCBIN_U32("graphics/evolution_scene/bg2.bin.lz");
+static const u16 sUnknown_085B51E4[] = INCBIN_U16("graphics/evolution_scene/gray_transition_intro.gbapal");
+static const u16 sUnknown_085B53E4[] = INCBIN_U16("graphics/evolution_scene/gray_transition_lighten.gbapal");
+static const u16 sUnknown_085B5544[] = INCBIN_U16("graphics/evolution_scene/gray_transition_darken.gbapal");
+static const u16 sUnknown_085B56E4[] = INCBIN_U16("graphics/evolution_scene/gray_transition_outro.gbapal");
+static const u16 sUnknown_085B5884[] = INCBIN_U16("graphics/evolution_scene/transition.gbapal");
+
+static const u8 Text_ShedinjaJapaneseName[] = _("ヌケニン");
+
+static const u8 sUnknown_085B58C9[][4] =
+{
+ { 0x00, 0x0C, 0x01, 0x06 },
+ { 0x0D, 0x24, 0x05, 0x02 },
+ { 0x0D, 0x18, 0x01, 0x02 },
+ { 0x25, 0x31, 0x01, 0x06 },
+};
+
+static const u8 sUnknown_085B58D9[][16] = {
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x0B, 0x00, 0x00 },
+ { 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x00 },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x00, 0x00 },
+ { 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x00, 0x00 },
+ { 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x00, 0x00 },
+ { 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, 0x00, 0x00 },
+ { 0x00, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x00, 0x00 },
+ { 0x00, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x00, 0x00 },
+ { 0x00, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x00, 0x00 },
+ { 0x00, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x00, 0x00 },
+ { 0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x00, 0x00 },
+ { 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x00, 0x00 },
+ { 0x00, 0x0B, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x00, 0x00 },
+ { 0x00, 0x0C, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x00, 0x00 },
+ { 0x00, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00 },
+ { 0x00, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x00, 0x00 },
+ { 0x00, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x00 },
+ { 0x00, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00 },
+ { 0x00, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00 },
+ { 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, 0x00 },
+ { 0x00, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00 },
+ { 0x00, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00 },
+ { 0x00, 0x05, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00 },
+ { 0x00, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x00, 0x00 },
+ { 0x00, 0x03, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x00, 0x00 },
+ { 0x00, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x00 },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x00, 0x00 },
+ { 0x00, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00 },
+ { 0x00, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+};
+
static void CB2_BeginEvolutionScene(void)
{
UpdatePaletteFade();
@@ -541,7 +607,7 @@ static void CreateShedinja(u16 preEvoSpecies, struct Pokemon* mon)
if (GetMonData(Shedinja, MON_DATA_SPECIES) == SPECIES_SHEDINJA
&& GetMonData(Shedinja, MON_DATA_LANGUAGE) == LANGUAGE_JAPANESE
&& GetMonData(mon, MON_DATA_SPECIES) == SPECIES_NINJASK)
- SetMonData(Shedinja, MON_DATA_NICKNAME, gText_ShedinjaJapaneseName2);
+ SetMonData(Shedinja, MON_DATA_NICKNAME, Text_ShedinjaJapaneseName);
}
}
@@ -591,14 +657,14 @@ static void Task_EvolutionScene(u8 taskID)
case 3:
if (EvoScene_IsMonAnimFinished(sEvoStructPtr->preEvoSpriteID)) // wait for animation, play tu du SE
{
- PlaySE(BGM_ME_SHINKA);
+ PlaySE(MUS_ME_SHINKA);
gTasks[taskID].tState++;
}
break;
case 4: // play evolution music and fade screen black
if (!IsSEPlaying())
{
- PlayNewMapMusic(BGM_SHINKA);
+ PlayNewMapMusic(MUS_SHINKA);
gTasks[taskID].tState++;
BeginNormalPaletteFade(0x1C, 4, 0, 0x10, 0);
}
@@ -674,7 +740,7 @@ static void Task_EvolutionScene(u8 taskID)
{
StringExpandPlaceholders(gStringVar4, gText_CongratsPkmnEvolved);
BattleHandleAddTextPrinter(gStringVar4, 0);
- PlayBGM(BGM_FANFA5);
+ PlayBGM(MUS_FANFA5);
gTasks[taskID].tState++;
SetMonData(mon, MON_DATA_SPECIES, (void*)(&gTasks[taskID].tPostEvoSpecies));
CalculateMonStats(mon);
@@ -695,7 +761,7 @@ static void Task_EvolutionScene(u8 taskID)
if (!(gTasks[taskID].tBits & TASK_BIT_LEARN_MOVE))
{
StopMapMusic();
- sub_8085784();
+ Overworld_PlaySpecialMapMusic();
}
gTasks[taskID].tBits |= TASK_BIT_LEARN_MOVE;
@@ -724,7 +790,7 @@ static void Task_EvolutionScene(u8 taskID)
if (!(gTasks[taskID].tBits & TASK_BIT_LEARN_MOVE))
{
StopMapMusic();
- sub_8085784();
+ Overworld_PlaySpecialMapMusic();
}
if (!gTasks[taskID].tEvoWasStopped)
CreateShedinja(gTasks[taskID].tPreEvoSpecies, mon);
@@ -769,7 +835,7 @@ static void Task_EvolutionScene(u8 taskID)
if (!IsTextPrinterActive(0) && !IsSEPlaying())
{
BufferMoveToLearnIntoBattleTextBuff2();
- PlayFanfare(BGM_FANFA1);
+ PlayFanfare(MUS_FANFA1);
BattleStringExpandPlaceholdersToDisplayedString(gBattleStringsTable[STRINGID_PKMNLEARNEDMOVE - BATTLESTRINGS_ID_ADDER]);
BattleHandleAddTextPrinter(gDisplayedStringBattle, 0);
gTasks[taskID].tLearnsFirstMove = 0x40; // re-used as a counter
@@ -959,15 +1025,15 @@ static void Task_TradeEvolutionScene(u8 taskID)
case 2:
if (IsCryFinished())
{
- m4aSongNumStop(BGM_SHINKA);
- PlaySE(BGM_ME_SHINKA);
+ m4aSongNumStop(MUS_SHINKA);
+ PlaySE(MUS_ME_SHINKA);
gTasks[taskID].tState++;
}
break;
case 3:
if (!IsSEPlaying())
{
- PlayBGM(BGM_SHINKA);
+ PlayBGM(MUS_SHINKA);
gTasks[taskID].tState++;
BeginNormalPaletteFade(0x1C, 4, 0, 0x10, 0);
}
@@ -1037,7 +1103,7 @@ static void Task_TradeEvolutionScene(u8 taskID)
{
StringExpandPlaceholders(gStringVar4, gText_CongratsPkmnEvolved);
sub_807F1A8(0, gStringVar4, 1);
- PlayFanfare(BGM_FANFA5);
+ PlayFanfare(MUS_FANFA5);
gTasks[taskID].tState++;
SetMonData(mon, MON_DATA_SPECIES, (&gTasks[taskID].tPostEvoSpecies));
CalculateMonStats(mon);
@@ -1070,7 +1136,7 @@ static void Task_TradeEvolutionScene(u8 taskID)
}
else
{
- PlayBGM(BGM_SHINKA);
+ PlayBGM(MUS_SHINKA);
sub_807F1A8(0, gText_CommunicationStandby5, 1);
gTasks[taskID].tState++;
}
@@ -1114,7 +1180,7 @@ static void Task_TradeEvolutionScene(u8 taskID)
if (!IsTextPrinterActive(0) && !IsSEPlaying())
{
BufferMoveToLearnIntoBattleTextBuff2();
- PlayFanfare(BGM_FANFA1);
+ PlayFanfare(MUS_FANFA1);
BattleStringExpandPlaceholdersToDisplayedString(gBattleStringsTable[STRINGID_PKMNLEARNEDMOVE - BATTLESTRINGS_ID_ADDER]);
sub_807F1A8(0, gDisplayedStringBattle, 1);
gTasks[taskID].tLearnsFirstMove = 0x40; // re-used as a counter
@@ -1327,17 +1393,17 @@ static void sub_813FDEC(u8 taskId)
if (data[5]++ < 20)
return;
- if (data[0]++ > gUnknown_085B58C9[data[2]][3])
+ if (data[0]++ > sUnknown_085B58C9[data[2]][3])
{
- if (gUnknown_085B58C9[data[2]][1] == data[1])
+ if (sUnknown_085B58C9[data[2]][1] == data[1])
{
data[3]++;
- if (data[3] == gUnknown_085B58C9[data[2]][2])
+ if (data[3] == sUnknown_085B58C9[data[2]][2])
{
data[3] = 0;
data[2]++;
}
- data[1] = gUnknown_085B58C9[data[2]][0];
+ data[1] = sUnknown_085B58C9[data[2]][0];
}
else
{
@@ -1408,7 +1474,7 @@ static void InitMovingBgValues(u16 *movingBgs)
{
for (j = 0; j < 16; j++)
{
- movingBgs[i * 16 + j] = gUnknown_085B5884[gUnknown_085B58D9[i * 16 + j]];
+ movingBgs[i * 16 + j] = sUnknown_085B5884[sUnknown_085B58D9[i][j]];
}
}
}
@@ -1425,11 +1491,11 @@ static void InitMovingBackgroundTask(bool8 isLink)
else
innerBgId = 1, outerBgId = 3;
- LoadPalette(gUnknown_085B51E4, 0xA0, 0x20);
+ LoadPalette(sUnknown_085B51E4, 0xA0, 0x20);
- copy_decompressed_tile_data_to_vram_autofree(1, gUnknown_085B4134, FALSE, 0, 0);
- CopyToBgTilemapBuffer(1, gUnknown_085B482C, 0, 0);
- CopyToBgTilemapBuffer(outerBgId, gUnknown_085B4D10, 0, 0);
+ copy_decompressed_tile_data_to_vram_autofree(1, sUnknown_085B4134, FALSE, 0, 0);
+ CopyToBgTilemapBuffer(1, sUnknown_085B482C, 0, 0);
+ CopyToBgTilemapBuffer(outerBgId, sUnknown_085B4D10, 0, 0);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(outerBgId);
diff --git a/src/field_door.c b/src/field_door.c
new file mode 100644
index 000000000..f73c6bb55
--- /dev/null
+++ b/src/field_door.c
@@ -0,0 +1,898 @@
+#include "global.h"
+#include "field_door.h"
+#include "field_camera.h"
+#include "fieldmap.h"
+#include "metatile_behavior.h"
+#include "event_data.h"
+#include "constants/songs.h"
+#include "constants/flags.h"
+#include "constants/maps.h"
+#include "task.h"
+
+bool8 sub_808A964(void);
+
+const u8 DoorAnimTiles_04[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/04/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/04/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/04/2.4bpp"),
+};
+
+// TODO: Make these blank palette includes?
+asm(".space 32");
+
+const u8 DoorAnimTiles_05[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/05/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/05/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/05/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_08[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/08/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/08/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/08/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_15[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/15/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/15/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/15/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_16[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/16/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/16/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/16/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_00[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/00/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/00/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/00/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_01[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/01/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/01/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/01/2.4bpp"),
+};
+
+const u8 DoorAnimTiles_02[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/02/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/02/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/02/2.4bpp"),
+};
+
+const u8 DoorAnimTiles_03[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/03/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/03/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/03/2.4bpp"),
+};
+
+const u8 DoorAnimTiles_06[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/06/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/06/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/06/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_07[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/07/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/07/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/07/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_09[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/09/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/09/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/09/2.4bpp"),
+};
+
+asm(".space 0x5900");
+
+const u8 DoorAnimTiles_UnusedTops[][0x40] =
+{
+ INCBIN_U8("graphics/door_anims/unused_848EDEC/0_top.4bpp"),
+ INCBIN_U8("graphics/door_anims/unused_848EDEC/1_top.4bpp"),
+ INCBIN_U8("graphics/door_anims/unused_848EDEC/2_top.4bpp"),
+};
+
+asm(".space 0x140");
+
+const u8 DoorAnimTiles_UnusedBottoms[][0x40] =
+{
+ INCBIN_U8("graphics/door_anims/unused_848EDEC/0_bottom.4bpp"),
+ INCBIN_U8("graphics/door_anims/unused_848EDEC/1_bottom.4bpp"),
+ INCBIN_U8("graphics/door_anims/unused_848EDEC/2_bottom.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_10[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/10/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/10/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/10/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_11[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/11/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/11/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/11/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_12[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/12/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/12/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/12/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_13[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/13/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/13/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/13/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_14[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/14/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/14/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/14/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_17[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/17/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/17/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/17/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_18[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/18/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/18/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/18/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_19[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/19/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/19/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/19/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_20[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/20/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/20/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/20/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_21[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/21/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/21/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/21/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_22[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/22/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/22/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/22/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_23[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/23/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/23/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/23/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_24[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/24/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/24/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/24/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_25[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/25/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/25/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/25/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_26[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/26/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/26/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/26/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_27[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/27/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/27/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/27/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_28[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/28/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/28/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/28/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_29[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/29/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/29/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/29/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_30[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/30/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/30/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/30/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_31[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/31/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/31/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/31/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_32[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/32/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/32/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/32/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_33[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/33/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/33/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/33/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_34[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/34/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/34/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/34/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_35[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/35/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/35/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/35/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_36[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/36/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/36/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/36/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_37[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/37/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/37/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/37/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_38[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/38/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/38/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/38/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_39[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/39/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/39/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/39/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_40[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/40/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/40/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/40/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_41[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/41/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/41/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/41/2.4bpp"),
+};
+
+const u8 DoorAnimTiles_42[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/42/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/42/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/42/2.4bpp"),
+ INCBIN_U8("graphics/door_anims/42/3.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_43[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/43/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/43/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/43/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_44[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/44/0_left.4bpp"),
+ INCBIN_U8("graphics/door_anims/44/0_right.4bpp"),
+ INCBIN_U8("graphics/door_anims/44/1_left.4bpp"),
+ INCBIN_U8("graphics/door_anims/44/1_right.4bpp"),
+ INCBIN_U8("graphics/door_anims/44/2_left.4bpp"),
+ INCBIN_U8("graphics/door_anims/44/2_right.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_45[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/45/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/45/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/45/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_46[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/46/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/46/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/46/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_47[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/47/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/47/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/47/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_48[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/48/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/48/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/48/2.4bpp"),
+ INCBIN_U8("graphics/door_anims/48/3.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_49[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/49/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/49/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/49/2.4bpp"),
+};
+
+asm(".space 32");
+
+const u8 DoorAnimTiles_50[][0x100] =
+{
+ INCBIN_U8("graphics/door_anims/50/0.4bpp"),
+ INCBIN_U8("graphics/door_anims/50/1.4bpp"),
+ INCBIN_U8("graphics/door_anims/50/2.4bpp"),
+};
+
+asm(".space 32");
+
+static const struct DoorAnimFrame gDoorOpenAnimFrames[] =
+{
+ {4, -1},
+ {4, 0},
+ {4, 0x100},
+ {4, 0x200},
+ {0, 0},
+};
+
+static const struct DoorAnimFrame gDoorCloseAnimFrames[] =
+{
+ {4, 0x200},
+ {4, 0x100},
+ {4, 0},
+ {4, -1},
+ {0, 0},
+};
+
+static const struct DoorAnimFrame gBigDoorOpenAnimFrames[] =
+{
+ {4, -1},
+ {4, 0},
+ {4, 0x200},
+ {4, 0x400},
+ {0, 0},
+};
+
+static const struct DoorAnimFrame gBigDoorCloseAnimFrames[] =
+{
+ {4, 0x400},
+ {4, 0x200},
+ {4, 0},
+ {4, -1},
+ {0, 0},
+};
+
+const u8 DoorAnimPalettes_8496FDC[] = {1, 1, 1, 1, 1, 1, 1, 1}; // door 00
+const u8 DoorAnimPalettes_8496FE4[] = {1, 1, 1, 1, 1, 1, 1, 1}; // door 01
+const u8 DoorAnimPalettes_8496FEC[] = {5, 5, 5, 5, 5, 5, 5, 5}; // door 02
+const u8 DoorAnimPalettes_8496FF4[] = {0, 0, 1, 1, 1, 1, 1, 1}; // door 03
+const u8 DoorAnimPalettes_8496FFC[] = {10, 10, 6, 6, 6, 6, 6, 6}; // door 04
+const u8 DoorAnimPalettes_8497004[] = {8, 8, 8, 8, 8, 8, 8, 8}; // door 05
+const u8 DoorAnimPalettes_849700C[] = {11, 11, 11, 11, 11, 11, 11, 11}; // door 06
+const u8 DoorAnimPalettes_8497014[] = {10, 10, 10, 10, 10, 10, 10, 10}; // door 07
+const u8 DoorAnimPalettes_849701C[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 08
+const u8 DoorAnimPalettes_8497024[] = {8, 8, 8, 8, 8, 8, 8, 8}; // door 09
+const u8 DoorAnimPalettes_849702C[] = {10, 10, 9, 9, 9, 9, 9, 9}; // door 10
+const u8 DoorAnimPalettes_8497034[] = {9, 9, 1, 1, 1, 1, 1, 1}; // door 11
+const u8 DoorAnimPalettes_849703C[] = {8, 8, 8, 8, 8, 8, 8, 8}; // door 12
+const u8 DoorAnimPalettes_8497044[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 13
+const u8 DoorAnimPalettes_849704C[] = {6, 6, 6, 6, 6, 6, 6, 6}; // door 14
+const u8 DoorAnimPalettes_8497054[] = {6, 6, 6, 6, 6, 6, 6, 6}; // door 15
+const u8 DoorAnimPalettes_849705C[] = {0, 0, 5, 5, 5, 5, 5, 5}; // door 16
+const u8 DoorAnimPalettes_8497064[] = {6, 6, 1, 1, 1, 1, 1, 1}; // door 17
+const u8 DoorAnimPalettes_849706C[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 18
+const u8 DoorAnimPalettes_8497074[] = {6, 6, 5, 5, 5, 5, 5, 5}; // door 19
+const u8 DoorAnimPalettes_849707C[] = {5, 5, 5, 5, 5, 5, 5, 5}; // door 20
+const u8 DoorAnimPalettes_8497084[] = {1, 1, 1, 1, 1, 1, 1, 1}; // door 21
+const u8 DoorAnimPalettes_849708C[] = {6, 6, 6, 6, 6, 6, 6, 6}; // door 22
+const u8 DoorAnimPalettes_8497094[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 23
+const u8 DoorAnimPalettes_849709C[] = {5, 5, 5, 5, 5, 5, 5, 5}; // door 24
+const u8 DoorAnimPalettes_84970A4[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 25
+const u8 DoorAnimPalettes_84970AC[] = {8, 8, 8, 8, 8, 8, 8, 8}; // door 26
+const u8 DoorAnimPalettes_84970B4[] = {6, 6, 6, 6, 6, 6, 6, 6}; // door 27
+const u8 DoorAnimPalettes_84970BC[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 28
+const u8 DoorAnimPalettes_84970C4[] = {11, 11, 7, 7, 7, 7, 7, 7}; // door 29
+const u8 DoorAnimPalettes_84970CC[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 30
+const u8 DoorAnimPalettes_84970D4[] = {6, 6, 7, 7, 7, 7, 7, 7}; // door 31
+const u8 DoorAnimPalettes_84970DC[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 32
+const u8 DoorAnimPalettes_84970E4[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 33
+const u8 DoorAnimPalettes_84970EC[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 34
+const u8 DoorAnimPalettes_84970F4[] = {1, 1, 1, 1, 1, 1, 1, 1}; // door 35
+const u8 DoorAnimPalettes_84970FC[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 36
+const u8 DoorAnimPalettes_8497104[] = {0, 0, 0, 0, 0, 0, 0, 0}; // door 37
+const u8 DoorAnimPalettes_849710C[] = {5, 5, 5, 5, 5, 5, 5, 5}; // door 38
+const u8 DoorAnimPalettes_8497114[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 39
+const u8 DoorAnimPalettes_849711C[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 40
+const u8 DoorAnimPalettes_8497124[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 41
+const u8 DoorAnimPalettes_849712C[] = {1, 1, 1, 1, 1, 1, 1, 1}; // doors 42, 43, and 44
+const u8 DoorAnimPalettes_8497134[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 45
+const u8 DoorAnimPalettes_849713C[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 46
+const u8 DoorAnimPalettes_8497144[] = {1, 1, 1, 1, 1, 1, 1, 1}; // unused
+const u8 DoorAnimPalettes_849714C[] = {1, 1, 1, 1, 1, 1, 1, 1}; // doors 47 and 48
+const u8 DoorAnimPalettes_8497154[] = {9, 9, 7, 7, 7, 7, 7, 7}; // door 49
+const u8 DoorAnimPalettes_849715C[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 50
+const u8 DoorAnimPalettes_8497164[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 51
+const u8 DoorAnimPalettes_849716C[] = {9, 9, 7, 7, 7, 7, 7, 7}; // door 52
+
+static const struct DoorGraphics gDoorAnimGraphicsTable[] =
+{
+ {0x021, 0, 1, DoorAnimTiles_00, DoorAnimPalettes_8496FDC}, // door 00
+ {0x061, 1, 1, DoorAnimTiles_01, DoorAnimPalettes_8496FE4}, // door 01
+ {0x1CD, 1, 1, DoorAnimTiles_02, DoorAnimPalettes_8496FEC}, // door 02
+ {0x041, 1, 1, DoorAnimTiles_03, DoorAnimPalettes_8496FF4}, // door 03
+ {0x248, 0, 1, DoorAnimTiles_04, DoorAnimPalettes_8496FFC}, // door 04
+ {0x249, 0, 1, DoorAnimTiles_05, DoorAnimPalettes_8497004}, // door 05
+ {0x22F, 0, 1, DoorAnimTiles_06, DoorAnimPalettes_849700C}, // door 06
+ {0x21F, 0, 1, DoorAnimTiles_07, DoorAnimPalettes_8497014}, // door 07
+ {0x2A5, 0, 1, DoorAnimTiles_08, DoorAnimPalettes_849701C}, // door 08
+ {0x287, 0, 1, DoorAnimTiles_09, DoorAnimPalettes_849702C}, // door 09
+ {0x2AC, 0, 1, DoorAnimTiles_10, DoorAnimPalettes_849706C}, // door 10
+ {0x3A1, 0, 1, DoorAnimTiles_11, DoorAnimPalettes_8497074}, // door 11
+ {0x2DC, 0, 1, DoorAnimTiles_12, DoorAnimPalettes_8497064}, // door 12
+ {0x225, 0, 1, DoorAnimTiles_13, DoorAnimPalettes_849705C}, // door 13
+ {0x1DB, 1, 1, DoorAnimTiles_14, DoorAnimPalettes_8497084}, // door 14
+ {0x246, 0, 1, DoorAnimTiles_15, DoorAnimPalettes_8497024}, // door 15
+ {0x28E, 0, 1, DoorAnimTiles_16, DoorAnimPalettes_849707C}, // door 16
+ {0x2A1, 0, 1, DoorAnimTiles_17, DoorAnimPalettes_8497034}, // door 17
+ {0x21C, 0, 1, DoorAnimTiles_18, DoorAnimPalettes_849704C}, // door 18
+ {0x21E, 0, 1, DoorAnimTiles_19, DoorAnimPalettes_8497054}, // door 19
+ {0x21D, 1, 1, DoorAnimTiles_20, DoorAnimPalettes_849703C}, // door 20
+ {0x21A, 0, 1, DoorAnimTiles_21, DoorAnimPalettes_8497044}, // door 21
+ {0x224, 0, 1, DoorAnimTiles_22, DoorAnimPalettes_849708C}, // door 22
+ {0x289, 0, 1, DoorAnimTiles_23, DoorAnimPalettes_8497094}, // door 23
+ {0x30C, 1, 1, DoorAnimTiles_24, DoorAnimPalettes_849709C}, // door 24
+ {0x32D, 1, 1, DoorAnimTiles_25, DoorAnimPalettes_84970A4}, // door 25
+ {0x2ED, 1, 1, DoorAnimTiles_26, DoorAnimPalettes_84970AC}, // door 26
+ {0x264, 1, 1, DoorAnimTiles_27, DoorAnimPalettes_84970B4}, // door 27
+ {0x22B, 0, 1, DoorAnimTiles_28, DoorAnimPalettes_84970BC}, // door 28
+ {0x2F7, 0, 1, DoorAnimTiles_29, DoorAnimPalettes_84970C4}, // door 29
+ {0x297, 0, 1, DoorAnimTiles_30, DoorAnimPalettes_84970CC}, // door 30
+ {0x285, 1, 1, DoorAnimTiles_31, DoorAnimPalettes_84970D4}, // door 31
+ {0x25D, 1, 1, DoorAnimTiles_32, DoorAnimPalettes_84970DC}, // door 32
+ {0x20E, 1, 1, DoorAnimTiles_33, DoorAnimPalettes_84970E4}, // door 33
+ {0x3B0, 1, 1, DoorAnimTiles_34, DoorAnimPalettes_84970EC}, // door 34
+ {0x28A, 1, 1, DoorAnimTiles_35, DoorAnimPalettes_84970F4}, // door 35
+ {0x263, 1, 1, DoorAnimTiles_36, DoorAnimPalettes_84970FC}, // door 36
+ {0x329, 1, 1, DoorAnimTiles_37, DoorAnimPalettes_8497104}, // door 37
+ {0x291, 0, 1, DoorAnimTiles_38, DoorAnimPalettes_849710C}, // door 38
+ {0x21B, 2, 1, DoorAnimTiles_39, DoorAnimPalettes_8497114}, // door 39
+ {0x209, 1, 1, DoorAnimTiles_40, DoorAnimPalettes_849711C}, // door 40
+ {0x219, 0, 1, DoorAnimTiles_41, DoorAnimPalettes_8497124}, // door 41
+ {0x393, 1, 1, DoorAnimTiles_42, DoorAnimPalettes_849712C}, // door 42
+ {0x3D4, 1, 1, DoorAnimTiles_42, DoorAnimPalettes_849712C}, // door 43
+ {0x36C, 1, 1, DoorAnimTiles_42, DoorAnimPalettes_849712C}, // door 44
+ {0x25E, 1, 1, DoorAnimTiles_43, DoorAnimPalettes_8497134}, // door 45
+ {0x2AD, 1, 2, DoorAnimTiles_44, DoorAnimPalettes_849713C}, // door 46
+ {0x3FC, 0, 1, DoorAnimTiles_45, DoorAnimPalettes_849714C}, // door 47
+ {0x396, 1, 1, DoorAnimTiles_46, DoorAnimPalettes_849714C}, // door 48
+ {0x20A, 1, 1, DoorAnimTiles_47, DoorAnimPalettes_8497154}, // door 49
+ {0x26B, 1, 1, DoorAnimTiles_48, DoorAnimPalettes_849715C}, // door 50
+ {0x32C, 1, 1, DoorAnimTiles_49, DoorAnimPalettes_8497164}, // door 51
+ {0x383, 1, 1, DoorAnimTiles_50, DoorAnimPalettes_849716C}, // door 52
+ {0, 0, 0, NULL, NULL},
+};
+
+static void CopyDoorTilesToVram(const struct DoorGraphics *gfx, const struct DoorAnimFrame *frame)
+{
+ if (gfx->size == 2)
+ CpuFastSet(gfx->tiles + frame->offset, (void *)(VRAM + 0x7E00), 0x80);
+ else
+ CpuFastSet(gfx->tiles + frame->offset, (void *)(VRAM + 0x7F00), 0x40);
+}
+
+static void door_build_blockdef(u16 *a, u16 b, const u8 *c)
+{
+ int i;
+ u16 unk;
+
+ for (i = 0; i < 4; i++)
+ {
+ unk = *(c++) << 12;
+ a[i] = unk | (b + i);
+ }
+ for (; i < 8; i++)
+ {
+ unk = *(c++) << 12;
+ a[i] = unk;
+ }
+}
+
+static void DrawCurrentDoorAnimFrame(const struct DoorGraphics *gfx, u32 x, u32 y, const u8 *pal)
+{
+ u16 arr[24];
+
+ if (gfx->size == 2)
+ {
+ door_build_blockdef(&arr[8], 0x3F0, pal);
+ DrawDoorMetatileAt(x, y - 1, &arr[8]);
+ door_build_blockdef(&arr[8], 0x3F4, pal + 4);
+ DrawDoorMetatileAt(x, y, &arr[8]);
+ door_build_blockdef(&arr[8], 0x3F8, pal);
+ DrawDoorMetatileAt(x + 1, y - 1, &arr[8]);
+ door_build_blockdef(&arr[8], 0x3FC, pal + 4);
+ DrawDoorMetatileAt(x + 1, y, &arr[8]);
+ }
+ else
+ {
+ door_build_blockdef(&arr[0], 0x3F8, pal);
+ DrawDoorMetatileAt(x, y - 1, &arr[0]);
+ door_build_blockdef(&arr[0], 0x3FC, pal + 4);
+ DrawDoorMetatileAt(x, y, &arr[0]);
+ }
+}
+
+static void DrawClosedDoorTiles(const struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ CurrentMapDrawMetatileAt(x, y - 1);
+ CurrentMapDrawMetatileAt(x, y);
+
+ if (gfx->size == 2)
+ {
+ CurrentMapDrawMetatileAt(x + 1, y - 1);
+ CurrentMapDrawMetatileAt(x + 1, y);
+ }
+}
+
+static void DrawDoor(const struct DoorGraphics *gfx, const struct DoorAnimFrame *frame, u32 x, u32 y)
+{
+ if (frame->offset == 0xFFFF)
+ {
+ DrawClosedDoorTiles(gfx, x, y);
+ if (sub_808A964())
+ DrawClosedDoorTiles(gfx, gSpecialVar_0x8004 + 7, gSpecialVar_0x8005 + 7);
+ }
+ else
+ {
+ CopyDoorTilesToVram(gfx, frame);
+ DrawCurrentDoorAnimFrame(gfx, x, y, gfx->palette);
+ if (sub_808A964())
+ DrawCurrentDoorAnimFrame(gfx, gSpecialVar_0x8004 + 7, gSpecialVar_0x8005 + 7, gfx->palette);
+ }
+}
+
+enum
+{
+ TD_FRAMELIST = 0,
+ TD_GFX = 2,
+ TD_FRAME = 4,
+ TD_COUNTER,
+ TD_X,
+ TD_Y
+};
+
+static bool32 sub_808A5F0(struct DoorGraphics *gfx, struct DoorAnimFrame *frames, s16 *taskData)
+{
+ if (taskData[TD_COUNTER] == 0)
+ DrawDoor(gfx, &frames[taskData[TD_FRAME]], taskData[TD_X], taskData[TD_Y]);
+ if (taskData[TD_COUNTER] == frames[taskData[TD_FRAME]].time)
+ {
+ taskData[TD_COUNTER] = 0;
+ taskData[TD_FRAME]++;
+ if (frames[taskData[TD_FRAME]].time == 0)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ taskData[TD_COUNTER]++;
+ return TRUE;
+}
+
+static void Task_AnimateDoor(u8 taskId)
+{
+ u16 *taskData = gTasks[taskId].data;
+ struct DoorAnimFrame *frames = (struct DoorAnimFrame *)(taskData[TD_FRAMELIST] << 16 | taskData[TD_FRAMELIST + 1]);
+ struct DoorGraphics *gfx = (struct DoorGraphics *)(taskData[TD_GFX] << 16 | taskData[TD_GFX + 1]);
+
+ if (sub_808A5F0(gfx, frames, taskData) == FALSE)
+ DestroyTask(taskId);
+}
+
+static const struct DoorAnimFrame *GetLastDoorFrame(const struct DoorAnimFrame *frame, const void *unused)
+{
+ while (frame->time != 0)
+ frame++;
+ return frame - 1;
+}
+
+static const struct DoorGraphics *GetDoorGraphics(const struct DoorGraphics *gfx, u16 metatileNum)
+{
+ while (gfx->tiles != NULL)
+ {
+ if (gfx->metatileNum == metatileNum)
+ return gfx;
+ gfx++;
+ }
+ return NULL;
+}
+
+static s8 StartDoorAnimationTask(const struct DoorGraphics *gfx, const struct DoorAnimFrame *frames, u32 x, u32 y)
+{
+ if (FuncIsActiveTask(Task_AnimateDoor) == TRUE)
+ return -1;
+ else
+ {
+ u8 taskId = CreateTask(Task_AnimateDoor, 0x50);
+ s16 *taskData = gTasks[taskId].data;
+
+ taskData[TD_X] = x;
+ taskData[TD_Y] = y;
+
+ taskData[TD_FRAMELIST + 1] = (u32)frames;
+ taskData[TD_FRAMELIST] = (u32)frames >> 16;
+
+ taskData[TD_GFX + 1] = (u32)gfx;
+ taskData[TD_GFX] = (u32)gfx >> 16;
+
+ return taskId;
+ }
+}
+
+static void DrawClosedDoor(const struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ DrawClosedDoorTiles(gfx, x, y);
+}
+
+static void DrawOpenedDoor(const struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx != NULL)
+ DrawDoor(gfx, GetLastDoorFrame(gDoorOpenAnimFrames, gDoorOpenAnimFrames), x, y);
+}
+
+static s8 StartDoorOpenAnimation(const struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx == NULL)
+ {
+ return -1;
+ }
+ else
+ {
+ if (gfx->size == 2)
+ return StartDoorAnimationTask(gfx, gBigDoorOpenAnimFrames, x, y);
+ else
+ return StartDoorAnimationTask(gfx, gDoorOpenAnimFrames, x, y);
+ }
+}
+
+static s8 StartDoorCloseAnimation(const struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx == NULL)
+ return -1;
+ else
+ return StartDoorAnimationTask(gfx, gDoorCloseAnimFrames, x, y);
+}
+
+static s8 cur_mapdata_get_door_x2_at(const struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx == NULL)
+ return -1;
+ else
+ return gfx->sound;
+}
+
+void unref_sub_808A83C(u32 x, u32 y)
+{
+ StartDoorOpenAnimation(gDoorAnimGraphicsTable, x, y);
+}
+
+void FieldSetDoorOpened(u32 x, u32 y)
+{
+ if (MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ DrawOpenedDoor(gDoorAnimGraphicsTable, x, y);
+}
+
+void FieldSetDoorClosed(u32 x, u32 y)
+{
+ if (MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ DrawClosedDoor(gDoorAnimGraphicsTable, x, y);
+}
+
+s8 FieldAnimateDoorClose(u32 x, u32 y)
+{
+ if (!MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ return -1;
+ else
+ return StartDoorCloseAnimation(gDoorAnimGraphicsTable, x, y);
+}
+
+s8 FieldAnimateDoorOpen(u32 x, u32 y)
+{
+ if (!MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ return -1;
+ else
+ return StartDoorOpenAnimation(gDoorAnimGraphicsTable, x, y);
+}
+
+bool8 FieldIsDoorAnimationRunning(void)
+{
+ return FuncIsActiveTask(Task_AnimateDoor);
+}
+
+u32 GetDoorSoundEffect(u32 x, u32 y)
+{
+ int sound = cur_mapdata_get_door_x2_at(gDoorAnimGraphicsTable, x, y);
+
+ if (sound == 0)
+ return SE_DOOR;
+ else if (sound == 1)
+ return SE_JIDO_DOA;
+ else if (sound == 2)
+ return SE_TU_SAA;
+ else
+ return SE_DOOR;
+}
+
+bool8 sub_808A964(void)
+{
+ if (FlagGet(FLAG_SPECIAL_FLAG_0x4002))
+ {
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR_2) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR_2))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
diff --git a/src/field_map_obj.c b/src/field_map_obj.c
index 6a99890a4..df80494b3 100755
--- a/src/field_map_obj.c
+++ b/src/field_map_obj.c
@@ -1174,11 +1174,11 @@ void npc_by_local_id_and_map_set_field_1_bit_x20(u8 localId, u8 mapNum, u8 mapGr
}
}
-void FieldObjectGetLocalIdAndMap(struct MapObject *mapObject, u8 *localId, u8 *mapNum, u8 *mapGroup)
+void FieldObjectGetLocalIdAndMap(struct MapObject *mapObject, void *localId, void *mapNum, void *mapGroup)
{
- *localId = mapObject->localId;
- *mapNum = mapObject->mapNum;
- *mapGroup = mapObject->mapGroup;
+ *(u8*)(localId) = mapObject->localId;
+ *(u8*)(mapNum) = mapObject->mapNum;
+ *(u8*)(mapGroup) = mapObject->mapGroup;
}
void sub_808E75C(s16 x, s16 y)
@@ -3231,7 +3231,7 @@ bool8 mss_npc_reset_oampriv3_1_unk2_unk3(struct MapObject *mapObject, struct Spr
bool8 sub_8091EC0(struct MapObject *mapObject, struct Sprite *sprite)
{
- if (gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C == 0xFF || gPlayerAvatar.running1 == 2)
+ if (gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C == 0xFF || gPlayerAvatar.tileTransitionState == 2)
{
return FALSE;
}
@@ -3410,7 +3410,7 @@ field_object_step(CopyPlayer2, gUnknown_0850DA90)
bool8 mss_08062EA4(struct MapObject *mapObject, struct Sprite *sprite)
{
- if (gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C == 0xFF || gPlayerAvatar.running1 == 2)
+ if (gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C == 0xFF || gPlayerAvatar.tileTransitionState == 2)
{
return FALSE;
}
@@ -3426,7 +3426,7 @@ void FieldObjectCB_TreeDisguise(struct Sprite *sprite)
mapObject = &gMapObjects[sprite->data[0]];
if (mapObject->mapobj_unk_21 == 0 || (mapObject->mapobj_unk_21 == 1 && !sprite->data[7]))
{
- FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ FieldObjectGetLocalIdAndMap(mapObject, &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]);
mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_TREE_DISGUISE);
mapObject->mapobj_unk_21 = 1;
sprite->data[7] ++;
@@ -3447,7 +3447,7 @@ void FieldObjectCB_MountainDisguise(struct Sprite *sprite)
mapObject = &gMapObjects[sprite->data[0]];
if (mapObject->mapobj_unk_21 == 0 || (mapObject->mapobj_unk_21 == 1 && !sprite->data[7]))
{
- FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ FieldObjectGetLocalIdAndMap(mapObject, &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]);
mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_MOUNTAIN_DISGUISE);
mapObject->mapobj_unk_21 = 1;
sprite->data[7] ++;
@@ -4694,7 +4694,7 @@ bool8 sub_80954CC(struct MapObject *mapObject, struct Sprite *sprite)
bool8 do_exclamation_mark_bubble_1(struct MapObject *mapObject, struct Sprite *sprite)
{
- FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ FieldObjectGetLocalIdAndMap(mapObject, &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]);
FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_1);
sprite->data[2] = 1;
return TRUE;
@@ -4702,7 +4702,7 @@ bool8 do_exclamation_mark_bubble_1(struct MapObject *mapObject, struct Sprite *s
bool8 do_exclamation_mark_bubble_2(struct MapObject *mapObject, struct Sprite *sprite)
{
- FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ FieldObjectGetLocalIdAndMap(mapObject, &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]);
FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_2);
sprite->data[2] = 1;
return TRUE;
@@ -4710,7 +4710,7 @@ bool8 do_exclamation_mark_bubble_2(struct MapObject *mapObject, struct Sprite *s
bool8 do_heart_bubble(struct MapObject *mapObject, struct Sprite *sprite)
{
- FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ FieldObjectGetLocalIdAndMap(mapObject, &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]);
FieldEffectStart(FLDEFF_HEART_ICON);
sprite->data[2] = 1;
return TRUE;
diff --git a/src/field_special_scene.c b/src/field_special_scene.c
index d46ddeaa6..a704beaab 100755
--- a/src/field_special_scene.c
+++ b/src/field_special_scene.c
@@ -211,7 +211,7 @@ void Task_HandleTruckSequence(u8 taskId)
data[1]++;
if (data[1] == 90)
{
- PlaySE(SE_TRACK_HAIK);
+ PlaySE(SE_TRACK_HAIKI);
data[1] = 0;
data[0] = 5;
}
diff --git a/src/fldeff_teleport.c b/src/fldeff_teleport.c
new file mode 100644
index 000000000..5b3492db0
--- /dev/null
+++ b/src/fldeff_teleport.c
@@ -0,0 +1,46 @@
+#include "global.h"
+#include "fldeff_teleport.h"
+#include "field_effect.h"
+#include "field_player_avatar.h"
+#include "party_menu.h"
+#include "overworld.h"
+#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;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void hm_teleport_run_dp02scr(void)
+{
+ Overworld_ResetStateAfterTeleport();
+ FieldEffectStart(FLDEFF_USE_TELEPORT);
+ gFieldEffectArguments[0] = (u32)GetCursorSelectionMonId();
+}
+
+bool8 FldEff_UseTeleport(void)
+{
+ u8 taskId = oei_task_add();
+ gTasks[taskId].data[8] = (u32)sub_817C94C >> 16;
+ gTasks[taskId].data[9] = (u32)sub_817C94C;
+ SetPlayerAvatarTransitionFlags(1);
+ return FALSE;
+}
+
+void sub_817C94C(void)
+{
+ FieldEffectActiveListRemove(FLDEFF_USE_TELEPORT);
+ sub_80B7FC8();
+}
+
+
diff --git a/src/hall_of_fame.c b/src/hall_of_fame.c
index 52babe346..4465f65a3 100644
--- a/src/hall_of_fame.c
+++ b/src/hall_of_fame.c
@@ -54,7 +54,7 @@ static EWRAM_DATA struct HofGfx *sHofGfxPtr = NULL;
extern bool8 gHasHallOfFameRecords;
extern u32 gUnknown_0203BCD4;
extern u8 gDecompressionBuffer[];
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern MainCallback gGameContinueCallback;
extern u32 gDamagedSaveSectors;
extern u8 gReservedSpritePaletteCount;
@@ -97,7 +97,7 @@ extern u16 sub_818D7D8(u16 species, u32 trainerId, u32 personality, u8 arg3, s16
extern void sub_8198204(u8 *dst, const u8 *src, u8, u8, u8);
extern bool8 sub_80F9C30(void);
extern void sub_8198314(void);
-extern void sub_8137C3C(void);
+extern void ReturnFromHallOfFamePC(void);
extern void sub_8198180(const u8 *src, u8, u8);
extern void sub_80F9BF4(u16, u16, u8);
extern void sub_81980F0(u8, u8, u8, u8, u16);
@@ -187,9 +187,9 @@ static const struct BgTemplate sHof_BgTemplates[] =
static const struct WindowTemplate sHof_WindowTemplate = {0, 2, 2, 0xE, 6, 0xE, 1};
-static const u8 gUnknown_085E5388[] = {0, 1, 2, 0};
+static const u8 sUnknown_085E5388[] = {0, 1, 2, 0};
-static const u8 gUnknown_085E538C[] = {0, 2, 3, 0, 4, 5, 0, 0};
+static const u8 sUnknown_085E538C[] = {0, 2, 3, 0, 4, 5, 0, 0};
static const struct CompressedSpriteSheet sHallOfFame_ConfettiSpriteSheet =
{
@@ -424,7 +424,7 @@ static bool8 InitHallOfFameScreen(void)
if (!gPaletteFade.active)
{
SetMainCallback2(CB2_HallOfFame);
- PlayBGM(BGM_DENDOU);
+ PlayBGM(MUS_DENDOU);
return FALSE;
}
break;
@@ -1040,7 +1040,7 @@ static void Task_HofPC_HandleInput(u8 taskId)
if (IsCryPlayingOrClearCrySongs())
{
StopCryAndClearCrySongs();
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
}
gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit;
}
@@ -1050,7 +1050,7 @@ static void Task_HofPC_HandleInput(u8 taskId)
if (IsCryPlayingOrClearCrySongs())
{
StopCryAndClearCrySongs();
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
}
gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit;
}
@@ -1108,7 +1108,7 @@ static void Task_HofPC_HandleExit(u8 taskId)
if (sHofMonPtr != NULL)
FREE_AND_SET_NULL(sHofMonPtr);
- sub_8137C3C();
+ ReturnFromHallOfFamePC();
}
}
@@ -1137,7 +1137,7 @@ static void HallOfFame_PrintWelcomeText(u8 unusedPossiblyWindowId, u8 unused2)
{
FillWindowPixelBuffer(0, 0);
PutWindowTilemap(0);
- box_print(0, 1, GetStringCenterAlignXOffset(1, gText_WelcomeToHOF, 0xD0), 1, gUnknown_085E5388, 0, gText_WelcomeToHOF);
+ box_print(0, 1, GetStringCenterAlignXOffset(1, gText_WelcomeToHOF, 0xD0), 1, sUnknown_085E5388, 0, gText_WelcomeToHOF);
CopyWindowToVram(0, 3);
}
@@ -1173,7 +1173,7 @@ static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 unused1, u
*(stringPtr)++ = CHAR_QUESTION_MARK;
}
stringPtr[0] = EOS;
- box_print(0, 1, 0x10, 1, gUnknown_085E5388, -1, text);
+ box_print(0, 1, 0x10, 1, sUnknown_085E5388, -1, text);
}
// nick, species names, gender and level
@@ -1182,13 +1182,13 @@ static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 unused1, u
if (currMon->species == SPECIES_EGG)
{
width = GetStringCenterAlignXOffset(1, text, 0xD0);
- box_print(0, 1, width, 1, gUnknown_085E5388, -1, text);
+ box_print(0, 1, width, 1, sUnknown_085E5388, -1, text);
CopyWindowToVram(0, 3);
}
else
{
width = GetStringRightAlignXOffset(1, text, 0x80);
- box_print(0, 1, width, 1, gUnknown_085E5388, -1, text);
+ box_print(0, 1, width, 1, sUnknown_085E5388, -1, text);
text[0] = CHAR_SLASH;
stringPtr = StringCopy(text + 1, gSpeciesNames[currMon->species]);
@@ -1209,15 +1209,15 @@ static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 unused1, u
}
stringPtr[0] = EOS;
- box_print(0, 1, 0x80, 1, gUnknown_085E5388, -1, text);
+ box_print(0, 1, 0x80, 1, sUnknown_085E5388, -1, text);
stringPtr = StringCopy(text, gText_Level);
ConvertIntToDecimalStringN(stringPtr, currMon->lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
- box_print(0, 1, 0x24, 0x11, gUnknown_085E5388, -1, text);
+ box_print(0, 1, 0x24, 0x11, sUnknown_085E5388, -1, text);
stringPtr = StringCopy(text, gText_IDNumber);
ConvertIntToDecimalStringN(stringPtr, (u16)(currMon->tid), STR_CONV_MODE_LEADING_ZEROS, 5);
- box_print(0, 1, 0x68, 0x11, gUnknown_085E5388, -1, text);
+ box_print(0, 1, 0x68, 0x11, sUnknown_085E5388, -1, text);
CopyWindowToVram(0, 3);
}
@@ -1232,13 +1232,13 @@ static void HallOfFame_PrintPlayerInfo(u8 unused1, u8 unused2)
FillWindowPixelBuffer(1, 0x11);
PutWindowTilemap(1);
SetWindowBorderStyle(1, FALSE, 0x21D, 0xD);
- box_print(1, 1, 0, 1, gUnknown_085E538C, -1, gText_Name);
+ box_print(1, 1, 0, 1, sUnknown_085E538C, -1, gText_Name);
width = GetStringRightAlignXOffset(1, gSaveBlock2Ptr->playerName, 0x70);
- box_print(1, 1, width, 1, gUnknown_085E538C, -1, gSaveBlock2Ptr->playerName);
+ box_print(1, 1, width, 1, sUnknown_085E538C, -1, gSaveBlock2Ptr->playerName);
trainerId = (gSaveBlock2Ptr->playerTrainerId[0]) | (gSaveBlock2Ptr->playerTrainerId[1] << 8);
- box_print(1, 1, 0, 0x11, gUnknown_085E538C, 0, gText_IDNumber);
+ box_print(1, 1, 0, 0x11, sUnknown_085E538C, 0, gText_IDNumber);
text[0] = (trainerId % 100000) / 10000 + CHAR_0;
text[1] = (trainerId % 10000) / 1000 + CHAR_0;
text[2] = (trainerId % 1000) / 100 + CHAR_0;
@@ -1246,9 +1246,9 @@ static void HallOfFame_PrintPlayerInfo(u8 unused1, u8 unused2)
text[4] = (trainerId % 10) / 1 + CHAR_0;
text[5] = EOS;
width = GetStringRightAlignXOffset(1, text, 0x70);
- box_print(1, 1, width, 0x11, gUnknown_085E538C, -1, text);
+ box_print(1, 1, width, 0x11, sUnknown_085E538C, -1, text);
- box_print(1, 1, 0, 0x21, gUnknown_085E538C, -1, gText_MainMenuTime);
+ box_print(1, 1, 0, 0x21, sUnknown_085E538C, -1, gText_MainMenuTime);
text[0] = (gSaveBlock2Ptr->playTimeHours / 100) + CHAR_0;
text[1] = (gSaveBlock2Ptr->playTimeHours % 100) / 10 + CHAR_0;
text[2] = (gSaveBlock2Ptr->playTimeHours % 10) + CHAR_0;
@@ -1264,7 +1264,7 @@ static void HallOfFame_PrintPlayerInfo(u8 unused1, u8 unused2)
text[6] = EOS;
width = GetStringRightAlignXOffset(1, text, 0x70);
- box_print(1, 1, width, 0x21, gUnknown_085E538C, -1, text);
+ box_print(1, 1, width, 0x21, sUnknown_085E538C, -1, text);
CopyWindowToVram(1, 3);
}
diff --git a/src/landmark.c b/src/landmark.c
new file mode 100644
index 000000000..4eade159a
--- /dev/null
+++ b/src/landmark.c
@@ -0,0 +1,441 @@
+#include "global.h"
+#include "event_data.h"
+#include "constants/region_map_sections.h"
+
+struct Landmark
+{
+ const u8 *name;
+ u16 flag;
+};
+
+struct LandmarkList
+{
+ u8 mapSection;
+ u8 id;
+ const struct Landmark *const *landmarks;
+};
+
+static const u8 LandmarkName_FlowerShop[] = _("FLOWER SHOP");
+static const u8 LandmarkName_PetalburgWoods[] = _("PETALBURG WOODS");
+static const u8 LandmarkName_MrBrineysCottage[] = _("MR. BRINEY’S COTTAGE");
+static const u8 LandmarkName_AbandonedShip[] = _("ABANDONED SHIP");
+static const u8 LandmarkName_SeashoreHouse[] = _("SEASHORE HOUSE");
+static const u8 LandmarkName_SlateportBeach[] = _("SLATEPORT BEACH");
+static const u8 LandmarkName_CyclingRoad[] = _("CYCLING ROAD");
+static const u8 LandmarkName_NewMauville[] = _("NEW MAUVILLE");
+static const u8 LandmarkName_TrickHouse[] = _("TRICK HOUSE");
+static const u8 LandmarkName_OldLadysRestShop[] = _("OLD LADY’S REST STOP");
+static const u8 LandmarkName_Desert[] = _("DESERT");
+static const u8 LandmarkName_WinstrateFamily[] = _("THE WINSTRATE FAMILY");
+static const u8 LandmarkName_CableCar[] = _("CABLE CAR");
+static const u8 LandmarkName_GlassWorkshop[] = _("GLASS WORKSHOP");
+static const u8 LandmarkName_WeatherInstitute[] = _("WEATHER INSTITUTE");
+static const u8 LandmarkName_MeteorFalls[] = _("METEOR FALLS");
+static const u8 LandmarkName_TunnelersRestHouse[] = _("TUNNELER’S RESTHOUSE");
+static const u8 LandmarkName_RusturfTunnel[] = _("RUSTURF TUNNEL");
+static const u8 LandmarkName_PokemonDayCare[] = _("POKéMON DAY CARE");
+static const u8 LandmarkName_SafariZoneEntrance[] = _("SAFARI ZONE ENTRANCE");
+static const u8 LandmarkName_MtPyre[] = _("MT. PYRE");
+static const u8 LandmarkName_ShoalCave[] = _("SHOAL CAVE");
+static const u8 LandmarkName_SeafloorCavern[] = _("SEAFLOOR CAVERN");
+static const u8 LandmarkName_GraniteCave[] = _("GRANITE CAVE");
+static const u8 LandmarkName_OceanCurrent[] = _("OCEAN CURRENT");
+static const u8 LandmarkName_LanettesHouse[] = _("LANETTE’S HOUSE");
+static const u8 LandmarkName_FieryPath[] = _("FIERY PATH");
+static const u8 LandmarkName_JaggedPass[] = _("JAGGED PASS");
+static const u8 LandmarkName_SkyPillar[] = _("SKY PILLAR");
+static const u8 LandmarkName_BerryMastersHouse[] = _("BERRY MASTER’S HOUSE");
+static const u8 LandmarkName_IslandCave[] = _("ISLAND CAVE");
+static const u8 LandmarkName_DesertRuins[] = _("DESERT RUINS");
+static const u8 LandmarkName_ScorchedSlab[] = _("SCORCHED SLAB");
+static const u8 LandmarkName_AncientTomb[] = _("ANCIENT TOMB");
+static const u8 LandmarkName_SealedChamber[] = _("SEALED CHAMBER");
+static const u8 LandmarkName_FossilManiacsHouse[] = _("FOSSIL MANIAC’S HOUSE");
+static const u8 LandmarkName_HuntersHouse[] = _("HUNTER’S HOUSE");
+static const u8 LandmarkName_MagmaHideout[] = _("MAGMA HIDEOUT");
+static const u8 LandmarkName_MirageTower[] = _("MIRAGE TOWER");
+static const u8 LandmarkName_AlteringCave[] = _("ALTERING CAVE");
+static const u8 LandmarkName_DesertUnderpass[] = _("DESERT UNDERPASS");
+static const u8 LandmarkName_TrainerHill[] = _("TRAINER HILL");
+
+static const struct Landmark Landmark_FlowerShop = {LandmarkName_FlowerShop, FLAG_LANDMARK_FLOWER_SHOP};
+static const struct Landmark Landmark_PetalburgWoods = {LandmarkName_PetalburgWoods, -1};
+static const struct Landmark Landmark_MrBrineysCottage = {LandmarkName_MrBrineysCottage, FLAG_LANDMARK_MR_BRINEY_HOUSE};
+static const struct Landmark Landmark_AbandonedShip = {LandmarkName_AbandonedShip, FLAG_LANDMARK_ABANDONED_SHIP};
+static const struct Landmark Landmark_SeashoreHouse = {LandmarkName_SeashoreHouse, FLAG_LANDMARK_SEASHORE_HOUSE};
+static const struct Landmark Landmark_SlateportBeach = {LandmarkName_SlateportBeach, -1};
+static const struct Landmark Landmark_CyclingRoad = {LandmarkName_CyclingRoad, -1};
+static const struct Landmark Landmark_NewMauville = {LandmarkName_NewMauville, FLAG_LANDMARK_NEW_MAUVILLE};
+static const struct Landmark Landmark_TrickHouse = {LandmarkName_TrickHouse, FLAG_LANDMARK_TRICK_HOUSE};
+static const struct Landmark Landmark_OldLadysRestShop = {LandmarkName_OldLadysRestShop, FLAG_LANDMARK_OLD_LADY_REST_SHOP};
+static const struct Landmark Landmark_Desert = {LandmarkName_Desert, -1};
+static const struct Landmark Landmark_WinstrateFamily = {LandmarkName_WinstrateFamily, FLAG_LANDMARK_WINSTRATE_FAMILY};
+static const struct Landmark Landmark_CableCar = {LandmarkName_CableCar, -1};
+static const struct Landmark Landmark_GlassWorkshop = {LandmarkName_GlassWorkshop, FLAG_LANDMARK_GLASS_WORKSHOP};
+static const struct Landmark Landmark_WeatherInstitute = {LandmarkName_WeatherInstitute, -1};
+static const struct Landmark Landmark_MeteorFalls = {LandmarkName_MeteorFalls, -1};
+static const struct Landmark Landmark_TunnelersRestHouse = {LandmarkName_TunnelersRestHouse, FLAG_LANDMARK_TUNNELERS_REST_HOUSE};
+static const struct Landmark Landmark_RusturfTunnel = {LandmarkName_RusturfTunnel, -1};
+static const struct Landmark Landmark_PokemonDayCare = {LandmarkName_PokemonDayCare, FLAG_LANDMARK_POKEMON_DAYCARE};
+static const struct Landmark Landmark_SafariZoneEntrance = {LandmarkName_SafariZoneEntrance, -1};
+static const struct Landmark Landmark_MtPyre = {LandmarkName_MtPyre, -1};
+static const struct Landmark Landmark_ShoalCave = {LandmarkName_ShoalCave, -1};
+static const struct Landmark Landmark_SeafloorCavern = {LandmarkName_SeafloorCavern, FLAG_LANDMARK_SEAFLOOR_CAVERN};
+static const struct Landmark Landmark_GraniteCave = {LandmarkName_GraniteCave, -1};
+static const struct Landmark Landmark_OceanCurrent = {LandmarkName_OceanCurrent, -1};
+static const struct Landmark Landmark_LanettesHouse = {LandmarkName_LanettesHouse, FLAG_LANDMARK_LANETTES_HOUSE};
+static const struct Landmark Landmark_FieryPath = {LandmarkName_FieryPath, FLAG_LANDMARK_FIERY_PATH};
+static const struct Landmark Landmark_JaggedPass = {LandmarkName_JaggedPass, -1};
+static const struct Landmark Landmark_BerryMastersHouse = {LandmarkName_BerryMastersHouse, FLAG_LANDMARK_BERRY_MASTERS_HOUSE};
+static const struct Landmark Landmark_IslandCave = {LandmarkName_IslandCave, FLAG_LANDMARK_ISLAND_CAVE};
+static const struct Landmark Landmark_DesertRuins = {LandmarkName_DesertRuins, FLAG_LANDMARK_DESERT_RUINS};
+static const struct Landmark Landmark_ScorchedSlab = {LandmarkName_ScorchedSlab, FLAG_LANDMARK_SCORCHED_SLAB};
+static const struct Landmark Landmark_AncientTomb = {LandmarkName_AncientTomb, FLAG_LANDMARK_ANCIENT_TOMB};
+static const struct Landmark Landmark_SealedChamber = {LandmarkName_SealedChamber, FLAG_LANDMARK_SEALED_CHAMBER};
+static const struct Landmark Landmark_FossilManiacsHouse = {LandmarkName_FossilManiacsHouse, FLAG_LANDMARK_FOSSIL_MANIACS_HOUSE};
+static const struct Landmark Landmark_HuntersHouse = {LandmarkName_HuntersHouse, FLAG_LANDMARK_HUNTERS_HOUSE};
+static const struct Landmark Landmark_SkyPillar = {LandmarkName_SkyPillar, FLAG_LANDMARK_SKY_PILLAR};
+static const struct Landmark Landmark_MirageTower = {LandmarkName_MirageTower, FLAG_LANDMARK_MIRAGE_TOWER};
+static const struct Landmark Landmark_AlteringCave = {LandmarkName_AlteringCave, FLAG_LANDMARK_ALTERING_CAVE};
+static const struct Landmark Landmark_DesertUnderpass = {LandmarkName_DesertUnderpass, FLAG_LANDMARK_DESERT_UNDERPASS};
+static const struct Landmark Landmark_TrainerHill = {LandmarkName_TrainerHill, FLAG_LANDMARK_TRAINER_HILL};
+
+static const struct Landmark *const Landmarks_Route103_2[] =
+{
+ &Landmark_AlteringCave,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route104_0[] =
+{
+ &Landmark_FlowerShop,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route104_1[] =
+{
+ &Landmark_PetalburgWoods,
+ &Landmark_MrBrineysCottage,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route105_0[] =
+{
+ &Landmark_IslandCave,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route106_1[] =
+{
+ &Landmark_GraniteCave,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route108_0[] =
+{
+ &Landmark_AbandonedShip,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route109_0[] =
+{
+ &Landmark_SeashoreHouse,
+ &Landmark_SlateportBeach,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route110_0[] =
+{
+ &Landmark_CyclingRoad,
+ &Landmark_NewMauville,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route110_1[] =
+{
+ &Landmark_CyclingRoad,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route110_2[] =
+{
+ &Landmark_CyclingRoad,
+ &Landmark_TrickHouse,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route111_0[] =
+{
+ &Landmark_OldLadysRestShop,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route111_1[] =
+{
+ &Landmark_Desert,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route111_2[] =
+{
+ &Landmark_MirageTower,
+ &Landmark_Desert,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route111_3[] =
+{
+ &Landmark_DesertRuins,
+ &Landmark_Desert,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route111_4[] =
+{
+ &Landmark_TrainerHill,
+ &Landmark_WinstrateFamily,
+ &Landmark_Desert,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route112_0[] =
+{
+ &Landmark_FieryPath,
+ &Landmark_JaggedPass,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route112_1[] =
+{
+ &Landmark_CableCar,
+ &Landmark_FieryPath,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route113_1[] =
+{
+ &Landmark_GlassWorkshop,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route114_1[] =
+{
+ &Landmark_DesertUnderpass,
+ &Landmark_FossilManiacsHouse,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route114_2[] =
+{
+ &Landmark_LanettesHouse,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_MeteorFalls[] =
+{
+ &Landmark_MeteorFalls,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route116_1[] =
+{
+ &Landmark_TunnelersRestHouse,
+ &Landmark_RusturfTunnel,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route116_2[] =
+{
+ &Landmark_RusturfTunnel,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route117_2[] =
+{
+ &Landmark_PokemonDayCare,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route119_1[] =
+{
+ &Landmark_WeatherInstitute,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route120_0[] =
+{
+ &Landmark_ScorchedSlab,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route120_2[] =
+{
+ &Landmark_AncientTomb,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route121_2[] =
+{
+ &Landmark_SafariZoneEntrance,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route122_0[] =
+{
+ &Landmark_MtPyre,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route123_0[] =
+{
+ &Landmark_BerryMastersHouse,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route124_7[] =
+{
+ &Landmark_HuntersHouse,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route125_2[] =
+{
+ &Landmark_ShoalCave,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route128_1[] =
+{
+ &Landmark_SeafloorCavern,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route131_1[] =
+{
+ &Landmark_SkyPillar,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_OceanCurrent[] =
+{
+ &Landmark_OceanCurrent,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_Route134_2[] =
+{
+ &Landmark_SealedChamber,
+ &Landmark_OceanCurrent,
+ NULL,
+};
+
+static const struct Landmark *const Landmarks_MtChimney_2[] =
+{
+ &Landmark_CableCar,
+ &Landmark_JaggedPass,
+ NULL,
+};
+
+static const struct LandmarkList gLandmarkLists[] =
+{
+ {MAPSEC_ROUTE_103, 2, Landmarks_Route103_2},
+ {MAPSEC_ROUTE_104, 0, Landmarks_Route104_0},
+ {MAPSEC_ROUTE_104, 1, Landmarks_Route104_1},
+ {MAPSEC_ROUTE_105, 0, Landmarks_Route105_0},
+ {MAPSEC_ROUTE_106, 1, Landmarks_Route106_1},
+ {MAPSEC_ROUTE_108, 0, Landmarks_Route108_0},
+ {MAPSEC_ROUTE_109, 0, Landmarks_Route109_0},
+ {MAPSEC_ROUTE_110, 0, Landmarks_Route110_0},
+ {MAPSEC_ROUTE_110, 1, Landmarks_Route110_1},
+ {MAPSEC_ROUTE_110, 2, Landmarks_Route110_2},
+ {MAPSEC_ROUTE_111, 0, Landmarks_Route111_0},
+ {MAPSEC_ROUTE_111, 1, Landmarks_Route111_1},
+ {MAPSEC_ROUTE_111, 2, Landmarks_Route111_2},
+ {MAPSEC_ROUTE_111, 3, Landmarks_Route111_3},
+ {MAPSEC_ROUTE_111, 4, Landmarks_Route111_4},
+ {MAPSEC_ROUTE_112, 0, Landmarks_Route112_0},
+ {MAPSEC_ROUTE_112, 1, Landmarks_Route112_1},
+ {MAPSEC_ROUTE_113, 1, Landmarks_Route113_1},
+ {MAPSEC_ROUTE_114, 1, Landmarks_Route114_1},
+ {MAPSEC_ROUTE_114, 2, Landmarks_Route114_2},
+ {MAPSEC_ROUTE_114, 3, Landmarks_MeteorFalls},
+ {MAPSEC_ROUTE_115, 0, Landmarks_MeteorFalls},
+ {MAPSEC_ROUTE_115, 1, Landmarks_MeteorFalls},
+ {MAPSEC_ROUTE_116, 1, Landmarks_Route116_1},
+ {MAPSEC_ROUTE_116, 2, Landmarks_Route116_2},
+ {MAPSEC_ROUTE_117, 2, Landmarks_Route117_2},
+ {MAPSEC_ROUTE_119, 1, Landmarks_Route119_1},
+ {MAPSEC_ROUTE_120, 0, Landmarks_Route120_0},
+ {MAPSEC_ROUTE_120, 2, Landmarks_Route120_2},
+ {MAPSEC_ROUTE_121, 2, Landmarks_Route121_2},
+ {MAPSEC_ROUTE_122, 0, Landmarks_Route122_0},
+ {MAPSEC_ROUTE_123, 0, Landmarks_Route123_0},
+ {MAPSEC_ROUTE_122, 1, Landmarks_Route122_0},
+ {MAPSEC_ROUTE_124, 7, Landmarks_Route124_7},
+ {MAPSEC_ROUTE_125, 2, Landmarks_Route125_2},
+ {MAPSEC_ROUTE_128, 1, Landmarks_Route128_1},
+ {MAPSEC_ROUTE_131, 1, Landmarks_Route131_1},
+ {MAPSEC_ROUTE_132, 0, Landmarks_OceanCurrent},
+ {MAPSEC_ROUTE_132, 1, Landmarks_OceanCurrent},
+ {MAPSEC_ROUTE_133, 0, Landmarks_OceanCurrent},
+ {MAPSEC_ROUTE_133, 1, Landmarks_OceanCurrent},
+ {MAPSEC_ROUTE_133, 2, Landmarks_OceanCurrent},
+ {MAPSEC_ROUTE_134, 0, Landmarks_OceanCurrent},
+ {MAPSEC_ROUTE_134, 1, Landmarks_OceanCurrent},
+ {MAPSEC_ROUTE_134, 2, Landmarks_Route134_2},
+ {MAPSEC_MT_CHIMNEY, 2, Landmarks_MtChimney_2},
+ {MAPSEC_NONE, 0, NULL},
+};
+
+static const struct Landmark *const *GetLandmarks(u8 mapSection, u8 id);
+
+const u8 *GetLandmarkName(u8 mapSection, u8 id, u8 count)
+{
+ const struct Landmark *const *landmarks = GetLandmarks(mapSection, id);
+
+ if (!landmarks)
+ return NULL;
+
+ while (1)
+ {
+ const struct Landmark *landmark = *landmarks;
+
+ if (landmark->flag == 0xFFFF || FlagGet(landmark->flag) == TRUE)
+ {
+ if (count == 0)
+ break;
+ else
+ count--;
+ }
+
+ landmarks++;
+ if (!*landmarks)
+ return NULL;
+ }
+
+ return (*landmarks)->name;
+}
+
+static const struct Landmark *const *GetLandmarks(u8 mapSection, u8 id)
+{
+ u16 i = 0;
+
+ for (; gLandmarkLists[i].mapSection != MAPSEC_NONE; i++)
+ {
+ if (gLandmarkLists[i].mapSection > mapSection)
+ return NULL;
+ if (gLandmarkLists[i].mapSection == mapSection)
+ break;
+ }
+
+ if (gLandmarkLists[i].mapSection == MAPSEC_NONE)
+ return NULL;
+
+ for (; gLandmarkLists[i].mapSection == mapSection; i++)
+ {
+ if (gLandmarkLists[i].id == id)
+ return gLandmarkLists[i].landmarks;
+ }
+
+ return NULL;
+}
diff --git a/src/libc.c b/src/libc.c
deleted file mode 100644
index 1f457957b..000000000
--- a/src/libc.c
+++ /dev/null
@@ -1,173 +0,0 @@
-#include "global.h"
-#include <stddef.h>
-
-#define LBLOCKSIZE (sizeof(long))
-
-// Nonzero if (long)X contains a NULL byte.
-#define CONTAINSNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-
-// Nonzero if X is not aligned on a "long" boundary.
-#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
-
-void *memcpy(void *dst0, const void *src0, size_t len0)
-{
- char *dst = dst0;
- const char *src = src0;
- long *aligned_dst;
- const long *aligned_src;
- unsigned int len = len0;
-
- // If the size is small, or either src or dst is unaligned,
- // then go to the byte copy loop. This should be rare.
- if(len >= 16 && !(UNALIGNED(src) | UNALIGNED(dst)))
- {
- aligned_dst = (long *)dst;
- aligned_src = (long *)src;
-
- // Copy 4X long words at a time if possible.
- while(len >= 16)
- {
- *aligned_dst++ = *aligned_src++;
- *aligned_dst++ = *aligned_src++;
- *aligned_dst++ = *aligned_src++;
- *aligned_dst++ = *aligned_src++;
- len -= 16;
- }
-
- // Copy one long word at a time if possible
- while(len >= 4)
- {
- *aligned_dst++ = *aligned_src++;
- len -= 4;
- }
-
- dst = (char *)aligned_dst;
- src = (char *)aligned_src;
- }
-
- // Pick up any remaining bytes with a byte copier.
- while(len--)
- *dst++ = *src++;
-
- return dst0;
-}
-
-void *memset(void *m, int c, size_t n)
-{
- char *s = (char *)m;
- int count, i;
- unsigned long buffer;
- unsigned long *aligned_addr;
- unsigned char *unaligned_addr;
-
- // If the size is small or m is unaligned,
- // then go to the byte copy loop. This should be rare.
- if(n >= LBLOCKSIZE && !UNALIGNED(m))
- {
- // We know that n is large and m is word-aligned.
- aligned_addr = (unsigned long *)m;
-
- // Store C into each char sized location in buffer so that
- // we can set large blocks quickly.
- c &= 0xFF;
- if(LBLOCKSIZE == 4)
- {
- buffer = (c << 8) | c;
- buffer |= (buffer << 16);
- }
- else
- {
- buffer = 0;
- for(i = 0; i < LBLOCKSIZE; i++)
- buffer = (buffer << 8) | c;
- }
-
- while(n >= LBLOCKSIZE * 4)
- {
- *aligned_addr++ = buffer;
- *aligned_addr++ = buffer;
- *aligned_addr++ = buffer;
- *aligned_addr++ = buffer;
- n -= LBLOCKSIZE * 4;
- }
- while(n >= LBLOCKSIZE)
- {
- *aligned_addr++ = buffer;
- n -= LBLOCKSIZE;
- }
-
- s = (char *)aligned_addr;
- }
-
- // Pick up the remainder with a bytewise loop.
- while(n--)
- *s++ = (char)c;
-
- return m;
-}
-
-int strcmp(const char *s1, const char *s2)
-{
- unsigned long *a1;
- unsigned long *a2;
-
- // If s1 or s2 are unaligned, then skip this and compare bytes.
- if(!(UNALIGNED(s1) | UNALIGNED(s2)))
- {
- // Compare them a word at a time.
- a1 = (unsigned long *)s1;
- a2 = (unsigned long *)s2;
- while(*a1 == *a2)
- {
- // If *a1 == *a2, and we find a null in *a1,
- // then the strings must be equal, so return zero.
- if(CONTAINSNULL(*a1))
- return 0;
-
- a1++;
- a2++;
- }
-
- s1 = (char *)a1;
- s2 = (char *)a2;
- }
-
- // Check the remaining few bytes.
- while(*s1 != '\0' && *s1 == *s2)
- {
- s1++;
- s2++;
- }
-
- return (*(unsigned char *) s1) - (*(unsigned char *) s2);
-}
-
-char* strcpy(char *dst0, const char *src0)
-{
- char *dst = dst0;
- const char *src = src0;
- unsigned long *a1;
- const unsigned long *a2;
-
- // If SRC or DEST is unaligned, then copy bytes.
- if(!(UNALIGNED(src) | UNALIGNED(dst)))
- {
- // SRC and DEST are both "long int" aligned, try to do "long int"
- // sized copies.
- a1 = (unsigned long *)dst;
- a2 = (unsigned long *)src;
- while(!CONTAINSNULL(*a2))
- {
- *a1++ = *a2++;
- }
-
- dst = (char *)a1;
- src = (char *)a2;
- }
-
- // Copy the remaining few bytes.
- while(*dst++ = *src++);
-
- return dst0;
-}
-
diff --git a/src/libisagbprn.c b/src/libisagbprn.c
new file mode 100755
index 000000000..e0e979e95
--- /dev/null
+++ b/src/libisagbprn.c
@@ -0,0 +1,177 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include "gba/gba.h"
+#include "config.h"
+
+#define AGB_PRINT_FLUSH_ADDR 0x9FE209D
+#define AGB_PRINT_STRUCT_ADDR 0x9FE20F8
+#define AGB_PRINT_PROTECT_ADDR 0x9FE2FFE
+#define WSCNT_DATA (WAITCNT_PHI_OUT_16MHZ | WAITCNT_WS0_S_2 | WAITCNT_WS0_N_4)
+
+// originally for auto no$gba support, the string "no$gba" should be at this address,
+// the user needs to read this string out as the memory viewer won't show it.
+#define NOCASHGBAIDADDR 0x4FFFA00
+#define NOCASHGBAPRINTADDR1 0x4FFFA10 // automatically adds a newline after the string has finished
+#define NOCASHGBAPRINTADDR2 0x4FFFA14 // does not automatically add the newline. by default, NOCASHGBAPRINTADDR2 is used. this is used to keep strings consistent between no$gba and VBA-RR, but a user can choose to forgo this.
+
+struct AGBPrintStruct
+{
+ u16 m_nRequest;
+ u16 m_nBank;
+ u16 m_nGet;
+ u16 m_nPut;
+};
+
+typedef void (*LPFN_PRINT_FLUSH)(void);
+
+#ifndef NDEBUG
+
+void AGBPrintFlush1Block(void);
+
+void AGBPrintInit(void)
+{
+ volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT;
+ u16 *pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
+ u16 nOldWSCNT = *pWSCNT;
+ *pWSCNT = WSCNT_DATA;
+ *pProtect = 0x20;
+ pPrint->m_nRequest = pPrint->m_nGet = pPrint->m_nPut = 0;
+ pPrint->m_nBank = 0xFD;
+ *pProtect = 0;
+ *pWSCNT = nOldWSCNT;
+}
+
+static void AGBPutcInternal(const char cChr)
+{
+ volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ u16 *pPrintBuf = (u16 *)(0x8000000 + (pPrint->m_nBank << 16));
+ u16 *pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
+ u16 nData = pPrintBuf[pPrint->m_nPut / 2];
+ *pProtect = 0x20;
+ nData = (pPrint->m_nPut & 1) ? (nData & 0xFF) | (cChr << 8) : (nData & 0xFF00) | cChr;
+ pPrintBuf[pPrint->m_nPut / 2] = nData;
+ pPrint->m_nPut++;
+ *pProtect = 0;
+}
+
+void AGBPutc(const char cChr)
+{
+ u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT;
+ u16 nOldWSCNT = *pWSCNT;
+ volatile struct AGBPrintStruct *pPrint;
+ *pWSCNT = WSCNT_DATA;
+ AGBPutcInternal(cChr);
+ *pWSCNT = nOldWSCNT;
+ pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ if (pPrint->m_nPut == ((pPrint->m_nGet - 1) & 0xFFFF))
+ AGBPrintFlush1Block();
+}
+
+void AGBPrint(const char *pBuf)
+{
+ volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT;
+ u16 nOldWSCNT = *pWSCNT;
+ *pWSCNT = WSCNT_DATA;
+ while (*pBuf)
+ {
+ AGBPutc(*pBuf);
+ pBuf++;
+ }
+ *pWSCNT = nOldWSCNT;
+}
+
+void AGBPrintf(const char *pBuf, ...)
+{
+ char bufPrint[0x100];
+ va_list vArgv;
+ va_start(vArgv, pBuf);
+ vsprintf(bufPrint, pBuf, vArgv);
+ va_end(vArgv);
+ AGBPrint(bufPrint);
+}
+
+static void AGBPrintTransferDataInternal(u32 bAllData)
+{
+ LPFN_PRINT_FLUSH lpfnFuncFlush;
+ u16 *pIME;
+ u16 nIME;
+ u16 *pWSCNT;
+ u16 nOldWSCNT;
+ u16 *pProtect;
+ volatile struct AGBPrintStruct *pPrint;
+
+ pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
+ pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ lpfnFuncFlush = (LPFN_PRINT_FLUSH)AGB_PRINT_FLUSH_ADDR;
+ pIME = (u16 *)REG_ADDR_IME;
+ nIME = *pIME;
+ pWSCNT = (u16 *)REG_ADDR_WAITCNT;
+ nOldWSCNT = *pWSCNT;
+ *pIME = nIME & ~1;
+ *pWSCNT = WSCNT_DATA;
+
+ if (bAllData)
+ {
+ while (pPrint->m_nPut != pPrint->m_nGet)
+ {
+ *pProtect = 0x20;
+ lpfnFuncFlush();
+ *pProtect = 0;
+ }
+ }
+ else if (pPrint->m_nPut != pPrint->m_nGet)
+ {
+ *pProtect = 0x20;
+ lpfnFuncFlush();
+ *pProtect = 0;
+ }
+
+ *pWSCNT = nOldWSCNT;
+ *pIME = nIME;
+}
+
+void AGBPrintFlush1Block(void)
+{
+ AGBPrintTransferDataInternal(FALSE);
+}
+
+void AGBPrintFlush(void)
+{
+ AGBPrintTransferDataInternal(TRUE);
+}
+
+void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopProgram)
+{
+ if (nStopProgram)
+ {
+ AGBPrintf("ASSERTION FAILED FILE=[%s] LINE=[%d] EXP=[%s] \n", pFile, nLine, pExpression);
+ AGBPrintFlush();
+ asm(".hword 0xEFFF");
+ }
+ else
+ {
+ AGBPrintf("WARING FILE=[%s] LINE=[%d] EXP=[%s] \n", pFile, nLine, pExpression);
+ }
+}
+
+// no$gba print functions, uncomment to use
+/*
+void NoCashGBAPrint(const char *pBuf)
+{
+ *(volatile u32*)NOCASHGBAPRINTADDR2 = (u32)pBuf;
+}
+
+void NoCashGBAPrintf(const char *pBuf, ...)
+{
+ char bufPrint[0x100];
+ va_list vArgv;
+ va_start(vArgv, pBuf);
+ vsprintf(bufPrint, pBuf, vArgv);
+ va_end(vArgv);
+ NoCashGBAPrint(bufPrint);
+}
+*/
+
+#endif
diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c
index 95270974a..927b87c72 100644
--- a/src/lilycove_lady.c
+++ b/src/lilycove_lady.c
@@ -29,10 +29,10 @@ static u8 sub_818E258(const u8 *);
extern const u8 gText_Lady2[];
-static const u16 gUnknown_0860B074[] = {
+static const u16 sUnknown_0860B074[] = {
0x62, 0xcb, 0xdc, 0xcc, 0xd1
};
-static const u16 gUnknown_0860B07E[] = {
+static const u16 sUnknown_0860B07E[] = {
0x1a, 0x14, 0x0a
};
@@ -119,11 +119,11 @@ static const u16 *const gUnknown_0860B1A4[] = {
Unknown_0860B192
};
-static const u16 gUnknown_0860B1E4[] = {
+static const u16 sUnknown_0860B1E4[] = {
0x0210, 0x0400, 0x0212, 0x1a26, 0x0208, 0x045d, 0x040a, 0x0411, 0x0464, 0x020e, 0x1a25, 0x181b, 0x1a24, 0x0420, 0x0410, 0x0400
};
-static const u16 gUnknown_0860B204[] = {
+static const u16 sUnknown_0860B204[] = {
0x007b, 0x007f, 0x0081, 0x0023, 0x0023, 0x0023, 0x00a5, 0x00a7, 0x00a6, 0x000b, 0x012f, 0x006b, 0x006d, 0x0044, 0x0044, 0x000c
};
@@ -176,7 +176,7 @@ static const u16 *const gUnknown_0860B2EC[] = {
Unknown_0860B2D6
};
-static const u16 gUnknown_0860B304[] = {
+static const u16 sUnknown_0860B304[] = {
0x0b, 0x6e, 0x40, 0x6f, 0x44, 0x47
};
@@ -218,7 +218,7 @@ static const u8 *const gUnknown_0860B338[] = {
gUnknown_085EADE7
};
-static const u16 gUnknown_0860B34C[] = {
+static const u16 sUnknown_0860B34C[] = {
0x0120, 0x013b, 0x011e, 0x013d, 0x0019
};
@@ -237,11 +237,11 @@ void sub_818D9C0(void)
{
LilycoveLady *lilycoveLady;
- VarSet(VAR_0x4010, gUnknown_0860B07E[GetLilycoveLadyId()]);
+ VarSet(VAR_0x4010, sUnknown_0860B07E[GetLilycoveLadyId()]);
if (GetLilycoveLadyId() == LILYCOVE_LADY_CONTEST)
{
lilycoveLady = &gSaveBlock1Ptr->lilycoveLady;
- VarSet(VAR_0x4011, gUnknown_0860B074[lilycoveLady->contest.category]);
+ VarSet(VAR_0x4011, sUnknown_0860B074[lilycoveLady->contest.category]);
gSpecialVar_Result = TRUE;
}
else
@@ -481,7 +481,7 @@ u16 sub_818DEA0(void)
u16 itemId;
gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour;
- itemId = gUnknown_0860B304[gUnknown_0203CD64->unk_00c];
+ itemId = sUnknown_0860B304[gUnknown_0203CD64->unk_00c];
sub_818DE88(itemId);
gUnknown_0203CD64->phase = 2;
return itemId;
@@ -508,8 +508,8 @@ static void sub_818DF00(void)
{
gUnknown_0203CD68->unk_002[i] = gUnknown_0860B1A4[v0][i];
}
- gUnknown_0203CD68->unk_014 = gUnknown_0860B1E4[v0];
- gUnknown_0203CD68->itemId = gUnknown_0860B204[v0];
+ gUnknown_0203CD68->unk_014 = sUnknown_0860B1E4[v0];
+ gUnknown_0203CD68->itemId = sUnknown_0860B204[v0];
gUnknown_0203CD68->unk_02b = v0;
gUnknown_0203CD68->playerName[0] = EOS;
}
@@ -581,13 +581,13 @@ u8 sub_818E06C(void)
{
i = 0;
}
- } while (sub_811F8D8(gUnknown_0860B1E4[i]) == 0);
+ } while (sub_811F8D8(sUnknown_0860B1E4[i]) == 0);
for (j = 0; j < 9; j ++)
{
quiz->unk_002[j] = gUnknown_0860B1A4[i][j];
}
- quiz->unk_014 = gUnknown_0860B1E4[i];
- quiz->itemId = gUnknown_0860B204[i];
+ quiz->unk_014 = sUnknown_0860B1E4[i];
+ quiz->itemId = sUnknown_0860B204[i];
quiz->unk_02b = i;
quiz->playerName[0] = EOS;
}
@@ -943,7 +943,7 @@ static void sub_818E6B0(u8 sheen)
}
}
-bool8 sub_818E704(struct Pokeblock *pokeblock)
+bool8 GivePokeblockToContestLady(struct Pokeblock *pokeblock)
{
u8 sheen;
bool8 response;
@@ -1079,7 +1079,7 @@ void sub_818E914(void)
void sub_818E92C(void)
{
- sub_81357FC(3, c2_exit_to_overworld_2_switch);
+ OpenPokeblockCase(3, c2_exit_to_overworld_2_switch);
}
void sub_818E940(void)
@@ -1091,7 +1091,7 @@ void sub_818E940(void)
void sub_818E960(void)
{
gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest;
- gSpecialVar_0x8005 = gUnknown_0860B34C[gUnknown_0203CD6C->category];
+ gSpecialVar_0x8005 = sUnknown_0860B34C[gUnknown_0203CD6C->category];
}
u8 sub_818E990(void)
diff --git a/src/link.c b/src/link.c
index 0634d2506..c59691bc8 100644
--- a/src/link.c
+++ b/src/link.c
@@ -22,7 +22,7 @@
#include "new_menu_helpers.h"
#include "text.h"
#include "strings.h"
-#include "songs.h"
+#include "constants/songs.h"
#include "sound.h"
#include "trade.h"
#include "battle.h"
@@ -1112,7 +1112,7 @@ static void SetBlockReceivedFlag(u8 who)
void ResetBlockReceivedFlags(void)
{
int i;
-
+
if (gWirelessCommType == TRUE)
{
for (i = 0; i < MAX_RFU_PLAYERS; i++)
@@ -1628,9 +1628,9 @@ void CB2_LinkError(void)
u8 *tilemapBuffer;
SetGpuReg(REG_OFFSET_DISPCNT, 0);
- m4aMPlayStop(&gMPlay_SE1);
- m4aMPlayStop(&gMPlay_SE2);
- m4aMPlayStop(&gMPlay_SE3);
+ m4aMPlayStop(&gMPlayInfo_SE1);
+ m4aMPlayStop(&gMPlayInfo_SE2);
+ m4aMPlayStop(&gMPlayInfo_SE3);
InitHeap(gHeap, HEAP_SIZE);
ResetSpriteData();
FreeAllSpritePalettes();
diff --git a/src/load_save.c b/src/load_save.c
index 2b40f2e92..a516c08c2 100644
--- a/src/load_save.c
+++ b/src/load_save.c
@@ -1,4 +1,4 @@
-#include "global.h"
+#include "global.h"
#include "gba/flash_internal.h"
#include "load_save.h"
#include "main.h"
@@ -28,7 +28,7 @@ struct LoadedSaveData
/*0x00F0*/ struct ItemSlot pokeBalls[16];
/*0x0130*/ struct ItemSlot TMsHMs[64];
/*0x0230*/ struct ItemSlot berries[46];
- /*0x02E8*/ struct MailStruct mail[16];
+ /*0x02E8*/ struct MailStruct mail[MAIL_COUNT];
};
EWRAM_DATA struct SaveBlock2 gSaveblock2 = {0};
@@ -80,45 +80,15 @@ void SetSaveBlocksPointers(u16 offset)
SetDecorationInventoriesPointers();
}
-// stuff i used to try and match MoveSaveBlocks_ResetHeap
-struct SaveBlocksInOne
-{
- struct SaveBlock2 sav2;
- struct SaveBlock1 sav1;
- struct PokemonStorage sav3;
-};
+extern u8 gHeap[];
-extern struct SaveBlocksInOne gHeap;
-
-#define ewram_addr 0x02000000 // oh no...
-#define ewram_addr2 0x02000f2c
-#define ewram_addr3 0x02004cb4
-
-#define eSaveBlockCopy (*(struct SaveBlocksInOne *)(ewram_addr + 0x0))
-#define eSaveBlock2Copy (*(struct SaveBlock2 *)((void*)(ewram_addr + 0x0)))
-#define eSaveBlock1Copy (*(struct SaveBlock1 *)((void*)(ewram_addr + sizeof(struct SaveBlock2))))
-#define eSaveBlock3Copy (*(struct PokemonStorage *)((void*)(ewram_addr + sizeof(struct SaveBlock2) + sizeof(struct SaveBlock1))))
-
-#ifdef NONMATCHING // this is one devil of a motherfucker
-/*
- The reason MoveSaveBlocks_ResetHeap mismatches is due to incorrect memcpys. Various
- things have been tried, such as: direct struct copys, ewram casts, use of defining
- the addresses manually, using memcpy anyway, delayed allocation of pointers at
- the start of function, as seen above and below. Scope declaration has been used to try and
- reproduce the correct macro thought to be used, but nothing has worked. It is worth
- noting that at this point that the compiler will delay the allocation of the save block
- pointers at the beginningto be allocated later: which might matter for matching this.
- Due to loading shared ewram heap areas directly, it is very likely emerald used ewram
- defines for this function, but there is no known example of a matching define.
- In addition, dead code might be present in the form of a runtime variable used
- to fix the address of the save blocks. This has been tested and is shown to affect
- the registers as well.
-*/
void MoveSaveBlocks_ResetHeap(void)
{
void *vblankCB, *hblankCB;
u32 encryptionKey;
- struct SaveBlock1 **sav1Copy = &gSaveBlock1Ptr; // r10;
+ struct SaveBlock2 *saveBlock2Copy;
+ struct SaveBlock1 *saveBlock1Copy;
+ struct PokemonStorage *pokemonStorageCopy;
// save interrupt functions and turn them off
vblankCB = gMain.vblankCallback;
@@ -127,22 +97,30 @@ void MoveSaveBlocks_ResetHeap(void)
gMain.hblankCallback = NULL;
gUnknown_0203CF5C = NULL;
+ saveBlock2Copy = (struct SaveBlock2 *)(gHeap);
+ saveBlock1Copy = (struct SaveBlock1 *)(gHeap + sizeof(struct SaveBlock2));
+ pokemonStorageCopy = (struct PokemonStorage *)(gHeap + sizeof(struct SaveBlock2) + sizeof(struct SaveBlock1));
+
// backup the saves.
- eSaveBlock1Copy = **sav1Copy;
- eSaveBlock2Copy = *gSaveBlock2Ptr;
- eSaveBlock3Copy = *gPokemonStoragePtr;
+ *saveBlock2Copy = *gSaveBlock2Ptr;
+ *saveBlock1Copy = *gSaveBlock1Ptr;
+ *pokemonStorageCopy = *gPokemonStoragePtr;
// change saveblocks' pointers
// argument is a sum of the individual trainerId bytes
- SetSaveBlocksPointers(eSaveBlock2Copy.playerTrainerId[0] + eSaveBlock2Copy.playerTrainerId[1] + eSaveBlock2Copy.playerTrainerId[2] + eSaveBlock2Copy.playerTrainerId[3]);
+ SetSaveBlocksPointers(
+ saveBlock2Copy->playerTrainerId[0] +
+ saveBlock2Copy->playerTrainerId[1] +
+ saveBlock2Copy->playerTrainerId[2] +
+ saveBlock2Copy->playerTrainerId[3]);
// restore saveblock data since the pointers changed
- **sav1Copy = eSaveBlock1Copy;
- *gSaveBlock2Ptr = eSaveBlock2Copy;
- *gPokemonStoragePtr = eSaveBlock3Copy;
+ *gSaveBlock2Ptr = *saveBlock2Copy;
+ *gSaveBlock1Ptr = *saveBlock1Copy;
+ *gPokemonStoragePtr = *pokemonStorageCopy;
// heap was destroyed in the copying process, so reset it
- InitHeap((void*)(0x02000000), 0x1C000);
+ InitHeap(gHeap, HEAP_SIZE);
// restore interrupt functions
gMain.hblankCallback = hblankCB;
@@ -153,105 +131,7 @@ void MoveSaveBlocks_ResetHeap(void)
ApplyNewEncryptionKeyToAllEncryptedData(encryptionKey);
gSaveBlock2Ptr->encryptionKey = encryptionKey;
}
-#else
-__attribute__((naked))
-void MoveSaveBlocks_ResetHeap(void)
-{
- asm(".syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r10\n\
- mov r6, r9\n\
- mov r5, r8\n\
- push {r5-r7}\n\
- sub sp, 0x8\n\
- ldr r5, =gMain\n\
- ldr r0, [r5, 0xC]\n\
- str r0, [sp]\n\
- ldr r1, [r5, 0x10]\n\
- str r1, [sp, 0x4]\n\
- movs r0, 0\n\
- str r0, [r5, 0xC]\n\
- str r0, [r5, 0x10]\n\
- ldr r1, =gUnknown_0203CF5C\n\
- str r0, [r1]\n\
- ldr r4, =0x02000000\n\
- ldr r0, =gSaveBlock2Ptr\n\
- ldr r1, [r0]\n\
- ldr r6, =0x00000f2c\n\
- adds r0, r4, 0\n\
- adds r2, r6, 0\n\
- bl memcpy\n\
- ldr r1, =gSaveBlock1Ptr\n\
- mov r10, r1\n\
- ldr r1, [r1]\n\
- ldr r7, =0x00003d88\n\
- ldr r0, =0x02000f2c\n\
- adds r2, r7, 0\n\
- bl memcpy\n\
- ldr r0, =gPokemonStoragePtr\n\
- mov r8, r0\n\
- ldr r1, [r0]\n\
- ldr r0, =0x000083d0\n\
- mov r9, r0\n\
- ldr r0, =0x02004cb4\n\
- mov r2, r9\n\
- bl memcpy\n\
- ldrb r1, [r4, 0xA]\n\
- ldrb r0, [r4, 0xB]\n\
- adds r1, r0\n\
- ldrb r0, [r4, 0xC]\n\
- adds r1, r0\n\
- ldrb r0, [r4, 0xD]\n\
- adds r0, r1\n\
- bl SetSaveBlocksPointers\n\
- ldr r1, =gSaveBlock2Ptr\n\
- ldr r0, [r1]\n\
- adds r1, r4, 0\n\
- adds r2, r6, 0\n\
- bl memcpy\n\
- mov r1, r10\n\
- ldr r0, [r1]\n\
- ldr r1, =0x02000f2c\n\
- adds r2, r7, 0\n\
- bl memcpy\n\
- mov r1, r8\n\
- ldr r0, [r1]\n\
- ldr r1, =0x02004cb4\n\
- mov r2, r9\n\
- bl memcpy\n\
- movs r1, 0xE0\n\
- lsls r1, 9\n\
- adds r0, r4, 0\n\
- bl InitHeap\n\
- ldr r0, [sp, 0x4]\n\
- str r0, [r5, 0x10]\n\
- ldr r1, [sp]\n\
- str r1, [r5, 0xC]\n\
- bl Random\n\
- adds r4, r0, 0\n\
- bl Random\n\
- lsls r4, 16\n\
- lsls r0, 16\n\
- lsrs r0, 16\n\
- adds r4, r0\n\
- adds r0, r4, 0\n\
- bl ApplyNewEncryptionKeyToAllEncryptedData\n\
- ldr r1, =gSaveBlock2Ptr\n\
- ldr r0, [r1]\n\
- adds r0, 0xAC\n\
- str r4, [r0]\n\
- add sp, 0x8\n\
- pop {r3-r5}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- mov r10, r5\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0\n\
- .pool\n\
- .syntax divided\n");
-}
-#endif
+
u8 sav2_x1_query_bit1(void)
{
@@ -330,7 +210,7 @@ void LoadSerializedGame(void)
void copy_bags_and_unk_data_from_save_blocks(void)
{
int i;
-
+
// load player items.
for (i = 0; i < 30; i++)
gLoadedSaveData.items[i] = gSaveBlock1Ptr->bagPocket_Items[i];
diff --git a/src/m4a_2.c b/src/m4a_2.c
index 2d3c65848..0625f05d1 100644
--- a/src/m4a_2.c
+++ b/src/m4a_2.c
@@ -11,10 +11,10 @@ void *gMPlayJumpTable[36];
struct CgbChannel gCgbChans[4];
struct MusicPlayerTrack gPokemonCryTracks[MAX_POKEMON_CRIES * 2];
struct PokemonCrySong gPokemonCrySong;
-struct MusicPlayerInfo gMPlay_BGM;
-struct MusicPlayerInfo gMPlay_SE1;
-struct MusicPlayerInfo gMPlay_SE2;
-struct MusicPlayerInfo gMPlay_SE3;
+struct MusicPlayerInfo gMPlayInfo_BGM;
+struct MusicPlayerInfo gMPlayInfo_SE1;
+struct MusicPlayerInfo gMPlayInfo_SE2;
+struct MusicPlayerInfo gMPlayInfo_SE3;
u8 gMPlayMemAccArea[0x10];
u32 MidiKeyToFreq(struct WaveData *wav, u8 key, u8 fineAdjust)
diff --git a/src/mail.c b/src/mail.c
index 877035fb6..68a55e242 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "mail.h"
#include "constants/items.h"
#include "main.h"
#include "overworld.h"
@@ -18,8 +19,43 @@
#include "constants/species.h"
#include "malloc.h"
#include "easy_chat.h"
-#include "mail_data.h"
-#include "mail.h"
+
+extern const u16 gMailPalette_Orange[];
+extern const u16 gMailPalette_Harbor[];
+extern const u16 gMailPalette_Glitter[];
+extern const u16 gMailPalette_Mech[];
+extern const u16 gMailPalette_Wood[];
+extern const u16 gMailPalette_Wave[];
+extern const u16 gMailPalette_Bead[];
+extern const u16 gMailPalette_Shadow[];
+extern const u16 gMailPalette_Tropic[];
+extern const u16 gMailPalette_Dream[];
+extern const u16 gMailPalette_Fab[];
+extern const u16 gMailPalette_Retro[];
+extern const u8 gMailTiles_Orange[];
+extern const u8 gMailTilemap_Orange[];
+extern const u8 gMailTiles_Harbor[];
+extern const u8 gMailTilemap_Harbor[];
+extern const u8 gMailTiles_Glitter[];
+extern const u8 gMailTilemap_Glitter[];
+extern const u8 gMailTiles_Mech[];
+extern const u8 gMailTilemap_Mech[];
+extern const u8 gMailTiles_Wood[];
+extern const u8 gMailTilemap_Wood[];
+extern const u8 gMailTiles_Wave[];
+extern const u8 gMailTilemap_Wave[];
+extern const u8 gMailTiles_Bead[];
+extern const u8 gMailTilemap_Bead[];
+extern const u8 gMailTiles_Shadow[];
+extern const u8 gMailTilemap_Shadow[];
+extern const u8 gMailTiles_Tropic[];
+extern const u8 gMailTilemap_Tropic[];
+extern const u8 gMailTiles_Dream[];
+extern const u8 gMailTilemap_Dream[];
+extern const u8 gMailTiles_Fab[];
+extern const u8 gMailTilemap_Fab[];
+extern const u8 gMailTiles_Retro[];
+extern const u8 gMailTilemap_Retro[];
// Static type declarations
@@ -51,9 +87,7 @@ struct MailGraphics
u16 color12;
};
-// Static RAM declarations
-
-static EWRAM_DATA struct
+struct MailRead
{
/*0x0000*/ u8 strbuf[8][64];
/*0x0200*/ u8 playerName[12];
@@ -72,22 +106,26 @@ static EWRAM_DATA struct
/*0x0228*/ const struct MailLayout *layout;
/*0x022c*/ u8 bg1TilemapBuffer[0x1000];
/*0x122c*/ u8 bg2TilemapBuffer[0x1000];
-} *gUnknown_0203A134 = NULL;
+};
+
+// Static RAM declarations
+
+static EWRAM_DATA struct MailRead *sMailRead = NULL;
// Static ROM declarations
-void sub_81219F0(void);
-void sub_8121A1C(void);
-void sub_8121B1C(void);
-void sub_8121C50(void);
-void sub_8121C64(void);
-void sub_8121C98(void);
-void sub_8121CC0(void);
-void sub_8121D00(void);
+static void CB2_InitMailRead(void);
+static void sub_8121A1C(void);
+static void sub_8121B1C(void);
+static void VBlankCB_MailRead(void);
+static void CB2_MailRead(void);
+static void CB2_WaitForPaletteExitOnKeyPress(void);
+static void CB2_ExitOnKeyPress(void);
+static void CB2_ExitMailReadFreeVars(void);
// .rodata
-const struct BgTemplate gUnknown_0859F290[] = {
+static const struct BgTemplate sUnknown_0859F290[] = {
{
.bg = 0,
.charBaseIndex = 2,
@@ -106,7 +144,7 @@ const struct BgTemplate gUnknown_0859F290[] = {
}
};
-const struct WindowTemplate gUnknown_0859F29C[] = {
+static const struct WindowTemplate sUnknown_0859F29C[] = {
{
.priority = 0,
.tilemapLeft = 2,
@@ -119,89 +157,52 @@ const struct WindowTemplate gUnknown_0859F29C[] = {
DUMMY_WIN_TEMPLATE
};
-const u8 gUnknown_0859F2AC[] = {
+static const u8 sUnknown_0859F2AC[] = {
0,
10,
11
};
-const u16 gUnknown_0859F2B0[][2] = {
+static const u16 sUnknown_0859F2B0[][2] = {
{ 0x6ACD, 0x51A5 },
{ 0x45FC, 0x38D4 }
};
-extern const u16 gUnknown_08DBE818[];
-extern const u16 gUnknown_08DBE838[];
-extern const u16 gUnknown_08DBE858[];
-extern const u16 gUnknown_08DBE878[];
-extern const u16 gUnknown_08DBE898[];
-extern const u16 gUnknown_08DBE8B8[];
-extern const u16 gUnknown_08DBE8D8[];
-extern const u16 gUnknown_08DBE8F8[];
-extern const u16 gUnknown_08DBE918[];
-extern const u16 gUnknown_08DBE938[];
-extern const u16 gUnknown_08DBE958[];
-extern const u16 gUnknown_08DBE978[];
-extern const u8 gUnknown_08DBE998[];
-extern const u8 gUnknown_08DBFBA4[];
-extern const u8 gUnknown_08DBEB38[];
-extern const u8 gUnknown_08DBFC7C[];
-extern const u8 gUnknown_08DBEC74[];
-extern const u8 gUnknown_08DBFD5C[];
-extern const u8 gUnknown_08DBEE84[];
-extern const u8 gUnknown_08DBFE68[];
-extern const u8 gUnknown_08DBEF5C[];
-extern const u8 gUnknown_08DBFF44[];
-extern const u8 gUnknown_08DBF154[];
-extern const u8 gUnknown_08DC0034[];
-extern const u8 gUnknown_08DBF2D4[];
-extern const u8 gUnknown_08DC0114[];
-extern const u8 gUnknown_08DBF37C[];
-extern const u8 gUnknown_08DC01F4[];
-extern const u8 gUnknown_08DBF50C[];
-extern const u8 gUnknown_08DC0300[];
-extern const u8 gUnknown_08DBF64C[];
-extern const u8 gUnknown_08DC03F0[];
-extern const u8 gUnknown_08DBF7B4[];
-extern const u8 gUnknown_08DC04E8[];
-extern const u8 gUnknown_08DBF904[];
-extern const u8 gUnknown_08DC0600[];
-
-const struct MailGraphics gUnknown_0859F2B8[] = {
+static const struct MailGraphics sUnknown_0859F2B8[] = {
{
- gUnknown_08DBE818, gUnknown_08DBE998, gUnknown_08DBFBA4, 0x02c0, 0x0000, 0x294a, 0x6739
+ gMailPalette_Orange, gMailTiles_Orange, gMailTilemap_Orange, 0x02c0, 0x0000, 0x294a, 0x6739
}, {
- gUnknown_08DBE838, gUnknown_08DBEB38, gUnknown_08DBFC7C, 0x02e0, 0x0000, 0x7fff, 0x4631
+ gMailPalette_Harbor, gMailTiles_Harbor, gMailTilemap_Harbor, 0x02e0, 0x0000, 0x7fff, 0x4631
}, {
- gUnknown_08DBE858, gUnknown_08DBEC74, gUnknown_08DBFD5C, 0x0400, 0x0000, 0x294a, 0x6739
+ gMailPalette_Glitter, gMailTiles_Glitter, gMailTilemap_Glitter, 0x0400, 0x0000, 0x294a, 0x6739
}, {
- gUnknown_08DBE878, gUnknown_08DBEE84, gUnknown_08DBFE68, 0x01e0, 0x0000, 0x7fff, 0x4631
+ gMailPalette_Mech, gMailTiles_Mech, gMailTilemap_Mech, 0x01e0, 0x0000, 0x7fff, 0x4631
}, {
- gUnknown_08DBE898, gUnknown_08DBEF5C, gUnknown_08DBFF44, 0x02e0, 0x0000, 0x7fff, 0x4631
+ gMailPalette_Wood, gMailTiles_Wood, gMailTilemap_Wood, 0x02e0, 0x0000, 0x7fff, 0x4631
}, {
- gUnknown_08DBE8B8, gUnknown_08DBF154, gUnknown_08DC0034, 0x0300, 0x0000, 0x294a, 0x6739
+ gMailPalette_Wave, gMailTiles_Wave, gMailTilemap_Wave, 0x0300, 0x0000, 0x294a, 0x6739
}, {
- gUnknown_08DBE8D8, gUnknown_08DBF2D4, gUnknown_08DC0114, 0x0140, 0x0000, 0x7fff, 0x4631
+ gMailPalette_Bead, gMailTiles_Bead, gMailTilemap_Bead, 0x0140, 0x0000, 0x7fff, 0x4631
}, {
- gUnknown_08DBE8F8, gUnknown_08DBF37C, gUnknown_08DC01F4, 0x0300, 0x0000, 0x7fff, 0x4631
+ gMailPalette_Shadow, gMailTiles_Shadow, gMailTilemap_Shadow, 0x0300, 0x0000, 0x7fff, 0x4631
}, {
- gUnknown_08DBE918, gUnknown_08DBF50C, gUnknown_08DC0300, 0x0220, 0x0000, 0x294a, 0x6739
+ gMailPalette_Tropic, gMailTiles_Tropic, gMailTilemap_Tropic, 0x0220, 0x0000, 0x294a, 0x6739
}, {
- gUnknown_08DBE938, gUnknown_08DBF64C, gUnknown_08DC03F0, 0x0340, 0x0000, 0x294a, 0x6739
+ gMailPalette_Dream, gMailTiles_Dream, gMailTilemap_Dream, 0x0340, 0x0000, 0x294a, 0x6739
}, {
- gUnknown_08DBE958, gUnknown_08DBF7B4, gUnknown_08DC04E8, 0x02a0, 0x0000, 0x294a, 0x6739
+ gMailPalette_Fab, gMailTiles_Fab, gMailTilemap_Fab, 0x02a0, 0x0000, 0x294a, 0x6739
}, {
- gUnknown_08DBE978, gUnknown_08DBF904, gUnknown_08DC0600, 0x0520, 0x0000, 0x294a, 0x6739
+ gMailPalette_Retro, gMailTiles_Retro, gMailTilemap_Retro, 0x0520, 0x0000, 0x294a, 0x6739
}
};
-const struct UnkMailStruct Unknown_0859F3A8[] = {
+static const struct UnkMailStruct Unknown_0859F3A8[] = {
{ .numEasyChatWords = 3, .lineHeight = 16 },
{ .numEasyChatWords = 3, .lineHeight = 16 },
{ .numEasyChatWords = 3, .lineHeight = 16 }
};
-const struct MailLayout gUnknown_0859F3B4[] = {
+static const struct MailLayout sUnknown_0859F3B4[] = {
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
@@ -216,7 +217,7 @@ const struct MailLayout gUnknown_0859F3B4[] = {
{ 0x03, 0x00, 0x00, 0x02, 0x00, Unknown_0859F3A8 }
};
-const struct UnkMailStruct Unknown_0859F444[] = {
+static const struct UnkMailStruct Unknown_0859F444[] = {
{ .numEasyChatWords = 2, .lineHeight = 16 },
{ .numEasyChatWords = 2, .lineHeight = 16 },
{ .numEasyChatWords = 2, .lineHeight = 16 },
@@ -224,7 +225,7 @@ const struct UnkMailStruct Unknown_0859F444[] = {
{ .numEasyChatWords = 1, .lineHeight = 16 }
};
-const struct MailLayout gUnknown_0859F458[] = {
+static const struct MailLayout sUnknown_0859F458[] = {
{ 0x05, 0x07, 0x58, 0x0b, 0x1e, Unknown_0859F444 },
{ 0x05, 0x0a, 0x60, 0x09, 0x1e, Unknown_0859F444 },
{ 0x05, 0x0c, 0x68, 0x05, 0x1e, Unknown_0859F444 },
@@ -241,23 +242,23 @@ const struct MailLayout gUnknown_0859F458[] = {
// What the heck are these meant to be? Call them u16 for now.
-const u16 Unknown_0859F4E8[] = {
+static const u16 Unknown_0859F4E8[] = {
0x00, 0x4000, 0x00, 0x00
};
-const u16 Unknown_0859F4F0[] = {
+static const u16 Unknown_0859F4F0[] = {
0x00, 0x00, -1, 0x00
};
-const u16 Unknown_0859F4F8[] = {
+static const u16 Unknown_0859F4F8[] = {
0x04, 0x00, -1, 0x00
};
-const u16 Unknown_0859F500[] = {
+static const u16 Unknown_0859F500[] = {
0x00, 0x40, -1, 0x00
};
-const u16 *const gUnknown_0859F508[] = {
+static const u16 *const sUnknown_0859F508[] = {
Unknown_0859F4F0,
Unknown_0859F4F8,
Unknown_0859F500
@@ -265,60 +266,62 @@ const u16 *const gUnknown_0859F508[] = {
// .text
-void sub_8121478(struct MailStruct *mail, MainCallback callback, bool8 flag) {
+void ReadMail(struct MailStruct *mail, void (*callback)(void), bool8 flag)
+{
u16 buffer[2];
u16 species;
- gUnknown_0203A134 = calloc(1, sizeof(*gUnknown_0203A134));
- gUnknown_0203A134->language = LANGUAGE_ENGLISH;
- gUnknown_0203A134->playerIsSender = TRUE;
- gUnknown_0203A134->parserSingle = CopyEasyChatWord;
- gUnknown_0203A134->parserMultiple = ConvertEasyChatWordsToString;
- if (mail->itemId >= ITEM_ORANGE_MAIL && mail->itemId <= ITEM_RETRO_MAIL) {
- gUnknown_0203A134->mailType = mail->itemId - ITEM_ORANGE_MAIL;
+ sMailRead = calloc(1, sizeof(*sMailRead));
+ sMailRead->language = LANGUAGE_ENGLISH;
+ sMailRead->playerIsSender = TRUE;
+ sMailRead->parserSingle = CopyEasyChatWord;
+ sMailRead->parserMultiple = ConvertEasyChatWordsToString;
+ if (IS_ITEM_MAIL(mail->itemId))
+ {
+ sMailRead->mailType = mail->itemId - ITEM_ORANGE_MAIL;
}
else
{
- gUnknown_0203A134->mailType = 0;
+ sMailRead->mailType = 0;
flag = FALSE;
}
- switch (gUnknown_0203A134->playerIsSender)
+ switch (sMailRead->playerIsSender)
{
case FALSE:
default:
- gUnknown_0203A134->layout = &gUnknown_0859F3B4[gUnknown_0203A134->mailType];
+ sMailRead->layout = &sUnknown_0859F3B4[sMailRead->mailType];
break;
case TRUE:
- gUnknown_0203A134->layout = &gUnknown_0859F458[gUnknown_0203A134->mailType];
+ sMailRead->layout = &sUnknown_0859F458[sMailRead->mailType];
break;
}
- species = sub_80D45E8(mail->species, buffer);
+ species = MailSpeciesToSpecies(mail->species, buffer);
if (species >= SPECIES_BULBASAUR && species < NUM_SPECIES)
{
- switch (gUnknown_0203A134->mailType)
+ switch (sMailRead->mailType)
{
default:
- gUnknown_0203A134->animsActive = 0;
+ sMailRead->animsActive = 0;
break;
case ITEM_BEAD_MAIL - ITEM_ORANGE_MAIL:
- gUnknown_0203A134->animsActive = 1;
+ sMailRead->animsActive = 1;
break;
case ITEM_DREAM_MAIL - ITEM_ORANGE_MAIL:
- gUnknown_0203A134->animsActive = 2;
+ sMailRead->animsActive = 2;
break;
}
}
else
{
- gUnknown_0203A134->animsActive = 0;
+ sMailRead->animsActive = 0;
}
- gUnknown_0203A134->mail = mail;
- gUnknown_0203A134->callback = callback;
- gUnknown_0203A134->flag = flag;
- SetMainCallback2(sub_81219F0);
+ sMailRead->mail = mail;
+ sMailRead->callback = callback;
+ sMailRead->flag = flag;
+ SetMainCallback2(CB2_InitMailRead);
}
-bool8 sub_81215EC(void)
+static bool8 MailReadBuildGraphics(void)
{
u16 icon;
@@ -352,21 +355,21 @@ bool8 sub_81215EC(void)
SetGpuReg(REG_OFFSET_BG2HOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG3HOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG3VOFS, 0x0000);
- SetGpuReg(REG_OFFSET_BLDCNT, 0x0000);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0x0000);
SetGpuReg(REG_OFFSET_BLDALPHA, 0x0000);
break;
case 6:
ResetBgsAndClearDma3BusyFlags(0);
- InitBgsFromTemplates(0, gUnknown_0859F290, 3);
- SetBgTilemapBuffer(1, gUnknown_0203A134->bg1TilemapBuffer);
- SetBgTilemapBuffer(2, gUnknown_0203A134->bg2TilemapBuffer);
+ InitBgsFromTemplates(0, sUnknown_0859F290, 3);
+ SetBgTilemapBuffer(1, sMailRead->bg1TilemapBuffer);
+ SetBgTilemapBuffer(2, sMailRead->bg2TilemapBuffer);
break;
case 7:
- InitWindows(gUnknown_0859F29C);
+ InitWindows(sUnknown_0859F29C);
DeactivateAllTextPrinters();
break;
case 8:
- decompress_and_copy_tile_data_to_vram(1, gUnknown_0859F2B8[gUnknown_0203A134->mailType].tiles, 0, 0, 0);
+ decompress_and_copy_tile_data_to_vram(1, sUnknown_0859F2B8[sMailRead->mailType].tiles, 0, 0, 0);
break;
case 9:
if (free_temp_tile_data_buffers_if_possible())
@@ -377,7 +380,7 @@ bool8 sub_81215EC(void)
case 10:
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 30, 20);
FillBgTilemapBufferRect_Palette0(2, 1, 0, 0, 30, 20);
- CopyToBgTilemapBuffer(1, gUnknown_0859F2B8[gUnknown_0203A134->mailType].tileMap, 0, 0);
+ CopyToBgTilemapBuffer(1, sUnknown_0859F2B8[sMailRead->mailType].tileMap, 0, 0);
break;
case 11:
CopyBgTilemapBufferToVram(0);
@@ -386,24 +389,24 @@ bool8 sub_81215EC(void)
break;
case 12:
LoadPalette(GetOverworldTextboxPalettePtr(), 240, 32);
- gPlttBufferUnfaded[250] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color10;
- gPlttBufferFaded[250] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color10;
- gPlttBufferUnfaded[251] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color12;
- gPlttBufferFaded[251] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color12;
- LoadPalette(gUnknown_0859F2B8[gUnknown_0203A134->mailType].palette, 0, 32);
- gPlttBufferUnfaded[10] = gUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][0];
- gPlttBufferFaded[10] = gUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][0];
- gPlttBufferUnfaded[11] = gUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][1];
- gPlttBufferFaded[11] = gUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][1];
+ gPlttBufferUnfaded[250] = sUnknown_0859F2B8[sMailRead->mailType].color10;
+ gPlttBufferFaded[250] = sUnknown_0859F2B8[sMailRead->mailType].color10;
+ gPlttBufferUnfaded[251] = sUnknown_0859F2B8[sMailRead->mailType].color12;
+ gPlttBufferFaded[251] = sUnknown_0859F2B8[sMailRead->mailType].color12;
+ LoadPalette(sUnknown_0859F2B8[sMailRead->mailType].palette, 0, 32);
+ gPlttBufferUnfaded[10] = sUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][0];
+ gPlttBufferFaded[10] = sUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][0];
+ gPlttBufferUnfaded[11] = sUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][1];
+ gPlttBufferFaded[11] = sUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][1];
break;
case 13:
- if (gUnknown_0203A134->flag)
+ if (sMailRead->flag)
{
sub_8121A1C();
}
break;
case 14:
- if (gUnknown_0203A134->flag)
+ if (sMailRead->flag)
{
sub_8121B1C();
RunTextPrinters();
@@ -416,20 +419,20 @@ bool8 sub_81215EC(void)
}
break;
case 16:
- SetVBlankCallback(sub_8121C50);
+ SetVBlankCallback(VBlankCB_MailRead);
gPaletteFade.bufferTransferDisabled = TRUE;
break;
case 17:
- icon = sub_80D2E84(gUnknown_0203A134->mail->species);
- switch (gUnknown_0203A134->animsActive)
+ icon = sub_80D2E84(sMailRead->mail->species);
+ switch (sMailRead->animsActive)
{
case 1:
sub_80D2F68(icon);
- gUnknown_0203A134->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x60, 0x80, 0, 0);
+ sMailRead->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x60, 0x80, 0, 0);
break;
case 2:
sub_80D2F68(icon);
- gUnknown_0203A134->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x28, 0x80, 0, 0);
+ sMailRead->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x28, 0x80, 0, 0);
break;
}
break;
@@ -440,53 +443,53 @@ bool8 sub_81215EC(void)
ShowBg(2);
BeginNormalPaletteFade(-1, 0, 16, 0, 0);
gPaletteFade.bufferTransferDisabled = FALSE;
- gUnknown_0203A134->callback2 = sub_8121C98;
+ sMailRead->callback2 = CB2_WaitForPaletteExitOnKeyPress;
return TRUE;
default:
return FALSE;
}
- gMain.state ++;
+ gMain.state++;
return FALSE;
}
-void sub_81219F0(void)
+static void CB2_InitMailRead(void)
{
do
{
- if (sub_81215EC() == TRUE)
+ if (MailReadBuildGraphics() == TRUE)
{
- SetMainCallback2(sub_8121C64);
+ SetMainCallback2(CB2_MailRead);
break;
}
} while (sub_81221AC() != TRUE);
}
-void sub_8121A1C(void)
+static void sub_8121A1C(void)
{
u16 i;
u8 total;
u8 *ptr;
total = 0;
- for (i = 0; i < gUnknown_0203A134->layout->numSubStructs; i ++)
+ for (i = 0; i < sMailRead->layout->numSubStructs; i ++)
{
- ConvertEasyChatWordsToString(gUnknown_0203A134->strbuf[i], &gUnknown_0203A134->mail->words[total], gUnknown_0203A134->layout->var8[i].numEasyChatWords, 1);
- total += gUnknown_0203A134->layout->var8[i].numEasyChatWords;
+ ConvertEasyChatWordsToString(sMailRead->strbuf[i], &sMailRead->mail->words[total], sMailRead->layout->var8[i].numEasyChatWords, 1);
+ total += sMailRead->layout->var8[i].numEasyChatWords;
}
- ptr = StringCopy(gUnknown_0203A134->playerName, gUnknown_0203A134->mail->playerName);
- if (!gUnknown_0203A134->playerIsSender)
+ ptr = StringCopy(sMailRead->playerName, sMailRead->mail->playerName);
+ if (!sMailRead->playerIsSender)
{
StringCopy(ptr, gText_FromSpace);
- gUnknown_0203A134->signatureWidth = gUnknown_0203A134->layout->signatureWidth - (StringLength(gUnknown_0203A134->playerName) * 8 - 0x60);
+ sMailRead->signatureWidth = sMailRead->layout->signatureWidth - (StringLength(sMailRead->playerName) * 8 - 0x60);
}
else
{
- sub_81DB52C(gUnknown_0203A134->playerName);
- gUnknown_0203A134->signatureWidth = gUnknown_0203A134->layout->signatureWidth;
+ sub_81DB52C(sMailRead->playerName);
+ sMailRead->signatureWidth = sMailRead->layout->signatureWidth;
}
}
-void sub_8121B1C(void)
+static void sub_8121B1C(void)
{
u16 i;
u8 strbuf[0x20];
@@ -500,77 +503,76 @@ void sub_8121B1C(void)
PutWindowTilemap(1);
FillWindowPixelBuffer(0, 0);
FillWindowPixelBuffer(1, 0);
- for (i = 0; i < gUnknown_0203A134->layout->numSubStructs; i ++)
+ for (i = 0; i < sMailRead->layout->numSubStructs; i ++)
{
- if (gUnknown_0203A134->strbuf[i][0] == EOS || gUnknown_0203A134->strbuf[i][0] == CHAR_SPACE)
+ if (sMailRead->strbuf[i][0] == EOS || sMailRead->strbuf[i][0] == CHAR_SPACE)
{
continue;
}
- box_print(0, 1, gUnknown_0203A134->layout->var8[i].xOffset + gUnknown_0203A134->layout->wordsYPos, y + gUnknown_0203A134->layout->wordsXPos, gUnknown_0859F2AC, 0, gUnknown_0203A134->strbuf[i]);
- y += gUnknown_0203A134->layout->var8[i].lineHeight;
+ box_print(0, 1, sMailRead->layout->var8[i].xOffset + sMailRead->layout->wordsYPos, y + sMailRead->layout->wordsXPos, sUnknown_0859F2AC, 0, sMailRead->strbuf[i]);
+ y += sMailRead->layout->var8[i].lineHeight;
}
bufptr = StringCopy(strbuf, gText_FromSpace);
- StringCopy(bufptr, gUnknown_0203A134->playerName);
- box_x = GetStringCenterAlignXOffset(1, strbuf, gUnknown_0203A134->signatureWidth) + 0x68;
- box_y = gUnknown_0203A134->layout->signatureYPos + 0x58;
- box_print(0, 1, box_x, box_y, gUnknown_0859F2AC, 0, strbuf);
+ StringCopy(bufptr, sMailRead->playerName);
+ box_x = GetStringCenterAlignXOffset(1, strbuf, sMailRead->signatureWidth) + 0x68;
+ box_y = sMailRead->layout->signatureYPos + 0x58;
+ box_print(0, 1, box_x, box_y, sUnknown_0859F2AC, 0, strbuf);
CopyWindowToVram(0, 3);
CopyWindowToVram(1, 3);
}
-void sub_8121C50(void)
+static void VBlankCB_MailRead(void)
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
-void sub_8121C64(void)
+static void CB2_MailRead(void)
{
- if (gUnknown_0203A134->animsActive != 0)
+ if (sMailRead->animsActive != 0)
{
AnimateSprites();
BuildOamBuffer();
}
- gUnknown_0203A134->callback2();
+ sMailRead->callback2();
}
-void sub_8121C98(void)
+static void CB2_WaitForPaletteExitOnKeyPress(void)
{
if (!UpdatePaletteFade())
{
- gUnknown_0203A134->callback2 = sub_8121CC0;
+ sMailRead->callback2 = CB2_ExitOnKeyPress;
}
}
-void sub_8121CC0(void)
+static void CB2_ExitOnKeyPress(void)
{
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
{
BeginNormalPaletteFade(-1, 0, 0, 16, 0);
- gUnknown_0203A134->callback2 = sub_8121D00;
+ sMailRead->callback2 = CB2_ExitMailReadFreeVars;
}
}
-void sub_8121D00(void)
+static void CB2_ExitMailReadFreeVars(void)
{
if (!UpdatePaletteFade())
{
- SetMainCallback2(gUnknown_0203A134->callback);
- switch (gUnknown_0203A134->animsActive)
+ SetMainCallback2(sMailRead->callback);
+ switch (sMailRead->animsActive)
{
case 1:
case 2:
- sub_80D2FF0(sub_80D2E84(gUnknown_0203A134->mail->species));
- sub_80D2EF8(&gSprites[gUnknown_0203A134->monIconSprite]);
+ sub_80D2FF0(sub_80D2E84(sMailRead->mail->species));
+ sub_80D2EF8(&gSprites[sMailRead->monIconSprite]);
}
- memset(gUnknown_0203A134, 0, sizeof(*gUnknown_0203A134));
+ memset(sMailRead, 0, sizeof(*sMailRead));
ResetPaletteFade();
UnsetBgTilemapBuffer(0);
UnsetBgTilemapBuffer(1);
ResetBgsAndClearDma3BusyFlags(0);
FreeAllWindowBuffers();
- free(gUnknown_0203A134);
- gUnknown_0203A134 = NULL;
+ FREE_AND_SET_NULL(sMailRead);
}
}
diff --git a/src/mail_data.c b/src/mail_data.c
new file mode 100644
index 000000000..ebb49febf
--- /dev/null
+++ b/src/mail_data.c
@@ -0,0 +1,203 @@
+#include "global.h"
+#include "mail.h"
+#include "constants/items.h"
+#include "pokemon.h"
+#include "pokemon_icon.h"
+#include "constants/species.h"
+#include "text.h"
+#include "international_string_util.h"
+
+void ClearMailData(void)
+{
+ u8 i;
+
+ for (i = 0; i < MAIL_COUNT; i++)
+ ClearMailStruct(&gSaveBlock1Ptr->mail[i]);
+}
+
+void ClearMailStruct(struct MailStruct *mail)
+{
+ s32 i;
+
+ for (i = 0; i < MAIL_WORDS_COUNT; i++)
+ mail->words[i] = 0xFFFF;
+
+ for (i = 0; i < PLAYER_NAME_LENGTH; i++)
+ mail->playerName[i] = EOS;
+
+ for (i = 0; i < 4; i++)
+ mail->trainerId[i] = 0;
+
+ mail->species = SPECIES_BULBASAUR;
+ mail->itemId = ITEM_NONE;
+}
+
+bool8 MonHasMail(struct Pokemon *mon)
+{
+ u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM);
+ if (ItemIsMail(heldItem) && GetMonData(mon, MON_DATA_MAIL) != 0xFF)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+u8 GiveMailToMon(struct Pokemon *mon, u16 itemId)
+{
+ u8 heldItem[2];
+ u8 id, i;
+ u16 species;
+ u32 personality;
+
+ heldItem[0] = itemId;
+ heldItem[1] = itemId >> 8;
+
+ for (id = 0; id < PARTY_SIZE; id++)
+ {
+ if (gSaveBlock1Ptr->mail[id].itemId == 0)
+ {
+ for (i = 0; i < MAIL_WORDS_COUNT; i++)
+ gSaveBlock1Ptr->mail[id].words[i] = 0xFFFF;
+
+ for (i = 0; i < PLAYER_NAME_LENGTH - 1; i++)
+ gSaveBlock1Ptr->mail[id].playerName[i] = gSaveBlock2Ptr->playerName[i];
+ gSaveBlock1Ptr->mail[id].playerName[i] = EOS;
+ PadNameString(gSaveBlock1Ptr->mail[id].playerName, CHAR_SPACE);
+
+ for (i = 0; i < 4; i++)
+ gSaveBlock1Ptr->mail[id].trainerId[i] = gSaveBlock2Ptr->playerTrainerId[i];
+
+ species = GetBoxMonData(&mon->box, MON_DATA_SPECIES);
+ personality = GetBoxMonData(&mon->box, MON_DATA_PERSONALITY);
+ gSaveBlock1Ptr->mail[id].species = SpeciesToMailSpecies(species, personality);
+ gSaveBlock1Ptr->mail[id].itemId = itemId;
+ SetMonData(mon, MON_DATA_MAIL, &id);
+ SetMonData(mon, MON_DATA_HELD_ITEM, heldItem);
+ return id;
+ }
+ }
+
+ return 0xFF;
+}
+
+u16 SpeciesToMailSpecies(u16 species, u32 personality)
+{
+ if (species == SPECIES_UNOWN)
+ {
+ u32 species = GetUnownLetterByPersonality(personality) + 30000;
+ return species;
+ }
+
+ return species;
+}
+
+u16 MailSpeciesToSpecies(u16 mailSpecies, u16 *buffer)
+{
+ u16 result;
+
+ if (mailSpecies >= 30000 && mailSpecies < (30000 + UNOWN_FORM_COUNT))
+ {
+ result = SPECIES_UNOWN;
+ *buffer = mailSpecies - 30000;
+ }
+ else
+ {
+ result = mailSpecies;
+ }
+
+ return result;
+}
+
+u8 GiveMailToMon2(struct Pokemon *mon, struct MailStruct *mail)
+{
+ u8 heldItem[2];
+ u16 itemId = mail->itemId;
+ u8 mailId = GiveMailToMon(mon, itemId);
+
+ if (mailId == 0xFF)
+ return 0xFF;
+
+ gSaveBlock1Ptr->mail[mailId] = *mail;
+
+ SetMonData(mon, MON_DATA_MAIL, &mailId);
+
+ heldItem[0] = itemId;
+ heldItem[1] = itemId >> 8;
+
+ SetMonData(mon, MON_DATA_HELD_ITEM, heldItem);
+
+ return mailId;
+}
+
+static bool32 DummyMailFunc(void)
+{
+ return FALSE;
+}
+
+void TakeMailFromMon(struct Pokemon *mon)
+{
+ u8 heldItem[2];
+ u8 mailId;
+
+ if (MonHasMail(mon))
+ {
+ mailId = GetMonData(mon, MON_DATA_MAIL);
+ gSaveBlock1Ptr->mail[mailId].itemId = ITEM_NONE;
+ mailId = 0xFF;
+ heldItem[0] = ITEM_NONE;
+ heldItem[1] = ITEM_NONE << 8;
+ SetMonData(mon, MON_DATA_MAIL, &mailId);
+ SetMonData(mon, MON_DATA_HELD_ITEM, heldItem);
+ }
+}
+
+void ClearMailItemId(u8 mailId)
+{
+ gSaveBlock1Ptr->mail[mailId].itemId = ITEM_NONE;
+}
+
+u8 TakeMailFromMon2(struct Pokemon *mon)
+{
+ u8 i;
+ u8 newHeldItem[2];
+ u8 newMailId;
+
+ newHeldItem[0] = ITEM_NONE;
+ newHeldItem[1] = ITEM_NONE << 8;
+ newMailId = 0xFF;
+
+ for (i = PARTY_SIZE; i < MAIL_COUNT; i++)
+ {
+ if (gSaveBlock1Ptr->mail[i].itemId == ITEM_NONE)
+ {
+ memcpy(&gSaveBlock1Ptr->mail[i], &gSaveBlock1Ptr->mail[GetMonData(mon, MON_DATA_MAIL)], sizeof(struct MailStruct));
+ gSaveBlock1Ptr->mail[GetMonData(mon, MON_DATA_MAIL)].itemId = ITEM_NONE;
+ SetMonData(mon, MON_DATA_MAIL, &newMailId);
+ SetMonData(mon, MON_DATA_HELD_ITEM, newHeldItem);
+ return i;
+ }
+ }
+
+ return 0xFF;
+}
+
+bool8 ItemIsMail(u16 itemId)
+{
+ switch (itemId)
+ {
+ case ITEM_ORANGE_MAIL:
+ case ITEM_HARBOR_MAIL:
+ case ITEM_GLITTER_MAIL:
+ case ITEM_MECH_MAIL:
+ case ITEM_WOOD_MAIL:
+ case ITEM_WAVE_MAIL:
+ case ITEM_BEAD_MAIL:
+ case ITEM_SHADOW_MAIL:
+ case ITEM_TROPIC_MAIL:
+ case ITEM_DREAM_MAIL:
+ case ITEM_FAB_MAIL:
+ case ITEM_RETRO_MAIL:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
diff --git a/src/main.c b/src/main.c
index 171202686..822aeda21 100644
--- a/src/main.c
+++ b/src/main.c
@@ -102,7 +102,7 @@ void AgbMain()
ClearDma3Requests();
ResetBgs();
SetDefaultFontsPointer();
- InitHeap(gHeap, 0x1C000);
+ InitHeap(gHeap, HEAP_SIZE);
gSoftResetDisabled = FALSE;
@@ -312,7 +312,6 @@ void SetSerialCallback(IntrCallback callback)
}
extern void CopyBufferedValuesToGpuRegs(void);
-extern void ProcessDma3Requests(void);
static void VBlankIntr(void)
{
diff --git a/src/new_game.c b/src/new_game.c
index 12873fec9..89771e92b 100644
--- a/src/new_game.c
+++ b/src/new_game.c
@@ -33,7 +33,6 @@ extern void Overworld_SetWarpDestination(s8 mapBank, s8 mapNo, s8 warpNo, s8 xPo
extern void warp_in(void);
extern void sub_80BB358(void);
extern void ResetBagScrollPositions(void);
-extern void sub_813624C(void); // clears something pokeblock related
extern void ResetPokedex(void);
extern void sub_8084400(void);
extern void ClearMailData(void);
@@ -148,7 +147,7 @@ void sub_808447C(void)
ZeroPlayerPartyMons();
ZeroEnemyPartyMons();
ResetBagScrollPositions();
- sub_813624C();
+ ResetPokeblockScrollPositions();
}
void NewGameInitData(void)
diff --git a/src/palette.c b/src/palette.c
index d4bb593da..d7b6ad479 100644
--- a/src/palette.c
+++ b/src/palette.c
@@ -65,7 +65,8 @@ static const struct PaletteStructTemplate gDummyPaletteStructTemplate = {
.uid = 0xFFFF,
.pst_field_B_5 = 1
};
-static const u8 gUnknown_0852489C[] = {
+
+static const u8 sRoundedDownGrayscaleMap[] = {
0, 0, 0, 0, 0,
5, 5, 5, 5, 5,
11, 11, 11, 11, 11,
@@ -620,7 +621,7 @@ static u8 UpdateFastPaletteFade(void)
gPlttBufferFaded[i] = r | (g << 5) | (b << 10);
}
break;
- case FAST_FADE_OUT_TO_WHTIE:
+ case FAST_FADE_OUT_TO_WHITE:
for (i = paletteOffsetStart; i < paletteOffsetEnd; i++)
{
struct PlttData *data = (struct PlttData *)&gPlttBufferFaded[i];
@@ -701,7 +702,7 @@ static u8 UpdateFastPaletteFade(void)
case FAST_FADE_IN_FROM_BLACK:
CpuCopy32(gPlttBufferUnfaded, gPlttBufferFaded, PLTT_SIZE);
break;
- case FAST_FADE_OUT_TO_WHTIE:
+ case FAST_FADE_OUT_TO_WHITE:
CpuFill32(0xFFFFFFFF, gPlttBufferFaded, PLTT_SIZE);
break;
case FAST_FADE_OUT_TO_BLACK:
@@ -838,10 +839,10 @@ void BlendPalettesUnfaded(u32 selectedPalettes, u8 coeff, u16 color)
void TintPalette_GrayScale(u16 *palette, u16 count)
{
- s32 r;
- s32 g;
- s32 b;
- s32 gray;
+ int r;
+ int g;
+ int b;
+ u32 gray;
int i;
for (i = 0; i < count; i++)
@@ -849,24 +850,23 @@ void TintPalette_GrayScale(u16 *palette, u16 count)
r = *palette & 0x1F;
g = (*palette >> 5) & 0x1F;
b = (*palette >> 10) & 0x1F;
-
- r *= 0x4C;
- r += g * 0x97;
- r += b * 0x1D;
-
+
+ r = r * Q_8_8(0.2969);
+ r += g * Q_8_8(0.5899);
+ r += b * Q_8_8(0.1133);
+
gray = r >> 8;
-
+
*palette++ = gray << 10 | gray << 5 | gray;
}
- return;
}
void TintPalette_GrayScale2(u16 *palette, u16 count)
{
- s32 r;
- s32 g;
- s32 b;
- s32 gray;
+ int r;
+ int g;
+ int b;
+ u32 gray;
int i;
for (i = 0; i < count; i++)
@@ -874,62 +874,60 @@ void TintPalette_GrayScale2(u16 *palette, u16 count)
r = *palette & 0x1F;
g = (*palette >> 5) & 0x1F;
b = (*palette >> 10) & 0x1F;
-
- r *= 0x4C;
- r += g * 0x97;
- r += b * 0x1D;
-
+
+ r = r * Q_8_8(0.2969);
+ r += g * Q_8_8(0.5899);
+ r += b * Q_8_8(0.1133);
+
gray = r >> 8;
-
- if ((u32)gray > 0x1F)
+
+ if (gray > 0x1F)
gray = 0x1F;
-
- gray = gUnknown_0852489C[gray];
-
+
+ gray = sRoundedDownGrayscaleMap[gray];
+
*palette++ = gray << 10 | gray << 5 | gray;
}
- return;
}
#ifdef NONMATCHING
void TintPalette_SepiaTone(u16 *palette, u16 count)
{
- s32 r;
- s32 g;
- s32 b;
+ int red;
+ int green;
+ int blue;
u32 gray;
u32 sepia;
s8 r2;
s8 g2;
s8 b2;
-
+
int i;
for (i = 0; i < count; i++)
{
r = *palette & 0x1F;
g = (*palette >> 5) & 0x1F;
b = (*palette >> 10) & 0x1F;
-
+
r *= 0x4C;
r += g * 0x97;
r += b * 0x1D;
-
+
gray = (s32)(r >> 8);
-
+
sepia = (gray * 0x133);
-
+
r2 = (u16)sepia >> 8;
-
+
g2 = gray;
-
+
b2 = (gray * 15);
-
+
if (r2 > 0x1F)
r2 = 0x1F;
-
+
*palette++ = b2 << 10 | g2 << 5 | r2;
}
- return;
}
#else
__attribute__((naked))
@@ -995,7 +993,7 @@ _080A2BA2:\n\
#endif // NONMATCHING
#ifdef NONMATCHING
-void sub_80A2BAC(u16 *palette, u16 count, u16 a3, u16 a4, u16 a5)
+void TintPalette_CustomTone(u16 *palette, u16 count, u16 a3, u16 a4, u16 a5)
{
s32 r;
s32 g;
@@ -1011,35 +1009,35 @@ void sub_80A2BAC(u16 *palette, u16 count, u16 a3, u16 a4, u16 a5)
r = *palette & 0x1F;
g = (*palette >> 5) & 0x1F;
b = (*palette >> 10) & 0x1F;
-
+
r *= 0x4C;
r += g * 0x97;
r += b * 0x1D;
-
+
gray = r >> 8;
-
+
r2 = (u16)(gray * a3) >> 8;
-
+
g2 = (u16)(gray * a4) >> 8;
-
+
b2 = (u16)(gray * a5) >> 8;
-
+
if (r2 > 0x1F)
r2 = 0x1F;
-
+
if (g2 > 0x1F)
g2 = 0x1F;
-
+
if (b2 > 0x1F)
b2 = 0x1F;
-
+
*palette++ = b2 << 10 | g2 << 5 | r2;
}
return;
}
#else
__attribute__((naked))
-void sub_80A2BAC(u16 *palette, u16 count, u16 a3, u16 a4, u16 a5)
+void TintPalette_CustomTone(u16 *palette, u16 count, u16 a3, u16 a4, u16 a5)
{
asm("push {r4-r7,lr}\n\
mov r7, r9\n\
@@ -1153,7 +1151,7 @@ void sub_80A2C44(u32 a1, s8 a2, u8 a3, u8 a4, u16 a5, u8 a6, u8 a7)
gTasks[taskId].func(taskId);
}
-u32 sub_80A2CF8(u8 var)
+bool32 sub_80A2CF8(u8 var)
{
int i;
@@ -1181,7 +1179,7 @@ void sub_80A2D54(u8 taskId)
{
u32 wordVar;
s16 *data;
- u16 temp;
+ s16 temp;
data = gTasks[taskId].data;
wordVar = GetWordTaskArg(taskId, 5);
@@ -1191,7 +1189,7 @@ void sub_80A2D54(u8 taskId)
data[4] = 0;
BlendPalettes(wordVar, data[0], data[7]);
temp = data[1];
- if (data[0] == (s16)temp)
+ if (data[0] == temp)
{
DestroyTask(taskId);
}
@@ -1200,12 +1198,12 @@ void sub_80A2D54(u8 taskId)
data[0] += data[2];
if (data[2] >= 0)
{
- if (data[0] < (s16)temp)
+ if (data[0] < temp)
{
return;
}
}
- else if (data[0] > (s16)temp)
+ else if (data[0] > temp)
{
return;
}
diff --git a/src/pokeball.c b/src/pokeball.c
index 127ba8e9d..b48e55135 100644
--- a/src/pokeball.c
+++ b/src/pokeball.c
@@ -21,7 +21,7 @@ extern u8 gBankTarget;
extern u16 gBattlePartyID[];
extern u8 gBankSpriteIds[];
extern u8 gHealthBoxesIds[];
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
// this file's functions
static void Task_DoPokeballSendOutAnim(u8 taskId);
@@ -773,11 +773,11 @@ static void SpriteCB_ReleaseMonFromBall(struct Sprite *sprite)
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
{
if (IsBGMPlaying())
- m4aMPlayStop(&gMPlay_BGM);
+ m4aMPlayStop(&gMPlayInfo_BGM);
}
else
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 128);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 128);
}
}
@@ -885,7 +885,7 @@ static void sub_80760F8(struct Sprite *sprite)
{
gDoingBattleAnim = FALSE;
m4aMPlayAllStop();
- PlaySE(BGM_FANFA5);
+ PlaySE(MUS_FANFA5);
}
else if (sprite->data[4] == 315)
{
diff --git a/src/pokeblock.c b/src/pokeblock.c
new file mode 100644
index 000000000..737f2c6f3
--- /dev/null
+++ b/src/pokeblock.c
@@ -0,0 +1,1337 @@
+#include "global.h"
+#include "pokeblock.h"
+#include "bg.h"
+#include "strings.h"
+#include "text.h"
+#include "menu.h"
+#include "task.h"
+#include "menu_helpers.h"
+#include "new_menu_helpers.h"
+#include "pokemon.h"
+#include "graphics.h"
+#include "malloc.h"
+#include "main.h"
+#include "battle.h"
+#include "battle_controllers.h"
+#include "palette.h"
+#include "unknown_task.h"
+#include "list_menu.h"
+#include "gpu_regs.h"
+#include "decompress.h"
+#include "international_string_util.h"
+#include "item.h"
+#include "constants/items.h"
+#include "string_util.h"
+#include "constants/songs.h"
+#include "sound.h"
+#include "berry.h"
+#include "menu_indicators.h"
+#include "event_data.h"
+#include "battle_message.h"
+#include "safari_zone.h"
+#include "lilycove_lady.h"
+
+#define POKEBLOCK_MAX_FEEL 99
+#define FIELD_E75_COUNT 7
+
+struct PokeblockMenuStruct
+{
+ u8 tilemap[0x800];
+ void (*callbackOnUse)(void);
+ const u8 *pokeblockOptionsIds;
+ u8 optionsNo;
+ u8 caseId;
+ u8 itemsNo;
+ u8 maxShowed;
+ struct ListMenuItem items[POKEBLOCKS_COUNT + 1];
+ u8 menuItemsStrings[POKEBLOCKS_COUNT + 1][0x20]; // + 1 because of STOW CASE item
+ u8 pokeblockCaseSpriteId;
+ u8 field_E75[FIELD_E75_COUNT];
+ u8 unkTaskId;
+ bool8 isSwapping;
+ s16 gfxState;
+ u8 unused[8];
+};
+
+struct PokeblockSavedData
+{
+ void (*callback)(void);
+ u16 lastItemPos;
+ u16 lastItemPage;
+};
+
+enum
+{
+ PKBL_USE_ON_FIELD,
+ PKBL_TOSS,
+ PKBL_CANCEL,
+ PKBL_USE_IN_BATTLE,
+ PKBL_USE_ON_FEEDER,
+ PKBL_GIVE_TO_LADY
+};
+
+extern u16 gSpecialVar_ItemId;
+extern void (*gFieldCallback)(void);
+
+extern const u16 gUnknown_0860F074[];
+
+extern void c2_exit_to_overworld_2_switch(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);
+extern void sub_80AF168(void);
+
+// this file's functions
+static void CB2_InitPokeblockMenu(void);
+static bool8 InitPokeblockMenu(void);
+static bool8 LoadPokeblockMenuGfx(void);
+static void HandleInitBackgrounds(void);
+static void HandleInitWindows(void);
+static void SetMenuItemsCountAndMaxShowed(void);
+static void sub_81362E0(void);
+static void sub_8136344(void);
+static void HandlePokeblockListMenuItems(void);
+static void sub_81363BC(void);
+static void MovePokeblockMenuCursor(u32 pkblId, bool8 arg1, struct ListMenu *arg2);
+static void PutPokeblockInfoText(void);
+static void HandlePokeblockMenuCursor(u16 cursorPos, u16 arg1);
+static void PutPokeblockListMenuString(u8 *dst, u16 pkblId);
+static void Task_HandlePokeblockMenuInput(u8 taskId);
+static void PokeblockAction_UseOnField(u8 taskId);
+static void PokeblockAction_Toss(u8 taskId);
+static void PokeblockAction_Cancel(u8 taskId);
+static void PokeblockAction_UseInBattle(u8 taskId);
+static void PokeblockAction_UseOnPokeblockFeeder(u8 taskId);
+static void PokeblockAction_GiveToContestLady(u8 taskId);
+static void TossPokeblockChoice_Yes(u8 taskId);
+static void TossPokeblockChoice_No(u8 taskId);
+static void Task_FreeDataAndExitPokeblockCase(u8 taskId);
+static void Task_HandlePokeblockOptionsInput(u8 taskId);
+static void PutPokeblockOptionsWindow(u8 taskId);
+static void Task_HandlePokeblocksSwapInput(u8 taskId);
+static void sub_8136470(struct Sprite *sprite);
+static void sub_8135FCC(s32 pkblId);
+static void HandlePokeblocksSwap(u8 taskId, bool8 noSwap);
+static void UsePokeblockOnField(void);
+static void ReturnToPokeblockCaseOnField(void);
+static void CreateTossPokeblockYesNoMenu(u8 taskId);
+static void HandleErasePokeblock(u8 taskId);
+
+// ram variables
+EWRAM_DATA static struct PokeblockSavedData sSavedPokeblockData = {0};
+EWRAM_DATA static struct PokeblockMenuStruct *sPokeblockMenu = NULL;
+
+// const rom data
+const s8 gPokeblockFlavorCompatibilityTable[] =
+{
+ // Cool, Beauty, Cute, Smart, Tough
+ 0, 0, 0, 0, 0, // Hardy
+ 1, 0, 0, 0, -1, // Lonely
+ 1, 0, -1, 0, 0, // Brave
+ 1, -1, 0, 0, 0, // Adamant
+ 1, 0, 0, -1, 0, // Naughty
+ -1, 0, 0, 0, 1, // Bold
+ 0, 0, 0, 0, 0, // Docile
+ 0, 0, -1, 0, 1, // Relaxed
+ 0, -1, 0, 0, 1, // Impish
+ 0, 0, 0, -1, 1, // Lax
+ -1, 0, 1, 0, 0, // Timid
+ 0, 0, 1, 0, -1, // Hasty
+ 0, 0, 0, 0, 0, // Serious
+ 0, -1, 1, 0, 0, // Jolly
+ 0, 0, 1, -1, 0, // Naive
+ -1, 1, 0, 0, 0, // Modest
+ 0, 1, 0, 0, -1, // Mild
+ 0, 1, -1, 0, 0, // Quiet
+ 0, 0, 0, 0, 0, // Bashful
+ 0, 1, 0, -1, 0, // Rash
+ -1, 0, 0, 1, 0, // Calm
+ 0, 0, 0, 1, -1, // Gentle
+ 0, 0, -1, 1, 0, // Sassy
+ 0, -1, 0, 1, 0, // Careful
+ 0, 0, 0, 0, 0 // Quirky
+};
+
+static const struct BgTemplate sBgTemplatesForPokeblockMenu[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 3,
+ .mapBaseIndex = 29,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0
+ }
+};
+
+const u8 *const gPokeblockNames[] =
+{
+ NULL,
+ gText_RedPokeblock,
+ gText_BluePokeblock,
+ gText_PinkPokeblock,
+ gText_GreenPokeblock,
+ gText_YellowPokeblock,
+ gText_PurplePokeblock,
+ gText_IndigoPokeblock,
+ gText_BrownPokeblock,
+ gText_LiteBluePokeblock,
+ gText_OlivePokeblock,
+ gText_GrayPokeblock,
+ gText_BlackPokeblock,
+ gText_WhitePokeblock,
+ gText_GoldPokeblock
+};
+
+static const struct MenuAction sPokeblockMenuActions[] =
+{
+ {gMenuText_Use, PokeblockAction_UseOnField},
+ {gMenuText_Toss, PokeblockAction_Toss},
+ {gText_Cancel2, PokeblockAction_Cancel},
+ {gMenuText_Use, PokeblockAction_UseInBattle},
+ {gMenuText_Use, PokeblockAction_UseOnPokeblockFeeder},
+ {gMenuText_Give2, PokeblockAction_GiveToContestLady},
+};
+
+static const u8 sActionsOnField[] = {PKBL_USE_ON_FIELD, PKBL_TOSS, PKBL_CANCEL};
+static const u8 sActionsInBattle[] = {PKBL_USE_IN_BATTLE, PKBL_CANCEL};
+static const u8 sActionsOnPokeblockFeeder[] = {PKBL_USE_ON_FEEDER, PKBL_CANCEL};
+static const u8 sActionsWhenGivingToLady[] = {PKBL_GIVE_TO_LADY, PKBL_CANCEL};
+
+static const struct YesNoFuncTable sTossYesNoFuncTable = {TossPokeblockChoice_Yes, TossPokeblockChoice_No};
+
+static const u8 sContestStatsMonData[] = {MON_DATA_COOL, MON_DATA_BEAUTY, MON_DATA_CUTE, MON_DATA_SMART, MON_DATA_TOUGH};
+
+static const struct OamData sOamData_PokeblockCase =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sSpriteAnim_PokeblockCase[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_PokeblockCase[] =
+{
+ sSpriteAnim_PokeblockCase
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_85B26C8[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, -2, 2),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 4),
+ AFFINEANIMCMD_FRAME(0, 0, -2, 4),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 2),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85B26F0[] =
+{
+ sSpriteAffineAnim_85B26C8
+};
+
+const struct CompressedSpriteSheet gPokeblockCase_SpriteSheet =
+{
+ gMenuPokeblockDevice_Gfx, 0x800, GFX_TAG_POKEBLOCK_CASE
+};
+
+const struct CompressedSpritePalette gPokeblockCase_SpritePal =
+{
+ gMenuPokeblockDevice_Pal, GFX_TAG_POKEBLOCK_CASE
+};
+
+static const struct SpriteTemplate sSpriteTemplate_PokeblockCase =
+{
+ GFX_TAG_POKEBLOCK_CASE,
+ GFX_TAG_POKEBLOCK_CASE,
+ &sOamData_PokeblockCase,
+ sSpriteAnimTable_PokeblockCase,
+ NULL,
+ gDummySpriteAffineAnimTable,
+ SpriteCallbackDummy
+};
+
+static const struct TextColor sTextColorInPokeblockMenu = {0, 2, 3};
+
+static const struct Pokeblock sFavoritePokeblocksTable[] =
+{
+ { PBLOCK_CLR_RED, 20, 0, 0, 0, 0, 20},
+ { PBLOCK_CLR_BLUE, 0, 20, 0, 0, 0, 20},
+ { PBLOCK_CLR_PINK, 0, 0, 20, 0, 0, 20},
+ { PBLOCK_CLR_GREEN, 0, 0, 0, 20, 0, 20},
+ { PBLOCK_CLR_YELLOW, 0, 0, 0, 0, 20, 20}
+};
+
+static const struct WindowTemplate sWindowTemplatesForPokeblockMenu[] =
+{
+ {0, 2, 1, 9, 2, 0xF, 0x1E},
+ {0, 0xF, 1, 0xE, 0x12, 0xF, 0x30},
+ {0, 2, 0xD, 5, 2, 0xF, 0x12C},
+ {0, 2, 0xF, 5, 2, 0xF, 0x136},
+ {0, 2, 0x11, 5, 2, 0xF, 0x140},
+ {0, 8, 0xD, 5, 2, 0xF, 0x14A},
+ {0, 8, 0xF, 5, 2, 0xF, 0x154},
+ {0, 0xB, 0x11, 2, 2, 0xF, 0x15E},
+ {1, 7, 5, 6, 6, 0xF, 0x162},
+ {1, 7, 7, 6, 4, 0xF, 0x186},
+ {1, 2, 0xF, 0x1B, 4, 0xF, 0x19E},
+ DUMMY_WIN_TEMPLATE
+};
+
+static const struct WindowTemplate sTossPkblockWindowTemplate = {1, 0x15, 9, 5, 4, 0xF, 0x20A};
+
+static const struct ListMenuTemplate sPokeblockListMenuTemplate =
+{
+ .items = NULL,
+ .moveCursorFunc = MovePokeblockMenuCursor,
+ .unk_08 = NULL,
+ .totalItems = 0,
+ .maxShowed = 0,
+ .unk_10 = 1,
+ .unk_11 = 0,
+ .unk_12 = 1,
+ .cursor_Y = 0,
+ .upText_Y = 1,
+ .cursorColor = 2,
+ .fillColor = 0,
+ .cursorShadowColor = 3,
+ .unk_16_0 = FALSE,
+ .spaceBetweenItems = 32,
+ .unk_16_7 = FALSE,
+ .unk_17_0 = 1,
+ .cursorKind = 1
+};
+
+// code
+void OpenPokeblockCase(u8 caseId, void (*callback)(void))
+{
+ sPokeblockMenu = Alloc(sizeof(*sPokeblockMenu));
+ sPokeblockMenu->caseId = caseId;
+ sPokeblockMenu->callbackOnUse = NULL;
+ sPokeblockMenu->unkTaskId = 0xFF;
+ sPokeblockMenu->isSwapping = FALSE;
+ sSavedPokeblockData.callback = callback;
+
+ switch (sPokeblockMenu->caseId)
+ {
+ case PBLOCK_CASE_BATTLE:
+ sPokeblockMenu->pokeblockOptionsIds = sActionsInBattle;
+ sPokeblockMenu->optionsNo = ARRAY_COUNT(sActionsInBattle);
+ break;
+ case PBLOCK_CASE_FEEDER:
+ sPokeblockMenu->pokeblockOptionsIds = sActionsOnPokeblockFeeder;
+ sPokeblockMenu->optionsNo = ARRAY_COUNT(sActionsOnPokeblockFeeder);
+ break;
+ case PBLOCK_CASE_GIVE:
+ sPokeblockMenu->pokeblockOptionsIds = sActionsWhenGivingToLady;
+ sPokeblockMenu->optionsNo = ARRAY_COUNT(sActionsWhenGivingToLady);
+ break;
+ default:
+ sPokeblockMenu->pokeblockOptionsIds = sActionsOnField;
+ sPokeblockMenu->optionsNo = ARRAY_COUNT(sActionsOnField);
+ break;
+ }
+
+ SetMainCallback2(CB2_InitPokeblockMenu);
+}
+
+void OpenPokeblockCaseInBattle(void)
+{
+ OpenPokeblockCase(PBLOCK_CASE_BATTLE, SetCB2ToReshowScreenAfterMenu2);
+}
+
+void OpenPokeblockCaseOnFeeder(void)
+{
+ OpenPokeblockCase(PBLOCK_CASE_FEEDER, c2_exit_to_overworld_2_switch);
+}
+
+static void CB2_PokeblockMenu(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ do_scheduled_bg_tilemap_copies_to_vram();
+ UpdatePaletteFade();
+}
+
+static void VBlankCB_PokeblockMenu(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void CB2_InitPokeblockMenu(void)
+{
+ while (1)
+ {
+ if (sub_81221EC() == TRUE)
+ break;
+ if (InitPokeblockMenu() == TRUE)
+ break;
+ if (sub_81221AC() == TRUE)
+ break;
+ }
+}
+
+static bool8 InitPokeblockMenu(void)
+{
+ u8 taskId;
+
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankHBlankCallbacksToNull();
+ clear_scheduled_bg_copies_to_vram();
+ gMain.state++;
+ break;
+ case 1:
+ remove_some_task();
+ gMain.state++;
+ break;
+ case 2:
+ FreeAllSpritePalettes();
+ gMain.state++;
+ break;
+ case 3:
+ ResetPaletteFade();
+ gPaletteFade.bufferTransferDisabled = 1;
+ gMain.state++;
+ break;
+ case 4:
+ ResetSpriteData();
+ gMain.state++;
+ break;
+ case 5:
+ if (sPokeblockMenu->caseId != PBLOCK_CASE_BATTLE)
+ ResetTasks();
+ gMain.state++;
+ break;
+ case 6:
+ HandleInitBackgrounds();
+ sPokeblockMenu->gfxState = 0;
+ gMain.state++;
+ break;
+ case 7:
+ if (!LoadPokeblockMenuGfx())
+ return FALSE;
+ gMain.state++;
+ break;
+ case 8:
+ SetMenuItemsCountAndMaxShowed();
+ sub_81362E0();
+ sub_8136344();
+ gMain.state++;
+ break;
+ case 9:
+ sPokeblockMenu->pokeblockCaseSpriteId = CreatePokeblockCaseSprite(56, 64, 0);
+ gMain.state++;
+ break;
+ case 10:
+ sub_8122344(&sPokeblockMenu->field_E75, FIELD_E75_COUNT);
+ gMain.state++;
+ break;
+ case 11:
+ HandlePokeblockMenuCursor(sSavedPokeblockData.lastItemPos, 0x1005);
+ gMain.state++;
+ break;
+ case 12:
+ HandleInitWindows();
+ gMain.state++;
+ break;
+ case 13:
+ HandlePokeblockListMenuItems();
+ gMain.state++;
+ break;
+ case 14:
+ sub_81363BC();
+ gMain.state++;
+ break;
+ case 15:
+ taskId = CreateTask(Task_HandlePokeblockMenuInput, 0);
+ gTasks[taskId].data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sSavedPokeblockData.lastItemPage, sSavedPokeblockData.lastItemPos);
+ gMain.state++;
+ break;
+ case 16:
+ PutPokeblockInfoText();
+ gMain.state++;
+ break;
+ case 17:
+ BlendPalettes(-1, 0x10, 0);
+ gMain.state++;
+ break;
+ case 18:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gPaletteFade.bufferTransferDisabled = 0;
+ gMain.state++;
+ break;
+ default:
+ SetVBlankCallback(VBlankCB_PokeblockMenu);
+ SetMainCallback2(CB2_PokeblockMenu);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void HandleInitBackgrounds(void)
+{
+ ResetVramOamAndBgCntRegs();
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, sBgTemplatesForPokeblockMenu, ARRAY_COUNT(sBgTemplatesForPokeblockMenu));
+ SetBgTilemapBuffer(2, sPokeblockMenu->tilemap);
+ ResetAllBgsCoordinates();
+ schedule_bg_copy_tilemap_to_vram(2);
+
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+
+ ShowBg(0);
+ ShowBg(1);
+ ShowBg(2);
+
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+}
+
+static bool8 LoadPokeblockMenuGfx(void)
+{
+ switch (sPokeblockMenu->gfxState)
+ {
+ case 0:
+ reset_temp_tile_data_buffers();
+ decompress_and_copy_tile_data_to_vram(2, gMenuPokeblock_Gfx, 0, 0, 0);
+ sPokeblockMenu->gfxState++;
+ break;
+ case 1:
+ if (free_temp_tile_data_buffers_if_possible() != TRUE)
+ {
+ LZDecompressWram(gMenuPokeblock_Tilemap, sPokeblockMenu->tilemap);
+ sPokeblockMenu->gfxState++;
+ }
+ break;
+ case 2:
+ LoadCompressedPalette(gMenuPokeblock_Pal, 0, 0xC0);
+ sPokeblockMenu->gfxState++;
+ break;
+ case 3:
+ LoadCompressedObjectPic(&gPokeblockCase_SpriteSheet);
+ sPokeblockMenu->gfxState++;
+ break;
+ case 4:
+ LoadCompressedObjectPalette(&gPokeblockCase_SpritePal);
+ sPokeblockMenu->gfxState++;
+ break;
+ case 5:
+ LoadListMenuArrowsGfx();
+ sPokeblockMenu->gfxState = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void HandleInitWindows(void)
+{
+ u8 i;
+
+ InitWindows(sWindowTemplatesForPokeblockMenu);
+ DeactivateAllTextPrinters();
+ sub_809882C(0, 1, 0xE0);
+ copy_textbox_border_tile_patterns_to_vram(0, 0xA, 0xD0);
+ LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
+
+ for (i = 0; i < ARRAY_COUNT(sWindowTemplatesForPokeblockMenu) - 1; i++)
+ {
+ FillWindowPixelBuffer(i, 0);
+ }
+
+ schedule_bg_copy_tilemap_to_vram(0);
+ schedule_bg_copy_tilemap_to_vram(1);
+}
+
+static void PrintOnPokeblockWindow(u8 windowId, const u8 *string, s32 x)
+{
+ AddTextPrinterParametrized2(windowId, 1, x, 1, 0, 0, &sTextColorInPokeblockMenu, 0, string);
+}
+
+static void PutPokeblockInfoText(void)
+{
+ u8 i;
+
+ const u8 *itemName = ItemId_GetItem(ITEM_POKEBLOCK_CASE)->name;
+ PrintOnPokeblockWindow(0, itemName, GetStringCenterAlignXOffset(1, itemName, 0x48));
+
+ PrintOnPokeblockWindow(2, gText_Spicy, 0);
+ PrintOnPokeblockWindow(3, gText_Dry, 0);
+ PrintOnPokeblockWindow(4, gText_Sweet, 0);
+ PrintOnPokeblockWindow(5, gText_Bitter, 0);
+ PrintOnPokeblockWindow(6, gText_Sour, 0);
+
+ for (i = 0; i < 8; i++)
+ {
+ PutWindowTilemap(i);
+ }
+}
+
+static void HandlePokeblockListMenuItems(void)
+{
+ u16 i;
+
+ for (i = 0; i < sPokeblockMenu->itemsNo - 1; i++)
+ {
+ PutPokeblockListMenuString(sPokeblockMenu->menuItemsStrings[i], i);
+ sPokeblockMenu->items[i].name = sPokeblockMenu->menuItemsStrings[i];
+ sPokeblockMenu->items[i].id = i;
+ }
+
+ StringCopy(sPokeblockMenu->menuItemsStrings[i], gText_StowCase);
+ sPokeblockMenu->items[i].name = sPokeblockMenu->menuItemsStrings[i];
+ sPokeblockMenu->items[i].id = LIST_B_PRESSED;
+
+ gMultiuseListMenuTemplate = sPokeblockListMenuTemplate;
+ gMultiuseListMenuTemplate.unk_17_0 = 7;
+ gMultiuseListMenuTemplate.totalItems = sPokeblockMenu->itemsNo;
+ gMultiuseListMenuTemplate.items = sPokeblockMenu->items;
+ gMultiuseListMenuTemplate.maxShowed = sPokeblockMenu->maxShowed;
+}
+
+static void PutPokeblockListMenuString(u8 *dst, u16 pkblId)
+{
+ struct Pokeblock *pkblock = &gSaveBlock1Ptr->pokeblocks[pkblId];
+ u8 *txtPtr = StringCopy(dst, gPokeblockNames[pkblock->color]);
+
+ *(txtPtr++) = EXT_CTRL_CODE_BEGIN;
+ *(txtPtr++) = 0x12;
+ *(txtPtr++) = 0x57;
+
+ ConvertIntToDecimalStringN(gStringVar1, GetHighestPokeblocksFlavorLevel(pkblock), STR_CONV_MODE_LEFT_ALIGN, 3);
+ StringExpandPlaceholders(txtPtr, gText_LvVar1);
+}
+
+static void MovePokeblockMenuCursor(u32 pkblId, bool8 arg1, struct ListMenu *arg2)
+{
+ if (arg1 != TRUE)
+ {
+ PlaySE(SE_SELECT);
+ gSprites[sPokeblockMenu->pokeblockCaseSpriteId].callback = sub_8136470;
+ }
+
+ if (!sPokeblockMenu->isSwapping)
+ sub_8135FCC(pkblId);
+}
+
+static void sub_8135FCC(s32 pkblId)
+{
+ u8 i;
+ struct Pokeblock *pokeblock;
+ u16 rectTilemapSrc[2];
+
+ FillWindowPixelBuffer(7, 0);
+
+ if (pkblId != LIST_B_PRESSED)
+ {
+ pokeblock = &gSaveBlock1Ptr->pokeblocks[pkblId];
+ rectTilemapSrc[0] = 0x17;
+ rectTilemapSrc[1] = 0x18;
+ for (i = 0; i < FLAVOR_COUNT; i++)
+ {
+ if (GetPokeblockData(pokeblock, PBLOCK_SPICY + i) > 0)
+ {
+ rectTilemapSrc[0] = (i << 0xC) + 0x17;
+ rectTilemapSrc[1] = (i << 0xC) + 0x18;
+ }
+ else
+ {
+ rectTilemapSrc[0] = 0xF;
+ rectTilemapSrc[1] = 0xF;
+ }
+ CopyToBgTilemapBufferRect(2, rectTilemapSrc, (i / 3 * 6) + 1, (i % 3 * 2) + 13, 1, 2);
+ }
+ ConvertIntToDecimalStringN(gStringVar1, GetPokeblocksFeel(pokeblock), STR_CONV_MODE_RIGHT_ALIGN, 2);
+ PrintOnPokeblockWindow(7, gStringVar1, 4);
+ }
+ else
+ {
+ rectTilemapSrc[0] = 0xF;
+ rectTilemapSrc[1] = 0xF;
+
+ for (i = 0; i < FLAVOR_COUNT; i++)
+ {
+ CopyToBgTilemapBufferRect(2, rectTilemapSrc, (i / 3 * 6) + 1, (i % 3 * 2) + 13, 1, 2);
+ }
+ CopyWindowToVram(7, 2);
+ }
+
+ schedule_bg_copy_tilemap_to_vram(0);
+ schedule_bg_copy_tilemap_to_vram(2);
+}
+
+static void HandlePokeblockMenuCursor(u16 cursorPos, u16 arg1)
+{
+ FillBgTilemapBufferRect_Palette0(2, arg1, 0xF, (cursorPos * 2) + 1, 0xE, 2);
+ schedule_bg_copy_tilemap_to_vram(2);
+}
+
+static void CompactPokeblockSlots(void)
+{
+ u16 i, j;
+
+ for (i = 0; i < POKEBLOCKS_COUNT - 1; i++)
+ {
+ for (j = i + 1; j < POKEBLOCKS_COUNT; j++)
+ {
+ if (gSaveBlock1Ptr->pokeblocks[i].color == 0)
+ {
+ struct Pokeblock temp = gSaveBlock1Ptr->pokeblocks[i];
+ gSaveBlock1Ptr->pokeblocks[i] = gSaveBlock1Ptr->pokeblocks[j];
+ gSaveBlock1Ptr->pokeblocks[j] = temp;
+ }
+ }
+ }
+}
+
+static void SwapSortPokeblocksInternalData(u32 id1, u32 id2)
+{
+ s16 i, count;
+ struct Pokeblock *pokeblocks = gSaveBlock1Ptr->pokeblocks;
+ struct Pokeblock *copyPokeblock1;
+
+ if (id1 == id2)
+ return;
+
+ copyPokeblock1 = Alloc(sizeof(struct Pokeblock));
+ *copyPokeblock1 = pokeblocks[id1];
+
+ if (id2 > id1)
+ {
+ id2--;
+ for (count = id2, i = id1; i < count; i++)
+ pokeblocks[i] = pokeblocks[i + 1];
+ }
+ else
+ {
+ for (count = id2, i = id1; i > count; i--)
+ pokeblocks[i] = pokeblocks[i - 1];
+ }
+
+ pokeblocks[id2] = *copyPokeblock1;
+ Free(copyPokeblock1);
+}
+
+void ResetPokeblockScrollPositions(void)
+{
+ sSavedPokeblockData.lastItemPos = 0;
+ sSavedPokeblockData.lastItemPage = 0;
+}
+
+static void SetMenuItemsCountAndMaxShowed(void)
+{
+ u16 i;
+
+ CompactPokeblockSlots();
+
+ for (sPokeblockMenu->itemsNo = 0, i = 0; i < POKEBLOCKS_COUNT; i++)
+ {
+ if (gSaveBlock1Ptr->pokeblocks[i].color != 0)
+ sPokeblockMenu->itemsNo++;
+ }
+
+ sPokeblockMenu->itemsNo++; // STOW CASE menu item
+
+ if (sPokeblockMenu->itemsNo > 9)
+ sPokeblockMenu->maxShowed = 9;
+ else
+ sPokeblockMenu->maxShowed = sPokeblockMenu->itemsNo;
+}
+
+static void sub_81362E0(void)
+{
+ if (sSavedPokeblockData.lastItemPage != 0)
+ {
+ if (sSavedPokeblockData.lastItemPage + sPokeblockMenu->maxShowed > sPokeblockMenu->itemsNo)
+ sSavedPokeblockData.lastItemPage = sPokeblockMenu->itemsNo - sPokeblockMenu->maxShowed;
+ }
+
+ if (sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos >= sPokeblockMenu->itemsNo)
+ {
+ if (sPokeblockMenu->itemsNo == 0)
+ sSavedPokeblockData.lastItemPos = 0;
+ else
+ sSavedPokeblockData.lastItemPos = sPokeblockMenu->itemsNo - 1;
+ }
+}
+
+static void sub_8136344(void)
+{
+ if (sSavedPokeblockData.lastItemPos > 4)
+ {
+ u8 i;
+
+ for (i = 0;
+ (i < sSavedPokeblockData.lastItemPos - 4) && (sSavedPokeblockData.lastItemPage + sPokeblockMenu->maxShowed != sPokeblockMenu->itemsNo);
+ sSavedPokeblockData.lastItemPos--, sSavedPokeblockData.lastItemPage++, i++);
+ }
+}
+
+static void sub_81363BC(void)
+{
+ if (sPokeblockMenu->unkTaskId == 0xFF)
+ {
+ sPokeblockMenu->unkTaskId = AddScrollIndicatorArrowPairParametrized(2, 0xB0, 8, 0x98, sPokeblockMenu->itemsNo - sPokeblockMenu->maxShowed,
+ 0x456, 0x456, &sSavedPokeblockData.lastItemPage);
+ }
+}
+
+static void sub_8136418(void)
+{
+ if (sPokeblockMenu->unkTaskId != 0xFF)
+ {
+ RemoveScrollIndicatorArrowPair(sPokeblockMenu->unkTaskId);
+ sPokeblockMenu->unkTaskId = 0xFF;
+ }
+}
+
+u8 CreatePokeblockCaseSprite(s16 x, s16 y, u8 subpriority)
+{
+ return CreateSprite(&sSpriteTemplate_PokeblockCase, x, y, subpriority);
+}
+
+static void sub_8136470(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 1)
+ sprite->data[0] = 0;
+
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->oam.affineMode = 1;
+ sprite->affineAnims = sSpriteAffineAnimTable_85B26F0;
+ InitSpriteAffineAnim(sprite);
+ sprite->data[0] = 1;
+ sprite->data[1] = 0;
+ break;
+ case 1:
+ if (++sprite->data[1] > 11)
+ {
+ sprite->oam.affineMode = 0;
+ sprite->data[0] = 0;
+ sprite->data[1] = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->callback = SpriteCallbackDummy;
+ }
+ break;
+ }
+}
+
+static void FadePaletteAndSetTaskToClosePokeblockCase(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskId].func = Task_FreeDataAndExitPokeblockCase;
+}
+
+static void Task_FreeDataAndExitPokeblockCase(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (!gPaletteFade.active)
+ {
+ if (sPokeblockMenu->caseId == PBLOCK_CASE_FEEDER || sPokeblockMenu->caseId == PBLOCK_CASE_GIVE)
+ gFieldCallback = sub_80AF168;
+
+ sub_81AE6C8(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ sub_8136418();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+
+ if (sPokeblockMenu->callbackOnUse != NULL)
+ SetMainCallback2(sPokeblockMenu->callbackOnUse);
+ else
+ SetMainCallback2(sSavedPokeblockData.callback);
+
+ FreeAllWindowBuffers();
+ Free(sPokeblockMenu);
+ DestroyTask(taskId);
+ }
+}
+
+static void Task_HandlePokeblockMenuInput(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (!gPaletteFade.active && sub_81221EC() != TRUE)
+ {
+ if (gMain.newKeys & SELECT_BUTTON)
+ {
+ sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ if (sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos != sPokeblockMenu->itemsNo - 1)
+ {
+ PlaySE(SE_SELECT);
+ HandlePokeblockMenuCursor(sSavedPokeblockData.lastItemPos, 0x2005);
+ data[2] = sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos;
+ sPokeblockMenu->isSwapping = TRUE;
+ gTasks[taskId].func = Task_HandlePokeblocksSwapInput;
+ }
+ }
+ else
+ {
+ u16 oldPosition = sSavedPokeblockData.lastItemPos;
+ s32 itemId = ListMenuHandleInputGetItemId(data[0]);
+
+ sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ if (oldPosition != sSavedPokeblockData.lastItemPos)
+ {
+ HandlePokeblockMenuCursor(oldPosition, 5);
+ HandlePokeblockMenuCursor(sSavedPokeblockData.lastItemPos, 0x1005);
+ }
+
+ switch (itemId)
+ {
+ case LIST_NOTHING_CHOSEN:
+ break;
+ case LIST_B_PRESSED:
+ PlaySE(SE_SELECT);
+ gSpecialVar_Result = 0xFFFF;
+ gSpecialVar_ItemId = 0;
+ FadePaletteAndSetTaskToClosePokeblockCase(taskId);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ gSpecialVar_ItemId = itemId;
+ PutPokeblockOptionsWindow(taskId);
+ break;
+ }
+ }
+ }
+}
+
+static void Task_HandlePokeblocksSwapInput(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (sub_81221EC() == TRUE)
+ return;
+
+ if (gMain.newKeys & SELECT_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ HandlePokeblocksSwap(taskId, FALSE);
+ }
+ else
+ {
+ u16 i = sSavedPokeblockData.lastItemPage;
+ u16 var = sSavedPokeblockData.lastItemPos;
+ s32 itemId = ListMenuHandleInputGetItemId(data[0]);
+
+ sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ if (i != sSavedPokeblockData.lastItemPage || var != sSavedPokeblockData.lastItemPos)
+ {
+ for (i = 0; i < 9; i++)
+ {
+ var = i + sSavedPokeblockData.lastItemPage;
+ if (var == data[2])
+ HandlePokeblockMenuCursor(i, 0x2005);
+ else
+ HandlePokeblockMenuCursor(i, 5);
+ }
+ }
+
+ sub_81223FC(sPokeblockMenu->field_E75, FIELD_E75_COUNT, 0);
+ sub_8122448(sPokeblockMenu->field_E75, FIELD_E75_COUNT, 0x80, (sSavedPokeblockData.lastItemPos * 16) + 8);
+
+ switch (itemId)
+ {
+ case LIST_NOTHING_CHOSEN:
+ break;
+ case LIST_B_PRESSED: // same id as STOW CASE field
+ PlaySE(SE_SELECT);
+ if (gMain.newKeys & A_BUTTON)
+ HandlePokeblocksSwap(taskId, FALSE);
+ else
+ HandlePokeblocksSwap(taskId, TRUE);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ HandlePokeblocksSwap(taskId, FALSE);
+ break;
+ }
+ }
+}
+
+static void HandlePokeblocksSwap(u8 taskId, bool8 noSwap)
+{
+ u8 i;
+ s16 *data = gTasks[taskId].data;
+ u16 swappedFromId = sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos;
+
+ sPokeblockMenu->isSwapping = FALSE;
+ sub_81AE6C8(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+
+ if (!noSwap && data[2] != swappedFromId && data[2] != swappedFromId - 1)
+ {
+ SwapSortPokeblocksInternalData(data[2], swappedFromId);
+ HandlePokeblockListMenuItems();
+ }
+
+ if (data[2] < swappedFromId)
+ sSavedPokeblockData.lastItemPos--;
+
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sSavedPokeblockData.lastItemPage, sSavedPokeblockData.lastItemPos);
+ schedule_bg_copy_tilemap_to_vram(0);
+ sub_81223FC(sPokeblockMenu->field_E75, FIELD_E75_COUNT, 1);
+
+ for (i = 0; i < 9; i++)
+ HandlePokeblockMenuCursor(i, 5);
+
+ HandlePokeblockMenuCursor(sSavedPokeblockData.lastItemPos, 0x1005);
+ gTasks[taskId].func = Task_HandlePokeblockMenuInput;
+}
+
+static void PutPokeblockOptionsWindow(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (sPokeblockMenu->optionsNo == 3)
+ data[1] = 8;
+ else
+ data[1] = 9;
+
+ sub_8136418();
+ SetWindowBorderStyle(data[1], 0, 1, 0xE);
+ sub_81995E4(data[1], sPokeblockMenu->optionsNo, sPokeblockMenuActions, sPokeblockMenu->pokeblockOptionsIds);
+ InitMenuInUpperLeftCornerPlaySoundWhenAPressed(data[1], sPokeblockMenu->optionsNo, 0);
+ PutWindowTilemap(data[1]);
+ schedule_bg_copy_tilemap_to_vram(1);
+
+ gTasks[taskId].func = Task_HandlePokeblockOptionsInput;
+}
+
+static void Task_HandlePokeblockOptionsInput(u8 taskId)
+{
+ s8 itemId;
+
+ if (sub_81221EC() == TRUE)
+ return;
+
+ itemId = ProcessMenuInputNoWrapAround();
+ if (itemId == MENU_NOTHING_CHOSEN)
+ {
+ return;
+ }
+ else if (itemId == MENU_B_PRESSED)
+ {
+ PlaySE(SE_SELECT);
+ PokeblockAction_Cancel(taskId);
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ sPokeblockMenuActions[sPokeblockMenu->pokeblockOptionsIds[itemId]].func.void_u8(taskId);
+ }
+}
+
+static void PokeblockAction_UseOnField(u8 taskId)
+{
+ sPokeblockMenu->callbackOnUse = UsePokeblockOnField;
+ FadePaletteAndSetTaskToClosePokeblockCase(taskId);
+}
+
+static void UsePokeblockOnField(void)
+{
+ ChooseMonToGivePokeblock(&gSaveBlock1Ptr->pokeblocks[gSpecialVar_ItemId], ReturnToPokeblockCaseOnField);
+}
+
+static void ReturnToPokeblockCaseOnField(void)
+{
+ OpenPokeblockCase(PBLOCK_CASE_FIELD, sSavedPokeblockData.callback);
+}
+
+static void PokeblockAction_Toss(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ sub_8198070(data[1], FALSE);
+ StringCopy(gStringVar1, gPokeblockNames[gSaveBlock1Ptr->pokeblocks[gSpecialVar_ItemId].color]);
+ StringExpandPlaceholders(gStringVar4, gText_ThrowAwayVar1);
+ DisplayMessageAndContinueTask(taskId, 10, 10, 13, 1, GetPlayerTextSpeed(), gStringVar4, CreateTossPokeblockYesNoMenu);
+}
+
+static void CreateTossPokeblockYesNoMenu(u8 taskId)
+{
+ CreateYesNoMenuWithCallbacks(taskId, &sTossPkblockWindowTemplate, 1, 0, 2, 1, 0xE, &sTossYesNoFuncTable);
+}
+
+static void TossPokeblockChoice_Yes(u8 taskId)
+{
+ StringExpandPlaceholders(gStringVar4, gText_Var1ThrownAway);
+ DisplayMessageAndContinueTask(taskId, 10, 10, 13, 1, GetPlayerTextSpeed(), gStringVar4, HandleErasePokeblock);
+}
+
+static void HandleErasePokeblock(u8 taskId)
+{
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ s16 *data;
+ u16 *lastPage, *lastPos;
+
+ TryClearPokeblock(gSpecialVar_ItemId);
+ PlaySE(SE_SELECT);
+
+ lastPage = &sSavedPokeblockData.lastItemPage;
+ lastPos = &sSavedPokeblockData.lastItemPos;
+ data = gTasks[taskId].data;
+
+ sub_81AE6C8(data[0], lastPage, lastPos);
+ HandlePokeblockMenuCursor(*lastPos, 5);
+ SetMenuItemsCountAndMaxShowed();
+ sub_81362E0();
+ HandlePokeblockListMenuItems();
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *lastPage, *lastPos);
+ HandlePokeblockMenuCursor(*lastPos, 0x1005);
+ schedule_bg_copy_tilemap_to_vram(0);
+ schedule_bg_copy_tilemap_to_vram(1);
+ TossPokeblockChoice_No(taskId);
+ }
+}
+
+static void TossPokeblockChoice_No(u8 taskId)
+{
+ sub_8197DF8(10, FALSE);
+ schedule_bg_copy_tilemap_to_vram(1);
+ sub_81363BC();
+ gTasks[taskId].func = Task_HandlePokeblockMenuInput;
+}
+
+static void PokeblockAction_UseInBattle(u8 taskId)
+{
+ u8 nature = GetNature(&gEnemyParty[0]);
+ s16 gain = PokeblockGetGain(nature, &gSaveBlock1Ptr->pokeblocks[gSpecialVar_ItemId]);
+ StringCopy(gBattleTextBuff1, gPokeblockNames[gSaveBlock1Ptr->pokeblocks[gSpecialVar_ItemId].color]);
+ TryClearPokeblock(gSpecialVar_ItemId);
+
+ gSpecialVar_ItemId = gSaveBlock1Ptr->pokeblocks[gSpecialVar_ItemId].color << 8;
+ if (gain == 0)
+ gSpecialVar_ItemId += 1;
+ else if (gain > 0)
+ gSpecialVar_ItemId += 2;
+ else
+ gSpecialVar_ItemId += 3;
+
+ FadePaletteAndSetTaskToClosePokeblockCase(taskId);
+}
+
+static void PokeblockAction_UseOnPokeblockFeeder(u8 taskId)
+{
+ SafariZoneActivatePokeblockFeeder(gSpecialVar_ItemId);
+ StringCopy(gStringVar1, gPokeblockNames[gSaveBlock1Ptr->pokeblocks[gSpecialVar_ItemId].color]);
+ gSpecialVar_Result = gSpecialVar_ItemId;
+ TryClearPokeblock(gSpecialVar_ItemId);
+ gSpecialVar_ItemId = 0;
+ FadePaletteAndSetTaskToClosePokeblockCase(taskId);
+}
+
+static void PokeblockAction_GiveToContestLady(u8 taskId)
+{
+ gSpecialVar_0x8004 = GivePokeblockToContestLady(&gSaveBlock1Ptr->pokeblocks[gSpecialVar_ItemId]);
+ gSpecialVar_Result = gSpecialVar_ItemId;
+ TryClearPokeblock(gSpecialVar_ItemId);
+ gSpecialVar_ItemId = 0;
+ FadePaletteAndSetTaskToClosePokeblockCase(taskId);
+}
+
+static void PokeblockAction_Cancel(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ sub_8198070(data[1], FALSE);
+ schedule_bg_copy_tilemap_to_vram(1);
+ sub_81363BC();
+ gTasks[taskId].func = Task_HandlePokeblockMenuInput;
+}
+
+static void ClearPokeblock(u8 pkblId)
+{
+ gSaveBlock1Ptr->pokeblocks[pkblId].color = 0;
+ gSaveBlock1Ptr->pokeblocks[pkblId].spicy = 0;
+ gSaveBlock1Ptr->pokeblocks[pkblId].dry = 0;
+ gSaveBlock1Ptr->pokeblocks[pkblId].sweet = 0;
+ gSaveBlock1Ptr->pokeblocks[pkblId].bitter = 0;
+ gSaveBlock1Ptr->pokeblocks[pkblId].sour = 0;
+ gSaveBlock1Ptr->pokeblocks[pkblId].feel = 0;
+}
+
+void ClearPokeblocks(void)
+{
+ u8 i;
+
+ for (i = 0; i < POKEBLOCKS_COUNT; i++)
+ ClearPokeblock(i);
+}
+
+u8 GetHighestPokeblocksFlavorLevel(const struct Pokeblock *pokeblock)
+{
+ u8 i;
+ u8 maxFlavor = GetPokeblockData(pokeblock, PBLOCK_SPICY);
+
+ for (i = PBLOCK_SPICY; i < FLAVOR_COUNT; i++)
+ {
+ u8 currFlavor = GetPokeblockData(pokeblock, PBLOCK_SPICY + i);
+ if (maxFlavor < currFlavor)
+ maxFlavor = currFlavor;
+ }
+
+ return maxFlavor;
+}
+
+u8 GetPokeblocksFeel(const struct Pokeblock *pokeblock)
+{
+ u8 feel = GetPokeblockData(pokeblock, PBLOCK_FEEL);
+ if (feel > POKEBLOCK_MAX_FEEL)
+ feel = POKEBLOCK_MAX_FEEL;
+
+ return feel;
+}
+
+s8 GetFirstFreePokeblockSlot(void)
+{
+ u8 i;
+
+ for (i = 0; i < POKEBLOCKS_COUNT; i++)
+ {
+ if (gSaveBlock1Ptr->pokeblocks[i].color == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+bool32 AddPokeblock(const struct Pokeblock *pokeblock)
+{
+ s8 slot = GetFirstFreePokeblockSlot();
+
+ if (slot == -1)
+ {
+ return FALSE;
+ }
+ else
+ {
+ gSaveBlock1Ptr->pokeblocks[slot] = *pokeblock;
+ return TRUE;
+ }
+}
+
+bool32 TryClearPokeblock(u8 pkblId)
+{
+ if (gSaveBlock1Ptr->pokeblocks[pkblId].color == 0)
+ {
+ return FALSE;
+ }
+ else
+ {
+ ClearPokeblock(pkblId);
+ return TRUE;
+ }
+}
+
+s16 GetPokeblockData(const struct Pokeblock *pokeblock, u8 field)
+{
+ if (field == PBLOCK_COLOR)
+ return pokeblock->color;
+ if (field == PBLOCK_SPICY)
+ return pokeblock->spicy;
+ if (field == PBLOCK_DRY)
+ return pokeblock->dry;
+ if (field == PBLOCK_SWEET)
+ return pokeblock->sweet;
+ if (field == PBLOCK_BITTER)
+ return pokeblock->bitter;
+ if (field == PBLOCK_SOUR)
+ return pokeblock->sour;
+ if (field == PBLOCK_FEEL)
+ return pokeblock->feel;
+
+ return 0;
+}
+
+s16 PokeblockGetGain(u8 nature, const struct Pokeblock *pokeblock)
+{
+ u8 flavor;
+ s16 curGain, totalGain = 0;
+
+ for (flavor = 0; flavor < FLAVOR_COUNT; flavor++)
+ {
+ curGain = GetPokeblockData(pokeblock, flavor + PBLOCK_SPICY);
+ if (curGain > 0)
+ totalGain += curGain * gPokeblockFlavorCompatibilityTable[5 * nature + flavor];
+ }
+
+ return totalGain;
+}
+
+void PokeblockCopyName(const struct Pokeblock *pokeblock, u8 *dest)
+{
+ u8 color = GetPokeblockData(pokeblock, PBLOCK_COLOR);
+ StringCopy(dest, gPokeblockNames[color]);
+}
+
+bool8 CopyMonFavoritePokeblockName(u8 nature, u8 *dest)
+{
+ u8 i;
+
+ for (i = 0; i < FLAVOR_COUNT; i++)
+ {
+ if (PokeblockGetGain(nature, &sFavoritePokeblocksTable[i]) > 0)
+ {
+ StringCopy(dest, gPokeblockNames[i + 1]);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+u8 GetPokeblocksFlavor(const struct Pokeblock *pokeblock)
+{
+ s16 bestFlavor = 0;
+ s16 i;
+
+ for (i = 0; i < FLAVOR_COUNT; i++)
+ {
+ if (GetPokeblockData(pokeblock, bestFlavor + 1) < GetPokeblockData(pokeblock, i + 1))
+ bestFlavor = i;
+ }
+
+ return bestFlavor;
+}
diff --git a/src/pokeblock_feed.c b/src/pokeblock_feed.c
new file mode 100644
index 000000000..b26da118c
--- /dev/null
+++ b/src/pokeblock_feed.c
@@ -0,0 +1,1108 @@
+#include "global.h"
+#include "pokeblock.h"
+#include "sprite.h"
+#include "task.h"
+#include "palette.h"
+#include "menu.h"
+#include "malloc.h"
+#include "pokemon.h"
+#include "blend_palette.h"
+#include "main.h"
+#include "menu_helpers.h"
+#include "bg.h"
+#include "gpu_regs.h"
+#include "data2.h"
+#include "decompress.h"
+#include "event_data.h"
+#include "strings.h"
+#include "string_util.h"
+#include "new_menu_helpers.h"
+#include "party_menu.h"
+#include "m4a.h"
+#include "sound.h"
+#include "trig.h"
+#include "graphics.h"
+#include "battle.h" // to get rid of once gMonSpritesGfxPtr is put elsewhere
+
+struct PokeblockFeedStruct
+{
+ struct Sprite *monSpritePtr;
+ struct Sprite savedMonSprite;
+ u8 tilemapBuffer[0x808];
+ s16 field_850[0x200];
+ s16 field_C50[0x200];
+ u8 field_1050;
+ u8 animId;
+ u8 field_1052;
+ bool8 noMonFlip;
+ u16 species;
+ u16 field_1056;
+ u16 field_1058;
+ u8 nature;
+ u8 monSpriteId_;
+ u8 field_105C;
+ u8 monSpriteId;
+ u8 pokeblockCaseSpriteId;
+ u8 pokeblockSpriteId;
+ s16 field_1060[15];
+ s16 loadGfxState;
+ u8 unused;
+};
+
+extern u16 gSpecialVar_ItemId;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
+extern struct SpriteTemplate gUnknown_0202499C;
+
+extern const u8 gBattleTerrainPalette_Frontier[];
+extern const u8 gBattleTerrainTiles_Building[];
+extern const u8 gUnknown_08D9BA44[];
+extern const struct CompressedSpriteSheet gMonFrontPicTable[];
+extern const u16 gUnknown_0860F074[];
+
+extern bool8 sub_81221EC(void);
+extern void sub_806A068(u16, u8);
+extern void sub_809882C(u8, u16, u8);
+
+// this file's functions
+static void HandleInitBackgrounds(void);
+static void HandleInitWindows(void);
+static void LaunchPokeblockFeedTask(void);
+static void SetPokeblockSpritePal(u8 pokeblockCaseId);
+static void sub_817A5CC(void);
+static void sub_8148108(u8 spriteId, bool8 a1);
+static void DoPokeblockCaseThrowEffect(u8 spriteId, bool8 arg1);
+static void PrepareMonToMoveToPokeblock(u8 spriteId);
+static void Task_HandleMonAtePokeblock(u8 taskId);
+static void Task_PaletteFadeToReturn(u8 taskId);
+static void sub_817A634(void);
+static void sub_817A468(struct Sprite *sprite);
+static void sub_817AB68(void);
+static void sub_817AA54(void);
+static bool8 sub_817A91C(void);
+static bool8 FreeMonSpriteOamMatrix(void);
+static bool8 sub_817A9E4(void);
+static bool8 LoadMonAndSceneGfx(struct Pokemon *mon);
+static u8 CreatePokeblockSprite(void);
+static u8 CreatePokeblockCaseSpriteForFeeding(void);
+static u8 CreateMonSprite(struct Pokemon *mon);
+static void SpriteCB_ThrownPokeblock(struct Sprite* sprite);
+
+// ram variables
+EWRAM_DATA static struct PokeblockFeedStruct *sPokeblockFeed = NULL;
+EWRAM_DATA static struct CompressedSpritePalette sPokeblockSpritePal = {0};
+
+// const rom data
+static const u8 sNatureToMonPokeblockAnim[][2] =
+{
+ { 0, 0 }, // HARDY
+ { 3, 0 }, // LONELY
+ { 4, 1 }, // BRAVE
+ { 5, 0 }, // ADAMANT
+ { 10, 0 }, // NAUGHTY
+ { 13, 0 }, // BOLD
+ { 15, 0 }, // DOCILE
+ { 16, 2 }, // RELAXED
+ { 18, 0 }, // IMPISH
+ { 19, 0 }, // LAX
+ { 20, 0 }, // TIMID
+ { 25, 0 }, // HASTY
+ { 27, 3 }, // SERIOUS
+ { 28, 0 }, // JOLLY
+ { 29, 0 }, // NAIVE
+ { 33, 4 }, // MODEST
+ { 36, 0 }, // MILD
+ { 37, 0 }, // QUIET
+ { 39, 0 }, // BASHFUL
+ { 42, 0 }, // RASH
+ { 45, 0 }, // CALM
+ { 46, 5 }, // GENTLE
+ { 47, 6 }, // SASSY
+ { 48, 0 }, // CAREFUL
+ { 53, 0 }, // QUIRKY
+};
+
+static const s16 sMonPokeblockAnims[][10] =
+{
+ // HARDY
+ { 0, 4, 0, 8, 24, 0, 0, 0, 12, 0},
+ { 0, 4, 0, 16, 24, 0, 0, 0, 12, 0},
+ { 0, 4, 0, 32, 32, 0, 0, 0, 16, 1},
+
+ // LONELY
+ { 0, 3, 6, 0, 48, 0, 0, 0, 24, 1},
+
+ // BRAVE
+ { 64, 16, -24, 0, 32, 0, 0, 0, 0, 1},
+
+ // ADAMANT
+ { 0, 4, 8, 0, 16, 0, -8, 0, 0, 0},
+ { 0, 0, 0, 0, 16, 0, 0, 0, 0, 0},
+ { 0, 4, 8, 0, 16, 0, -8, 0, 0, 0},
+ { 0, 0, 0, 0, 16, 0, 0, 0, 0, 0},
+ { 0, 4, -16, 0, 4, 0, 16, 0, 0, 1},
+
+ // NAUGHTY
+ { 0, 3, 6, 0, 12, 0, 0, 0, 6, 0},
+ { 0, 3, -6, 0, 12, 0, 0, 0, 6, 0},
+ { 0, 16, 16, 0, 45, 1, 0, 0, 0, 1},
+
+ // BOLD
+ { 0, 16, 0, 24, 32, 0, 0, 0, 16, 0},
+ { 0, 16, 0, 23, 32, 0, 0, 0, 16, 1},
+
+ // DOCILE
+ { 0, 0, 0, 0, 80, 0, 0, 0, 0, 1},
+
+ // RELAXED
+ { 0, 2, 8, 0, 32, 0, 0, 0, 0, 0},
+ { 0, 2, -8, 0, 32, 0, 0, 0, 0, 1},
+
+ // IMPISH
+ { 0, 32, 2, 1, 48, 1, 0, 0, 24, 1},
+
+ // LAX
+ { 0, 2, 16, 16, 128, 0, 0, 0, 0, 1},
+
+ // TIMID
+ { 0, 2, -8, 0, 48, 0, -24, 0, 0, 0},
+ { 0, 0, 0, 0, 8, 0, 0, 0, 0, 0},
+ { 64, 32, 2, 0, 36, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 8, 0, 0, 0, 0, 0},
+ { 0, 2, 8, 0, 48, 0, 24, 0, 0, 1},
+
+ // HASTY
+ { 64, 24, 16, 0, 32, 0, 0, 0, 0, 0},
+ { 0, 28, 2, 1, 32, 1, 0, 0, 16, 1},
+
+ // SERIOUS
+ { 0, 0, 0, 0, 32, 0, 0, 0, 0, 1},
+
+ // JOLLY
+ { 64, 16, -16, 2, 48, 0, 0, 0, 32, 1},
+
+ // NAIVE
+ { 0, 12, -8, 4, 24, 0, 8, 0, 12, 0},
+ { 0, 12, 8, 8, 24, 0, -16, 0, 12, 0},
+ { 0, 12, -8, 16, 24, 0, 16, 0, 12, 0},
+ { 0, 12, 8, 28, 24, 0, -8, 0, 12, 1},
+
+ // MODEST
+ { 0, 0, 0, 0, 8, 0, 0, 0, 0, 0},
+ { 64, 16, -4, 0, 32, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 8, 0, 0, 0, 0, 1},
+
+ // MILD
+ { 128, 4, 0, 8, 64, 0, 0, 0, 0, 1},
+
+ // QUIET
+ { 0, 2, 16, 0, 48, 0, 0, 0, 0, 0},
+ { 128, 2, 16, 0, 48, 0, 0, 0, 0, 1},
+
+ // BASHFUL
+ { 0, 2, -4, 0, 48, 0, -48, 0, 0, 0},
+ { 0, 0, 0, 0, 80, 0, 0, 0, 0, 0},
+ { 0, 2, 8, 0, 24, 0, 48, 0, 0, 1},
+
+ // RASH
+ { 64, 4, 64, 58, 52, 0, -88, 0, 0, 0},
+ { 0, 0, 0, 0, 80, 0, 0, 0, 0, 0},
+ { 0, 24, 80, 0, 32, 0, 88, 0, 0, 1},
+
+ // CALM
+ { 0, 2, 16, 4, 64, 0, 0, 0, 0, 1},
+
+ // GENTLE
+ { 0, 0, 0, 0, 32, 0, 0, 0, 0, 1},
+
+ // SASSY
+ { 0, 0, 0, 0, 42, 0, 0, 0, 0, 1},
+
+ // CAREFUL
+ { 0, 4, 0, 8, 24, 0, 0, 0, 12, 0},
+ { 0, 0, 0, 0, 12, 0, 0, 0, 0, 0},
+ { 0, 4, 0, 12, 24, 0, 0, 0, 12, 0},
+ { 0, 0, 0, 0, 12, 0, 0, 0, 0, 0},
+ { 0, 4, 0, 4, 24, 0, 0, 0, 12, 1},
+
+ // QUIRKY
+ { 0, 4, 16, 12, 64, 0, 0, 0, 0, 0},
+ { 0, -4, 16, 12, 64, 0, 0, 0, 0, 1},
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411E90[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411EA0[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, 12, 1),
+ AFFINEANIMCMD_FRAME(0, 0, 0, 30),
+ AFFINEANIMCMD_FRAME(0, 0, -12, 1),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411EC0[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0, 0, 12, 1),
+ AFFINEANIMCMD_FRAME(0, 0, 0, 28),
+ AFFINEANIMCMD_FRAME(0, 0, -4, 3),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411EE8[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 32),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 16),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F08[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 32),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 16),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F30[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 8),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F50[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 8),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F78[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 32),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 8),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F98[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 32),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 8),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411FC0[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 4),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 24),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 4),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411FE0[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 4),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 24),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 4),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8412008[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 24),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -12, 2),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8412028[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 24),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -12, 2),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85F04FC[] =
+{
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411EA0,
+ sSpriteAffineAnim_8411EE8,
+ sSpriteAffineAnim_8411F30,
+ sSpriteAffineAnim_8411F78,
+ sSpriteAffineAnim_8411FC0,
+ sSpriteAffineAnim_8412008,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411EC0,
+ sSpriteAffineAnim_8411F08,
+ sSpriteAffineAnim_8411F50,
+ sSpriteAffineAnim_8411F98,
+ sSpriteAffineAnim_8411FE0,
+ sSpriteAffineAnim_8412028,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+};
+
+static const struct BgTemplate sBackgroundTemplates[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0
+ }
+};
+
+static const struct WindowTemplate sWindowTemplates[] =
+{
+ {0, 1, 0xF, 0x1C, 4, 0xF, 0xA},
+ DUMMY_WIN_TEMPLATE
+};
+
+static const u8* const sPokeblocksPals[] =
+{
+ gPokeblockRed_Pal,
+ gPokeblockBlue_Pal,
+ gPokeblockPink_Pal,
+ gPokeblockGreen_Pal,
+ gPokeblockYellow_Pal,
+ gPokeblockPurple_Pal,
+ gPokeblockIndigo_Pal,
+ gPokeblockBrown_Pal,
+ gPokeblockLiteBlue_Pal,
+ gPokeblockOlive_Pal,
+ gPokeblockGray_Pal,
+ gPokeblockBlack_Pal,
+ gPokeblockWhite_Pal,
+ gPokeblockGold_Pal
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_84120DC[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_MonNoFlip[] =
+{
+ sSpriteAffineAnim_84120DC
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_84120F0[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 16, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 16, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 16, 1),
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8412148[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -16, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -16, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -16, 1),
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85F0664[] =
+{
+ sSpriteAffineAnim_84120DC
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85F0668[] =
+{
+ sSpriteAffineAnim_84120F0
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85F066C[] =
+{
+ sSpriteAffineAnim_8412148
+};
+
+static const struct OamData sThrownPokeblockOamData =
+{
+ .y = 0,
+ .affineMode = 3,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sThrownPokeblockSpriteAnim[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sThrownPokeblockAnimTable[] =
+{
+ sThrownPokeblockSpriteAnim,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_84121C0[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(-8, -8, 0, 1),
+ AFFINEANIMCMD_JUMP(1)
+};
+
+static const union AffineAnimCmd *const sThrownPokeblockAffineAnimTable[] =
+{
+ sSpriteAffineAnim_84121C0
+};
+
+static const struct CompressedSpriteSheet sPokeblock_SpriteSheet =
+{
+ gPokeblock_Gfx, 0x20, GFX_TAG_POKEBLOCK
+};
+
+static const struct SpriteTemplate sThrownPokeblockSpriteTemplate =
+{
+ .tileTag = GFX_TAG_POKEBLOCK,
+ .paletteTag = GFX_TAG_POKEBLOCK,
+ .oam = &sThrownPokeblockOamData,
+ .anims = sThrownPokeblockAnimTable,
+ .images = NULL,
+ .affineAnims = sThrownPokeblockAffineAnimTable,
+ .callback = SpriteCB_ThrownPokeblock
+};
+
+// code
+static void CB2_PokeblockFeed(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ do_scheduled_bg_tilemap_copies_to_vram();
+ UpdatePaletteFade();
+}
+
+static void VBlankCB_PokeblockFeed(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static bool8 TransitionToPokeblockFeedScene(void)
+{
+ switch (gMain.state)
+ {
+ case 0:
+ sPokeblockFeed = AllocZeroed(sizeof(*sPokeblockFeed));
+ SetVBlankHBlankCallbacksToNull();
+ clear_scheduled_bg_copies_to_vram();
+ gMain.state++;
+ break;
+ case 1:
+ ResetPaletteFade();
+ gPaletteFade.bufferTransferDisabled = 1;
+ gMain.state++;
+ break;
+ case 2:
+ ResetSpriteData();
+ gMain.state++;
+ break;
+ case 3:
+ FreeAllSpritePalettes();
+ gMain.state++;
+ break;
+ case 4:
+ AllocateMonSpritesGfx();
+ gMain.state++;
+ break;
+ case 5:
+ HandleInitBackgrounds();
+ gMain.state++;
+ break;
+ case 6:
+ HandleInitWindows();
+ gMain.state++;
+ break;
+ case 7:
+ if (LoadMonAndSceneGfx(&gPlayerParty[gPokeblockMonId]))
+ {
+ gMain.state++;
+ }
+ break;
+ case 8:
+ sPokeblockFeed->pokeblockCaseSpriteId = CreatePokeblockCaseSpriteForFeeding();
+ gMain.state++;
+ break;
+ case 9:
+ sPokeblockFeed->monSpriteId = CreateMonSprite(&gPlayerParty[gPokeblockMonId]);
+ gMain.state++;
+ break;
+ case 10:
+ SetWindowBorderStyle(0, 1, 1, 14);
+ gMain.state++;
+ break;
+ case 11:
+ LaunchPokeblockFeedTask();
+ gMain.state++;
+ break;
+ case 12:
+ BlendPalettes(-1, 0x10, 0);
+ gMain.state++;
+ break;
+ case 13:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gPaletteFade.bufferTransferDisabled = 0;
+ gMain.state++;
+ break;
+ default:
+ SetVBlankCallback(VBlankCB_PokeblockFeed);
+ SetMainCallback2(CB2_PokeblockFeed);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CB2_PreparePokeblockFeedScene(void)
+{
+ while (1)
+ {
+ if (sub_81221EC() == TRUE)
+ break;
+ if (TransitionToPokeblockFeedScene() == TRUE)
+ break;
+ if (sub_81221AC() == TRUE)
+ break;
+ }
+}
+
+static void HandleInitBackgrounds(void)
+{
+ ResetVramOamAndBgCntRegs();
+
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, sBackgroundTemplates, ARRAY_COUNT(sBackgroundTemplates));
+ SetBgTilemapBuffer(1, sPokeblockFeed->tilemapBuffer);
+ ResetAllBgsCoordinates();
+ schedule_bg_copy_tilemap_to_vram(1);
+
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+
+ ShowBg(0);
+ ShowBg(1);
+
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+}
+
+static bool8 LoadMonAndSceneGfx(struct Pokemon *mon)
+{
+ u16 species;
+ u32 personality, trainerId;
+ const struct CompressedSpritePalette *palette;
+
+ switch (sPokeblockFeed->loadGfxState)
+ {
+ case 0:
+ species = GetMonData(mon, MON_DATA_SPECIES2);
+ personality = GetMonData(mon, MON_DATA_PERSONALITY);
+ HandleLoadSpecialPokePic_2(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites[1], species, personality);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 1:
+ species = GetMonData(mon, MON_DATA_SPECIES2);
+ personality = GetMonData(mon, MON_DATA_PERSONALITY);
+ trainerId = GetMonData(mon, MON_DATA_OT_ID);
+ palette = GetMonSpritePalStructFromOtIdPersonality(species, trainerId, personality);
+
+ LoadCompressedObjectPalette(palette);
+ sub_806A068(palette->tag, 1);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 2:
+ LoadCompressedObjectPic(&gPokeblockCase_SpriteSheet);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 3:
+ LoadCompressedObjectPalette(&gPokeblockCase_SpritePal);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 4:
+ LoadCompressedObjectPic(&sPokeblock_SpriteSheet);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 5:
+ SetPokeblockSpritePal(gSpecialVar_ItemId);
+ LoadCompressedObjectPalette(&sPokeblockSpritePal);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 6:
+ reset_temp_tile_data_buffers();
+ decompress_and_copy_tile_data_to_vram(1, gBattleTerrainTiles_Building, 0, 0, 0);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 7:
+ if (free_temp_tile_data_buffers_if_possible() != TRUE)
+ {
+ LZDecompressWram(gUnknown_08D9BA44, sPokeblockFeed->tilemapBuffer);
+ sPokeblockFeed->loadGfxState++;
+ }
+ break;
+ case 8:
+ LoadCompressedPalette(gBattleTerrainPalette_Frontier, 0x20, 0x60);
+ sPokeblockFeed->loadGfxState = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void HandleInitWindows(void)
+{
+ InitWindows(sWindowTemplates);
+ DeactivateAllTextPrinters();
+ sub_809882C(0, 1, 0xE0);
+ LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
+ FillWindowPixelBuffer(0, 0);
+ PutWindowTilemap(0);
+ schedule_bg_copy_tilemap_to_vram(0);
+}
+
+static void SetPokeblockSpritePal(u8 pokeblockCaseId)
+{
+ u8 colorId = GetPokeblockData(&gSaveBlock1Ptr->pokeblocks[pokeblockCaseId], PBLOCK_COLOR);
+ sPokeblockSpritePal.data = sPokeblocksPals[colorId - 1];
+ sPokeblockSpritePal.tag = GFX_TAG_POKEBLOCK;
+}
+
+// defines for task data fields
+
+#define tFrames data[0]
+#define tData1 data[1]
+
+static void Task_HandlePokeblockFeed(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ switch (gTasks[taskId].tFrames)
+ {
+ case 0:
+ sPokeblockFeed->field_1050 = 0;
+ sPokeblockFeed->field_1058 = 0;
+ sub_817A5CC();
+ break;
+ case 255:
+ DoPokeblockCaseThrowEffect(sPokeblockFeed->pokeblockCaseSpriteId, gTasks[taskId].tData1);
+ break;
+ case 269:
+ sPokeblockFeed->pokeblockSpriteId = CreatePokeblockSprite();
+ break;
+ case 281:
+ PrepareMonToMoveToPokeblock(sPokeblockFeed->monSpriteId);
+ break;
+ case 297:
+ gTasks[taskId].func = Task_HandleMonAtePokeblock;
+ return;
+ }
+
+ if (sPokeblockFeed->field_1058 < sPokeblockFeed->field_1056)
+ sub_817A634();
+ else if (sPokeblockFeed->field_1058 == sPokeblockFeed->field_1056)
+ gTasks[taskId].tFrames = 254;
+
+ sPokeblockFeed->field_1058++;
+ gTasks[taskId].tFrames++;
+ }
+}
+
+static void LaunchPokeblockFeedTask(void)
+{
+ u8 taskId = CreateTask(Task_HandlePokeblockFeed, 0);
+ gTasks[taskId].tFrames = 0;
+ gTasks[taskId].tData1 = 1;
+}
+
+static void Task_WaitForAtePokeblockText(u8 taskId)
+{
+ if (RunTextPrintersRetIsActive(0) != TRUE)
+ gTasks[taskId].func = Task_PaletteFadeToReturn;
+}
+
+static void Task_HandleMonAtePokeblock(u8 taskId)
+{
+ struct Pokemon *mon = &gPlayerParty[gPokeblockMonId];
+ struct Pokeblock *pokeblock = &gSaveBlock1Ptr->pokeblocks[gSpecialVar_ItemId];
+
+ gPokeblockGain = PokeblockGetGain(GetNature(mon), pokeblock);
+ GetMonNickname(mon, gStringVar1);
+ PokeblockCopyName(pokeblock, gStringVar2);
+
+ if (gPokeblockGain == 0)
+ StringExpandPlaceholders(gStringVar4, gText_Var1AteTheVar2);
+ else if (gPokeblockGain > 0)
+ StringExpandPlaceholders(gStringVar4, gText_Var1HappilyAteVar2);
+ else
+ StringExpandPlaceholders(gStringVar4, gText_Var1DisdainfullyAteVar2);
+
+ gTextFlags.flag_0 = 1;
+ AddTextPrinterParametrized(0, 1, gStringVar4, GetPlayerTextSpeed(), NULL, 2, 1, 3);
+ gTasks[taskId].func = Task_WaitForAtePokeblockText;
+}
+
+static void Task_ReturnAfterPaletteFade(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, -1, 0x100);
+ SetMainCallback2(gMain.savedCallback);
+ DestroyTask(taskId);
+ FreeAllWindowBuffers();
+ Free(sPokeblockFeed);
+ FreeMonSpritesGfx();
+ }
+}
+
+static void Task_PaletteFadeToReturn(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskId].func = Task_ReturnAfterPaletteFade;
+}
+
+#undef tFrames
+#undef tData1
+
+// defines for mon sprite data fields
+
+#define tDelta data[0]
+#define tDeltaMod data[1]
+#define tSpecies data[2]
+
+static u8 CreateMonSprite(struct Pokemon* mon)
+{
+ u16 species = GetMonData(mon, MON_DATA_SPECIES2);
+ u8 spriteId = CreateSprite(&gUnknown_0202499C, 48, 80, 2);
+
+ sPokeblockFeed->species = species;
+ sPokeblockFeed->monSpriteId_ = spriteId;
+ sPokeblockFeed->nature = GetNature(mon);
+ gSprites[spriteId].tSpecies = species;
+ gSprites[spriteId].callback = SpriteCallbackDummy;
+
+ sPokeblockFeed->noMonFlip = TRUE;
+ if (!IsPokeSpriteNotFlipped(species))
+ {
+ gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_MonNoFlip;
+ gSprites[spriteId].oam.affineMode = 3;
+ CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
+ sPokeblockFeed->noMonFlip = FALSE;
+ }
+
+ return spriteId;
+}
+
+static void PrepareMonToMoveToPokeblock(u8 spriteId)
+{
+ gSprites[spriteId].pos1.x = 48;
+ gSprites[spriteId].pos1.y = 80;
+ gSprites[spriteId].tDelta = -8;
+ gSprites[spriteId].tDeltaMod = 1;
+ gSprites[spriteId].callback = sub_817A468;
+}
+
+static void sub_817A468(struct Sprite* sprite)
+{
+ sprite->pos1.x += 4;
+ sprite->pos1.y += sprite->tDelta;
+ sprite->tDelta += sprite->tDeltaMod;
+
+ if (sprite->tDelta == 0)
+ PlayCry1(sprite->tSpecies, 0);
+ if (sprite->tDelta == 9)
+ sprite->callback = SpriteCallbackDummy;
+}
+
+#undef tDelta
+#undef tDeltaMod
+#undef tSpecies
+
+static u8 CreatePokeblockCaseSpriteForFeeding(void)
+{
+ u8 spriteId = CreatePokeblockCaseSprite(188, 100, 2);
+ gSprites[spriteId].oam.affineMode = 1;
+ gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_85F0664;
+ gSprites[spriteId].callback = SpriteCallbackDummy;
+ InitSpriteAffineAnim(&gSprites[spriteId]);
+ return spriteId;
+}
+
+static void DoPokeblockCaseThrowEffect(u8 spriteId, bool8 a1)
+{
+ FreeOamMatrix(gSprites[spriteId].oam.matrixNum);
+ gSprites[spriteId].oam.affineMode = 3;
+
+ if (!a1)
+ gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_85F0668;
+ else
+ gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_85F066C;
+
+ InitSpriteAffineAnim(&gSprites[spriteId]);
+}
+
+// defines for the pokeblock sprite data fields
+#define tDelta data[0]
+#define tDeltaMod data[1]
+
+static u8 CreatePokeblockSprite(void)
+{
+ u8 spriteId = CreateSprite(&sThrownPokeblockSpriteTemplate, 174, 84, 1);
+ gSprites[spriteId].tDelta = -12;
+ gSprites[spriteId].tDeltaMod = 1;
+ return spriteId;
+}
+
+static void SpriteCB_ThrownPokeblock(struct Sprite* sprite)
+{
+ sprite->pos1.x -= 4;
+ sprite->pos1.y += sprite->tDelta;
+ sprite->tDelta += sprite->tDeltaMod;
+ if (sprite->tDelta == 10)
+ DestroySprite(sprite);
+}
+
+#undef tDelta
+#undef tDeltaMod
+
+static void sub_817A5CC(void)
+{
+ u8 animId, i;
+ struct PokeblockFeedStruct *pokeblockFeed;
+
+ pokeblockFeed = sPokeblockFeed;
+ pokeblockFeed->field_1056 = 1;
+ animId = sNatureToMonPokeblockAnim[pokeblockFeed->nature][0];
+ for (i = 0; i < 8; i++, animId++)
+ {
+ pokeblockFeed->field_1056 += sMonPokeblockAnims[animId][4];
+ if (sMonPokeblockAnims[animId][9] == 1)
+ break;
+ }
+}
+
+static void sub_817A634(void)
+{
+ struct PokeblockFeedStruct *pokeblockFeed = sPokeblockFeed;
+
+ switch (pokeblockFeed->field_1050)
+ {
+ case 0:
+ pokeblockFeed->animId = sNatureToMonPokeblockAnim[pokeblockFeed->nature][0];
+ pokeblockFeed->monSpritePtr = &gSprites[pokeblockFeed->monSpriteId_];
+ pokeblockFeed->savedMonSprite = *pokeblockFeed->monSpritePtr;
+ pokeblockFeed->field_1050 = 10;
+ break;
+ case 1 ... 9:
+ break;
+ case 10:
+ sub_817A91C();
+ if (sNatureToMonPokeblockAnim[pokeblockFeed->nature][1] != 0)
+ {
+ pokeblockFeed->monSpritePtr->oam.affineMode = 3;
+ pokeblockFeed->monSpritePtr->oam.matrixNum = 0;
+ pokeblockFeed->monSpritePtr->affineAnims = sSpriteAffineAnimTable_85F04FC;
+ InitSpriteAffineAnim(pokeblockFeed->monSpritePtr);
+ }
+ pokeblockFeed->field_1050 = 50;
+ case 50:
+ if (sNatureToMonPokeblockAnim[pokeblockFeed->nature][1] != 0)
+ {
+ if (!pokeblockFeed->noMonFlip) // double negation, so mon's sprite is flipped
+ StartSpriteAffineAnim(pokeblockFeed->monSpritePtr, sNatureToMonPokeblockAnim[pokeblockFeed->nature][1] + 10);
+ else
+ StartSpriteAffineAnim(pokeblockFeed->monSpritePtr, sNatureToMonPokeblockAnim[pokeblockFeed->nature][1]);
+ }
+ pokeblockFeed->field_1050 = 60;
+ break;
+ case 60:
+ if (sub_817A9E4() == TRUE)
+ {
+ if (pokeblockFeed->field_1060[9] == 0)
+ {
+ pokeblockFeed->animId++;
+ sub_817A91C();
+ pokeblockFeed->field_1050 = 60;
+ }
+ else
+ {
+ FreeOamMatrix(pokeblockFeed->monSpritePtr->oam.matrixNum);
+ pokeblockFeed->field_1050 = 70;
+ }
+ }
+ break;
+ case 70:
+ FreeMonSpriteOamMatrix();
+ pokeblockFeed->animId = 0;
+ pokeblockFeed->field_1050 = 0;
+ break;
+ case 71 ... 90:
+ break;
+ }
+}
+
+static bool8 sub_817A91C(void)
+{
+ struct PokeblockFeedStruct *pokeblockFeed = sPokeblockFeed;
+ u8 i;
+
+ for (i = 0; i < 10; i++)
+ pokeblockFeed->field_1060[i] = sMonPokeblockAnims[pokeblockFeed->animId][i];
+
+ if (pokeblockFeed->field_1060[4] == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ pokeblockFeed->field_1060[10] = Sin(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[2]);
+ pokeblockFeed->field_1060[11] = Cos(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[3]);
+ pokeblockFeed->field_1060[12] = pokeblockFeed->field_1060[4];
+ pokeblockFeed->field_1060[13] = pokeblockFeed->monSpritePtr->pos2.x;
+ pokeblockFeed->field_1060[14] = pokeblockFeed->monSpritePtr->pos2.y;
+ sub_817AB68();
+ pokeblockFeed->field_1060[4] = pokeblockFeed->field_1060[12];
+ sub_817AA54();
+ pokeblockFeed->field_1060[4] = pokeblockFeed->field_1060[12];
+ return FALSE;
+ }
+}
+
+static bool8 sub_817A9E4(void)
+{
+ u16 var = sPokeblockFeed->field_1060[12] - sPokeblockFeed->field_1060[4];
+
+ sPokeblockFeed->monSpritePtr->pos2.x = sPokeblockFeed->field_850[var];
+ sPokeblockFeed->monSpritePtr->pos2.y = sPokeblockFeed->field_C50[var];
+
+ if (--sPokeblockFeed->field_1060[4] == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 FreeMonSpriteOamMatrix(void)
+{
+ FreeSpriteOamMatrix(sPokeblockFeed->monSpritePtr);
+ return FALSE;
+}
+
+static void sub_817AA54(void)
+{
+ struct PokeblockFeedStruct *pokeblockFeed = sPokeblockFeed;
+ u16 i;
+ u16 r8 = pokeblockFeed->field_1060[8];
+ u16 r7 = pokeblockFeed->field_1060[12] - r8;
+ s16 var3 = pokeblockFeed->field_1060[13] + pokeblockFeed->field_1060[6];
+ s16 r9 = pokeblockFeed->field_1060[14] + pokeblockFeed->field_1060[7];
+
+ for (i = 0; i < r7 - 1; i++)
+ {
+ s16 r1 = pokeblockFeed->field_850[r8 + i] - (var3);
+ s16 r4 = pokeblockFeed->field_C50[r8 + i] - r9;
+
+ pokeblockFeed->field_850[r8 + i] -= r1 * (i + 1) / r7;
+ pokeblockFeed->field_C50[r8 + i] -= r4 * (i + 1) / r7;
+ }
+
+ pokeblockFeed->field_850[(r8 + r7) - 1] = var3;
+ pokeblockFeed->field_C50[(r8 + r7) - 1] = r9;
+}
+
+static void sub_817AB68(void)
+{
+ struct PokeblockFeedStruct *pokeblockFeed = sPokeblockFeed;
+ bool8 var_24 = FALSE;
+ s16 r8 = pokeblockFeed->field_1060[13] - pokeblockFeed->field_1060[10];
+ s16 r7 = pokeblockFeed->field_1060[14] - pokeblockFeed->field_1060[11];
+
+ while (1)
+ {
+ u16 r5;
+ u16 r4;
+ u16 var;
+
+ var = abs(pokeblockFeed->field_1060[5]);
+ r5 = var + pokeblockFeed->field_1060[3];
+ pokeblockFeed->field_1060[3] = r5;
+
+ if (pokeblockFeed->field_1060[2] < 0)
+ var_24 = TRUE;
+
+ r4 = pokeblockFeed->field_1060[12] - pokeblockFeed->field_1060[4];
+
+ if (pokeblockFeed->field_1060[4] == 0)
+ break;
+
+ if (!var_24)
+ {
+ pokeblockFeed->field_850[r4] = Sin(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[2] + r5 / 0x100) + r8;
+ pokeblockFeed->field_C50[r4] = Cos(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[3] + r5 / 0x100) + r7;
+ }
+ else
+ {
+ pokeblockFeed->field_850[r4] = Sin(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[2] - r5 / 0x100) + r8;
+ pokeblockFeed->field_C50[r4] = Cos(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[3] - r5 / 0x100) + r7;
+ }
+
+ pokeblockFeed->field_1060[0] += pokeblockFeed->field_1060[1];
+ pokeblockFeed->field_1060[0] &= 0xFF;
+ pokeblockFeed->field_1060[4]--;
+ }
+}
diff --git a/src/pokedex.c b/src/pokedex.c
new file mode 100644
index 000000000..a74594865
--- /dev/null
+++ b/src/pokedex.c
@@ -0,0 +1,542 @@
+#include "global.h"
+#include "gba/m4a_internal.h"
+#include "pokedex.h"
+#include "sprite.h"
+#include "graphics.h"
+#include "decompress.h"
+#include "bg.h"
+#include "window.h"
+
+// this file's functions
+void sub_80BE604(struct Sprite *sprite);
+void sub_80BE658(struct Sprite *sprite);
+void sub_80BE758(struct Sprite *sprite);
+void sub_80BE780(struct Sprite *sprite);
+void sub_80BE44C(struct Sprite *sprite);
+void sub_80BE834(struct Sprite *sprite);
+
+// const rom data
+#include "data/pokedex_orders.h"
+
+static const struct OamData sOamData_855CFE4 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_855CFEC =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_855CFF4 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_855CFFC =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 2,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_855D004 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_855D00C =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 2,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_855D014[] =
+{
+ ANIMCMD_FRAME(3, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D01C[] =
+{
+ ANIMCMD_FRAME(1, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D024[] =
+{
+ ANIMCMD_FRAME(16, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D02C[] =
+{
+ ANIMCMD_FRAME(48, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D034[] =
+{
+ ANIMCMD_FRAME(40, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D03C[] =
+{
+ ANIMCMD_FRAME(32, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D044[] =
+{
+ ANIMCMD_FRAME(56, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D04C[] =
+{
+ ANIMCMD_FRAME(64, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D054[] =
+{
+ ANIMCMD_FRAME(96, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D05C[] =
+{
+ ANIMCMD_FRAME(160, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D064[] =
+{
+ ANIMCMD_FRAME(168, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D06C[] =
+{
+ ANIMCMD_FRAME(128, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D074[] =
+{
+ ANIMCMD_FRAME(130, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D07C[] =
+{
+ ANIMCMD_FRAME(132, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D084[] =
+{
+ ANIMCMD_FRAME(134, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D08C[] =
+{
+ ANIMCMD_FRAME(136, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D094[] =
+{
+ ANIMCMD_FRAME(138, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D09C[] =
+{
+ ANIMCMD_FRAME(140, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0A4[] =
+{
+ ANIMCMD_FRAME(142, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0AC[] =
+{
+ ANIMCMD_FRAME(144, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0B4[] =
+{
+ ANIMCMD_FRAME(146, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0BC[] =
+{
+ ANIMCMD_FRAME(176, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0C4[] =
+{
+ ANIMCMD_FRAME(178, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0CC[] =
+{
+ ANIMCMD_FRAME(180, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0D4[] =
+{
+ ANIMCMD_FRAME(182, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0DC[] =
+{
+ ANIMCMD_FRAME(184, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0E4[] =
+{
+ ANIMCMD_FRAME(186, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0EC[] =
+{
+ ANIMCMD_FRAME(188, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0F4[] =
+{
+ ANIMCMD_FRAME(190, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D0FC[] =
+{
+ ANIMCMD_FRAME(192, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D104[] =
+{
+ ANIMCMD_FRAME(194, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_855D10C[] =
+{
+ ANIMCMD_FRAME(4, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_855D114[] =
+{
+ sSpriteAnim_855D014
+};
+
+static const union AnimCmd *const sSpriteAnimTable_855D118[] =
+{
+ sSpriteAnim_855D01C
+};
+
+static const union AnimCmd *const sSpriteAnimTable_855D11C[] =
+{
+ sSpriteAnim_855D024
+};
+
+static const union AnimCmd *const sSpriteAnimTable_855D120[] =
+{
+ sSpriteAnim_855D02C,
+ sSpriteAnim_855D034,
+ sSpriteAnim_855D03C,
+ sSpriteAnim_855D044
+};
+
+static const union AnimCmd *const sSpriteAnimTable_855D130[] =
+{
+ sSpriteAnim_855D04C,
+ sSpriteAnim_855D054
+};
+
+static const union AnimCmd *const sSpriteAnimTable_855D138[] =
+{
+ sSpriteAnim_855D05C,
+ sSpriteAnim_855D064
+};
+
+static const union AnimCmd *const sSpriteAnimTable_855D140[] =
+{
+ sSpriteAnim_855D06C,
+ sSpriteAnim_855D074,
+ sSpriteAnim_855D07C,
+ sSpriteAnim_855D084,
+ sSpriteAnim_855D08C,
+ sSpriteAnim_855D094,
+ sSpriteAnim_855D09C,
+ sSpriteAnim_855D0A4,
+ sSpriteAnim_855D0AC,
+ sSpriteAnim_855D0B4
+};
+
+static const union AnimCmd *const sSpriteAnimTable_855D168[] =
+{
+ sSpriteAnim_855D0BC,
+ sSpriteAnim_855D0C4,
+ sSpriteAnim_855D0CC,
+ sSpriteAnim_855D0D4,
+ sSpriteAnim_855D0DC,
+ sSpriteAnim_855D0E4,
+ sSpriteAnim_855D0EC,
+ sSpriteAnim_855D0F4,
+ sSpriteAnim_855D0FC,
+ sSpriteAnim_855D104
+};
+
+static const union AnimCmd *const sSpriteAnimTable_855D190[] =
+{
+ sSpriteAnim_855D10C
+};
+
+const struct SpriteTemplate gUnknown_0855D194 =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &sOamData_855CFE4,
+ .anims = sSpriteAnimTable_855D114,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BE604,
+};
+
+const struct SpriteTemplate gUnknown_0855D1AC =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &sOamData_855CFEC,
+ .anims = sSpriteAnimTable_855D118,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BE658,
+};
+
+const struct SpriteTemplate gUnknown_0855D1C4 =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &sOamData_855CFF4,
+ .anims = sSpriteAnimTable_855D120,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BE758,
+};
+
+const struct SpriteTemplate gUnknown_0855D1DC =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &sOamData_855CFFC,
+ .anims = sSpriteAnimTable_855D11C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BE780,
+};
+
+const struct SpriteTemplate gUnknown_0855D1F4 =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &sOamData_855D004,
+ .anims = sSpriteAnimTable_855D130,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BE44C,
+};
+
+const struct SpriteTemplate gUnknown_0855D20C =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &sOamData_855CFF4,
+ .anims = sSpriteAnimTable_855D138,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BE44C,
+};
+
+const struct SpriteTemplate gUnknown_0855D224 =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &sOamData_855D00C,
+ .anims = sSpriteAnimTable_855D140,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BE44C,
+};
+
+const struct SpriteTemplate gUnknown_0855D23C =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &sOamData_855D00C,
+ .anims = sSpriteAnimTable_855D168,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BE44C,
+};
+
+const struct SpriteTemplate gUnknown_0855D254 =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &sOamData_855D00C,
+ .anims = sSpriteAnimTable_855D190,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BE834,
+};
+
+const struct CompressedSpriteSheet gSpriteSheets_0855D26C[] =
+{
+ {gPokedexMenu2_Gfx, 0x2000, 4096},
+ {0}
+};
+
+const struct CompressedSpritePalette gSpritePalettes_0855D26C[] =
+{
+ {gPokedexText_Pal, 4096},
+ {0}
+};
+
+const u8 gUnknown_0855D28C[] = {0x4, 0x8, 0x10, 0x20, 0x20};
+const u8 gUnknown_0855D291[] = {0x8, 0x4, 0x2, 0x1, 0x1};
+
+const struct BgTemplate gBgTemplates_0855D298[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 12,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 13,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 14,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0
+ },
+ {
+ .bg = 3,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 15,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0
+ }
+};
+
+const struct WindowTemplate sWindowTemplates_0855D2A8[] =
+{
+ {2, 0, 0, 0x20, 0x20, 0, 1},
+ DUMMY_WIN_TEMPLATE
+};
+
diff --git a/src/pokemon_2.c b/src/pokemon_2.c
index a4d00112b..db176e025 100644
--- a/src/pokemon_2.c
+++ b/src/pokemon_2.c
@@ -1155,7 +1155,7 @@ u8 GetMonsStateToDoubles_2(void)
s32 aliveCount = 0;
s32 i;
- for (i = 0; i < 6; i++)
+ for (i = 0; i < PARTY_SIZE; i++)
{
u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL);
if (species != SPECIES_EGG && species != SPECIES_NONE
diff --git a/src/pokemon_3.c b/src/pokemon_3.c
index a419dd46e..95ec4b6a2 100644
--- a/src/pokemon_3.c
+++ b/src/pokemon_3.c
@@ -11,8 +11,7 @@
#include "link.h"
#include "constants/hold_effects.h"
#include "random.h"
-#include "trainer_classes.h"
-#include "trainer_ids.h"
+#include "constants/trainers.h"
#include "constants/songs.h"
#include "sound.h"
#include "m4a.h"
@@ -22,6 +21,7 @@
#include "constants/abilities.h"
#include "pokemon_animation.h"
#include "pokedex.h"
+#include "pokeblock.h"
extern struct BattlePokemon gBattleMons[4];
extern struct BattleEnigmaBerry gEnigmaBerries[4];
@@ -59,7 +59,6 @@ extern const u8 gText_PkmnsXPreventsSwitching[];
extern const struct CompressedSpritePalette gMonPaletteTable[];
extern const struct CompressedSpritePalette gMonShinyPaletteTable[];
extern const u16 gHMMoves[];
-extern const s8 gPokeblockFlavorCompatibilityTable[];
extern const u8 gMonAnimationDelayTable[];
extern const u8 gMonFrontAnimIdsTable[];
@@ -692,9 +691,9 @@ void AdjustFriendship(struct Pokemon *mon, u8 event)
if ((event != 5 || !(Random() & 1))
&& (event != 3
|| ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)
- && (gTrainers[gTrainerBattleOpponent_A].trainerClass == CLASS_ELITE_FOUR
- || gTrainers[gTrainerBattleOpponent_A].trainerClass == CLASS_LEADER
- || gTrainers[gTrainerBattleOpponent_A].trainerClass == CLASS_CHAMPION))))
+ && (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_ELITE_FOUR
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_LEADER
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_CHAMPION))))
{
s8 mod = gUnknown_08329ECE[event][friendshipLevel];
if (mod > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
@@ -1146,55 +1145,57 @@ void ClearBattleMonForms(void)
u16 GetBattleBGM(void)
{
if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON)
- return 0x1E0;
+ return MUS_BATTLE34;
if (gBattleTypeFlags & BATTLE_TYPE_REGI)
- return 0x1DF;
+ return MUS_BATTLE36;
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
- return 0x1DC;
+ return MUS_BATTLE20;
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
{
u8 trainerClass;
+
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
trainerClass = GetFrontierOpponentClass(gTrainerBattleOpponent_A);
else if (gBattleTypeFlags & BATTLE_TYPE_x4000000)
- trainerClass = CLASS_EXPERT;
+ trainerClass = TRAINER_CLASS_EXPERT;
else
trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass;
+
switch (trainerClass)
{
- case CLASS_AQUA_LEADER:
- case CLASS_MAGMA_LEADER:
- return 0x1E3;
- case CLASS_TEAM_AQUA:
- case CLASS_TEAM_MAGMA:
- case CLASS_AQUA_ADMIN:
- case CLASS_MAGMA_ADMIN:
- return 0x1DB;
- case CLASS_LEADER:
- return 0x1DD;
- case CLASS_CHAMPION:
- return 0x1DE;
- case CLASS_PKMN_TRAINER_RIVAL:
+ case TRAINER_CLASS_AQUA_LEADER:
+ case TRAINER_CLASS_MAGMA_LEADER:
+ return MUS_BATTLE30;
+ case TRAINER_CLASS_TEAM_AQUA:
+ case TRAINER_CLASS_TEAM_MAGMA:
+ case TRAINER_CLASS_AQUA_ADMIN:
+ case TRAINER_CLASS_MAGMA_ADMIN:
+ return MUS_BATTLE31;
+ case TRAINER_CLASS_LEADER:
+ return MUS_BATTLE32;
+ case TRAINER_CLASS_CHAMPION:
+ return MUS_BATTLE33;
+ case TRAINER_CLASS_PKMN_TRAINER_3:
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
- return 0x1E1;
+ return MUS_BATTLE35;
if (!StringCompare(gTrainers[gTrainerBattleOpponent_A].trainerName, gText_BattleWallyName))
- return 0x1DC;
- return 0x1E1;
- case CLASS_ELITE_FOUR:
- return 0x1E2;
- case CLASS_SALON_MAIDEN:
- case CLASS_DOME_ACE:
- case CLASS_PALACE_MAVEN:
- case CLASS_ARENA_TYCOON:
- case CLASS_FACTORY_HEAD:
- case CLASS_PIKE_QUEEN:
- case CLASS_PYRAMID_KING:
- return 0x1D7;
+ return MUS_BATTLE20;
+ return MUS_BATTLE35;
+ case TRAINER_CLASS_ELITE_FOUR:
+ return MUS_BATTLE38;
+ case TRAINER_CLASS_SALON_MAIDEN:
+ case TRAINER_CLASS_DOME_ACE:
+ case TRAINER_CLASS_PALACE_MAVEN:
+ case TRAINER_CLASS_ARENA_TYCOON:
+ case TRAINER_CLASS_FACTORY_HEAD:
+ case TRAINER_CLASS_PIKE_QUEEN:
+ case TRAINER_CLASS_PYRAMID_KING:
+ return MUS_VS_FRONT;
default:
- return 0x1DC;
+ return MUS_BATTLE20;
}
}
- return 0x1DA;
+ return MUS_BATTLE27;
}
void PlayBattleBGM(void)
@@ -1297,21 +1298,21 @@ bool8 IsPokeSpriteNotFlipped(u16 species)
return gBaseStats[species].noFlip;
}
-s8 GetMonFlavorRelation(struct Pokemon *mon, u8 a2)
+s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor)
{
u8 nature = GetNature(mon);
- return gPokeblockFlavorCompatibilityTable[nature * 5 + a2];
+ return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor];
}
-s8 GetFlavorRelationByPersonality(u32 personality, u8 a2)
+s8 GetFlavorRelationByPersonality(u32 personality, u8 flavor)
{
u8 nature = GetNatureFromPersonality(personality);
- return gPokeblockFlavorCompatibilityTable[nature * 5 + a2];
+ return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor];
}
bool8 IsTradedMon(struct Pokemon *mon)
{
- u8 otName[8];
+ u8 otName[OT_NAME_LENGTH + 1];
u32 otId;
GetMonData(mon, MON_DATA_OT_NAME, otName);
otId = GetMonData(mon, MON_DATA_OT_ID, 0);
@@ -1396,7 +1397,7 @@ static s32 GetWildMonTableIdInAlteringCave(u16 species)
void SetWildMonHeldItem(void)
{
- if (!(gBattleTypeFlags & (BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID | BATTLE_TYPE_x100000)))
+ if (!(gBattleTypeFlags & (BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID | BATTLE_TYPE_PIKE)))
{
u16 rnd = Random() % 100;
u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, 0);
@@ -1462,12 +1463,14 @@ bool8 IsShinyOtIdPersonality(u32 otId, u32 personality)
return retVal;
}
-const u8* GetTrainerPartnerName(void)
+const u8 *GetTrainerPartnerName(void)
{
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
if (gPartnerTrainerId == STEVEN_PARTNER_ID)
- return gTrainers[TRAINER_ID_STEVEN].trainerName;
+ {
+ return gTrainers[TRAINER_STEVEN].trainerName;
+ }
else
{
GetFrontierTrainerName(gStringVar1, gPartnerTrainerId);
@@ -1682,14 +1685,14 @@ void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality)
}
}
-const u8* GetTrainerClassNameFromId(u16 trainerId)
+const u8 *GetTrainerClassNameFromId(u16 trainerId)
{
if (trainerId > NO_OF_TRAINERS)
trainerId = 0;
return gTrainerClassNames[gTrainers[trainerId].trainerClass];
}
-const u8* GetTrainerNameFromId(u16 trainerId)
+const u8 *GetTrainerNameFromId(u16 trainerId)
{
if (trainerId > NO_OF_TRAINERS)
trainerId = 0;
diff --git a/src/pokemon_icon.c b/src/pokemon_icon.c
new file mode 100644
index 000000000..4d1cc51c5
--- /dev/null
+++ b/src/pokemon_icon.c
@@ -0,0 +1,1014 @@
+#include "global.h"
+#include "sprite.h"
+#include "graphics.h"
+
+#define POKE_ICON_BASE_PAL_TAG 56000
+
+const u8 * const gMonIconTable[] =
+{
+ gMonIcon_Bulbasaur,
+ gMonIcon_Bulbasaur,
+ gMonIcon_Ivysaur,
+ gMonIcon_Venusaur,
+ gMonIcon_Charmander,
+ gMonIcon_Charmeleon,
+ gMonIcon_Charizard,
+ gMonIcon_Squirtle,
+ gMonIcon_Wartortle,
+ gMonIcon_Blastoise,
+ gMonIcon_Caterpie,
+ gMonIcon_Metapod,
+ gMonIcon_Butterfree,
+ gMonIcon_Weedle,
+ gMonIcon_Kakuna,
+ gMonIcon_Beedrill,
+ gMonIcon_Pidgey,
+ gMonIcon_Pidgeotto,
+ gMonIcon_Pidgeot,
+ gMonIcon_Rattata,
+ gMonIcon_Raticate,
+ gMonIcon_Spearow,
+ gMonIcon_Fearow,
+ gMonIcon_Ekans,
+ gMonIcon_Arbok,
+ gMonIcon_Pikachu,
+ gMonIcon_Raichu,
+ gMonIcon_Sandshrew,
+ gMonIcon_Sandslash,
+ gMonIcon_NidoranF,
+ gMonIcon_Nidorina,
+ gMonIcon_Nidoqueen,
+ gMonIcon_NidoranM,
+ gMonIcon_Nidorino,
+ gMonIcon_Nidoking,
+ gMonIcon_Clefairy,
+ gMonIcon_Clefable,
+ gMonIcon_Vulpix,
+ gMonIcon_Ninetales,
+ gMonIcon_Jigglypuff,
+ gMonIcon_Wigglytuff,
+ gMonIcon_Zubat,
+ gMonIcon_Golbat,
+ gMonIcon_Oddish,
+ gMonIcon_Gloom,
+ gMonIcon_Vileplume,
+ gMonIcon_Paras,
+ gMonIcon_Parasect,
+ gMonIcon_Venonat,
+ gMonIcon_Venomoth,
+ gMonIcon_Diglett,
+ gMonIcon_Dugtrio,
+ gMonIcon_Meowth,
+ gMonIcon_Persian,
+ gMonIcon_Psyduck,
+ gMonIcon_Golduck,
+ gMonIcon_Mankey,
+ gMonIcon_Primeape,
+ gMonIcon_Growlithe,
+ gMonIcon_Arcanine,
+ gMonIcon_Poliwag,
+ gMonIcon_Poliwhirl,
+ gMonIcon_Poliwrath,
+ gMonIcon_Abra,
+ gMonIcon_Kadabra,
+ gMonIcon_Alakazam,
+ gMonIcon_Machop,
+ gMonIcon_Machoke,
+ gMonIcon_Machamp,
+ gMonIcon_Bellsprout,
+ gMonIcon_Weepinbell,
+ gMonIcon_Victreebel,
+ gMonIcon_Tentacool,
+ gMonIcon_Tentacruel,
+ gMonIcon_Geodude,
+ gMonIcon_Graveler,
+ gMonIcon_Golem,
+ gMonIcon_Ponyta,
+ gMonIcon_Rapidash,
+ gMonIcon_Slowpoke,
+ gMonIcon_Slowbro,
+ gMonIcon_Magnemite,
+ gMonIcon_Magneton,
+ gMonIcon_Farfetchd,
+ gMonIcon_Doduo,
+ gMonIcon_Dodrio,
+ gMonIcon_Seel,
+ gMonIcon_Dewgong,
+ gMonIcon_Grimer,
+ gMonIcon_Muk,
+ gMonIcon_Shellder,
+ gMonIcon_Cloyster,
+ gMonIcon_Gastly,
+ gMonIcon_Haunter,
+ gMonIcon_Gengar,
+ gMonIcon_Onix,
+ gMonIcon_Drowzee,
+ gMonIcon_Hypno,
+ gMonIcon_Krabby,
+ gMonIcon_Kingler,
+ gMonIcon_Voltorb,
+ gMonIcon_Electrode,
+ gMonIcon_Exeggcute,
+ gMonIcon_Exeggutor,
+ gMonIcon_Cubone,
+ gMonIcon_Marowak,
+ gMonIcon_Hitmonlee,
+ gMonIcon_Hitmonchan,
+ gMonIcon_Lickitung,
+ gMonIcon_Koffing,
+ gMonIcon_Weezing,
+ gMonIcon_Rhyhorn,
+ gMonIcon_Rhydon,
+ gMonIcon_Chansey,
+ gMonIcon_Tangela,
+ gMonIcon_Kangaskhan,
+ gMonIcon_Horsea,
+ gMonIcon_Seadra,
+ gMonIcon_Goldeen,
+ gMonIcon_Seaking,
+ gMonIcon_Staryu,
+ gMonIcon_Starmie,
+ gMonIcon_Mrmime,
+ gMonIcon_Scyther,
+ gMonIcon_Jynx,
+ gMonIcon_Electabuzz,
+ gMonIcon_Magmar,
+ gMonIcon_Pinsir,
+ gMonIcon_Tauros,
+ gMonIcon_Magikarp,
+ gMonIcon_Gyarados,
+ gMonIcon_Lapras,
+ gMonIcon_Ditto,
+ gMonIcon_Eevee,
+ gMonIcon_Vaporeon,
+ gMonIcon_Jolteon,
+ gMonIcon_Flareon,
+ gMonIcon_Porygon,
+ gMonIcon_Omanyte,
+ gMonIcon_Omastar,
+ gMonIcon_Kabuto,
+ gMonIcon_Kabutops,
+ gMonIcon_Aerodactyl,
+ gMonIcon_Snorlax,
+ gMonIcon_Articuno,
+ gMonIcon_Zapdos,
+ gMonIcon_Moltres,
+ gMonIcon_Dratini,
+ gMonIcon_Dragonair,
+ gMonIcon_Dragonite,
+ gMonIcon_Mewtwo,
+ gMonIcon_Mew,
+ gMonIcon_Chikorita,
+ gMonIcon_Bayleef,
+ gMonIcon_Meganium,
+ gMonIcon_Cyndaquil,
+ gMonIcon_Quilava,
+ gMonIcon_Typhlosion,
+ gMonIcon_Totodile,
+ gMonIcon_Croconaw,
+ gMonIcon_Feraligatr,
+ gMonIcon_Sentret,
+ gMonIcon_Furret,
+ gMonIcon_Hoothoot,
+ gMonIcon_Noctowl,
+ gMonIcon_Ledyba,
+ gMonIcon_Ledian,
+ gMonIcon_Spinarak,
+ gMonIcon_Ariados,
+ gMonIcon_Crobat,
+ gMonIcon_Chinchou,
+ gMonIcon_Lanturn,
+ gMonIcon_Pichu,
+ gMonIcon_Cleffa,
+ gMonIcon_Igglybuff,
+ gMonIcon_Togepi,
+ gMonIcon_Togetic,
+ gMonIcon_Natu,
+ gMonIcon_Xatu,
+ gMonIcon_Mareep,
+ gMonIcon_Flaaffy,
+ gMonIcon_Ampharos,
+ gMonIcon_Bellossom,
+ gMonIcon_Marill,
+ gMonIcon_Azumarill,
+ gMonIcon_Sudowoodo,
+ gMonIcon_Politoed,
+ gMonIcon_Hoppip,
+ gMonIcon_Skiploom,
+ gMonIcon_Jumpluff,
+ gMonIcon_Aipom,
+ gMonIcon_Sunkern,
+ gMonIcon_Sunflora,
+ gMonIcon_Yanma,
+ gMonIcon_Wooper,
+ gMonIcon_Quagsire,
+ gMonIcon_Espeon,
+ gMonIcon_Umbreon,
+ gMonIcon_Murkrow,
+ gMonIcon_Slowking,
+ gMonIcon_Misdreavus,
+ gMonIcon_UnownA,
+ gMonIcon_Wobbuffet,
+ gMonIcon_Girafarig,
+ gMonIcon_Pineco,
+ gMonIcon_Forretress,
+ gMonIcon_Dunsparce,
+ gMonIcon_Gligar,
+ gMonIcon_Steelix,
+ gMonIcon_Snubbull,
+ gMonIcon_Granbull,
+ gMonIcon_Qwilfish,
+ gMonIcon_Scizor,
+ gMonIcon_Shuckle,
+ gMonIcon_Heracross,
+ gMonIcon_Sneasel,
+ gMonIcon_Teddiursa,
+ gMonIcon_Ursaring,
+ gMonIcon_Slugma,
+ gMonIcon_Magcargo,
+ gMonIcon_Swinub,
+ gMonIcon_Piloswine,
+ gMonIcon_Corsola,
+ gMonIcon_Remoraid,
+ gMonIcon_Octillery,
+ gMonIcon_Delibird,
+ gMonIcon_Mantine,
+ gMonIcon_Skarmory,
+ gMonIcon_Houndour,
+ gMonIcon_Houndoom,
+ gMonIcon_Kingdra,
+ gMonIcon_Phanpy,
+ gMonIcon_Donphan,
+ gMonIcon_Porygon2,
+ gMonIcon_Stantler,
+ gMonIcon_Smeargle,
+ gMonIcon_Tyrogue,
+ gMonIcon_Hitmontop,
+ gMonIcon_Smoochum,
+ gMonIcon_Elekid,
+ gMonIcon_Magby,
+ gMonIcon_Miltank,
+ gMonIcon_Blissey,
+ gMonIcon_Raikou,
+ gMonIcon_Entei,
+ gMonIcon_Suicune,
+ gMonIcon_Larvitar,
+ gMonIcon_Pupitar,
+ gMonIcon_Tyranitar,
+ gMonIcon_Lugia,
+ gMonIcon_HoOh,
+ gMonIcon_Celebi,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_QuestionMark,
+ gMonIcon_Treecko,
+ gMonIcon_Grovyle,
+ gMonIcon_Sceptile,
+ gMonIcon_Torchic,
+ gMonIcon_Combusken,
+ gMonIcon_Blaziken,
+ gMonIcon_Mudkip,
+ gMonIcon_Marshtomp,
+ gMonIcon_Swampert,
+ gMonIcon_Poochyena,
+ gMonIcon_Mightyena,
+ gMonIcon_Zigzagoon,
+ gMonIcon_Linoone,
+ gMonIcon_Wurmple,
+ gMonIcon_Silcoon,
+ gMonIcon_Beautifly,
+ gMonIcon_Cascoon,
+ gMonIcon_Dustox,
+ gMonIcon_Lotad,
+ gMonIcon_Lombre,
+ gMonIcon_Ludicolo,
+ gMonIcon_Seedot,
+ gMonIcon_Nuzleaf,
+ gMonIcon_Shiftry,
+ gMonIcon_Nincada,
+ gMonIcon_Ninjask,
+ gMonIcon_Shedinja,
+ gMonIcon_Taillow,
+ gMonIcon_Swellow,
+ gMonIcon_Shroomish,
+ gMonIcon_Breloom,
+ gMonIcon_Spinda,
+ gMonIcon_Wingull,
+ gMonIcon_Pelipper,
+ gMonIcon_Surskit,
+ gMonIcon_Masquerain,
+ gMonIcon_Wailmer,
+ gMonIcon_Wailord,
+ gMonIcon_Skitty,
+ gMonIcon_Delcatty,
+ gMonIcon_Kecleon,
+ gMonIcon_Baltoy,
+ gMonIcon_Claydol,
+ gMonIcon_Nosepass,
+ gMonIcon_Torkoal,
+ gMonIcon_Sableye,
+ gMonIcon_Barboach,
+ gMonIcon_Whiscash,
+ gMonIcon_Luvdisc,
+ gMonIcon_Corphish,
+ gMonIcon_Crawdaunt,
+ gMonIcon_Feebas,
+ gMonIcon_Milotic,
+ gMonIcon_Carvanha,
+ gMonIcon_Sharpedo,
+ gMonIcon_Trapinch,
+ gMonIcon_Vibrava,
+ gMonIcon_Flygon,
+ gMonIcon_Makuhita,
+ gMonIcon_Hariyama,
+ gMonIcon_Electrike,
+ gMonIcon_Manectric,
+ gMonIcon_Numel,
+ gMonIcon_Camerupt,
+ gMonIcon_Spheal,
+ gMonIcon_Sealeo,
+ gMonIcon_Walrein,
+ gMonIcon_Cacnea,
+ gMonIcon_Cacturne,
+ gMonIcon_Snorunt,
+ gMonIcon_Glalie,
+ gMonIcon_Lunatone,
+ gMonIcon_Solrock,
+ gMonIcon_Azurill,
+ gMonIcon_Spoink,
+ gMonIcon_Grumpig,
+ gMonIcon_Plusle,
+ gMonIcon_Minun,
+ gMonIcon_Mawile,
+ gMonIcon_Meditite,
+ gMonIcon_Medicham,
+ gMonIcon_Swablu,
+ gMonIcon_Altaria,
+ gMonIcon_Wynaut,
+ gMonIcon_Duskull,
+ gMonIcon_Dusclops,
+ gMonIcon_Roselia,
+ gMonIcon_Slakoth,
+ gMonIcon_Vigoroth,
+ gMonIcon_Slaking,
+ gMonIcon_Gulpin,
+ gMonIcon_Swalot,
+ gMonIcon_Tropius,
+ gMonIcon_Whismur,
+ gMonIcon_Loudred,
+ gMonIcon_Exploud,
+ gMonIcon_Clamperl,
+ gMonIcon_Huntail,
+ gMonIcon_Gorebyss,
+ gMonIcon_Absol,
+ gMonIcon_Shuppet,
+ gMonIcon_Banette,
+ gMonIcon_Seviper,
+ gMonIcon_Zangoose,
+ gMonIcon_Relicanth,
+ gMonIcon_Aron,
+ gMonIcon_Lairon,
+ gMonIcon_Aggron,
+ gMonIcon_Castform,
+ gMonIcon_Volbeat,
+ gMonIcon_Illumise,
+ gMonIcon_Lileep,
+ gMonIcon_Cradily,
+ gMonIcon_Anorith,
+ gMonIcon_Armaldo,
+ gMonIcon_Ralts,
+ gMonIcon_Kirlia,
+ gMonIcon_Gardevoir,
+ gMonIcon_Bagon,
+ gMonIcon_Shelgon,
+ gMonIcon_Salamence,
+ gMonIcon_Beldum,
+ gMonIcon_Metang,
+ gMonIcon_Metagross,
+ gMonIcon_Regirock,
+ gMonIcon_Regice,
+ gMonIcon_Registeel,
+ gMonIcon_Kyogre,
+ gMonIcon_Groudon,
+ gMonIcon_Rayquaza,
+ gMonIcon_Latias,
+ gMonIcon_Latios,
+ gMonIcon_Jirachi,
+ gMonIcon_Deoxys,
+ gMonIcon_Chimecho,
+ gMonIcon_Egg,
+ gMonIcon_UnownB,
+ gMonIcon_UnownC,
+ gMonIcon_UnownD,
+ gMonIcon_UnownE,
+ gMonIcon_UnownF,
+ gMonIcon_UnownG,
+ gMonIcon_UnownH,
+ gMonIcon_UnownI,
+ gMonIcon_UnownJ,
+ gMonIcon_UnownK,
+ gMonIcon_UnownL,
+ gMonIcon_UnownM,
+ gMonIcon_UnownN,
+ gMonIcon_UnownO,
+ gMonIcon_UnownP,
+ gMonIcon_UnownQ,
+ gMonIcon_UnownR,
+ gMonIcon_UnownS,
+ gMonIcon_UnownT,
+ gMonIcon_UnownU,
+ gMonIcon_UnownV,
+ gMonIcon_UnownW,
+ gMonIcon_UnownX,
+ gMonIcon_UnownY,
+ gMonIcon_UnownZ,
+ gMonIcon_UnownExclamationMark,
+ gMonIcon_UnownQuestionMark,
+};
+
+const u8 gMonIconPaletteIndices[] =
+{
+ 0, // ??????????
+ 1, // Bulbasaur
+ 1, // Ivysaur
+ 1, // Venusaur
+ 0, // Charmander
+ 0, // Charmeleon
+ 0, // Charizard
+ 0, // Squirtle
+ 2, // Wartortle
+ 2, // Blastoise
+ 1, // Caterpie
+ 1, // Metapod
+ 0, // Butterfree
+ 1, // Weedle
+ 2, // Kakuna
+ 2, // Beedrill
+ 0, // Pidgey
+ 0, // Pidgeotto
+ 0, // Pidgeot
+ 2, // Rattata
+ 1, // Raticate
+ 0, // Spearow
+ 0, // Fearow
+ 2, // Ekans
+ 2, // Arbok
+ 2, // Pikachu
+ 0, // Raichu
+ 2, // Sandshrew
+ 2, // Sandslash
+ 2, // Nidoran♀
+ 2, // Nidorina
+ 2, // Nidoqueen
+ 2, // Nidoran♂
+ 2, // Nidorino
+ 2, // Nidoking
+ 0, // Clefairy
+ 0, // Clefable
+ 2, // Vulpix
+ 1, // Ninetales
+ 0, // Jigglypuff
+ 0, // Wigglytuff
+ 2, // Zubat
+ 2, // Golbat
+ 1, // Oddish
+ 0, // Gloom
+ 0, // Vileplume
+ 0, // Paras
+ 0, // Parasect
+ 0, // Venonat
+ 2, // Venomoth
+ 2, // Diglett
+ 2, // Dugtrio
+ 1, // Meowth
+ 1, // Persian
+ 1, // Psyduck
+ 2, // Golduck
+ 1, // Mankey
+ 2, // Primeape
+ 0, // Growlithe
+ 0, // Arcanine
+ 0, // Poliwag
+ 0, // Poliwhirl
+ 0, // Poliwrath
+ 2, // Abra
+ 2, // Kadabra
+ 2, // Alakazam
+ 0, // Machop
+ 2, // Machoke
+ 0, // Machamp
+ 1, // Bellsprout
+ 1, // Weepinbell
+ 1, // Victreebel
+ 2, // Tentacool
+ 2, // Tentacruel
+ 1, // Geodude
+ 1, // Graveler
+ 1, // Golem
+ 0, // Ponyta
+ 0, // Rapidash
+ 0, // Slowpoke
+ 0, // Slowbro
+ 0, // Magnemite
+ 0, // Magneton
+ 1, // Farfetch'd
+ 2, // Doduo
+ 2, // Dodrio
+ 2, // Seel
+ 2, // Dewgong
+ 2, // Grimer
+ 2, // Muk
+ 2, // Shellder
+ 2, // Cloyster
+ 2, // Gastly
+ 2, // Haunter
+ 2, // Gengar
+ 2, // Onix
+ 2, // Drowzee
+ 1, // Hypno
+ 2, // Krabby
+ 2, // Kingler
+ 0, // Voltorb
+ 0, // Electrode
+ 0, // Exeggcute
+ 1, // Exeggutor
+ 1, // Cubone
+ 1, // Marowak
+ 2, // Hitmonlee
+ 2, // Hitmonchan
+ 1, // Lickitung
+ 2, // Koffing
+ 2, // Weezing
+ 1, // Rhyhorn
+ 1, // Rhydon
+ 0, // Chansey
+ 0, // Tangela
+ 1, // Kangaskhan
+ 0, // Horsea
+ 0, // Seadra
+ 0, // Goldeen
+ 0, // Seaking
+ 2, // Staryu
+ 2, // Starmie
+ 0, // Mr. mime
+ 1, // Scyther
+ 2, // Jynx
+ 1, // Electabuzz
+ 0, // Magmar
+ 2, // Pinsir
+ 2, // Tauros
+ 0, // Magikarp
+ 0, // Gyarados
+ 2, // Lapras
+ 2, // Ditto
+ 2, // Eevee
+ 0, // Vaporeon
+ 0, // Jolteon
+ 0, // Flareon
+ 0, // Porygon
+ 0, // Omanyte
+ 0, // Omastar
+ 2, // Kabuto
+ 2, // Kabutops
+ 0, // Aerodactyl
+ 1, // Snorlax
+ 0, // Articuno
+ 0, // Zapdos
+ 0, // Moltres
+ 0, // Dratini
+ 0, // Dragonair
+ 2, // Dragonite
+ 2, // Mewtwo
+ 0, // Mew
+ 1, // Chikorita
+ 1, // Bayleef
+ 1, // Meganium
+ 1, // Cyndaquil
+ 1, // Quilava
+ 1, // Typhlosion
+ 2, // Totodile
+ 2, // Croconaw
+ 2, // Feraligatr
+ 2, // Sentret
+ 2, // Furret
+ 2, // Hoothoot
+ 2, // Noctowl
+ 0, // Ledyba
+ 0, // Ledian
+ 1, // Spinarak
+ 0, // Ariados
+ 2, // Crobat
+ 2, // Chinchou
+ 0, // Lanturn
+ 0, // Pichu
+ 0, // Cleffa
+ 1, // Igglybuff
+ 2, // Togepi
+ 2, // Togetic
+ 0, // Natu
+ 0, // Xatu
+ 2, // Mareep
+ 0, // Flaaffy
+ 0, // Ampharos
+ 1, // Bellossom
+ 2, // Marill
+ 2, // Azumarill
+ 1, // Sudowoodo
+ 1, // Politoed
+ 1, // Hoppip
+ 1, // Skiploom
+ 2, // Jumpluff
+ 2, // Aipom
+ 1, // Sunkern
+ 1, // Sunflora
+ 1, // Yanma
+ 0, // Wooper
+ 0, // Quagsire
+ 2, // Espeon
+ 2, // Umbreon
+ 2, // Murkrow
+ 0, // Slowking
+ 0, // Misdreavus
+ 0, // Unown A
+ 0, // Wobbuffet
+ 1, // Girafarig
+ 0, // Pineco
+ 2, // Forretress
+ 2, // Dunsparce
+ 2, // Gligar
+ 0, // Steelix
+ 0, // Snubbull
+ 2, // Granbull
+ 0, // Qwilfish
+ 0, // Scizor
+ 1, // Shuckle
+ 2, // Heracross
+ 0, // Sneasel
+ 0, // Teddiursa
+ 2, // Ursaring
+ 0, // Slugma
+ 0, // Magcargo
+ 2, // Swinub
+ 2, // Piloswine
+ 0, // Corsola
+ 0, // Remoraid
+ 0, // Octillery
+ 0, // Delibird
+ 2, // Mantine
+ 0, // Skarmory
+ 0, // Houndour
+ 0, // Houndoom
+ 0, // Kingdra
+ 0, // Phanpy
+ 0, // Donphan
+ 0, // Porygon2
+ 2, // Stantler
+ 1, // Smeargle
+ 2, // Tyrogue
+ 2, // Hitmontop
+ 1, // Smoochum
+ 1, // Elekid
+ 1, // Magby
+ 1, // Miltank
+ 1, // Blissey
+ 0, // Raikou
+ 2, // Entei
+ 0, // Suicune
+ 1, // Larvitar
+ 0, // Pupitar
+ 1, // Tyranitar
+ 0, // Lugia
+ 1, // Ho-Oh
+ 1, // Celebi
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 0, // ?
+ 1, // Treecko
+ 0, // Grovyle
+ 1, // Sceptile
+ 0, // Torchic
+ 0, // Combusken
+ 0, // Blaziken
+ 0, // Mudkip
+ 0, // Marshtomp
+ 0, // Swampert
+ 2, // Poochyena
+ 2, // Mightyena
+ 2, // Zigzagoon
+ 2, // Linoone
+ 0, // Wurmple
+ 2, // Silcoon
+ 0, // Beautifly
+ 2, // Cascoon
+ 1, // Dustox
+ 1, // Lotad
+ 1, // Lombre
+ 1, // Ludicolo
+ 1, // Seedot
+ 1, // Nuzleaf
+ 0, // Shiftry
+ 1, // Nincada
+ 1, // Ninjask
+ 1, // Shedinja
+ 2, // Taillow
+ 2, // Swellow
+ 1, // Shroomish
+ 1, // Breloom
+ 1, // Spinda
+ 0, // Wingull
+ 0, // Pelipper
+ 2, // Surskit
+ 0, // Masquerain
+ 2, // Wailmer
+ 0, // Wailord
+ 0, // Skitty
+ 2, // Delcatty
+ 1, // Kecleon
+ 1, // Baltoy
+ 0, // Claydol
+ 0, // Nosepass
+ 1, // Torkoal
+ 2, // Sableye
+ 0, // Barboach
+ 0, // Whiscash
+ 0, // Luvdisc
+ 0, // Corphish
+ 0, // Crawdaunt
+ 2, // Feebas
+ 0, // Milotic
+ 0, // Carvanha
+ 0, // Sharpedo
+ 1, // Trapinch
+ 1, // Vibrava
+ 1, // Flygon
+ 2, // Makuhita
+ 1, // Hariyama
+ 1, // Electrike
+ 0, // Manectric
+ 1, // Numel
+ 0, // Camerupt
+ 2, // Spheal
+ 2, // Sealeo
+ 0, // Walrein
+ 1, // Cacnea
+ 1, // Cacturne
+ 2, // Snorunt
+ 0, // Glalie
+ 1, // Lunatone
+ 0, // Solrock
+ 2, // Azurill
+ 0, // Spoink
+ 2, // Grumpig
+ 0, // Plusle
+ 0, // Minun
+ 2, // Mawile
+ 0, // Meditite
+ 0, // Medicham
+ 0, // Swablu
+ 0, // Altaria
+ 0, // Wynaut
+ 0, // Duskull
+ 0, // Dusclops
+ 0, // Roselia
+ 2, // Slakoth
+ 2, // Vigoroth
+ 1, // Slaking
+ 1, // Gulpin
+ 2, // Swalot
+ 1, // Tropius
+ 0, // Whismur
+ 2, // Loudred
+ 2, // Exploud
+ 0, // Clamperl
+ 0, // Huntail
+ 0, // Gorebyss
+ 0, // Absol
+ 0, // Shuppet
+ 0, // Banette
+ 2, // Seviper
+ 0, // Zangoose
+ 1, // Relicanth
+ 2, // Aron
+ 2, // Lairon
+ 2, // Aggron
+ 0, // Castform
+ 0, // Volbeat
+ 2, // Illumise
+ 2, // Lileep
+ 0, // Cradily
+ 0, // Anorith
+ 0, // Armaldo
+ 1, // Ralts
+ 1, // Kirlia
+ 1, // Gardevoir
+ 2, // Bagon
+ 2, // Shelgon
+ 0, // Salamence
+ 0, // Beldum
+ 0, // Metang
+ 0, // Metagross
+ 2, // Regirock
+ 2, // Regice
+ 2, // Registeel
+ 2, // Kyogre
+ 0, // Groudon
+ 1, // Rayquaza
+ 0, // Latias
+ 2, // Latios
+ 0, // Jirachi
+ 0, // Deoxys
+ 0, // Chimecho
+ 1, // Egg
+ 0, // Unown B
+ 0, // Unown C
+ 0, // Unown D
+ 0, // Unown E
+ 0, // Unown F
+ 0, // Unown G
+ 0, // Unown H
+ 0, // Unown I
+ 0, // Unown J
+ 0, // Unown K
+ 0, // Unown L
+ 0, // Unown M
+ 0, // Unown N
+ 0, // Unown O
+ 0, // Unown P
+ 0, // Unown Q
+ 0, // Unown R
+ 0, // Unown S
+ 0, // Unown T
+ 0, // Unown U
+ 0, // Unown V
+ 0, // Unown W
+ 0, // Unown X
+ 0, // Unown Y
+ 0, // Unown Z
+ 0, // Unown Exclamation Mark
+ 0, // Unown Question Mark
+};
+
+const struct SpritePalette gMonIconPaletteTable[] =
+{
+ { gMonIconPalettes[0], POKE_ICON_BASE_PAL_TAG + 0 },
+ { gMonIconPalettes[1], POKE_ICON_BASE_PAL_TAG + 1 },
+ { gMonIconPalettes[2], POKE_ICON_BASE_PAL_TAG + 2 },
+
+// There are only 3 actual palettes. The following are unused
+// and don't point to valid data.
+ { gMonIconPalettes[3], POKE_ICON_BASE_PAL_TAG + 3 },
+ { gMonIconPalettes[4], POKE_ICON_BASE_PAL_TAG + 4 },
+ { gMonIconPalettes[5], POKE_ICON_BASE_PAL_TAG + 5 },
+};
+
+const struct OamData sMonIconOamData =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+// fastest to slowest
+
+static const union AnimCmd sAnim_0[] =
+{
+ ANIMCMD_FRAME(0, 6),
+ ANIMCMD_FRAME(1, 6),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sAnim_1[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(1, 8),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sAnim_2[] =
+{
+ ANIMCMD_FRAME(0, 14),
+ ANIMCMD_FRAME(1, 14),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sAnim_3[] =
+{
+ ANIMCMD_FRAME(0, 22),
+ ANIMCMD_FRAME(1, 22),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sAnim_4[] =
+{
+ ANIMCMD_FRAME(0, 29),
+ ANIMCMD_FRAME(0, 29), // frame 0 is repeated
+ ANIMCMD_JUMP(0),
+};
+
+const union AnimCmd *const sMonIconAnims[] =
+{
+ sAnim_0,
+ sAnim_1,
+ sAnim_2,
+ sAnim_3,
+ sAnim_4,
+};
+
+static const union AffineAnimCmd sAffineAnim_0[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, 0, 10),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sAffineAnim_1[] =
+{
+ AFFINEANIMCMD_FRAME(-2, -2, 0, 122),
+ AFFINEANIMCMD_END,
+};
+
+const union AffineAnimCmd *const sMonIconAffineAnims[] =
+{
+ sAffineAnim_0,
+ sAffineAnim_1,
+};
+
+const u16 sSpriteImageSizes[3][4] =
+{
+ // square
+ {
+ 0x20, // 1×1
+ 0x80, // 2×2
+ 0x200, // 4×4
+ 0x800, // 8×8
+ },
+
+ // horizontal rectangle
+ {
+ 0x40, // 2×1
+ 0x80, // 4×1
+ 0x100, // 4×2
+ 0x400, // 8×4
+ },
+
+ // vertical rectangle
+ {
+ 0x40, // 1×2
+ 0x80, // 1×4
+ 0x100, // 2×4
+ 0x400, // 4×8
+ },
+};
diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c
index bdf4427c7..bb196dd27 100644
--- a/src/pokemon_storage_system.c
+++ b/src/pokemon_storage_system.c
@@ -5,9 +5,76 @@
#include "event_data.h"
#include "string_util.h"
#include "text.h"
+#include "strings.h"
+#include "window.h"
IWRAM_DATA u8 gUnknown_03000F78[0x188];
+struct OptionAndDescription
+{
+ const u8 *optionTxt;
+ const u8 *descriptionTxt;
+};
+
+// const rom data
+const struct OptionAndDescription gUnknown_085716C0[] =
+{
+ {gText_WithdrawPokemon, gText_WithdrawMonDescription},
+ {gText_DepositPokemon, gText_DepositMonDescription},
+ {gText_MovePokemon, gText_MoveMonDescription},
+ {gText_MoveItems, gText_MoveItemsDescription},
+ {gText_SeeYa, gText_SeeYaDescription}
+};
+
+const struct WindowTemplate gUnknown_085716E8 = {0, 1, 1, 0x11, 0xA, 0xF, 1};
+
+static const union AnimCmd sSpriteAnim_85716F0[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85716F8[] =
+{
+ ANIMCMD_FRAME(4, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8571700[] =
+{
+ ANIMCMD_FRAME(6, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8571708[] =
+{
+ ANIMCMD_FRAME(10, 5),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const sSpriteAnimTable_8571710[] =
+{
+ sSpriteAnim_85716F0,
+ sSpriteAnim_85716F8,
+ sSpriteAnim_8571700,
+ sSpriteAnim_8571708
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8571720[] =
+{
+ AFFINEANIMCMD_FRAME(0xE0, 0xE0, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_8571730[] =
+{
+ sSpriteAffineAnim_8571720
+};
+
+const struct TextColor gUnknown_08571734[] = {4, 0xF, 0xE};
+const u8 gUnknown_08571737[] = _("/30");
+
+// code
u8 CountMonsInBox(u8 boxId)
{
u16 i, count;
diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c
index b00979945..e56448d8b 100755
--- a/src/pokemon_summary_screen.c
+++ b/src/pokemon_summary_screen.c
@@ -41,7 +41,7 @@ struct ContestEffect
extern struct UnkSummaryStruct* gUnknown_0203CF1C;
extern struct BgTemplate gUnknown_0861CBB4;
extern u8 gUnknown_0203CF20;
-extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern s8 gUnknown_0861CC1C[];
extern u8 gUnknown_08329D22[];
extern u8 gUnknown_0203CF21;
@@ -50,7 +50,7 @@ extern struct UnkStruct_61CC04 gUnknown_0861CC04;
extern struct UnkStruct_61CC04 gUnknown_0861CC10;
extern struct UnkStruct_61CC04 gUnknown_0861CBEC;
extern struct UnkStruct_61CC04 gUnknown_0861CBF8;
-extern u16 gUnknown_08DC3CD4[];
+extern u16 gSummaryScreenWindow_Tilemap[];
extern struct ContestMove gContestMoves[];
extern struct ContestEffect gContestEffects[];
extern struct WindowTemplate gUnknown_0861CC24;
@@ -73,7 +73,7 @@ extern void do_scheduled_bg_tilemap_copies_to_vram(void);
extern u8 sub_81221EC();
extern u8 sub_81221AC();
extern void SetVBlankHBlankCallbacksToNull();
-extern void sub_8121DA0();
+extern void ResetVramOamAndBgCntRegs();
extern void clear_scheduled_bg_copies_to_vram();
extern void remove_some_task();
extern void ResetBgsAndClearDma3BusyFlags(u32 leftoverFireRedLeafGreenVariable);
@@ -93,7 +93,7 @@ extern struct CompressedSpriteSheet gUnknown_0861D074;
extern struct CompressedSpriteSheet gUnknown_0861D0F8;
extern struct CompressedSpritePalette gUnknown_0861D100;
extern struct CompressedSpritePalette gUnknown_0861D07C;
-extern u8 gUnknown_08D97B84;
+extern u8 gMoveTypes_Pal;
extern u8 gUnknown_08D97D0C;
extern void reset_temp_tile_data_buffers();
extern void decompress_and_copy_tile_data_to_vram(u8 a, void* tiledata, u8 b, u8 c, u8 d);
@@ -193,7 +193,7 @@ void sub_81C4A88();
void sub_81C4280();
void sub_81C0510(u8 taskId);
void sub_81C171C(u8 taskId);
-void sub_8121E10();
+void ResetAllBgsCoordinates();
u8 sub_81B205C(struct Pokemon* a);
void sub_81C1DA4(u16 a, s16 b);
void sub_81C1EFC(u16 a, s16 b, u16 c);
@@ -450,7 +450,7 @@ bool8 sub_81BFB10(void)
{
case 0:
SetVBlankHBlankCallbacksToNull();
- sub_8121DA0();
+ ResetVramOamAndBgCntRegs();
clear_scheduled_bg_copies_to_vram();
gMain.state++;
break;
@@ -578,7 +578,7 @@ void sub_81BFE24()
SetBgTilemapBuffer(1, &gUnknown_0203CF1C->unkTilemap2);
SetBgTilemapBuffer(2, &gUnknown_0203CF1C->unkTilemap1);
SetBgTilemapBuffer(3, &gUnknown_0203CF1C->unkTilemap0);
- sub_8121E10();
+ ResetAllBgsCoordinates();
schedule_bg_copy_tilemap_to_vram(1);
schedule_bg_copy_tilemap_to_vram(2);
schedule_bg_copy_tilemap_to_vram(3);
@@ -648,7 +648,7 @@ u8 sub_81BFEB0()
gUnknown_0203CF1C->unk40F0++;
break;
case 12:
- LoadCompressedPalette(&gUnknown_08D97B84, 0x1D0, 0x60);
+ LoadCompressedPalette(&gMoveTypes_Pal, 0x1D0, 0x60);
gUnknown_0203CF1C->unk40F0 = 0;
return 1;
}
@@ -793,7 +793,7 @@ void sub_81C0484(u8 taskId)
ResetSpriteData();
FreeAllSpritePalettes();
StopCryAndClearCrySongs();
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
if (gMonSpritesGfxPtr == 0)
sub_806F47C(0);
sub_81C0434();
@@ -2343,18 +2343,18 @@ void sub_81C2194(u16 *a, u16 b, u8 c)
{
for (i = 0; i < 20; i++)
{
- a[(i + var) << 1] = gUnknown_08DC3CD4[i] + b;
- a[((i + var) << 1) + 0x40] = gUnknown_08DC3CD4[i] + b;
- a[((i + var) << 1) + 0x80] = gUnknown_08DC3CD4[i + 20] + b;
+ a[(i + var) << 1] = gSummaryScreenWindow_Tilemap[i] + b;
+ a[((i + var) << 1) + 0x40] = gSummaryScreenWindow_Tilemap[i] + b;
+ a[((i + var) << 1) + 0x80] = gSummaryScreenWindow_Tilemap[i + 20] + b;
}
}
else
{
for (i = 0; i < 20; i++)
{
- a[(i + var)] = gUnknown_08DC3CD4[i + 20] + b;
- a[((i + var)) + 0x40] = gUnknown_08DC3CD4[i + 40] + b;
- a[((i + var)) + 0x80] = gUnknown_08DC3CD4[i + 40] + b;
+ a[(i + var)] = gSummaryScreenWindow_Tilemap[i + 20] + b;
+ a[((i + var)) + 0x40] = gSummaryScreenWindow_Tilemap[i + 40] + b;
+ a[((i + var)) + 0x80] = gSummaryScreenWindow_Tilemap[i + 40] + b;
}
}
}
@@ -2372,7 +2372,7 @@ void sub_81C2194(u16 *a, u16 b, u8 c)
cmp r2, 0\n\
bne _081C21E4\n\
movs r3, 0\n\
- ldr r5, =gUnknown_08DC3CD4\n\
+ ldr r5, =gSummaryScreenWindow_Tilemap\n\
_081C21A8:\n\
adds r2, r7, r3\n\
lsls r2, 1\n\
@@ -2402,7 +2402,7 @@ _081C21A8:\n\
.pool\n\
_081C21E4:\n\
movs r3, 0\n\
- ldr r5, =gUnknown_08DC3CD4\n\
+ ldr r5, =gSummaryScreenWindow_Tilemap\n\
_081C21E8:\n\
adds r1, r7, r3\n\
lsls r1, 1\n\
diff --git a/src/rayquaza_scene.c b/src/rayquaza_scene.c
new file mode 100644
index 000000000..ce8747395
--- /dev/null
+++ b/src/rayquaza_scene.c
@@ -0,0 +1,1164 @@
+#include "global.h"
+#include "sprite.h"
+#include "task.h"
+#include "graphics.h"
+#include "bg.h"
+
+struct UnkRayquazaStruct
+{
+ u32 field_0;
+ u32 field_4;
+ u32 field_8;
+};
+
+// this file's functions
+void sub_81D7134(u8 taskId);
+void sub_81D7F4C(u8 taskId);
+void sub_81D84EC(u8 taskId);
+void sub_81D8980(u8 taskId);
+void sub_81D8DB4(u8 taskId);
+void sub_81D6800(u8 taskId);
+
+void sub_81D8260(struct Sprite *sprite);
+void sub_81D961C(struct Sprite *sprite);
+
+// const rom data
+const TaskFunc gUnknown_0862A6A0[] =
+{
+ sub_81D7134,
+ sub_81D7134,
+ sub_81D7F4C,
+ sub_81D84EC,
+ sub_81D8980,
+ sub_81D8DB4,
+ sub_81D6800
+};
+
+static const struct OamData sOamData_862A6BC =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_862A6C4 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_862A6CC =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_862A6D4 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_862A6DC =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_862A6E4 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 2,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_862A6EC =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_862A6F4 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_862A6FC[] =
+{
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_FRAME(64, 30),
+ ANIMCMD_FRAME(128, 30),
+ ANIMCMD_FRAME(64, 30),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sSpriteAnim_862A710[] =
+{
+ ANIMCMD_FRAME(192, 30),
+ ANIMCMD_FRAME(256, 30),
+ ANIMCMD_FRAME(320, 30),
+ ANIMCMD_FRAME(256, 30),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862A724[] =
+{
+ sSpriteAnim_862A6FC,
+ sSpriteAnim_862A710
+};
+
+const struct SpriteTemplate gUnknown_0862A72C =
+{
+ .tileTag = 30505,
+ .paletteTag = 30505,
+ .oam = &sOamData_862A6BC,
+ .anims = sSpriteAnimTable_862A724,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AnimCmd sSpriteAnim_862A744[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862A74C[] =
+{
+ sSpriteAnim_862A744
+};
+
+const struct SpriteTemplate gUnknown_0862A750 =
+{
+ .tileTag = 30506,
+ .paletteTag = 30505,
+ .oam = &sOamData_862A6C4,
+ .anims = sSpriteAnimTable_862A74C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AnimCmd sSpriteAnim_862A768[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862A770[] =
+{
+ sSpriteAnim_862A768
+};
+
+const struct SpriteTemplate gUnknown_0862A774 =
+{
+ .tileTag = 30507,
+ .paletteTag = 30505,
+ .oam = &sOamData_862A6CC,
+ .anims = sSpriteAnimTable_862A770,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AnimCmd sSpriteAnim_862A78C[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A794[] =
+{
+ ANIMCMD_FRAME(8, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A79C[] =
+{
+ ANIMCMD_FRAME(16, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A7A4[] =
+{
+ ANIMCMD_FRAME(24, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A7AC[] =
+{
+ ANIMCMD_FRAME(32, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A7B4[] =
+{
+ ANIMCMD_FRAME(40, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A7BC[] =
+{
+ ANIMCMD_FRAME(48, 36),
+ ANIMCMD_FRAME(64, 36),
+ ANIMCMD_FRAME(80, 36),
+ ANIMCMD_FRAME(64, 36),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sSpriteAnim_862A7D0[] =
+{
+ ANIMCMD_FRAME(56, 36),
+ ANIMCMD_FRAME(72, 36),
+ ANIMCMD_FRAME(88, 36),
+ ANIMCMD_FRAME(72, 36),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sSpriteAnim_862A7E4[] =
+{
+ ANIMCMD_FRAME(96, 36),
+ ANIMCMD_FRAME(104, 36),
+ ANIMCMD_FRAME(112, 36),
+ ANIMCMD_FRAME(104, 36),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862A7F8[] =
+{
+ sSpriteAnim_862A78C,
+ sSpriteAnim_862A794,
+ sSpriteAnim_862A79C,
+ sSpriteAnim_862A7A4,
+ sSpriteAnim_862A7AC,
+ sSpriteAnim_862A7B4,
+ sSpriteAnim_862A7BC,
+ sSpriteAnim_862A7D0,
+ sSpriteAnim_862A7E4
+};
+
+const struct SpriteTemplate gUnknown_0862A81C =
+{
+ .tileTag = 30508,
+ .paletteTag = 30508,
+ .oam = &sOamData_862A6D4,
+ .anims = sSpriteAnimTable_862A7F8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AnimCmd sSpriteAnim_862A834[] =
+{
+ ANIMCMD_FRAME(0, 36),
+ ANIMCMD_FRAME(2, 36),
+ ANIMCMD_FRAME(4, 36),
+ ANIMCMD_FRAME(2, 36),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862A848[] =
+{
+ sSpriteAnim_862A834
+};
+
+const struct SpriteTemplate gUnknown_0862A84C =
+{
+ .tileTag = 30509,
+ .paletteTag = 30508,
+ .oam = &sOamData_862A6DC,
+ .anims = sSpriteAnimTable_862A848,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct SpriteTemplate gUnknown_0862A864 =
+{
+ .tileTag = 30510,
+ .paletteTag = 30508,
+ .oam = &sOamData_862A6C4,
+ .anims = sSpriteAnimTable_862A74C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct UnkRayquazaStruct gUnknown_0862A87C = {0x4000014, 0xA2600001, 1};
+
+const struct BgTemplate gUnknown_0862A888[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 29,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ },
+};
+
+static const union AnimCmd sSpriteAnim_862A894[] =
+{
+ ANIMCMD_FRAME(0, 20),
+ ANIMCMD_FRAME(64, 20),
+ ANIMCMD_FRAME(128, 20),
+ ANIMCMD_FRAME(64, 20),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sSpriteAnim_862A8A8[] =
+{
+ ANIMCMD_FRAME(192, 20),
+ ANIMCMD_FRAME(256, 20),
+ ANIMCMD_FRAME(320, 20),
+ ANIMCMD_FRAME(256, 20),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862A8BC[] =
+{
+ sSpriteAnim_862A894,
+ sSpriteAnim_862A8A8
+};
+
+const struct CompressedSpriteSheet gUnknown_0862A8C4 =
+{
+ gRaySceneGroudon_Gfx, 0x3000, 30505
+};
+
+const struct CompressedSpritePalette gUnknown_0862A8CC =
+{
+ gRaySceneGroudon_Pal, 30505
+};
+
+const struct SpriteTemplate gUnknown_0862A8D4 =
+{
+ .tileTag = 30505,
+ .paletteTag = 30505,
+ .oam = &sOamData_862A6BC,
+ .anims = sSpriteAnimTable_862A8BC,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AnimCmd sSpriteAnim_862A8EC[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862A8F4[] =
+{
+ sSpriteAnim_862A8EC
+};
+
+const struct CompressedSpriteSheet gUnknown_0862A8F8 =
+{
+ gRaySceneGroudon2_Gfx, 0x200, 30506
+};
+
+const struct SpriteTemplate gUnknown_0862A900 =
+{
+ .tileTag = 30506,
+ .paletteTag = 30505,
+ .oam = &sOamData_862A6C4,
+ .anims = sSpriteAnimTable_862A8F4,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AnimCmd sSpriteAnim_862A918[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862A920[] =
+{
+ sSpriteAnim_862A918
+};
+
+const struct CompressedSpriteSheet gUnknown_0862A924 =
+{
+ gRaySceneGroudon3_Gfx, 0x400, 30507
+};
+
+const struct SpriteTemplate gUnknown_0862A92C =
+{
+ .tileTag = 30507,
+ .paletteTag = 30505,
+ .oam = &sOamData_862A6CC,
+ .anims = sSpriteAnimTable_862A920,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AnimCmd sSpriteAnim_862A944[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A94C[] =
+{
+ ANIMCMD_FRAME(8, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A954[] =
+{
+ ANIMCMD_FRAME(16, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A95C[] =
+{
+ ANIMCMD_FRAME(24, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A964[] =
+{
+ ANIMCMD_FRAME(32, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A96C[] =
+{
+ ANIMCMD_FRAME(40, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862A974[] =
+{
+ ANIMCMD_FRAME(48, 24),
+ ANIMCMD_FRAME(64, 24),
+ ANIMCMD_FRAME(80, 24),
+ ANIMCMD_FRAME(64, 24),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sSpriteAnim_862A988[] =
+{
+ ANIMCMD_FRAME(56, 24),
+ ANIMCMD_FRAME(72, 24),
+ ANIMCMD_FRAME(88, 24),
+ ANIMCMD_FRAME(72, 24),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sSpriteAnim_862A99C[] =
+{
+ ANIMCMD_FRAME(96, 24),
+ ANIMCMD_FRAME(104, 24),
+ ANIMCMD_FRAME(112, 24),
+ ANIMCMD_FRAME(104, 24),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862A9B0[] =
+{
+ sSpriteAnim_862A944,
+ sSpriteAnim_862A94C,
+ sSpriteAnim_862A954,
+ sSpriteAnim_862A95C,
+ sSpriteAnim_862A964,
+ sSpriteAnim_862A96C,
+ sSpriteAnim_862A974,
+ sSpriteAnim_862A988,
+ sSpriteAnim_862A99C
+};
+
+const struct CompressedSpriteSheet gUnknown_0862A9D4 =
+{
+ gRaySceneKyogre_Gfx, 0xF00, 30508
+};
+
+const struct CompressedSpritePalette gUnknown_0862A9DC =
+{
+ gRaySceneKyogre_Pal, 30508
+};
+
+const struct SpriteTemplate gUnknown_0862A9E4 =
+{
+ .tileTag = 30508,
+ .paletteTag = 30508,
+ .oam = &sOamData_862A6D4,
+ .anims = sSpriteAnimTable_862A9B0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AnimCmd sSpriteAnim_862A9FC[] =
+{
+ ANIMCMD_FRAME(0, 24),
+ ANIMCMD_FRAME(2, 24),
+ ANIMCMD_FRAME(4, 24),
+ ANIMCMD_FRAME(2, 24),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862AA10[] =
+{
+ sSpriteAnim_862A9FC
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AA14 =
+{
+ gRaySceneKyogre2_Gfx, 0xC0, 30509
+};
+
+const struct SpriteTemplate gUnknown_0862AA1C =
+{
+ .tileTag = 30509,
+ .paletteTag = 30508,
+ .oam = &sOamData_862A6DC,
+ .anims = sSpriteAnimTable_862AA10,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AA34 =
+{
+ gRaySceneKyogre3_Gfx, 0x200, 30510
+};
+
+const struct SpriteTemplate gUnknown_0862AA3C =
+{
+ .tileTag = 30510,
+ .paletteTag = 30508,
+ .oam = &sOamData_862A6C4,
+ .anims = sSpriteAnimTable_862A8F4,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct BgTemplate gUnknown_0862AA54[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 1,
+ .mapBaseIndex = 29,
+ .screenSize = 1,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ }
+};
+
+static const union AnimCmd sSpriteAnim_862AA60[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862AA68[] =
+{
+ sSpriteAnim_862AA60
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_862AA6C[] =
+{
+ AFFINEANIMCMD_FRAME(-64, -64, 0, 1),
+ AFFINEANIMCMD_FRAME(32, 32, 0, 14),
+ AFFINEANIMCMD_FRAME(256, 256, 0, 0),
+ AFFINEANIMCMD_JUMP(0)
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_862AA8C[] =
+{
+ sSpriteAffineAnim_862AA6C
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AA90 =
+{
+ gRaySceneSmoke_Gfx, 0x100, 30555
+};
+
+const struct CompressedSpritePalette gUnknown_0862AA98 =
+{
+ gRaySceneSmoke_Pal, 30555
+};
+
+const struct SpriteTemplate gUnknown_0862AAA0 =
+{
+ .tileTag = 30555,
+ .paletteTag = 30555,
+ .oam = &sOamData_862A6D4,
+ .anims = sSpriteAnimTable_862AA68,
+ .images = NULL,
+ .affineAnims = sSpriteAffineAnimTable_862AA8C,
+ .callback = sub_81D8260,
+};
+
+const s8 gUnknown_0862AAB8[][2] =
+{
+ {-1, 5},
+ {-3, -4},
+ {5, -3},
+ {-7, 2},
+ {-9, -1},
+ {1, -5},
+ {3, 4},
+ {-5, 3},
+ {7, -2},
+ {9, 1}
+};
+
+const struct BgTemplate gUnknown_0862AACC[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 1,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 29,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0
+ },
+ {
+ .bg = 3,
+ .charBaseIndex = 1,
+ .mapBaseIndex = 28,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0
+ }
+};
+
+static const union AnimCmd sSpriteAnim_862AADC[] =
+{
+ ANIMCMD_FRAME(0, 32),
+ ANIMCMD_FRAME(64, 32),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862AAE8[] =
+{
+ sSpriteAnim_862AADC
+};
+
+static const union AnimCmd sSpriteAnim_862AAEC[] =
+{
+ ANIMCMD_FRAME(0, 32),
+ ANIMCMD_FRAME(8, 32),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862AAF8[] =
+{
+ sSpriteAnim_862AAEC
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AAFC =
+{
+ gRaySceneRayquazaFly1_Gfx, 0x1000, 30556
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AB04 =
+{
+ gRaySceneRayquazaTail_Gfx, 0x200, 30557
+};
+
+const struct CompressedSpritePalette gUnknown_0862AB0C =
+{
+ gRaySceneRayquaza_Pal, 30556
+};
+
+const struct SpriteTemplate gUnknown_0862AB14 =
+{
+ .tileTag = 30556,
+ .paletteTag = 30556,
+ .oam = &sOamData_862A6BC,
+ .anims = sSpriteAnimTable_862AAE8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct SpriteTemplate gUnknown_0862AB2C =
+{
+ .tileTag = 30557,
+ .paletteTag = 30556,
+ .oam = &sOamData_862A6E4,
+ .anims = sSpriteAnimTable_862AAF8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct BgTemplate gUnknown_0862AB44[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 1,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 29,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0
+ },
+ {
+ .bg = 3,
+ .charBaseIndex = 3,
+ .mapBaseIndex = 28,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0
+ }
+};
+
+static const union AnimCmd sSpriteAnim_862AB54[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862AB5C[] =
+{
+ ANIMCMD_FRAME(0, 48),
+ ANIMCMD_FRAME(64, 32),
+ ANIMCMD_FRAME(0, 48),
+ ANIMCMD_FRAME(128, 32),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862AB70[] =
+{
+ sSpriteAnim_862AB54,
+ sSpriteAnim_862AB5C
+};
+
+static const union AnimCmd sSpriteAnim_862AB78[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862AB80[] =
+{
+ sSpriteAnim_862AB78,
+};
+
+static const union AnimCmd sSpriteAnim_862AB84[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862AB8C[] =
+{
+ ANIMCMD_FRAME(16, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862AB94[] =
+{
+ ANIMCMD_FRAME(32, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862AB9C[] =
+{
+ sSpriteAnim_862AB84,
+ sSpriteAnim_862AB8C,
+ sSpriteAnim_862AB94
+};
+
+static const union AnimCmd sSpriteAnim_862ABA8[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862ABB0[] =
+{
+ ANIMCMD_FRAME(64, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862ABB8[] =
+{
+ ANIMCMD_FRAME(128, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862ABC0[] =
+{
+ ANIMCMD_FRAME(192, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862ABC8[] =
+{
+ sSpriteAnim_862ABA8,
+ sSpriteAnim_862ABB0,
+ sSpriteAnim_862ABB8,
+ sSpriteAnim_862ABC0
+};
+
+static const union AnimCmd sSpriteAnim_862ABD8[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862ABE0[] =
+{
+ ANIMCMD_FRAME(16, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862ABE8[] =
+{
+ ANIMCMD_FRAME(32, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_862ABF0[] =
+{
+ ANIMCMD_FRAME(48, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862ABF8[] =
+{
+ sSpriteAnim_862ABD8,
+ sSpriteAnim_862ABE0,
+ sSpriteAnim_862ABE8,
+ sSpriteAnim_862ABF0
+};
+
+static const union AnimCmd sSpriteAnim_862AC08[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(4, 8),
+ ANIMCMD_FRAME(8, 8),
+ ANIMCMD_FRAME(12, 8),
+ ANIMCMD_FRAME(16, 8),
+ ANIMCMD_FRAME(20, 8),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd *const sSpriteAnimTable_862AC24[] =
+{
+ sSpriteAnim_862AC08
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AC28 =
+{
+ gRaySceneGroudonLeft_Gfx, 0x1800, 30565
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AC30 =
+{
+ gRaySceneGroudonTail_Gfx, 0x80, 30566
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AC38 =
+{
+ gRaySceneKyogreRight_Gfx, 0x600, 30568
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AC40 =
+{
+ gRaySceneRayquazaHover_Gfx, 0x2000, 30569
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AC48 =
+{
+ gRaySceneRayquazaFlyIn_Gfx, 0x800, 30570
+};
+
+const struct CompressedSpriteSheet gUnknown_0862AC50 =
+{
+ gRaySceneSplash_Gfx, 0x300, 30571
+};
+
+const struct CompressedSpritePalette gUnknown_0862AC58 =
+{
+ gRaySceneGroudonLeft_Pal, 30565
+};
+
+const struct CompressedSpritePalette gUnknown_0862AC60 =
+{
+ gRaySceneKyogreRight_Pal, 30568
+};
+
+const struct CompressedSpritePalette gUnknown_0862AC68 =
+{
+ gRaySceneRayquazaHover_Pal, 30569
+};
+
+const struct CompressedSpritePalette gUnknown_0862AC70 =
+{
+ gRaySceneSplash_Pal, 30571
+};
+
+const struct SpriteTemplate gUnknown_0862AC78 =
+{
+ .tileTag = 30565,
+ .paletteTag = 30565,
+ .oam = &sOamData_862A6BC,
+ .anims = sSpriteAnimTable_862AB70,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct SpriteTemplate gUnknown_0862AC90 =
+{
+ .tileTag = 30566,
+ .paletteTag = 30565,
+ .oam = &sOamData_862A6EC,
+ .anims = sSpriteAnimTable_862AB80,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct SpriteTemplate gUnknown_0862ACA8 =
+{
+ .tileTag = 30568,
+ .paletteTag = 30568,
+ .oam = &sOamData_862A6C4,
+ .anims = sSpriteAnimTable_862AB9C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct SpriteTemplate gUnknown_0862ACC0 =
+{
+ .tileTag = 30569,
+ .paletteTag = 30569,
+ .oam = &sOamData_862A6BC,
+ .anims = sSpriteAnimTable_862ABC8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_81D961C,
+};
+
+const struct SpriteTemplate gUnknown_0862ACD8 =
+{
+ .tileTag = 30570,
+ .paletteTag = 30569,
+ .oam = &sOamData_862A6C4,
+ .anims = sSpriteAnimTable_862ABF8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct SpriteTemplate gUnknown_0862ACF0 =
+{
+ .tileTag = 30571,
+ .paletteTag = 30571,
+ .oam = &sOamData_862A6F4,
+ .anims = sSpriteAnimTable_862AC24,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct BgTemplate gUnknown_0862AD08[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 1,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 1,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 29,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ }
+};
+
diff --git a/src/recorded_battle.c b/src/recorded_battle.c
index 4f3fe4ab9..c88229c61 100644
--- a/src/recorded_battle.c
+++ b/src/recorded_battle.c
@@ -19,7 +19,7 @@
| BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_ROAMER | BATTLE_TYPE_EREADER_TRAINER \
| BATTLE_TYPE_KYOGRE_GROUDON | BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_REGI \
| BATTLE_TYPE_RECORDED | BATTLE_TYPE_x4000000 | BATTLE_TYPE_SECRET_BASE \
- | BATTLE_TYPE_GROUDON | BATTLE_TYPE_KYORGE | BATTLE_TYPE_RAYQUAZA))
+ | BATTLE_TYPE_GROUDON | BATTLE_TYPE_KYOGRE | BATTLE_TYPE_RAYQUAZA))
extern u32 gBattleTypeFlags;
extern u16 gTrainerBattleOpponent_A;
diff --git a/src/region_map.c b/src/region_map.c
index b7fc625ca..086c0ba68 100644
--- a/src/region_map.c
+++ b/src/region_map.c
@@ -21,6 +21,7 @@
#include "m4a.h"
#include "field_effect.h"
#include "region_map.h"
+#include "constants/region_map_sections.h"
#define MAP_WIDTH 28
#define MAP_HEIGHT 15
@@ -239,9 +240,9 @@ static const u8 sRegionMapFrameTilemapLZ[] = INCBIN_U8("graphics/pokenav/map_fra
static const u16 Unknown_085A1D48[] = INCBIN_U16("graphics/pokenav/fly_target_icons.gbapal");
-static const u8 gUnknown_085A1D68[] = INCBIN_U8("graphics/pokenav/fly_target_icons.4bpp.lz");
+static const u8 sUnknown_085A1D68[] = INCBIN_U8("graphics/pokenav/fly_target_icons.4bpp.lz");
-static const u8 gUnknown_085A1E3C[][3] = {
+static const u8 sUnknown_085A1E3C[][3] = {
{MAP_GROUP(LITTLEROOT_TOWN), MAP_NUM(LITTLEROOT_TOWN), 1},
{MAP_GROUP(OLDALE_TOWN), MAP_NUM(OLDALE_TOWN), 14},
{MAP_GROUP(DEWFORD_TOWN), MAP_NUM(DEWFORD_TOWN), 15},
@@ -306,7 +307,7 @@ static const struct {
} gUnknown_085A1EDC[] = {
gUnknown_085A1ED4,
MAPSEC_EVER_GRANDE_CITY,
- FLAG_SYS_POKEMON_LEAGUE_FLY
+ FLAG_LANDMARK_POKEMON_LEAGUE
};
static const struct BgTemplate gUnknown_085A1EE4[] = {
@@ -326,8 +327,8 @@ static const struct SpritePalette gUnknown_085A1F10 = {
Unknown_085A1D48, 2
};
-static const u16 gUnknown_085A1F18[][2] = {
- {FLAG_UNLOCK_BATTLE_FRONTIER, MAPSEC_BATTLE_FRONTIER},
+static const u16 sUnknown_085A1F18[][2] = {
+ {FLAG_LANDMARK_BATTLE_FRONTIER, MAPSEC_BATTLE_FRONTIER},
{-1, MAPSEC_NONE}
};
@@ -1126,9 +1127,9 @@ static u8 get_flagnr_blue_points(u16 mapSecId)
case MAPSEC_EVER_GRANDE_CITY:
return FlagGet(FLAG_VISITED_EVER_GRANDE_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
case MAPSEC_BATTLE_FRONTIER:
- return FlagGet(FLAG_UNLOCK_BATTLE_FRONTIER) ? MAPSECTYPE_BATTLE_FRONTIER : MAPSECTYPE_NONE;
+ return FlagGet(FLAG_LANDMARK_BATTLE_FRONTIER) ? MAPSECTYPE_BATTLE_FRONTIER : MAPSECTYPE_NONE;
case MAPSEC_SOUTHERN_ISLAND:
- return FlagGet(FLAG_UNLOCK_SOUTHERN_ISLAND) ? MAPSECTYPE_PLAIN : MAPSECTYPE_NONE;
+ return FlagGet(FLAG_LANDMARK_SOUTHERN_ISLAND) ? MAPSECTYPE_PLAIN : MAPSECTYPE_NONE;
default:
return MAPSECTYPE_PLAIN;
}
@@ -1738,7 +1739,7 @@ static void sub_8124A70(void)
{
struct SpriteSheet sheet;
- LZ77UnCompWram(gUnknown_085A1D68, gUnknown_0203A148->unk_88c);
+ LZ77UnCompWram(sUnknown_085A1D68, gUnknown_0203A148->unk_88c);
sheet.data = gUnknown_0203A148->unk_88c;
sheet.size = 0x1c0;
sheet.tag = 2;
@@ -1806,11 +1807,11 @@ static void sub_8124BE4(void)
u16 mapSecId;
u8 spriteId;
- for (i = 0; gUnknown_085A1F18[i][1] != MAPSEC_NONE; i++)
+ for (i = 0; sUnknown_085A1F18[i][1] != MAPSEC_NONE; i++)
{
- if (FlagGet(gUnknown_085A1F18[i][0]))
+ if (FlagGet(sUnknown_085A1F18[i][0]))
{
- mapSecId = gUnknown_085A1F18[i][1];
+ mapSecId = sUnknown_085A1F18[i][1];
sub_8124630(mapSecId, &x, &y, &width, &height);
x = (x + MAPCURSOR_X_MIN) * 8;
y = (y + MAPCURSOR_Y_MIN) * 8;
@@ -1916,16 +1917,16 @@ static void sub_8124E0C(void)
sub_8084CCC(gSaveBlock2Ptr->playerGender == MALE ? 0x0C : 0x0D);
break;
case MAPSEC_EVER_GRANDE_CITY:
- sub_8084CCC(FlagGet(FLAG_SYS_POKEMON_LEAGUE_FLY) && gUnknown_0203A148->regionMap.posWithinMapSec == 0 ? 0x14 : 0x0B);
+ sub_8084CCC(FlagGet(FLAG_LANDMARK_POKEMON_LEAGUE) && gUnknown_0203A148->regionMap.posWithinMapSec == 0 ? 0x14 : 0x0B);
break;
default:
- if (gUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][2] != 0)
+ if (sUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][2] != 0)
{
- sub_8084CCC(gUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][2]);
+ sub_8084CCC(sUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][2]);
}
else
{
- warp1_set_2(gUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][0], gUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][1], -1);
+ warp1_set_2(sUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][0], sUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][1], -1);
}
break;
}
diff --git a/src/reset_save_heap.c b/src/reset_save_heap.c
index d4dbc5f42..099edce49 100644
--- a/src/reset_save_heap.c
+++ b/src/reset_save_heap.c
@@ -23,10 +23,8 @@ void sub_81700F8(void)
ResetSaveCounters();
sub_81534D0(0);
if (gSaveFileStatus == 0 || gSaveFileStatus == 2)
- {
Sav2_ClearSetDefault();
- }
SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound);
- InitHeap(gHeap, 0x1c000);
+ InitHeap(gHeap, HEAP_SIZE);
SetMainCallback2(sub_8086230);
}
diff --git a/src/reshow_battle_screen.c b/src/reshow_battle_screen.c
index 1475c019b..32c85a5ee 100644
--- a/src/reshow_battle_screen.c
+++ b/src/reshow_battle_screen.c
@@ -35,7 +35,7 @@ extern struct SpriteTemplate gUnknown_0202499C;
extern const union AnimCmd * const * const gMonAnimationsSpriteAnimsPtrTable[];
extern void dp12_8087EA4(void);
-extern void trs_config(void);
+extern void sub_8035658(void);
extern bool8 IsDoubleBattle(void);
extern u8 GetSubstituteSpriteDefault_Y(u8 bank);
extern u8 GetBankSpriteDefault_Y(u8 bank);
@@ -73,7 +73,7 @@ static void CB2_ReshowBattleScreenAfterMenu(void)
{
case 0:
dp12_8087EA4();
- trs_config();
+ sub_8035658();
SetBgAttribute(1, BG_CTRL_ATTR_VISIBLE, 0);
SetBgAttribute(2, BG_CTRL_ATTR_VISIBLE, 0);
ShowBg(0);
diff --git a/src/battle_1.c b/src/rom_8034C54.c
index 5e4ef5583..4d4492524 100644
--- a/src/battle_1.c
+++ b/src/rom_8034C54.c
@@ -1,17 +1,5 @@
-
-// Includes
#include "global.h"
-// Static type declarations
-
-// Static RAM declarations
-
IWRAM_DATA u32 gUnknown_03000DD4;
IWRAM_DATA u32 gUnknown_03000DD8;
IWRAM_DATA u32 gUnknown_03000DDC;
-
-// Static ROM declarations
-
-// .rodata
-
-// .text
diff --git a/src/safari_zone.c b/src/safari_zone.c
index 19a26dad9..ce1eb65bc 100644
--- a/src/safari_zone.c
+++ b/src/safari_zone.c
@@ -5,6 +5,7 @@
#include "main.h"
#include "battle.h"
#include "string_util.h"
+#include "pokeblock.h"
struct PokeblockFeeder
{
@@ -24,7 +25,6 @@ extern u8 EventScript_2A4B8A[];
extern u8 EventScript_2A4B6F[];
extern u8 EventScript_2A4B4C[];
extern u8 EventScript_2A4B9B[];
-extern const u8* const gPokeblockNames[];
extern void sub_80EE44C(u8, u8);
extern void IncrementGameStat(u8 index);
@@ -105,7 +105,7 @@ void SafariZoneRetirePrompt(void)
ScriptContext1_SetupScript(EventScript_2A4B6F);
}
-void sub_80FC190(void)
+void CB2_EndSafariBattle(void)
{
sSafariZoneFleedMons += gBattleResults.field_1F;
if (gBattleOutcome == BATTLE_CAUGHT)
diff --git a/src/save_failed_screen.c b/src/save_failed_screen.c
index ef01f0293..218ef68d7 100755
--- a/src/save_failed_screen.c
+++ b/src/save_failed_screen.c
@@ -154,8 +154,8 @@ static const u8 sClockFrames[8][3] =
{ 5, 1, 0 },
};
-static const u8 gSaveFailedClockPal[] = INCBIN_U8("graphics/misc/clock_small.gbapal");
-static const u8 gSaveFailedClockGfx[] = INCBIN_U8("graphics/misc/clock_small.4bpp.lz");
+static const u8 sSaveFailedClockPal[] = INCBIN_U8("graphics/misc/clock_small.gbapal");
+static const u8 sSaveFailedClockGfx[] = INCBIN_U8("graphics/misc/clock_small.4bpp.lz");
static void CB2_SaveFailedScreen(void);
static void CB2_WipeSave(void);
@@ -221,7 +221,7 @@ static void CB2_SaveFailedScreen(void)
LZ77UnCompVram(gBirchHelpGfx, (void *)VRAM);
LZ77UnCompVram(gBirchBagTilemap, (void *)(VRAM + 0x7000));
LZ77UnCompVram(gBirchGrassTilemap, (void *)(VRAM + 0x7800));
- LZ77UnCompVram(gSaveFailedClockGfx, (void *)(VRAM + 0x10020));
+ LZ77UnCompVram(sSaveFailedClockGfx, (void *)(VRAM + 0x10020));
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gUnknown_085EFD88, 3);
SetBgTilemapBuffer(0, (void *)&gDecompressionBuffer[0x2000]);
@@ -238,7 +238,7 @@ static void CB2_SaveFailedScreen(void)
ResetTasks();
ResetPaletteFade();
LoadPalette(gBirchBagGrassPal, 0, 0x40);
- LoadPalette(gSaveFailedClockPal, 0x100, 0x20);
+ LoadPalette(sSaveFailedClockPal, 0x100, 0x20);
LoadPalette(gUnknown_0850FEFC, 0xE0, 0x20);
LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
SetWindowBorderStyle(gSaveFailedWindowIds[TEXT_WIN_ID], FALSE, 0x214, 0xE);
diff --git a/src/scrcmd.c b/src/scrcmd.c
index 504d001ea..0557cd95e 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -656,7 +656,7 @@ bool8 ScrCmd_fadescreenspeed(struct ScriptContext *ctx)
bool8 ScrCmd_fadescreenswapbuffers(struct ScriptContext *ctx)
{
u8 mode = ScriptReadByte(ctx);
-
+
switch (mode)
{
case 1:
@@ -1445,7 +1445,7 @@ bool8 ScrCmd_drawboxtext(struct ScriptContext *ctx)
u8 top = ScriptReadByte(ctx);
u8 multichoiceId = ScriptReadByte(ctx);
u8 ignoreBPress = ScriptReadByte(ctx);
-
+
/*if (Multichoice(left, top, multichoiceId, ignoreBPress) == TRUE)
{
ScriptContext1_Stop();
@@ -1501,31 +1501,31 @@ bool8 ScrCmd_braillemessage(struct ScriptContext *ctx)
u8 y;
StringExpandPlaceholders(gStringVar4, ptr + 6);
-
+
width = GetStringWidth(6, gStringVar4, -1) / 8;
-
+
if (width > 0x1C)
width = 0x1C;
-
+
for (i = 0, height = 4; gStringVar4[i] != 0xFF;)
{
if (gStringVar4[i++] == 0xFE)
height += 3;
}
-
+
if (height > 0x12)
height = 0x12;
-
+
x = width + 2;
temp1 = (0x1E - x) / 2;
x = temp1 + 1;
temp1 = ((x - temp1 - 1) * 8 + 3);
-
+
y = height + 2;
temp2 = (0x14 - y) / 2;
y = temp2 + 2;
temp2 = ((y - temp2 - 1) * 8);
-
+
sub_8198A50(&template1, 0, x, y, width, height, 0xF, 0x1);
template2 = template1;
gUnknown_03000F30 = AddWindow(&template2);
@@ -1924,7 +1924,7 @@ bool8 ScrCmd_hidemoneybox(struct ScriptContext *ctx)
{
/*u8 x = ScriptReadByte(ctx);
u8 y = ScriptReadByte(ctx);*/
-
+
HideMoneyBox();
return FALSE;
}
@@ -1979,13 +1979,13 @@ bool8 ScrCmd_dotrainerbattle(struct ScriptContext *ctx)
return TRUE;
}
-bool8 ScrCmd_ontrainerbattleend(struct ScriptContext *ctx)
+bool8 ScrCmd_gotopostbattlescript(struct ScriptContext *ctx)
{
ctx->scriptPtr = BattleSetup_GetScriptAddrAfterBattle();
return FALSE;
}
-bool8 ScrCmd_ontrainerbattleendgoto(struct ScriptContext *ctx)
+bool8 ScrCmd_gotobeatenscript(struct ScriptContext *ctx)
{
ctx->scriptPtr = BattleSetup_GetTrainerPostBattleScript();
return FALSE;
@@ -1995,7 +1995,7 @@ bool8 ScrCmd_checktrainerflag(struct ScriptContext *ctx)
{
u16 index = VarGet(ScriptReadHalfword(ctx));
- ctx->comparisonResult = HasTrainerAlreadyBeenFought(index);
+ ctx->comparisonResult = HasTrainerBeenFought(index);
return FALSE;
}
@@ -2003,7 +2003,7 @@ bool8 ScrCmd_settrainerflag(struct ScriptContext *ctx)
{
u16 index = VarGet(ScriptReadHalfword(ctx));
- trainer_flag_set(index);
+ SetTrainerFlag(index);
return FALSE;
}
@@ -2011,7 +2011,7 @@ bool8 ScrCmd_cleartrainerflag(struct ScriptContext *ctx)
{
u16 index = VarGet(ScriptReadHalfword(ctx));
- trainer_flag_clear(index);
+ ClearTrainerFlag(index);
return FALSE;
}
@@ -2089,7 +2089,7 @@ bool8 ScrCmd_getpricereduction(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_choosecontestpkmn(struct ScriptContext *ctx)
+bool8 ScrCmd_choosecontestmon(struct ScriptContext *ctx)
{
sub_81B9404();
ScriptContext1_Stop();
@@ -2332,7 +2332,7 @@ bool8 ScrCmd_mossdeepgym4(struct ScriptContext *ctx)
bool8 ScrCmd_cmdD8(struct ScriptContext *ctx)
{
- gSelectedMapObject = sub_80B47BC();
+ gSelectedMapObject = GetCurrentApproachingTrainerMapObjectId();
return FALSE;
}
@@ -2374,7 +2374,7 @@ bool8 ScrCmd_checkmonobedience(struct ScriptContext *ctx)
bool8 ScrCmd_cmdCF(struct ScriptContext *ctx)
{
const u8* v1 = sub_8099244();
-
+
if (v1)
{
((u8*)gUnknown_020375C0) = ctx->scriptPtr;
diff --git a/src/secret_base.c b/src/secret_base.c
index 6d66e6576..bf6bec1f8 100644
--- a/src/secret_base.c
+++ b/src/secret_base.c
@@ -1082,13 +1082,13 @@ void game_continue(u8 taskId)
if (sub_80E9878(i))
{
sub_80E9780(gUnknown_0203A020->names[count], i);
- gUnknown_0203A020->items[count].unk_00 = gUnknown_0203A020->names[count];
- gUnknown_0203A020->items[count].unk_04 = i;
+ gUnknown_0203A020->items[count].name = gUnknown_0203A020->names[count];
+ gUnknown_0203A020->items[count].id = i;
count ++;
}
}
- gUnknown_0203A020->items[count].unk_00 = gText_Cancel;
- gUnknown_0203A020->items[count].unk_04 = -2;
+ gUnknown_0203A020->items[count].name = gText_Cancel;
+ gUnknown_0203A020->items[count].id = -2;
data[0] = count + 1;
if (data[0] < 8)
{
@@ -1098,11 +1098,11 @@ void game_continue(u8 taskId)
{
data[3] = 8;
}
- gUnknown_03006310 = gUnknown_0858D07C;
- gUnknown_03006310.unk_10 = data[6];
- gUnknown_03006310.totalItems = data[0];
- gUnknown_03006310.items = gUnknown_0203A020->items;
- gUnknown_03006310.maxShowed = data[3];
+ gMultiuseListMenuTemplate = gUnknown_0858D07C;
+ gMultiuseListMenuTemplate.unk_10 = data[6];
+ gMultiuseListMenuTemplate.totalItems = data[0];
+ gMultiuseListMenuTemplate.items = gUnknown_0203A020->items;
+ gMultiuseListMenuTemplate.maxShowed = data[3];
}
void sub_80E9DEC(u32 a0, bool8 flag, struct ListMenu *menu)
@@ -1119,7 +1119,7 @@ void sub_80E9E00(u8 taskId)
data = gTasks[taskId].data;
SetStandardWindowBorderStyle(data[6], 0);
- data[5] = ListMenuInit(&gUnknown_03006310, data[2], data[1]);
+ data[5] = ListMenuInit(&gMultiuseListMenuTemplate, data[2], data[1]);
sub_80E9E44(taskId);
schedule_bg_copy_tilemap_to_vram(0);
}
@@ -1138,8 +1138,8 @@ void sub_80E9E90(u8 taskId)
s32 input;
data = gTasks[taskId].data;
- input = ListMenuHandleInput(data[5]);
- get_coro_args_x18_x1A(data[5], &data[2], &data[1]);
+ input = ListMenuHandleInputGetItemId(data[5]);
+ sub_81AE860(data[5], &data[2], &data[1]);
switch (input)
{
case -1:
@@ -1283,7 +1283,7 @@ u8 sub_80EA20C(u8 secretBaseRecordId)
return (gSaveBlock1Ptr->secretBases[secretBaseRecordId].trainerId[0] % 5) + (gSaveBlock1Ptr->secretBases[secretBaseRecordId].gender * 5);
}
-const u8 *sub_80EA250(void)
+const u8 *GetSecretBaseTrainerLoseText(void)
{
u8 param;
diff --git a/src/sound.c b/src/sound.c
index 086fede67..ba3f659cc 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -29,10 +29,10 @@ IWRAM_DATA static u16 sFanfareCounter;
bool8 gDisableMusic;
extern u32 gBattleTypeFlags;
-extern struct MusicPlayerInfo gMPlay_BGM;
-extern struct MusicPlayerInfo gMPlay_SE1;
-extern struct MusicPlayerInfo gMPlay_SE2;
-extern struct MusicPlayerInfo gMPlay_SE3;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_SE1;
+extern struct MusicPlayerInfo gMPlayInfo_SE2;
+extern struct MusicPlayerInfo gMPlayInfo_SE3;
extern struct ToneData gCryTable[];
extern struct ToneData gCryTable2[];
extern const struct Fanfare sFanfares[];
@@ -171,7 +171,7 @@ bool8 IsNotWaitingForBGMStop(void)
void PlayFanfareByFanfareNum(u8 fanfareNum)
{
u16 songNum;
- m4aMPlayStop(&gMPlay_BGM);
+ m4aMPlayStop(&gMPlayInfo_BGM);
songNum = sFanfares[fanfareNum].songNum;
sFanfareCounter = sFanfares[fanfareNum].duration;
m4aSongNumStart(songNum);
@@ -187,9 +187,9 @@ bool8 WaitFanfare(bool8 stop)
else
{
if (!stop)
- m4aMPlayContinue(&gMPlay_BGM);
+ m4aMPlayContinue(&gMPlayInfo_BGM);
else
- m4aSongNumStart(SE_STOP);
+ m4aSongNumStart(MUS_DUMMY);
return TRUE;
}
@@ -232,7 +232,7 @@ static void Task_Fanfare(u8 taskId)
}
else
{
- m4aMPlayContinue(&gMPlay_BGM);
+ m4aMPlayContinue(&gMPlayInfo_BGM);
DestroyTask(taskId);
}
}
@@ -250,46 +250,46 @@ void FadeInNewBGM(u16 songNum, u8 speed)
if (songNum == 0xFFFF)
songNum = 0;
m4aSongNumStart(songNum);
- m4aMPlayImmInit(&gMPlay_BGM);
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0);
+ m4aMPlayImmInit(&gMPlayInfo_BGM);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0);
m4aSongNumStop(songNum);
- m4aMPlayFadeIn(&gMPlay_BGM, speed);
+ m4aMPlayFadeIn(&gMPlayInfo_BGM, speed);
}
void FadeOutBGMTemporarily(u8 speed)
{
- m4aMPlayFadeOutTemporarily(&gMPlay_BGM, speed);
+ m4aMPlayFadeOutTemporarily(&gMPlayInfo_BGM, speed);
}
bool8 IsBGMPausedOrStopped(void)
{
- if (gMPlay_BGM.status & MUSICPLAYER_STATUS_PAUSE)
+ if (gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_PAUSE)
return TRUE;
- if (!(gMPlay_BGM.status & MUSICPLAYER_STATUS_TRACK))
+ if (!(gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_TRACK))
return TRUE;
return FALSE;
}
void FadeInBGM(u8 speed)
{
- m4aMPlayFadeIn(&gMPlay_BGM, speed);
+ m4aMPlayFadeIn(&gMPlayInfo_BGM, speed);
}
void FadeOutBGM(u8 speed)
{
- m4aMPlayFadeOut(&gMPlay_BGM, speed);
+ m4aMPlayFadeOut(&gMPlayInfo_BGM, speed);
}
bool8 IsBGMStopped(void)
{
- if (!(gMPlay_BGM.status & MUSICPLAYER_STATUS_TRACK))
+ if (!(gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_TRACK))
return TRUE;
return FALSE;
}
void PlayCry1(u16 species, s8 pan)
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 85);
PlayCryInternal(species, pan, CRY_VOLUME, 10, 0);
gPokemonCryBGMDuckingCounter = 2;
RestoreBGMVolumeAfterPokemonCry();
@@ -308,7 +308,7 @@ void PlayCry3(u16 species, s8 pan, u8 mode)
}
else
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 85);
PlayCryInternal(species, pan, CRY_VOLUME, 10, mode);
gPokemonCryBGMDuckingCounter = 2;
RestoreBGMVolumeAfterPokemonCry();
@@ -324,7 +324,7 @@ void PlayCry4(u16 species, s8 pan, u8 mode)
else
{
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 85);
PlayCryInternal(species, pan, CRY_VOLUME, 10, mode);
}
}
@@ -337,7 +337,7 @@ void PlayCry6(u16 species, s8 pan, u8 mode) // not present in R/S
}
else
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 85);
PlayCryInternal(species, pan, CRY_VOLUME, 10, mode);
gPokemonCryBGMDuckingCounter = 2;
}
@@ -345,7 +345,7 @@ void PlayCry6(u16 species, s8 pan, u8 mode) // not present in R/S
void PlayCry5(u16 species, u8 mode)
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 85);
PlayCryInternal(species, 0, CRY_VOLUME, 10, mode);
gPokemonCryBGMDuckingCounter = 2;
RestoreBGMVolumeAfterPokemonCry();
@@ -529,7 +529,7 @@ static void Task_DuckBGMForPokemonCry(u8 taskId)
if (!IsPokemonCryPlaying(gMPlay_PokemonCry))
{
- m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 256);
DestroyTask(taskId);
}
}
@@ -557,55 +557,55 @@ void PlaySE(u16 songNum)
void PlaySE12WithPanning(u16 songNum, s8 pan)
{
m4aSongNumStart(songNum);
- m4aMPlayImmInit(&gMPlay_SE1);
- m4aMPlayImmInit(&gMPlay_SE2);
- m4aMPlayPanpotControl(&gMPlay_SE1, 0xFFFF, pan);
- m4aMPlayPanpotControl(&gMPlay_SE2, 0xFFFF, pan);
+ m4aMPlayImmInit(&gMPlayInfo_SE1);
+ m4aMPlayImmInit(&gMPlayInfo_SE2);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE1, 0xFFFF, pan);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE2, 0xFFFF, pan);
}
void PlaySE1WithPanning(u16 songNum, s8 pan)
{
m4aSongNumStart(songNum);
- m4aMPlayImmInit(&gMPlay_SE1);
- m4aMPlayPanpotControl(&gMPlay_SE1, 0xFFFF, pan);
+ m4aMPlayImmInit(&gMPlayInfo_SE1);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE1, 0xFFFF, pan);
}
void PlaySE2WithPanning(u16 songNum, s8 pan)
{
m4aSongNumStart(songNum);
- m4aMPlayImmInit(&gMPlay_SE2);
- m4aMPlayPanpotControl(&gMPlay_SE2, 0xFFFF, pan);
+ m4aMPlayImmInit(&gMPlayInfo_SE2);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE2, 0xFFFF, pan);
}
void SE12PanpotControl(s8 pan)
{
- m4aMPlayPanpotControl(&gMPlay_SE1, 0xFFFF, pan);
- m4aMPlayPanpotControl(&gMPlay_SE2, 0xFFFF, pan);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE1, 0xFFFF, pan);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE2, 0xFFFF, pan);
}
bool8 IsSEPlaying(void)
{
- if ((gMPlay_SE1.status & MUSICPLAYER_STATUS_PAUSE) && (gMPlay_SE2.status & MUSICPLAYER_STATUS_PAUSE))
+ if ((gMPlayInfo_SE1.status & MUSICPLAYER_STATUS_PAUSE) && (gMPlayInfo_SE2.status & MUSICPLAYER_STATUS_PAUSE))
return FALSE;
- if (!(gMPlay_SE1.status & MUSICPLAYER_STATUS_TRACK) && !(gMPlay_SE2.status & MUSICPLAYER_STATUS_TRACK))
+ if (!(gMPlayInfo_SE1.status & MUSICPLAYER_STATUS_TRACK) && !(gMPlayInfo_SE2.status & MUSICPLAYER_STATUS_TRACK))
return FALSE;
return TRUE;
}
bool8 IsBGMPlaying(void)
{
- if (gMPlay_BGM.status & MUSICPLAYER_STATUS_PAUSE)
+ if (gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_PAUSE)
return FALSE;
- if (!(gMPlay_BGM.status & MUSICPLAYER_STATUS_TRACK))
+ if (!(gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_TRACK))
return FALSE;
return TRUE;
}
bool8 IsSpecialSEPlaying(void)
{
- if (gMPlay_SE3.status & MUSICPLAYER_STATUS_PAUSE)
+ if (gMPlayInfo_SE3.status & MUSICPLAYER_STATUS_PAUSE)
return FALSE;
- if (!(gMPlay_SE3.status & MUSICPLAYER_STATUS_TRACK))
+ if (!(gMPlayInfo_SE3.status & MUSICPLAYER_STATUS_TRACK))
return FALSE;
return TRUE;
}
diff --git a/src/sprite.c b/src/sprite.c
index 9db61d2e9..6d76b9854 100644
--- a/src/sprite.c
+++ b/src/sprite.c
@@ -240,7 +240,7 @@ static const AffineAnimCmdFunc sAffineAnimCmdFuncs[] =
AffineAnimCmd_frame,
};
-static const s32 gUnknown_082EC6F4[24] =
+static const s32 sUnknown_082EC6F4[24] =
{
8, 8, 0x10, 0x10, 0x20, 0x20,
0x40, 0x40, 0x10, 8, 0x20, 8,
@@ -1214,14 +1214,14 @@ void obj_update_pos2(struct Sprite* sprite, s32 a1, s32 a2)
u8 matrixNum = sprite->oam.matrixNum;
if (a1 != 0x800)
{
- var0 = gUnknown_082EC6F4[sprite->oam.size * 8 + sprite->oam.shape * 32];
+ var0 = sUnknown_082EC6F4[sprite->oam.size * 8 + sprite->oam.shape * 32];
var1 = var0 << 8;
var2 = (var0 << 16) / gOamMatrices[matrixNum].a;
sprite->pos2.x = sub_8007E28(var1, var2, a1);
}
if (a2 != 0x800)
{
- var0 = gUnknown_082EC6F4[4 + (sprite->oam.size * 8 + sprite->oam.shape * 32)];
+ var0 = sUnknown_082EC6F4[4 + (sprite->oam.size * 8 + sprite->oam.shape * 32)];
var1 = var0 << 8;
var2 = (var0 << 16) / gOamMatrices[matrixNum].d;
sprite->pos2.y = sub_8007E28(var1, var2, a2);
@@ -1247,7 +1247,7 @@ void obj_update_pos2(struct Sprite* sprite, s32 a1, s32 a2)
mov r9, r0\n\
cmp r6, r9\n\
beq _08007EA2\n\
- ldr r2, =gUnknown_082EC6F4\n\
+ ldr r2, =sUnknown_082EC6F4\n\
lsrs r1, 6\n\
lsls r1, 3\n\
ldrb r0, [r5, 0x1]\n\
@@ -1272,7 +1272,7 @@ void obj_update_pos2(struct Sprite* sprite, s32 a1, s32 a2)
_08007EA2:\n\
cmp r8, r9\n\
beq _08007EDA\n\
- ldr r2, =gUnknown_082EC6F4\n\
+ ldr r2, =sUnknown_082EC6F4\n\
ldrb r1, [r5, 0x3]\n\
lsrs r1, 6\n\
lsls r1, 3\n\
diff --git a/src/start_menu.c b/src/start_menu.c
index f45fd8626..a820cd992 100644
--- a/src/start_menu.c
+++ b/src/start_menu.c
@@ -6,6 +6,8 @@
#include "window.h"
#include "string_util.h"
#include "text.h"
+#include "strings.h"
+#include "bg.h"
// Menu actions
enum
@@ -25,15 +27,6 @@ enum
MENU_ACTION_PYRAMID_BAG
};
-static void BuildStartMenuActions_LinkMode(void);
-static void BuildStartMenuActions_UnionRoom(void);
-static void BuildStartMenuActions_SafariZone(void);
-static void BuildStartMenuActions_BattlePike(void);
-static void BuildStartMenuActions_BattlePyramid(void);
-static void BuildStartMenuActions_MultiBattleRoom(void);
-static void BuildStartMenuActions_Normal(void);
-u8 StartMenu_PlayerName(void);
-
extern bool32 is_c1_link_related_active(void);
extern bool32 InUnionRoom(void);
extern bool8 InBattlePike(void);
@@ -42,12 +35,91 @@ extern bool8 InMultiBattleRoom(void);
extern void sub_81973FC(u8 windowId, u8 a1);
extern void sub_8198070(u8 windowId, u8 a1);
+// this file's functions
+static void BuildStartMenuActions_LinkMode(void);
+static void BuildStartMenuActions_UnionRoom(void);
+static void BuildStartMenuActions_SafariZone(void);
+static void BuildStartMenuActions_BattlePike(void);
+static void BuildStartMenuActions_BattlePyramid(void);
+static void BuildStartMenuActions_MultiBattleRoom(void);
+static void BuildStartMenuActions_Normal(void);
+bool8 StartMenu_Pokedex(void);
+bool8 StartMenu_Pokemon(void);
+bool8 StartMenu_Bag(void);
+bool8 StartMenu_PokeNav(void);
+bool8 StartMenu_PlayerName(void);
+bool8 StartMenu_Save(void);
+bool8 StartMenu_Option(void);
+bool8 StartMenu_Exit(void);
+bool8 StartMenu_SafariZoneRetire(void);
+bool8 StartMenu_LinkModePlayerName(void);
+bool8 StartMenu_BattlePyramidRetire(void);
+bool8 StartMenu_BattlePyramidBag(void);
+
+// EWRAM vars
EWRAM_DATA u8 sSafariBallsWindowId = 0;
EWRAM_DATA u8 sBattlePyramidFloorWindowId = 0;
EWRAM_DATA u8 sStartMenuCursorPos = 0;
EWRAM_DATA u8 sNumStartMenuActions = 0;
EWRAM_DATA u8 sCurrentStartMenuActions[9] = {0};
+// const rom data
+static const struct WindowTemplate gSafariBallsWindowTemplate = {0, 1, 1, 9, 4, 0xF, 8};
+
+static const u8* const sPyramindFloorNames[] =
+{
+ gText_Floor1,
+ gText_Floor2,
+ gText_Floor3,
+ gText_Floor4,
+ gText_Floor5,
+ gText_Floor6,
+ gText_Floor7,
+ gText_Peak
+};
+
+static const struct WindowTemplate gPyramidFloorWindowTemplate_2 = {0, 1, 1, 0xA, 4, 0xF, 8};
+static const struct WindowTemplate gPyramidFloorWindowTemplate_1 = {0, 1, 1, 0xC, 4, 0xF, 8};
+
+const struct MenuAction sStartMenuItems[] =
+{
+ {gText_MenuPokedex, {.u8_void = StartMenu_Pokedex}},
+ {gText_MenuPokemon, {.u8_void = StartMenu_Pokemon}},
+ {gText_MenuBag, {.u8_void = StartMenu_Bag}},
+ {gText_MenuPokenav, {.u8_void = StartMenu_PokeNav}},
+ {gText_MenuPlayer, {.u8_void = StartMenu_PlayerName}},
+ {gText_MenuSave, {.u8_void = StartMenu_Save}},
+ {gText_MenuOption, {.u8_void = StartMenu_Option}},
+ {gText_MenuExit, {.u8_void = StartMenu_Exit}},
+ {gText_MenuRetire, {.u8_void = StartMenu_SafariZoneRetire}},
+ {gText_MenuPlayer, {.u8_void = StartMenu_LinkModePlayerName}},
+ {gText_MenuRest, {.u8_void = StartMenu_Save}},
+ {gText_MenuRetire, {.u8_void = StartMenu_BattlePyramidRetire}},
+ {gText_MenuBag, {.u8_void = StartMenu_BattlePyramidBag}}
+};
+
+const struct BgTemplate gUnknown_085105A8[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ }
+};
+
+const struct WindowTemplate gUnknown_085105AC[] =
+{
+ {0, 2, 0xF, 0x1A, 4, 0xF, 0x194},
+ DUMMY_WIN_TEMPLATE
+};
+
+const struct WindowTemplate gUnknown_085105BC = {0, 1, 1, 0xE, 0xA, 0xF, 8};
+
+// code
void BuildStartMenuActions(void)
{
sNumStartMenuActions = 0;
@@ -148,11 +220,6 @@ static void BuildStartMenuActions_MultiBattleRoom(void)
AddStartMenuAction(MENU_ACTION_EXIT);
}
-extern const struct WindowTemplate gSafariBallsWindowTemplate;
-extern const struct WindowTemplate gPyramidFloorWindowTemplate_1;
-extern const struct WindowTemplate gPyramidFloorWindowTemplate_2;
-extern const u8 gText_SafariBallStock[];
-
void DisplaySafariBallsWindow(void)
{
sSafariBallsWindowId = AddWindow(&gSafariBallsWindowTemplate);
@@ -164,9 +231,6 @@ void DisplaySafariBallsWindow(void)
CopyWindowToVram(sSafariBallsWindowId, 2);
}
-extern const u8* const gUnknown_08510510[];
-extern const u8 gText_BattlePyramidFloor[];
-
void DisplayPyramidFloorWindow(void)
{
// TODO: fix location
@@ -176,7 +240,7 @@ void DisplayPyramidFloorWindow(void)
sBattlePyramidFloorWindowId = AddWindow(&gPyramidFloorWindowTemplate_2);
PutWindowTilemap(sBattlePyramidFloorWindowId);
sub_81973FC(sBattlePyramidFloorWindowId, 0);
- StringCopy(gStringVar1, gUnknown_08510510[gSaveBlock2Ptr->field_CAA[4]]);
+ StringCopy(gStringVar1, sPyramindFloorNames[gSaveBlock2Ptr->field_CAA[4]]);
StringExpandPlaceholders(gStringVar4, gText_BattlePyramidFloor);
PrintTextOnWindow(sBattlePyramidFloorWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
CopyWindowToVram(sBattlePyramidFloorWindowId, 2);
@@ -197,8 +261,6 @@ void RemoveExtraStartMenuWindows(void)
}
}
-extern const struct MenuAction sStartMenuItems[];
-
/*
// Prints n menu items starting at *index
static bool32 PrintStartMenuItemsMultistep(s16 *index, u32 n)
diff --git a/src/text.c b/src/text.c
index a13ed162d..5db3ba308 100644
--- a/src/text.c
+++ b/src/text.c
@@ -2418,12 +2418,12 @@ _08005ABA:\n\
strb r0, [r6, #0x9]\n\
b _08005A0A\n\
_08005ABE:\n\
- ldr r0, =gMPlay_BGM\n\
+ ldr r0, =gMPlayInfo_BGM\n\
bl m4aMPlayStop\n\
b _08005A0A\n\
.pool\n\
_08005ACC:\n\
- ldr r0, =gMPlay_BGM\n\
+ ldr r0, =gMPlayInfo_BGM\n\
bl m4aMPlayContinue\n\
b _08005A0A\n\
.pool\n\
diff --git a/src/tileset_anims.c b/src/tileset_anims.c
index 4ad787e1c..f89cfdd2b 100644
--- a/src/tileset_anims.c
+++ b/src/tileset_anims.c
@@ -5,6 +5,7 @@
#include "blend_palette.h"
#include "battle_transition.h"
#include "task.h"
+#include "battle_transition.h"
// Static type declarations
@@ -1392,7 +1393,7 @@ static void sub_80A1818(u16 a1)
{
CpuCopy16(gTilesetAnims_BattleDomePals0[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32);
BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF);
- if ((u8)FindTaskIdByFunc(sub_8149DFC) != 0xFF )
+ if ((u8)FindTaskIdByFunc(TransitionPhase1_Task_RunFuncs) != 0xFF )
{
sSecondaryTilesetCB = sub_80A1670;
sSecondaryTilesetCBBufferSize = 0x20;
@@ -1402,7 +1403,7 @@ static void sub_80A1818(u16 a1)
static void sub_80A1884(u16 a1)
{
CpuCopy16(gTilesetAnims_BattleDomePals0[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32);
- if ((u8)FindTaskIdByFunc(sub_8149DFC) == 0xFF )
+ if ((u8)FindTaskIdByFunc(TransitionPhase1_Task_RunFuncs) == 0xFF )
{
BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF);
if (!--sSecondaryTilesetCBBufferSize)
diff --git a/src/trainer_see.c b/src/trainer_see.c
new file mode 100644
index 000000000..53bc5cbbb
--- /dev/null
+++ b/src/trainer_see.c
@@ -0,0 +1,781 @@
+#include "global.h"
+#include "trainer_see.h"
+#include "battle_setup.h"
+#include "pokemon.h"
+#include "sprite.h"
+#include "field_effect.h"
+#include "field_map_obj.h"
+#include "field_player_avatar.h"
+#include "map_obj_8097404.h"
+#include "pokenav.h"
+#include "task.h"
+#include "util.h"
+#include "script.h"
+#include "event_data.h"
+#include "script_movement.h"
+
+extern bool8 InBattlePyramid(void);
+extern bool32 InTrainerHill(void);
+extern bool8 GetBattlePyramidTrainerFlag(u8 mapObjectId);
+extern bool8 GetTrainerHillTrainerFlag(u8 mapObjectId);
+extern void sub_809BE48(u16 npcId);
+
+// this file's functions
+static u8 CheckTrainer(u8 mapObjectId);
+static u8 GetTrainerApproachDistance(struct MapObject *trainerObj);
+static u8 CheckPathBetweenTrainerAndPlayer(struct MapObject *trainerObj, u8 approachDistance, u8 direction);
+static void TrainerApproachPlayer(struct MapObject *trainerObj, u8 range);
+static void Task_RunTrainerSeeFuncList(u8 taskId);
+static void Task_DestroyTrainerApproachTask(u8 taskId);
+static void SetIconSpriteData(struct Sprite *sprite, u16 fldEffId, u8 spriteAnimNum);
+
+static u8 GetTrainerApproachDistanceSouth(struct MapObject *trainerObj, s16 range, s16 x, s16 y);
+static u8 GetTrainerApproachDistanceNorth(struct MapObject *trainerObj, s16 range, s16 x, s16 y);
+static u8 GetTrainerApproachDistanceWest(struct MapObject *trainerObj, s16 range, s16 x, s16 y);
+static u8 GetTrainerApproachDistanceEast(struct MapObject *trainerObj, s16 range, s16 x, s16 y);
+
+static bool8 sub_80B4178(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B417C(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B41C0(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B4200(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B425C(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B4318(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B435C(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B4390(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B43AC(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B43E0(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B4438(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80B44AC(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+
+static void SpriteCB_TrainerIcons(struct Sprite *sprite);
+
+// IWRAM common
+u16 gUnknown_03006080;
+u8 gUnknown_03006084[4];
+struct ApproachingTrainer gApproachingTrainers[2];
+u8 gNoOfApproachingTrainers;
+u8 gUnknown_030060AC;
+
+// EWRAM
+EWRAM_DATA u8 gApproachingTrainerId = 0;
+
+// const rom data
+static const u8 sEmotion_ExclamationMarkGfx[] = INCBIN_U8("graphics/misc/emotion_exclamation.4bpp");
+static const u8 sEmotion_QuestionMarkGfx[] = INCBIN_U8("graphics/misc/emotion_question.4bpp");
+static const u8 sEmotion_HeartGfx[] = INCBIN_U8("graphics/misc/emotion_heart.4bpp");
+
+static u8 (*const sDirectionalApproachDistanceFuncs[])(struct MapObject *trainerObj, s16 range, s16 x, s16 y) =
+{
+ GetTrainerApproachDistanceSouth,
+ GetTrainerApproachDistanceNorth,
+ GetTrainerApproachDistanceWest,
+ GetTrainerApproachDistanceEast,
+};
+
+static bool8 (*const sTrainerSeeFuncList[])(u8 taskId, struct Task *task, struct MapObject *trainerObj) =
+{
+ sub_80B4178,
+ sub_80B417C,
+ sub_80B41C0,
+ sub_80B4200,
+ sub_80B425C,
+ sub_80B4318,
+ sub_80B435C,
+ sub_80B4390,
+ sub_80B43AC,
+ sub_80B43E0,
+ sub_80B4438,
+ sub_80B44AC
+};
+
+static bool8 (*const sTrainerSeeFuncList2[])(u8 taskId, struct Task *task, struct MapObject *trainerObj) =
+{
+ sub_80B43AC,
+ sub_80B43E0,
+ sub_80B4438,
+ sub_80B44AC,
+};
+
+static const struct OamData sOamData_Icons =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct SpriteFrameImage sSpriteImageTable_ExclamationQuestionMark[] =
+{
+ {sEmotion_ExclamationMarkGfx, 0x80},
+ {sEmotion_QuestionMarkGfx, 0x80}
+};
+
+static const struct SpriteFrameImage sSpriteImageTable_HeartIcon[] =
+{
+ {sEmotion_HeartGfx, 0x80}
+};
+
+static const union AnimCmd sSpriteAnim_Icons1[] =
+{
+ ANIMCMD_FRAME(0, 60),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_Icons2[] =
+{
+ ANIMCMD_FRAME(1, 60),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_Icons[] =
+{
+ sSpriteAnim_Icons1,
+ sSpriteAnim_Icons2
+};
+
+static const struct SpriteTemplate sSpriteTemplate_ExclamationQuestionMark =
+{
+ .tileTag = 0xffff,
+ .paletteTag = 0xffff,
+ .oam = &sOamData_Icons,
+ .anims = sSpriteAnimTable_Icons,
+ .images = sSpriteImageTable_ExclamationQuestionMark,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_TrainerIcons
+};
+
+static const struct SpriteTemplate sSpriteTemplate_HeartIcon =
+{
+ .tileTag = 0xffff,
+ .paletteTag = 0x1004,
+ .oam = &sOamData_Icons,
+ .anims = sSpriteAnimTable_Icons,
+ .images = sSpriteImageTable_HeartIcon,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_TrainerIcons
+};
+
+// code
+bool8 CheckForTrainersWantingBattle(void)
+{
+ u8 i;
+
+ gNoOfApproachingTrainers = 0;
+ gApproachingTrainerId = 0;
+
+ for (i = 0; i < MAP_OBJECTS_COUNT; i++)
+ {
+ u8 retVal;
+
+ if (!gMapObjects[i].active)
+ continue;
+ if (gMapObjects[i].trainerType != 1 && gMapObjects[i].trainerType != 3)
+ continue;
+
+ retVal = CheckTrainer(i);
+ if (retVal == 2)
+ break; // two trainers have been found
+
+ if (retVal == 0) // no trainers
+ continue;
+
+ if (gNoOfApproachingTrainers > 1)
+ break;
+ if (GetMonsStateToDoubles_2() != 0) // one trainer found and cant have a double battle
+ break;
+ }
+
+ if (gNoOfApproachingTrainers == 1)
+ {
+ ResetTrainerOpponentIds();
+ ConfigureAndSetUpOneTrainerBattle(gApproachingTrainers[gNoOfApproachingTrainers - 1].mapObjectId,
+ gApproachingTrainers[gNoOfApproachingTrainers - 1].trainerScriptPtr);
+ gUnknown_030060AC = 1;
+ return TRUE;
+ }
+ else if (gNoOfApproachingTrainers == 2)
+ {
+ ResetTrainerOpponentIds();
+ for (i = 0; i < gNoOfApproachingTrainers; i++, gApproachingTrainerId++)
+ {
+ ConfigureTwoTrainersBattle(gApproachingTrainers[i].mapObjectId,
+ gApproachingTrainers[i].trainerScriptPtr);
+ }
+ SetUpTwoTrainersBattle();
+ gApproachingTrainerId = 0;
+ gUnknown_030060AC = 1;
+ return TRUE;
+ }
+ else
+ {
+ gUnknown_030060AC = 0;
+ return FALSE;
+ }
+}
+
+static u8 CheckTrainer(u8 mapObjectId)
+{
+ const u8 *scriptPtr;
+ u8 ret = 1;
+ u8 approachDistance;
+
+ if (InTrainerHill() == TRUE)
+ scriptPtr = sub_81D62AC();
+ else
+ scriptPtr = GetFieldObjectScriptPointerByFieldObjectId(mapObjectId);
+
+ if (InBattlePyramid())
+ {
+ if (GetBattlePyramidTrainerFlag(mapObjectId))
+ return 0;
+ }
+ else if (InTrainerHill() == TRUE)
+ {
+ if (GetTrainerHillTrainerFlag(mapObjectId))
+ return 0;
+ }
+ else
+ {
+ if (GetTrainerFlagFromScriptPointer(scriptPtr))
+ return 0;
+ }
+
+ approachDistance = GetTrainerApproachDistance(&gMapObjects[mapObjectId]);
+
+ if (approachDistance != 0)
+ {
+ if (scriptPtr[1] == TRAINER_BATTLE_DOUBLE
+ || scriptPtr[1] == TRAINER_BATTLE_REMATCH_DOUBLE
+ || scriptPtr[1] == TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE)
+ {
+ if (GetMonsStateToDoubles_2() != 0)
+ return 0;
+
+ ret = 2;
+ }
+
+ gApproachingTrainers[gNoOfApproachingTrainers].mapObjectId = mapObjectId;
+ gApproachingTrainers[gNoOfApproachingTrainers].trainerScriptPtr = scriptPtr;
+ gApproachingTrainers[gNoOfApproachingTrainers].radius = approachDistance;
+ TrainerApproachPlayer(&gMapObjects[mapObjectId], approachDistance - 1);
+ gNoOfApproachingTrainers++;
+
+ return ret;
+ }
+
+ return 0;
+}
+
+static u8 GetTrainerApproachDistance(struct MapObject *trainerObj)
+{
+ s16 x, y;
+ u8 i;
+ u8 approachDistance;
+
+ PlayerGetDestCoords(&x, &y);
+ if (trainerObj->trainerType == 1) // can only see in one direction
+ {
+ approachDistance = sDirectionalApproachDistanceFuncs[trainerObj->mapobj_unk_18 - 1](trainerObj, trainerObj->trainerRange_berryTreeId, x, y);
+ return CheckPathBetweenTrainerAndPlayer(trainerObj, approachDistance, trainerObj->mapobj_unk_18);
+ }
+ else // can see in all directions
+ {
+ for (i = 0; i < 4; i++)
+ {
+ approachDistance = sDirectionalApproachDistanceFuncs[i](trainerObj, trainerObj->trainerRange_berryTreeId, x, y);
+ if (CheckPathBetweenTrainerAndPlayer(trainerObj, approachDistance, i + 1)) // directions are 1-4 instead of 0-3. south north west east
+ return approachDistance;
+ }
+ }
+
+ return 0;
+}
+
+// Returns how far south the player is from trainer. 0 if out of trainer's sight.
+static u8 GetTrainerApproachDistanceSouth(struct MapObject *trainerObj, s16 range, s16 x, s16 y)
+{
+ if (trainerObj->coords2.x == x
+ && y > trainerObj->coords2.y
+ && y <= trainerObj->coords2.y + range)
+ return (y - trainerObj->coords2.y);
+ else
+ return 0;
+}
+
+// Returns how far north the player is from trainer. 0 if out of trainer's sight.
+static u8 GetTrainerApproachDistanceNorth(struct MapObject *trainerObj, s16 range, s16 x, s16 y)
+{
+ if (trainerObj->coords2.x == x
+ && y < trainerObj->coords2.y
+ && y >= trainerObj->coords2.y - range)
+ return (trainerObj->coords2.y - y);
+ else
+ return 0;
+}
+
+// Returns how far west the player is from trainer. 0 if out of trainer's sight.
+static u8 GetTrainerApproachDistanceWest(struct MapObject *trainerObj, s16 range, s16 x, s16 y)
+{
+ if (trainerObj->coords2.y == y
+ && x < trainerObj->coords2.x
+ && x >= trainerObj->coords2.x - range)
+ return (trainerObj->coords2.x - x);
+ else
+ return 0;
+}
+
+// Returns how far east the player is from trainer. 0 if out of trainer's sight.
+static u8 GetTrainerApproachDistanceEast(struct MapObject *trainerObj, s16 range, s16 x, s16 y)
+{
+ if (trainerObj->coords2.y == y
+ && x > trainerObj->coords2.x
+ && x <= trainerObj->coords2.x + range)
+ return (x - trainerObj->coords2.x);
+ else
+ return 0;
+}
+
+#define COLLISION_MASK (~1)
+
+static u8 CheckPathBetweenTrainerAndPlayer(struct MapObject *trainerObj, u8 approachDistance, u8 direction)
+{
+ s16 x, y;
+ u8 unk19_temp;
+ u8 unk19b_temp;
+ u8 i;
+ u8 collision;
+
+ if (approachDistance == 0)
+ return 0;
+
+ x = trainerObj->coords2.x;
+ y = trainerObj->coords2.y;
+
+ MoveCoords(direction, &x, &y);
+ for (i = 0; i < approachDistance - 1; i++, MoveCoords(direction, &x, &y))
+ {
+ collision = sub_8092C8C(trainerObj, x, y, direction);
+ if (collision != 0 && (collision & COLLISION_MASK))
+ return 0;
+ }
+
+ // preserve mapobj_unk_19 before clearing.
+ unk19_temp = trainerObj->range.as_nybbles.x;
+ unk19b_temp = trainerObj->range.as_nybbles.y;
+ trainerObj->range.as_nybbles.x = 0;
+ trainerObj->range.as_nybbles.y = 0;
+
+ collision = npc_block_way(trainerObj, x, y, direction);
+
+ trainerObj->range.as_nybbles.x = unk19_temp;
+ trainerObj->range.as_nybbles.y = unk19b_temp;
+ if (collision == 4)
+ return approachDistance;
+
+ return 0;
+}
+
+#define tFuncId data[0]
+#define tTrainerRange data[3]
+#define tOutOfAshSpriteId data[4]
+#define tTrainerMapObjectId data[7]
+
+static void TrainerApproachPlayer(struct MapObject *trainerObj, u8 range)
+{
+ struct Task *task;
+
+ gApproachingTrainers[gNoOfApproachingTrainers].taskId = CreateTask(Task_RunTrainerSeeFuncList, 0x50);
+ task = &gTasks[gApproachingTrainers[gNoOfApproachingTrainers].taskId];
+ task->tTrainerRange = range;
+ task->tTrainerMapObjectId = gApproachingTrainers[gNoOfApproachingTrainers].mapObjectId;
+}
+
+static void sub_80B40C8(TaskFunc followupFunc)
+{
+ u8 taskId;
+ TaskFunc taskFunc;
+
+ if (gApproachingTrainerId == 0)
+ taskId = gApproachingTrainers[0].taskId;
+ else
+ taskId = gApproachingTrainers[1].taskId;
+
+ taskFunc = Task_RunTrainerSeeFuncList;
+ SetTaskFuncWithFollowupFunc(taskId, taskFunc, followupFunc);
+ gTasks[taskId].tFuncId = 1;
+ taskFunc(taskId);
+}
+
+static void Task_RunTrainerSeeFuncList(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ struct MapObject *trainerObj = &gMapObjects[task->tTrainerMapObjectId];
+
+ if (!trainerObj->active)
+ {
+ SwitchTaskToFollowupFunc(taskId);
+ }
+ else
+ {
+ while (sTrainerSeeFuncList[task->tFuncId](taskId, task, trainerObj));
+ }
+}
+
+static bool8 sub_80B4178(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ return FALSE;
+}
+
+static bool8 sub_80B417C(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ u8 direction;
+
+ FieldObjectGetLocalIdAndMap(trainerObj, &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]);
+ FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_1);
+ direction = GetFaceDirectionAnimId(trainerObj->mapobj_unk_18);
+ FieldObjectSetSpecialAnim(trainerObj, direction);
+ task->tFuncId++;
+ return TRUE;
+}
+
+static bool8 sub_80B41C0(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (FieldEffectActiveListContains(FLDEFF_EXCLAMATION_MARK_ICON_1))
+ {
+ return FALSE;
+ }
+ else
+ {
+ task->tFuncId++;
+ if (trainerObj->animPattern == 57 || trainerObj->animPattern == 58)
+ task->tFuncId = 6;
+ if (trainerObj->animPattern == 63)
+ task->tFuncId = 8;
+ return TRUE;
+ }
+}
+
+static bool8 sub_80B4200(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (!(FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj)) || FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ {
+ if (task->tTrainerRange)
+ {
+ FieldObjectSetSpecialAnim(trainerObj, GetGoSpeed0AnimId(trainerObj->mapobj_unk_18));
+ task->tTrainerRange--;
+ }
+ else
+ {
+ FieldObjectSetSpecialAnim(trainerObj, 0x3E);
+ task->tFuncId++;
+ }
+ }
+ return FALSE;
+}
+
+static bool8 sub_80B425C(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ struct MapObject *playerObj;
+
+ if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj) && !FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ return FALSE;
+
+ npc_set_running_behaviour_etc(trainerObj, npc_running_behaviour_by_direction(trainerObj->mapobj_unk_18));
+ sub_808F23C(trainerObj, npc_running_behaviour_by_direction(trainerObj->mapobj_unk_18));
+ sub_808F208(trainerObj);
+
+ playerObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerObj) && !FieldObjectClearAnimIfSpecialAnimFinished(playerObj))
+ return FALSE;
+
+ sub_808BCE8();
+ FieldObjectSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], GetFaceDirectionAnimId(GetOppositeDirection(trainerObj->mapobj_unk_18)));
+ task->tFuncId++;
+ return FALSE;
+}
+
+static bool8 sub_80B4318(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ struct MapObject *playerObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerObj)
+ || FieldObjectClearAnimIfSpecialAnimFinished(playerObj))
+ SwitchTaskToFollowupFunc(taskId);
+ return FALSE;
+}
+
+static bool8 sub_80B435C(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj)
+ || FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ {
+ FieldObjectSetSpecialAnim(trainerObj, 0x59);
+ task->tFuncId++;
+ }
+ return FALSE;
+}
+
+static bool8 sub_80B4390(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ task->tFuncId = 3;
+
+ return FALSE;
+}
+
+static bool8 sub_80B43AC(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj)
+ || FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ {
+ FieldObjectSetSpecialAnim(trainerObj, 0x3E);
+ task->tFuncId++;
+ }
+ return FALSE;
+}
+
+static bool8 sub_80B43E0(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(trainerObj))
+ {
+ gFieldEffectArguments[0] = trainerObj->coords2.x;
+ gFieldEffectArguments[1] = trainerObj->coords2.y;
+ gFieldEffectArguments[2] = gSprites[trainerObj->spriteId].subpriority - 1;
+ gFieldEffectArguments[3] = 2;
+ task->tOutOfAshSpriteId = FieldEffectStart(FLDEFF_POP_OUT_OF_ASH);
+ task->tFuncId++;
+ }
+ return FALSE;
+}
+
+static bool8 sub_80B4438(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ struct Sprite *sprite;
+
+ if (gSprites[task->tOutOfAshSpriteId].animCmdIndex == 2)
+ {
+ trainerObj->mapobj_bit_26 = 0;
+ trainerObj->mapobj_bit_2 = 1;
+
+ sprite = &gSprites[trainerObj->spriteId];
+ sprite->oam.priority = 2;
+ FieldObjectClearAnimIfSpecialAnimFinished(trainerObj);
+ FieldObjectSetSpecialAnim(trainerObj, sub_80934BC(trainerObj->mapobj_unk_18));
+ task->tFuncId++;
+ }
+
+ return FALSE;
+}
+
+static bool8 sub_80B44AC(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (!FieldEffectActiveListContains(FLDEFF_POP_OUT_OF_ASH))
+ task->tFuncId = 3;
+
+ return FALSE;
+}
+
+#undef tFuncId
+#undef tTrainerRange
+#undef tOutOfAshSpriteId
+#undef tTrainerMapObjectId
+
+static void sub_80B44C8(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ struct MapObject *mapObj;
+
+ // another mapObj loaded into by loadword?
+ LoadWordFromTwoHalfwords(&task->data[1], (u32 *)&mapObj);
+ if (!task->data[7])
+ {
+ FieldObjectClearAnim(mapObj);
+ task->data[7]++;
+ }
+ sTrainerSeeFuncList2[task->data[0]](taskId, task, mapObj);
+ if (task->data[0] == 3 && !FieldEffectActiveListContains(FLDEFF_POP_OUT_OF_ASH))
+ {
+ npc_set_running_behaviour_etc(mapObj, npc_running_behaviour_by_direction(mapObj->mapobj_unk_18));
+ sub_808F23C(mapObj, npc_running_behaviour_by_direction(mapObj->mapobj_unk_18));
+ DestroyTask(taskId);
+ }
+ else
+ {
+ mapObj->mapobj_bit_7 = 0;
+ }
+}
+
+void sub_80B4578(struct MapObject *var)
+{
+ StoreWordInTwoHalfwords(&gTasks[CreateTask(sub_80B44C8, 0)].data[1], (u32)var);
+}
+
+void EndTrainerApproach(void)
+{
+ sub_80B40C8(Task_DestroyTrainerApproachTask);
+}
+
+static void Task_DestroyTrainerApproachTask(u8 taskId)
+{
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+void sub_80B45D0(void)
+{
+ if (gNoOfApproachingTrainers == 2)
+ {
+ if (gApproachingTrainerId == 0)
+ {
+ gApproachingTrainerId++;
+ gSpecialVar_Result = 1;
+ UnfreezeMapObjects();
+ sub_80974D0(gApproachingTrainers[1].mapObjectId);
+ }
+ else
+ {
+ gApproachingTrainerId = 0;
+ gSpecialVar_Result = 0;
+ }
+ }
+ else
+ {
+ gSpecialVar_Result = 0;
+ }
+}
+
+#define sLocalId data[0]
+#define sMapNum data[1]
+#define sMapGroup data[2]
+#define sData3 data[3]
+#define sData4 data[4]
+#define sFldEffId data[7]
+
+u8 FldEff_ExclamationMarkIcon1(void)
+{
+ u8 spriteId = CreateSpriteAtEnd(&sSpriteTemplate_ExclamationQuestionMark, 0, 0, 0x53);
+
+ if (spriteId != MAX_SPRITES)
+ SetIconSpriteData(&gSprites[spriteId], FLDEFF_EXCLAMATION_MARK_ICON_1, 0);
+
+ return 0;
+}
+
+u8 FldEff_ExclamationMarkIcon2(void)
+{
+ u8 spriteId = CreateSpriteAtEnd(&sSpriteTemplate_ExclamationQuestionMark, 0, 0, 0x52);
+
+ if (spriteId != MAX_SPRITES)
+ SetIconSpriteData(&gSprites[spriteId], FLDEFF_EXCLAMATION_MARK_ICON_2, 1);
+
+ return 0;
+}
+
+u8 FldEff_HeartIcon(void)
+{
+ u8 spriteId = CreateSpriteAtEnd(&sSpriteTemplate_HeartIcon, 0, 0, 0x52);
+
+ if (spriteId != MAX_SPRITES)
+ {
+ struct Sprite *sprite = &gSprites[spriteId];
+
+ SetIconSpriteData(sprite, FLDEFF_HEART_ICON, 0);
+ sprite->oam.paletteNum = 2;
+ }
+
+ return 0;
+}
+
+static void SetIconSpriteData(struct Sprite *sprite, u16 fldEffId, u8 spriteAnimNum)
+{
+ sprite->oam.priority = 1;
+ sprite->coordOffsetEnabled = 1;
+
+ sprite->sLocalId = gFieldEffectArguments[0];
+ sprite->sMapNum = gFieldEffectArguments[1];
+ sprite->sMapGroup = gFieldEffectArguments[2];
+ sprite->sData3 = -5;
+ sprite->sFldEffId = fldEffId;
+
+ StartSpriteAnim(sprite, spriteAnimNum);
+}
+
+static void SpriteCB_TrainerIcons(struct Sprite *sprite)
+{
+ u8 mapObjId;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(sprite->sLocalId, sprite->sMapNum, sprite->sMapGroup, &mapObjId)
+ || sprite->animEnded)
+ {
+ FieldEffectStop(sprite, sprite->sFldEffId);
+ }
+ else
+ {
+ struct Sprite *mapObjSprite = &gSprites[gMapObjects[mapObjId].spriteId];
+ sprite->sData4 += sprite->sData3;
+ sprite->pos1.x = mapObjSprite->pos1.x;
+ sprite->pos1.y = mapObjSprite->pos1.y - 16;
+ sprite->pos2.x = mapObjSprite->pos2.x;
+ sprite->pos2.y = mapObjSprite->pos2.y + sprite->sData4;
+ if (sprite->sData4)
+ sprite->sData3++;
+ else
+ sprite->sData3 = 0;
+ }
+}
+
+#undef sLocalId
+#undef sMapNum
+#undef sMapGroup
+#undef sData3
+#undef sData4
+#undef sFldEffId
+
+u8 GetCurrentApproachingTrainerMapObjectId(void)
+{
+ if (gApproachingTrainerId == 0)
+ return gApproachingTrainers[0].mapObjectId;
+ else
+ return gApproachingTrainers[1].mapObjectId;
+}
+
+u8 GetChosenApproachingTrainerMapObjectId(u8 arrayId)
+{
+ if (arrayId >= ARRAY_COUNT(gApproachingTrainers))
+ return 0;
+ else if (arrayId == 0)
+ return gApproachingTrainers[0].mapObjectId;
+ else
+ return gApproachingTrainers[1].mapObjectId;
+}
+
+void sub_80B4808(void)
+{
+ struct MapObject *trainerObj;
+
+ if (gUnknown_030060AC == 1)
+ {
+ trainerObj = &gMapObjects[gApproachingTrainers[gUnknown_03006080].mapObjectId];
+ gUnknown_03006084[0] = GetFaceDirectionAnimId(GetOppositeDirection(trainerObj->mapobj_unk_18));
+ gUnknown_03006084[1] = 0xFE;
+ ScriptMovement_StartObjectMovementScript(0xFF, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, gUnknown_03006084);
+ }
+ else
+ {
+ trainerObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ gUnknown_03006084[0] = GetFaceDirectionAnimId(trainerObj->mapobj_unk_18);
+ gUnknown_03006084[1] = 0xFE;
+ ScriptMovement_StartObjectMovementScript(0xFF, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, gUnknown_03006084);
+ }
+
+ sub_809BE48(0xFF);
+}
diff --git a/src/tv.c b/src/tv.c
index 205adbf4d..af0c7069c 100644
--- a/src/tv.c
+++ b/src/tv.c
@@ -1,5 +1,3 @@
-
-// Includes
#include "global.h"
#include "rtc.h"
#include "overworld.h"
@@ -34,6 +32,7 @@
#include "naming_screen.h"
#include "malloc.h"
#include "region_map.h"
+#include "constants/region_map_sections.h"
#include "decoration.h"
#include "secret_base.h"
#include "tv.h"
@@ -6504,7 +6503,7 @@ void DoTVShowTodaysRivalTrainer(void)
break;
case 1:
TV_PrintIntToStringVar(0, show->rivalTrainer.badgeCount);
- if (FlagGet(CODE_FLAGS + 0x48))
+ if (FlagGet(FLAG_LANDMARK_BATTLE_FRONTIER))
{
if (show->rivalTrainer.nSilverSymbols || show->rivalTrainer.nGoldSymbols)
{
@@ -6521,7 +6520,7 @@ void DoTVShowTodaysRivalTrainer(void)
}
break;
case 2:
- if (FlagGet(CODE_FLAGS + 0x48))
+ if (FlagGet(FLAG_LANDMARK_BATTLE_FRONTIER))
{
if (show->rivalTrainer.nSilverSymbols || show->rivalTrainer.nGoldSymbols)
{
diff --git a/src/unk_81BAD84.c b/src/unk_81BAD84.c
index 9ba98dd87..c0d891c12 100644
--- a/src/unk_81BAD84.c
+++ b/src/unk_81BAD84.c
@@ -7,29 +7,29 @@ const struct {
const u16 *pltt;
} gUnknown_08617128[] = {
{
- gUnknown_08DD87C0,
- gUnknown_08DD8EE0,
- gUnknown_08DD8780
+ gBerryFixGameboy_Gfx,
+ gBerryFixGameboy_Tilemap,
+ gBerryFixGameboy_Pal
}, {
- gUnknown_08DD90E0,
- gUnknown_08DD9718,
- gUnknown_08DD9080
+ gBerryFixGameboyLogo_Gfx,
+ gBerryFixGameboyLogo_Tilemap,
+ gBerryFixGameboyLogo_Pal
}, {
- gUnknown_08DD98B4,
- gUnknown_08DD9E58,
- gUnknown_08DD9874
+ gBerryFixGbaTransfer_Gfx,
+ gBerryFixGbaTransfer_Tilemap,
+ gBerryFixGbaTransfer_Pal
}, {
- gUnknown_08DDA02C,
- gUnknown_08DDA63C,
- gUnknown_08DD9FEC
+ gBerryFixGbaTransferHighlight_Gfx,
+ gBerryFixGbaTransferHighlight_Tilemap,
+ gBerryFixGbaTransferHighlight_Pal
}, {
- gUnknown_08DDA840,
- gUnknown_08DDAE40,
- gUnknown_08DDA800
+ gBerryFixGbaTransferError_Gfx,
+ gBerryFixGbaTransferError_Tilemap,
+ gBerryFixGbaTransferError_Pal
}, {
- gUnknown_08DDB020,
- gUnknown_08DDB2C4,
- gUnknown_08DDAFE0
+ gBerryFixWindow_Gfx,
+ gBerryFixWindow_Tilemap,
+ gBerryFixWindow_Pal
}
};
diff --git a/src/unk_text_util_2.c b/src/unk_text_util_2.c
index d88af611f..8eaab32b6 100644
--- a/src/unk_text_util_2.c
+++ b/src/unk_text_util_2.c
@@ -4,8 +4,8 @@
#include "text.h"
#include "sound.h"
-static const u8 gUnknown_08616124[] = {1, 2, 4};
-static const u16 gFont6BrailleGlyphs[] = INCBIN_U16("data/graphics/fonts/font6.fwjpnfont");
+static const u8 sUnknown_08616124[] = {1, 2, 4};
+static const u16 sFont6BrailleGlyphs[] = INCBIN_U16("data/graphics/fonts/font6.fwjpnfont");
static void DecompressGlyphFont6(u16);
@@ -13,7 +13,7 @@ u16 Font6Func(struct TextPrinter *textPrinter)
{
u16 char_;
struct TextPrinterSubStruct *sub;
-
+
sub = &textPrinter->sub_union.sub;
switch (textPrinter->state)
{
@@ -163,15 +163,15 @@ u16 Font6Func(struct TextPrinter *textPrinter)
case 4:
if (textPrinter->scrollDistance)
{
- if (textPrinter->scrollDistance < gUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed])
+ if (textPrinter->scrollDistance < sUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed])
{
ScrollWindow(textPrinter->subPrinter.windowId, 0, textPrinter->scrollDistance, textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4));
textPrinter->scrollDistance = 0;
}
else
{
- ScrollWindow(textPrinter->subPrinter.windowId, 0, gUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed], textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4));
- textPrinter->scrollDistance -= gUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed];
+ ScrollWindow(textPrinter->subPrinter.windowId, 0, sUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed], textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4));
+ textPrinter->scrollDistance -= sUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed];
}
CopyWindowToVram(textPrinter->subPrinter.windowId, 2);
}
@@ -204,7 +204,7 @@ static void DecompressGlyphFont6(u16 glyph)
{
const u16 *glyphs;
- glyphs = gFont6BrailleGlyphs + 0x100 * (glyph / 8) + 0x10 * (glyph % 8);
+ glyphs = sFont6BrailleGlyphs + 0x100 * (glyph / 8) + 0x10 * (glyph % 8);
DecompressGlyphTile(glyphs, (u16 *)gUnknown_03002F90);
DecompressGlyphTile(glyphs + 0x8, (u16 *)(gUnknown_03002F90 + 0x20));
DecompressGlyphTile(glyphs + 0x80, (u16 *)(gUnknown_03002F90 + 0x40));
diff --git a/src/use_pokeblock.c b/src/use_pokeblock.c
new file mode 100644
index 000000000..12f475c93
--- /dev/null
+++ b/src/use_pokeblock.c
@@ -0,0 +1,230 @@
+#include "global.h"
+#include "main.h"
+#include "pokeblock.h"
+#include "malloc.h"
+#include "palette.h"
+#include "pokenav.h"
+#include "unknown_task.h"
+#include "text.h"
+#include "bg.h"
+#include "window.h"
+#include "text_window.h"
+
+struct UsePokeblockSubStruct
+{
+ void (*field_0)(void);
+ void (*callback)(void);
+ struct Pokeblock *pokeblock;
+ struct Pokemon *pokemon;
+ u8 stringBuffer[0x40];
+ u8 field_50;
+ u8 field_51;
+ u8 field_52;
+ u8 field_53;
+ u8 field_54;
+ u8 field_55;
+ u8 field_56;
+ u8 field_57[5];
+ u8 field_5c[5];
+ u8 field_61[5];
+ s16 field_66[5];
+};
+
+struct UsePokeblockStruct
+{
+ u8 field_0[0x7C58];
+ u8 field_7C58[0x378];
+ struct UsePokeblockSubStruct info;
+};
+
+extern u16 gKeyRepeatStartDelay;
+
+// this file's functions
+void sub_816636C(void (*func)(void));
+void sub_8166380(void);
+void sub_816631C(void);
+void sub_81662C0(void);
+void sub_8166564(void);
+void sub_8166304(void);
+void sub_81668F8(void);
+void sub_8167420(void);
+void sub_8167760(void);
+u8 sub_81672E4(u8 arg0);
+bool8 sub_8168328(void);
+bool8 sub_8167930(void);
+void sub_8167608(u8 arg0);
+void sub_8167BA0(u16 arg0, u8 copyToVramMode);
+
+extern const struct BgTemplate gUnknown_085DFCCC[4];
+extern const struct WindowTemplate gUnknown_085DFCDC[];
+
+// ram variables
+EWRAM_DATA struct UsePokeblockSubStruct *gUnknown_0203BC90 = NULL;
+EWRAM_DATA void (*gUnknown_0203BC94)(void) = NULL;
+EWRAM_DATA struct Pokeblock *gUnknown_0203BC98 = NULL;
+EWRAM_DATA u8 gPokeblockMonId = 0;
+EWRAM_DATA s16 gPokeblockGain = 0;
+EWRAM_DATA void *gUnknown_0203BCA0 = NULL;
+EWRAM_DATA void *gUnknown_0203BCA4 = NULL;
+EWRAM_DATA void *gUnknown_0203BCA8 = NULL;
+EWRAM_DATA struct UsePokeblockStruct *gUnknown_0203BCAC = NULL;
+
+// const rom data
+// todo: make it static once the file is decompiled
+
+// code
+void ChooseMonToGivePokeblock(struct Pokeblock *pokeblock, void (*callback)(void))
+{
+ gUnknown_0203BCAC = AllocZeroed(0x806C);
+ gUnknown_0203BC90 = &gUnknown_0203BCAC->info;
+ gUnknown_0203BC90->pokeblock = pokeblock;
+ gUnknown_0203BC90->callback = callback;
+ sub_816636C(sub_8166380);
+ SetMainCallback2(sub_816631C);
+}
+
+void CB2_ReturnAndChooseMonToGivePokeblock(void)
+{
+ gUnknown_0203BCAC = AllocZeroed(0x806C);
+ gUnknown_0203BC90 = &gUnknown_0203BCAC->info;
+ gUnknown_0203BC90->pokeblock = gUnknown_0203BC98;
+ gUnknown_0203BC90->callback = gUnknown_0203BC94;
+ gPokeblockMonId = sub_81672E4(gPokeblockMonId);
+ gUnknown_0203BC90->field_56 = gPokeblockMonId < 4 ? 0 : 1;
+ sub_816636C(sub_8166380);
+ SetMainCallback2(sub_81662C0);
+}
+
+void sub_81662C0(void)
+{
+ gUnknown_0203BC90->field_0();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ if (gUnknown_0203BC90->field_0 == sub_8166564)
+ {
+ gUnknown_0203BC90->field_50 = 0;
+ SetMainCallback2(sub_8166304);
+ }
+}
+
+void sub_8166304(void)
+{
+ sub_81668F8();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+void sub_816631C(void)
+{
+ gUnknown_0203BC90->field_0();
+ AnimateSprites();
+ BuildOamBuffer();
+ RunTextPrinters();
+ UpdatePaletteFade();
+}
+
+void sub_8166340(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+ sub_81D2108(gUnknown_0203BCAC->field_7C58);
+ sub_80BA0A8();
+}
+
+void sub_816636C(void (*func)(void))
+{
+ gUnknown_0203BC90->field_0 = func;
+ gUnknown_0203BC90->field_50 = 0;
+}
+
+void sub_8166380(void)
+{
+ switch (gUnknown_0203BC90->field_50)
+ {
+ case 0:
+ gUnknown_0203BCAC->field_0[0x7B10] = 0xFF;
+ sub_81D1ED4(gUnknown_0203BCAC->field_7C58);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 1:
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 2:
+ SetVBlankCallback(NULL);
+ CpuFill32(0, (void*)(VRAM), VRAM_SIZE);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 3:
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, gUnknown_085DFCCC, ARRAY_COUNT(gUnknown_085DFCCC));
+ InitWindows(gUnknown_085DFCDC);
+ DeactivateAllTextPrinters();
+ sub_809882C(0, 0x97, 0xE0);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 4:
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 5:
+ if (!sub_8168328())
+ {
+ gUnknown_0203BC90->field_50++;
+ }
+ break;
+ case 6:
+ gKeyRepeatStartDelay = 20;
+ sub_8167420();
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 7:
+ if (!sub_8167930())
+ {
+ gUnknown_0203BC90->field_50++;
+ }
+ break;
+ case 8:
+ sub_8167608(0);
+ sub_8167760();
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 9:
+ if (!sub_81D312C(&gUnknown_0203BCAC->field_0[0x7B0E]))
+ {
+ gUnknown_0203BC90->field_50++;
+ }
+ break;
+ case 10:
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 11:
+ sub_81D2754(gUnknown_0203BCAC->field_7C58, &gUnknown_0203BCAC->field_0[0x7C6C]);
+ sub_81D20AC(gUnknown_0203BCAC->field_7C58);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 12:
+ if (!sub_81D20BC(gUnknown_0203BCAC->field_7C58))
+ {
+ sub_81D1F84(gUnknown_0203BCAC->field_7C58, &gUnknown_0203BCAC->field_7C58[0x14], &gUnknown_0203BCAC->field_7C58[0x14]);
+ gUnknown_0203BC90->field_50++;
+ }
+ break;
+ case 13:
+ sub_81D2230(gUnknown_0203BCAC->field_7C58);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 14:
+ PutWindowTilemap(0);
+ PutWindowTilemap(1);
+ sub_8167BA0(0, 1);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 15:
+ sub_816636C(sub_8166564);
+ break;
+ }
+}
diff --git a/src/wallclock.c b/src/wallclock.c
index 892ef3f05..ea6137c5d 100644
--- a/src/wallclock.c
+++ b/src/wallclock.c
@@ -16,7 +16,7 @@
#include "task.h"
#include "strings.h"
#include "sound.h"
-#include "songs.h"
+#include "constants/songs.h"
#include "trig.h"
#include "decompress.h"
@@ -57,8 +57,8 @@ static void SpriteCB_PMIndicator(struct Sprite *sprite);
// rodata
-static const u8 gUnknown_085B1F58[] = INCBIN_U8("graphics/wallclock/graphics_85b1f58.4bpp.lz");
-static const u16 gUnknown_085B21D4[] = INCBIN_U16("graphics/wallclock/palette_85b21d4.gbapal");
+static const u8 sUnknown_085B1F58[] = INCBIN_U8("graphics/wallclock/graphics_85b1f58.4bpp.lz");
+static const u16 sUnknown_085B21D4[] = INCBIN_U16("graphics/wallclock/palette_85b21d4.gbapal");
static const struct WindowTemplate gUnknown_085B21DC[] = {
{ 0x00, 0x03, 0x11, 0x18, 0x02, 0x0e, 0x200 },
{ 0x02, 0x18, 0x10, 0x06, 0x02, 0x0c, 0x230 },
@@ -88,12 +88,12 @@ static const struct BgTemplate gUnknown_085B21FC[] = {
}
};
static const struct CompressedSpriteSheet gUnknown_085B2208 = {
- gUnknown_085B1F58, 0x2000, TAG_GFX_WALL_CLOCK_HAND
+ sUnknown_085B1F58, 0x2000, TAG_GFX_WALL_CLOCK_HAND
};
static const u32 filler_85B2210[2] = {};
static const struct SpritePalette gUnknown_085B2218[] = {
- { gUnknown_08DCC01C, TAG_PAL_WALL_CLOCK_HAND },
- { gUnknown_08DCC03C, 0x1001 },
+ { gWallclockMale_Pal, TAG_PAL_WALL_CLOCK_HAND },
+ { gWallclockFemale_Pal, 0x1001 },
{}
};
static const struct OamData Unknown_085B2230 = {
@@ -561,17 +561,17 @@ static void LoadWallClockGraphics(void)
DmaFillLarge16(3, 0, (void *)VRAM, VRAM_SIZE, 0x1000);
DmaClear32(3, (void *)OAM, OAM_SIZE);
DmaClear16(3, (void *)PLTT, PLTT_SIZE);
- LZ77UnCompVram(gUnknown_08DCC05C, (void *)VRAM);
+ LZ77UnCompVram(gWallclock_Gfx, (void *)VRAM);
if (gSpecialVar_0x8004 == 0)
{
- LoadPalette(gUnknown_08DCC01C, 0x00, 0x20);
+ LoadPalette(gWallclockMale_Pal, 0x00, 0x20);
}
else
{
- LoadPalette(gUnknown_08DCC03C, 0x00, 0x20);
+ LoadPalette(gWallclockFemale_Pal, 0x00, 0x20);
}
LoadPalette(GetOverworldTextboxPalettePtr(), 0xe0, 0x20);
- LoadPalette(gUnknown_085B21D4, 0xc0, 0x08);
+ LoadPalette(sUnknown_085B21D4, 0xc0, 0x08);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gUnknown_085B21FC, 3);
InitWindows(gUnknown_085B21DC);
@@ -666,27 +666,27 @@ void Cb2_ViewWallClock(void)
angle1 = 90;
angle2 = 135;
}
-
+
spriteId = CreateSprite(&gUnknown_085B2250, 0x78, 0x50, 1);
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[spriteId].oam.matrixNum = 0;
-
+
spriteId = CreateSprite(&gUnknown_085B2268, 0x78, 0x50, 0);
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[spriteId].oam.matrixNum = 1;
-
+
spriteId = CreateSprite(&gUnknown_085B22A0, 0x78, 0x50, 2);
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].data[1] = angle1;
-
+
spriteId = CreateSprite(&gUnknown_085B22B8, 0x78, 0x50, 2);
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].data[1] = angle2;
-
+
WallClockInit();
-
+
PrintTextOnWindow(1, 1, gText_Cancel4, 0, 1, 0, NULL);
PutWindowTilemap(1);
schedule_bg_copy_tilemap_to_vram(2);
diff --git a/src/window.c b/src/window.c
index f4cb48ec0..3913b5800 100644
--- a/src/window.c
+++ b/src/window.c
@@ -465,696 +465,74 @@ void FillWindowPixelBuffer(u8 windowId, u8 fillValue)
CpuFastFill8(fillValue, gWindows[windowId].tileData, 0x20 * fillSize);
}
-// functionally equivalent, its fucking hard to match
-#ifdef NONMATCHING
+#define MOVE_TILES_DOWN(a) \
+{ \
+ destOffset = i + (a); \
+ srcOffset = i + (((width * (distanceLoop & ~7)) | (distanceLoop & 7)) * 4); \
+ if (srcOffset < size) \
+ *(u32*)(tileData + destOffset) = *(u32*)(tileData + srcOffset); \
+ else \
+ *(u32*)(tileData + destOffset) = fillValue32; \
+ distanceLoop++; \
+}
+
+#define MOVE_TILES_UP(a) \
+{ \
+ destOffset = i + (a); \
+ srcOffset = i + (((width * (distanceLoop & ~7)) | (distanceLoop & 7)) * 4); \
+ if (srcOffset < size) \
+ *(u32*)(tileData - destOffset) = *(u32*)(tileData - srcOffset); \
+ else \
+ *(u32*)(tileData - destOffset) = fillValue32; \
+ distanceLoop++; \
+}
+
void ScrollWindow(u8 windowId, u8 direction, u8 distance, u8 fillValue)
{
- s32 i, id1, id2, size;
- u32 distanceLoop, toFill, width;
- u8 *tileData;
- struct WindowTemplate window;
-
- tileData = gWindows[windowId].tileData;
- toFill = (fillValue << 0x18) | (fillValue << 0x10) | (fillValue << 8) | fillValue;
- window = gWindows[windowId].window;
- size = 0x20 * (window.height * window.width);
- width = window.width;
- if (direction != 1)
+ struct WindowTemplate window = gWindows[windowId].window;
+ u8 *tileData = gWindows[windowId].tileData;
+ u32 fillValue32 = (fillValue << 24) | (fillValue << 16) | (fillValue << 8) | fillValue;
+ s32 size = window.height * window.width * 32;
+ u32 width = window.width;
+ s32 i;
+ s32 srcOffset, destOffset;
+ u32 distanceLoop;
+
+ switch (direction)
{
- s32 signedDirection = direction;
- if (signedDirection <= 1)
+ case 0:
+ for (i = 0; i < size; i += 32)
{
- if (signedDirection == 0)
- {
- for (i = 0; i < size; i += 0x20)
- {
- distanceLoop = distance;
- id1 = i + 0;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData + id1) = *(u32*)(tileData + id2);
- else
- *(u32*)(tileData + id1) = toFill;
-
- distanceLoop++;
- id1 = i + 4;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData + id1) = *(u32*)(tileData + id2);
- else
- *(u32*)(tileData + id1) = toFill;
-
- distanceLoop++;
- id1 = i + 8;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData + id1) = *(u32*)(tileData + id2);
- else
- *(u32*)(tileData + id1) = toFill;
-
- distanceLoop++;
- id1 = i + 12;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData + id1) = *(u32*)(tileData + id2);
- else
- *(u32*)(tileData + id1) = toFill;
-
- distanceLoop++;
- id1 = i + 16;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData + id1) = *(u32*)(tileData + id2);
- else
- *(u32*)(tileData + id1) = toFill;
-
- distanceLoop++;
- id1 = i + 20;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData + id1) = *(u32*)(tileData + id2);
- else
- *(u32*)(tileData + id1) = toFill;
-
- distanceLoop++;
- id1 = i + 24;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData + id1) = *(u32*)(tileData + id2);
- else
- *(u32*)(tileData + id1) = toFill;
-
- distanceLoop++;
- id1 = i + 28;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData + id1) = *(u32*)(tileData + id2);
- else
- *(u32*)(tileData + id1) = toFill;
- }
- }
+ distanceLoop = distance;
+ MOVE_TILES_DOWN(0)
+ MOVE_TILES_DOWN(4)
+ MOVE_TILES_DOWN(8)
+ MOVE_TILES_DOWN(12)
+ MOVE_TILES_DOWN(16)
+ MOVE_TILES_DOWN(20)
+ MOVE_TILES_DOWN(24)
+ MOVE_TILES_DOWN(28)
}
- }
- else
- {
+ break;
+ case 1:
tileData += size - 4;
- for (i = 0; i < size; i += 0x20)
+ for (i = 0; i < size; i += 32)
{
distanceLoop = distance;
- id1 = i + 0;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData - id1) = *(u32*)(tileData - id2);
- else
- *(u32*)(tileData - id1) = toFill;
-
- distanceLoop++;
- id1 = i + 4;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData - id1) = *(u32*)(tileData - id2);
- else
- *(u32*)(tileData - id1) = toFill;
-
- distanceLoop++;
- id1 = i + 8;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData - id1) = *(u32*)(tileData - id2);
- else
- *(u32*)(tileData - id1) = toFill;
-
- distanceLoop++;
- id1 = i + 12;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData - id1) = *(u32*)(tileData - id2);
- else
- *(u32*)(tileData - id1) = toFill;
-
- distanceLoop++;
- id1 = i + 16;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData - id1) = *(u32*)(tileData - id2);
- else
- *(u32*)(tileData - id1) = toFill;
-
- distanceLoop++;
- id1 = i + 20;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData - id1) = *(u32*)(tileData - id2);
- else
- *(u32*)(tileData - id1) = toFill;
-
- distanceLoop++;
- id1 = i + 24;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData - id1) = *(u32*)(tileData - id2);
- else
- *(u32*)(tileData - id1) = toFill;
-
- distanceLoop++;
- id1 = i + 28;
- id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
- if (id2 < size)
- *(u32*)(tileData - id1) = *(u32*)(tileData - id2);
- else
- *(u32*)(tileData - id1) = toFill;
+ MOVE_TILES_UP(0)
+ MOVE_TILES_UP(4)
+ MOVE_TILES_UP(8)
+ MOVE_TILES_UP(12)
+ MOVE_TILES_UP(16)
+ MOVE_TILES_UP(20)
+ MOVE_TILES_UP(24)
+ MOVE_TILES_UP(28)
}
+ break;
+ case 2:
+ break;
}
}
-#else
-__attribute__((naked))
-void ScrollWindow(u8 windowId, u8 direction, u8 distance, u8 fillValue)
-{
- asm(".syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r10\n\
- mov r6, r9\n\
- mov r5, r8\n\
- push {r5-r7}\n\
- sub sp, 0x8\n\
- lsls r0, 24\n\
- lsrs r0, 24\n\
- lsls r1, 24\n\
- lsrs r1, 24\n\
- mov r8, r1\n\
- lsls r2, 24\n\
- lsrs r2, 24\n\
- str r2, [sp]\n\
- lsls r3, 24\n\
- lsrs r3, 24\n\
- ldr r2, =gWindows\n\
- lsls r1, r0, 1\n\
- adds r1, r0\n\
- lsls r1, 2\n\
- adds r4, r1, r2\n\
- adds r2, 0x8\n\
- adds r1, r2\n\
- ldr r5, [r1]\n\
- lsls r7, r3, 24\n\
- lsls r0, r3, 16\n\
- orrs r7, r0\n\
- lsls r0, r3, 8\n\
- orrs r7, r0\n\
- orrs r7, r3\n\
- ldr r1, [r4]\n\
- ldr r2, [r4, 0x4]\n\
- ldrb r3, [r4, 0x4]\n\
- lsrs r0, r1, 24\n\
- muls r0, r3\n\
- lsls r6, r0, 5\n\
- lsrs r1, 24\n\
- mov r12, r1\n\
- mov r0, r8\n\
- cmp r0, 0x1\n\
- bne _08003CE8\n\
- b _08003E9E\n\
-_08003CE8:\n\
- cmp r0, 0x1\n\
- ble _08003CEE\n\
- b _08004046\n\
-_08003CEE:\n\
- cmp r0, 0\n\
- beq _08003CF4\n\
- b _08004046\n\
-_08003CF4:\n\
- movs r4, 0\n\
- cmp r4, r6\n\
- blt _08003CFC\n\
- b _08004046\n\
-_08003CFC:\n\
- movs r1, 0x8\n\
- negs r1, r1\n\
- mov r9, r1\n\
- movs r2, 0x7\n\
- mov r8, r2\n\
- mov r10, r5\n\
-_08003D08:\n\
- ldr r3, [sp]\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- adds r0, r3, 0\n\
- mov r2, r8\n\
- ands r0, r2\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003D34\n\
- adds r0, r5, r1\n\
- ldr r0, [r0]\n\
- mov r1, r10\n\
- str r0, [r1]\n\
- b _08003D38\n\
- .pool\n\
-_08003D34:\n\
- mov r2, r10\n\
- str r7, [r2]\n\
-_08003D38:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0x4\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003D64\n\
- adds r0, r5, r2\n\
- adds r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003D68\n\
-_08003D64:\n\
- adds r0, r5, r2\n\
- str r7, [r0]\n\
-_08003D68:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x8\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003D96\n\
- adds r0, r5, r2\n\
- adds r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003D9A\n\
-_08003D96:\n\
- adds r0, r5, r2\n\
- str r7, [r0]\n\
-_08003D9A:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0xC\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003DC8\n\
- adds r0, r5, r2\n\
- adds r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003DCC\n\
-_08003DC8:\n\
- adds r0, r5, r2\n\
- str r7, [r0]\n\
-_08003DCC:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x10\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003DFA\n\
- adds r0, r5, r2\n\
- adds r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003DFE\n\
-_08003DFA:\n\
- adds r0, r5, r2\n\
- str r7, [r0]\n\
-_08003DFE:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x14\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003E2C\n\
- adds r0, r5, r2\n\
- adds r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003E30\n\
-_08003E2C:\n\
- adds r0, r5, r2\n\
- str r7, [r0]\n\
-_08003E30:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x18\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003E5E\n\
- adds r0, r5, r2\n\
- adds r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003E62\n\
-_08003E5E:\n\
- adds r0, r5, r2\n\
- str r7, [r0]\n\
-_08003E62:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x1C\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- adds r0, r1, 0\n\
- mov r1, r8\n\
- ands r3, r1\n\
- orrs r0, r3\n\
- lsls r0, 2\n\
- adds r1, r4, r0\n\
- cmp r1, r6\n\
- bge _08003E8C\n\
- adds r0, r5, r2\n\
- adds r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003E90\n\
-_08003E8C:\n\
- adds r0, r5, r2\n\
- str r7, [r0]\n\
-_08003E90:\n\
- movs r2, 0x20\n\
- add r10, r2\n\
- adds r4, 0x20\n\
- cmp r4, r6\n\
- bge _08003E9C\n\
- b _08003D08\n\
-_08003E9C:\n\
- b _08004046\n\
-_08003E9E:\n\
- subs r0, r6, 0x4\n\
- adds r5, r0\n\
- movs r4, 0\n\
- cmp r4, r6\n\
- blt _08003EAA\n\
- b _08004046\n\
-_08003EAA:\n\
- movs r0, 0x8\n\
- negs r0, r0\n\
- mov r9, r0\n\
- movs r1, 0x7\n\
- mov r8, r1\n\
- mov r10, r5\n\
-_08003EB6:\n\
- ldr r3, [sp]\n\
- adds r0, r3, 0\n\
- mov r2, r9\n\
- ands r0, r2\n\
- mov r1, r12\n\
- muls r1, r0\n\
- adds r0, r3, 0\n\
- mov r2, r8\n\
- ands r0, r2\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003EDC\n\
- subs r0, r5, r1\n\
- ldr r0, [r0]\n\
- mov r1, r10\n\
- str r0, [r1]\n\
- b _08003EE0\n\
-_08003EDC:\n\
- mov r2, r10\n\
- str r7, [r2]\n\
-_08003EE0:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0x4\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003F0C\n\
- subs r0, r5, r2\n\
- subs r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003F10\n\
-_08003F0C:\n\
- subs r0, r5, r2\n\
- str r7, [r0]\n\
-_08003F10:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x8\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003F3E\n\
- subs r0, r5, r2\n\
- subs r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003F42\n\
-_08003F3E:\n\
- subs r0, r5, r2\n\
- str r7, [r0]\n\
-_08003F42:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0xC\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003F70\n\
- subs r0, r5, r2\n\
- subs r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003F74\n\
-_08003F70:\n\
- subs r0, r5, r2\n\
- str r7, [r0]\n\
-_08003F74:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x10\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003FA2\n\
- subs r0, r5, r2\n\
- subs r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003FA6\n\
-_08003FA2:\n\
- subs r0, r5, r2\n\
- str r7, [r0]\n\
-_08003FA6:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x14\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08003FD4\n\
- subs r0, r5, r2\n\
- subs r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08003FD8\n\
-_08003FD4:\n\
- subs r0, r5, r2\n\
- str r7, [r0]\n\
-_08003FD8:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x18\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- str r1, [sp, 0x4]\n\
- adds r0, r3, 0\n\
- mov r1, r8\n\
- ands r0, r1\n\
- ldr r1, [sp, 0x4]\n\
- orrs r1, r0\n\
- lsls r1, 2\n\
- adds r1, r4, r1\n\
- cmp r1, r6\n\
- bge _08004006\n\
- subs r0, r5, r2\n\
- subs r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _0800400A\n\
-_08004006:\n\
- subs r0, r5, r2\n\
- str r7, [r0]\n\
-_0800400A:\n\
- adds r3, 0x1\n\
- adds r2, r4, 0\n\
- adds r2, 0x1C\n\
- adds r0, r3, 0\n\
- mov r1, r9\n\
- ands r0, r1\n\
- mov r1, r12\n\
- muls r1, r0\n\
- adds r0, r1, 0\n\
- mov r1, r8\n\
- ands r3, r1\n\
- orrs r0, r3\n\
- lsls r0, 2\n\
- adds r1, r4, r0\n\
- cmp r1, r6\n\
- bge _08004034\n\
- subs r0, r5, r2\n\
- subs r1, r5, r1\n\
- ldr r1, [r1]\n\
- str r1, [r0]\n\
- b _08004038\n\
-_08004034:\n\
- subs r0, r5, r2\n\
- str r7, [r0]\n\
-_08004038:\n\
- movs r2, 0x20\n\
- negs r2, r2\n\
- add r10, r2\n\
- adds r4, 0x20\n\
- cmp r4, r6\n\
- bge _08004046\n\
- b _08003EB6\n\
-_08004046:\n\
- add sp, 0x8\n\
- pop {r3-r5}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- mov r10, r5\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0\n\
- .syntax divided");
-}
-#endif // NONMATCHING
void CallWindowFunction(u8 windowId, void ( *func)(u8, u8, u8, u8, u8, u8))
{