summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoryenatch <yenatch@gmail.com>2017-07-05 21:37:14 -0400
committeryenatch <yenatch@gmail.com>2017-07-05 21:37:14 -0400
commit06bf25405c98257e47953b5d3c327e314ea371b3 (patch)
tree81be5b612621bdd74f632dbedb9f85c4d1d203b9 /src
parent282cae4a9fbd019a973fb6618337d29a61f97f42 (diff)
parentbe05c5bd52769b58316986bd7451cb2483571099 (diff)
Merge remote-tracking branch 'origin/master' into merge-pika
Conflicts: include/use_pokeblock.h
Diffstat (limited to 'src')
-rw-r--r--src/battle_10.c1322
-rw-r--r--src/battle_2.c199
-rw-r--r--src/battle_811DA74.c9
-rw-r--r--src/battle_ai.c283
-rw-r--r--src/battle_anim_8137220.c2
-rw-r--r--src/battle_party_menu.c2
-rw-r--r--src/berry.c2
-rw-r--r--src/berry_tag_screen.c2
-rw-r--r--src/calculate_base_damage.c6
-rwxr-xr-x[-rw-r--r--]src/decoration.c8
-rw-r--r--[-rwxr-xr-x]src/field_map_obj.c0
-rw-r--r--[-rwxr-xr-x]src/field_map_obj_helpers.c0
-rw-r--r--src/field_special_scene.c2
-rwxr-xr-xsrc/field_tasks.c859
-rw-r--r--src/item_use.c1
-rw-r--r--src/link.c2
-rw-r--r--src/menu.c2
-rw-r--r--src/mori_debug_menu.c2
-rw-r--r--src/party_menu.c2
-rw-r--r--src/player_pc.c1
-rwxr-xr-xsrc/pokeblock.c1116
-rw-r--r--src/pokemon_2.c11
-rw-r--r--src/pokemon_3.c44
-rw-r--r--src/pokemon_data.c128
-rw-r--r--src/rom4.c2
-rw-r--r--src/rotating_gate.c1228
-rwxr-xr-xsrc/sound_check_menu.c2198
-rw-r--r--src/tv.c23
28 files changed, 7132 insertions, 324 deletions
diff --git a/src/battle_10.c b/src/battle_10.c
new file mode 100644
index 000000000..34e4f75b1
--- /dev/null
+++ b/src/battle_10.c
@@ -0,0 +1,1322 @@
+#include "global.h"
+#include "battle.h"
+#include "battle_interface.h"
+#include "data2.h"
+#include "link.h"
+#include "palette.h"
+#include "rom_8077ABC.h"
+#include "rom3.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "string_util.h"
+#include "task.h"
+#include "text.h"
+#include "util.h"
+
+struct UnknownStruct3
+{
+ u16 moves[4];
+ u8 pp[4];
+ u8 ppBonuses;
+};
+
+extern u8 gActiveBank;
+extern u8 gBattleBufferA[][0x200];
+extern u8 gObjectBankIDs[];
+extern u16 gBattlePartyID[];
+extern u8 gHealthboxIDs[];
+extern u16 gBattleTypeFlags;
+extern u8 gBattleMonForms[];
+extern void (*gBattleBankFunc[])(void);
+extern u32 *gDisableStructMoveAnim;
+extern u32 gMoveDmgMoveAnim;
+extern u16 gMovePowerMoveAnim;
+extern u8 gHappinessMoveAnim;
+extern u16 gWeatherMoveAnim;
+extern u32 gPID_perBank[];
+extern u8 gAnimScriptActive;
+extern void (*gAnimScriptCallback)(void);
+extern u8 gDisplayedStringBattle[];
+extern bool8 gDoingBattleAnim;
+extern u8 gBattleOutcome;
+extern u16 gUnknown_02024DE8;
+extern u8 gUnknown_02024E68[];
+extern struct SpriteTemplate gUnknown_02024E8C;
+extern u8 gUnknown_0202F7C4;
+extern struct Window gUnknown_03004210;
+extern u16 gUnknown_030042A0;
+extern u16 gUnknown_030042A4;
+extern u8 gUnknown_0300434C[];
+
+extern u8 sub_8077F68();
+extern u8 sub_8079E90();
+extern u8 GetBankIdentity(u8);
+extern void sub_8031794(struct Pokemon *, u8);
+extern void sub_8037A74(void);
+extern void sub_8032984(u8, u16);
+extern void sub_8037E30(void);
+extern void sub_80312F0(struct Sprite *);
+extern u8 sub_8046400();
+extern void sub_8032A08();
+extern void sub_8043DB0();
+extern void sub_8037BBC(void);
+extern s32 sub_803FC34(u16);
+extern void sub_8031A6C(u16, u8);
+extern void sub_80313A0(struct Sprite *);
+extern void sub_803757C(void);
+extern void oamt_add_pos2_onto_pos1();
+extern void oamt_set_x3A_32();
+extern void sub_8078B34(struct Sprite *);
+extern void sub_80375B4(void);
+extern void sub_8010384(struct Sprite *);
+extern void sub_8037B78(void);
+extern u8 sub_8031720();
+extern u8 mplay_80342A4();
+extern void ExecuteMoveAnim();
+extern void sub_80326EC();
+extern void sub_8031F24(void);
+extern void sub_80324BC();
+extern void BufferStringBattle();
+extern void sub_8037C2C(void);
+extern void sub_8043D84();
+extern void sub_8037B24(void);
+extern void sub_8045A5C();
+extern void sub_8037FAC(void);
+extern void move_anim_start_t2_for_situation();
+extern void dp01t_0F_4_move_anim(void);
+extern void sub_8047858();
+extern u8 GetBankSide(u8);
+extern void sub_80E43C0();
+extern void sub_803A3A8(struct Sprite *);
+extern void sub_8044CA0(u8);
+extern void nullsub_47(void);
+extern bool8 IsDoubleBattle(void);
+extern void sub_8037840(void);
+extern void sub_8031B74();
+extern u8 sub_8078874();
+extern u8 move_anim_start_t3();
+extern void sub_8037FD8(void);
+extern void sub_8037F34(void);
+extern void dp01_tbl4_exec_completed(void);
+
+u32 dp01_getattr_by_ch1_for_player_pokemon__(u8, u8 *);
+void sub_8038900(u8);
+void sub_8039430(u8, u8);
+void sub_8039648(void);
+void sub_8039B64(void);
+void sub_803A2C4(u8);
+void sub_803A4E0(void);
+
+void LinkOpponentHandleGetAttributes(void)
+{
+ u8 buffer[0x100];
+ u32 r6 = 0;
+ u8 r4;
+ s32 i;
+
+ if (gBattleBufferA[gActiveBank][2] == 0)
+ {
+ r6 = dp01_getattr_by_ch1_for_player_pokemon__(gBattlePartyID[gActiveBank], buffer);
+ }
+ else
+ {
+ r4 = gBattleBufferA[gActiveBank][2];
+ for (i = 0; i < 6; i++)
+ {
+ if (r4 & 1)
+ r6 += dp01_getattr_by_ch1_for_player_pokemon__(i, buffer + r6);
+ r4 >>= 1;
+ }
+ }
+ dp01_build_cmdbuf_x1D_1D_numargs_varargs(1, r6, buffer);
+ dp01_tbl4_exec_completed();
+}
+
+u32 dp01_getattr_by_ch1_for_player_pokemon__(u8 a, u8 *buffer)
+{
+ struct BattlePokemon battlePokemon;
+ struct UnknownStruct3 moveData;
+ u8 nickname[20];
+ u8 *src;
+ s16 data16;
+ u32 data32;
+ s32 size = 0;
+
+ switch (gBattleBufferA[gActiveBank][1])
+ {
+ case 0:
+ battlePokemon.species = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES);
+ battlePokemon.item = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM);
+ for (size = 0; size < 4; size++)
+ {
+ battlePokemon.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size);
+ battlePokemon.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size);
+ }
+ battlePokemon.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES);
+ battlePokemon.friendship = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP);
+ battlePokemon.experience = GetMonData(&gEnemyParty[a], MON_DATA_EXP);
+ battlePokemon.hpIV = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV);
+ battlePokemon.attackIV = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV);
+ battlePokemon.defenseIV = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV);
+ battlePokemon.speedIV = GetMonData(&gEnemyParty[a], MON_DATA_SPD_IV);
+ battlePokemon.spAttackIV = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV);
+ battlePokemon.spDefenseIV = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV);
+ battlePokemon.personality = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY);
+ battlePokemon.status1 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS);
+ battlePokemon.level = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL);
+ battlePokemon.hp = GetMonData(&gEnemyParty[a], MON_DATA_HP);
+ battlePokemon.maxHP = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP);
+ battlePokemon.attack = GetMonData(&gEnemyParty[a], MON_DATA_ATK);
+ battlePokemon.defense = GetMonData(&gEnemyParty[a], MON_DATA_DEF);
+ battlePokemon.speed = GetMonData(&gEnemyParty[a], MON_DATA_SPD);
+ battlePokemon.spAttack = GetMonData(&gEnemyParty[a], MON_DATA_SPATK);
+ battlePokemon.spDefense = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF);
+ battlePokemon.isEgg = GetMonData(&gEnemyParty[a], MON_DATA_IS_EGG);
+ battlePokemon.altAbility = GetMonData(&gEnemyParty[a], MON_DATA_ALT_ABILITY);
+ battlePokemon.otId = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID);
+ GetMonData(&gEnemyParty[a], MON_DATA_NICKNAME, nickname);
+ StringCopy10(battlePokemon.nickname, nickname);
+ GetMonData(&gEnemyParty[a], MON_DATA_OT_NAME, battlePokemon.otName);
+ src = (u8 *)&battlePokemon;
+ for (size = 0; size < sizeof(battlePokemon); size++)
+ buffer[size] = src[size];
+ break;
+ case 1:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 2:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 3:
+ for (size = 0; size < 4; size++)
+ {
+ moveData.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size);
+ moveData.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size);
+ }
+ moveData.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES);
+ src = (u8 *)&moveData;
+ for (size = 0; size < sizeof(moveData); size++)
+ buffer[size] = src[size];
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBank][1] - 4);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 8:
+ for (size = 0; size < 4; size++)
+ buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size);
+ buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES);
+ size++;
+ break;
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBank][1] - 9);
+ size = 1;
+ break;
+ case 17:
+ data32 = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID);
+ buffer[0] = (data32 & 0x000000FF);
+ buffer[1] = (data32 & 0x0000FF00) >> 8;
+ buffer[2] = (data32 & 0x00FF0000) >> 16;
+ size = 3;
+ break;
+ case 18:
+ data32 = GetMonData(&gEnemyParty[a], MON_DATA_EXP);
+ buffer[0] = (data32 & 0x000000FF);
+ buffer[1] = (data32 & 0x0000FF00) >> 8;
+ buffer[2] = (data32 & 0x00FF0000) >> 16;
+ size = 3;
+ break;
+ case 19:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_EV);
+ size = 1;
+ break;
+ case 20:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_EV);
+ size = 1;
+ break;
+ case 21:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_EV);
+ size = 1;
+ break;
+ case 22:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPD_EV);
+ size = 1;
+ break;
+ case 23:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV);
+ size = 1;
+ break;
+ case 24:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV);
+ size = 1;
+ break;
+ case 25:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP);
+ size = 1;
+ break;
+ case 26:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKERUS);
+ size = 1;
+ break;
+ case 27:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION);
+ size = 1;
+ break;
+ case 28:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL);
+ size = 1;
+ break;
+ case 29:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_GAME);
+ size = 1;
+ break;
+ case 30:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKEBALL);
+ size = 1;
+ break;
+ case 31:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV);
+ buffer[1] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV);
+ buffer[2] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV);
+ buffer[3] = GetMonData(&gEnemyParty[a], MON_DATA_SPD_IV);
+ buffer[4] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV);
+ buffer[5] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV);
+ size = 6;
+ break;
+ case 32:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV);
+ size = 1;
+ break;
+ case 33:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV);
+ size = 1;
+ break;
+ case 34:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV);
+ size = 1;
+ break;
+ case 35:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPD_IV);
+ size = 1;
+ break;
+ case 36:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV);
+ size = 1;
+ break;
+ case 37:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV);
+ size = 1;
+ break;
+ case 38:
+ data32 = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY);
+ buffer[0] = (data32 & 0x000000FF);
+ buffer[1] = (data32 & 0x0000FF00) >> 8;
+ buffer[2] = (data32 & 0x00FF0000) >> 16;
+ buffer[3] = (data32 & 0xFF000000) >> 24;
+ size = 4;
+ break;
+ case 39:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 40:
+ data32 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS);
+ buffer[0] = (data32 & 0x000000FF);
+ buffer[1] = (data32 & 0x0000FF00) >> 8;
+ buffer[2] = (data32 & 0x00FF0000) >> 16;
+ buffer[3] = (data32 & 0xFF000000) >> 24;
+ size = 4;
+ break;
+ case 41:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL);
+ size = 1;
+ break;
+ case 42:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_HP);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 43:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 44:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_ATK);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 45:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_DEF);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 46:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPD);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 47:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPATK);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 48:
+ data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF);
+ buffer[0] = data16;
+ buffer[1] = data16 >> 8;
+ size = 2;
+ break;
+ case 49:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL);
+ size = 1;
+ break;
+ case 50:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY);
+ size = 1;
+ break;
+ case 51:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE);
+ size = 1;
+ break;
+ case 52:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART);
+ size = 1;
+ break;
+ case 53:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH);
+ size = 1;
+ break;
+ case 54:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SHEEN);
+ size = 1;
+ break;
+ case 55:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON);
+ size = 1;
+ break;
+ case 56:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON);
+ size = 1;
+ break;
+ case 57:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON);
+ size = 1;
+ break;
+ case 58:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON);
+ size = 1;
+ break;
+ case 59:
+ buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON);
+ size = 1;
+ break;
+ }
+ return size;
+}
+
+void sub_803889C(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_80388A8(void)
+{
+ u8 i;
+ u8 r4;
+
+ if (gBattleBufferA[gActiveBank][2] == 0)
+ {
+ sub_8038900(gBattlePartyID[gActiveBank]);
+ }
+ else
+ {
+ r4 = gBattleBufferA[gActiveBank][2];
+ for (i = 0; i < 6; i++)
+ {
+ if (r4 & 1)
+ sub_8038900(i);
+ r4 >>= 1;
+ }
+ }
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8038900(u8 a)
+{
+ struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBank][3];
+ struct UnknownStruct3 *moveData = (struct UnknownStruct3 *)&gBattleBufferA[gActiveBank][3];
+ s32 i;
+
+ switch (gBattleBufferA[gActiveBank][1])
+ {
+ case 0:
+ {
+ u8 iv;
+
+ SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, (u8 *)&battlePokemon->species);
+ SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, (u8 *)&battlePokemon->item);
+ for (i = 0; i < 4; i++)
+ {
+ SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, (u8 *)&battlePokemon->moves[i]);
+ SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, (u8 *)&battlePokemon->pp[i]);
+ }
+ SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, (u8 *)&battlePokemon->ppBonuses);
+ SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, (u8 *)&battlePokemon->friendship);
+ SetMonData(&gEnemyParty[a], MON_DATA_EXP, (u8 *)&battlePokemon->experience);
+ iv = battlePokemon->hpIV;
+ SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, (u8 *)&iv);
+ iv = battlePokemon->attackIV;
+ SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, (u8 *)&iv);
+ iv = battlePokemon->defenseIV;
+ SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, (u8 *)&iv);
+ iv = battlePokemon->speedIV;
+ SetMonData(&gEnemyParty[a], MON_DATA_SPD_IV, (u8 *)&iv);
+ iv = battlePokemon->spAttackIV;
+ SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, (u8 *)&iv);
+ iv = battlePokemon->spDefenseIV;
+ SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, (u8 *)&iv);
+ SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, (u8 *)&battlePokemon->personality);
+ SetMonData(&gEnemyParty[a], MON_DATA_STATUS, (u8 *)&battlePokemon->status1);
+ SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, (u8 *)&battlePokemon->level);
+ SetMonData(&gEnemyParty[a], MON_DATA_HP, (u8 *)&battlePokemon->hp);
+ SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, (u8 *)&battlePokemon->maxHP);
+ SetMonData(&gEnemyParty[a], MON_DATA_ATK, (u8 *)&battlePokemon->attack);
+ SetMonData(&gEnemyParty[a], MON_DATA_DEF, (u8 *)&battlePokemon->defense);
+ SetMonData(&gEnemyParty[a], MON_DATA_SPD, (u8 *)&battlePokemon->speed);
+ SetMonData(&gEnemyParty[a], MON_DATA_SPATK, (u8 *)&battlePokemon->spAttack);
+ SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, (u8 *)&battlePokemon->spDefense);
+ }
+ break;
+ case 1:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 2:
+ SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 3:
+ for (i = 0; i < 4; i++)
+ {
+ SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, (u8 *)&moveData->moves[i]);
+ SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, (u8 *)&moveData->pp[i]);
+ }
+ SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses);
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBank][1] - 4, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 8:
+ SetMonData(&gEnemyParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBank][3]);
+ SetMonData(&gEnemyParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBank][4]);
+ SetMonData(&gEnemyParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBank][5]);
+ SetMonData(&gEnemyParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBank][6]);
+ SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBank][7]);
+ break;
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ SetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBank][1] - 9, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 17:
+ SetMonData(&gEnemyParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 18:
+ SetMonData(&gEnemyParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 19:
+ SetMonData(&gEnemyParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 20:
+ SetMonData(&gEnemyParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 21:
+ SetMonData(&gEnemyParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 22:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPD_EV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 23:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 24:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 25:
+ SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 26:
+ SetMonData(&gEnemyParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 27:
+ SetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 28:
+ SetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 29:
+ SetMonData(&gEnemyParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 30:
+ SetMonData(&gEnemyParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 31:
+ SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBank][3]);
+ SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBank][4]);
+ SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBank][5]);
+ SetMonData(&gEnemyParty[a], MON_DATA_SPD_IV, &gBattleBufferA[gActiveBank][6]);
+ SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBank][7]);
+ SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBank][8]);
+ break;
+ case 32:
+ SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 33:
+ SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 34:
+ SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 35:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPD_IV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 36:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 37:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 38:
+ SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 39:
+ SetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 40:
+ SetMonData(&gEnemyParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 41:
+ SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 42:
+ SetMonData(&gEnemyParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 43:
+ SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 44:
+ SetMonData(&gEnemyParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 45:
+ SetMonData(&gEnemyParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 46:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPD, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 47:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 48:
+ SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 49:
+ SetMonData(&gEnemyParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 50:
+ SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 51:
+ SetMonData(&gEnemyParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 52:
+ SetMonData(&gEnemyParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 53:
+ SetMonData(&gEnemyParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 54:
+ SetMonData(&gEnemyParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 55:
+ SetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 56:
+ SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 57:
+ SetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 58:
+ SetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBank][3]);
+ break;
+ case 59:
+ SetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBank][3]);
+ break;
+ }
+}
+
+void sub_8039220(void)
+{
+ u8 *dst;
+ u8 i;
+
+ dst = (u8 *)&gEnemyParty[gBattlePartyID[gActiveBank]] + gBattleBufferA[gActiveBank][1];
+ for (i = 0; i < gBattleBufferA[gActiveBank][2]; i++)
+ dst[i] = gBattleBufferA[gActiveBank][3 + i];
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039294(void)
+{
+ u16 species = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES);
+
+ sub_8031794(&gEnemyParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ GetMonSpriteTemplate_803C56C(species, GetBankIdentity(gActiveBank));
+ gObjectBankIDs[gActiveBank] = CreateSprite(
+ &gUnknown_02024E8C,
+ sub_8077ABC(gActiveBank, 2),
+ sub_8077F68(gActiveBank),
+ sub_8079E90(gActiveBank));
+ gSprites[gObjectBankIDs[gActiveBank]].pos2.x = -240;
+ gSprites[gObjectBankIDs[gActiveBank]].data0 = gActiveBank;
+ gSprites[gObjectBankIDs[gActiveBank]].oam.paletteNum = gActiveBank;
+ StartSpriteAnim(&gSprites[gObjectBankIDs[gActiveBank]], gBattleMonForms[gActiveBank]);
+ sub_8032984(gActiveBank, GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES));
+ gBattleBankFunc[gActiveBank] = sub_8037A74;
+}
+
+void sub_80393E4(void)
+{
+ gBattlePartyID[gActiveBank] = gBattleBufferA[gActiveBank][1];
+ sub_8039430(gActiveBank, gBattleBufferA[gActiveBank][2]);
+ gBattleBankFunc[gActiveBank] = sub_8037E30;
+}
+
+void sub_8039430(u8 a, u8 b)
+{
+ u16 species;
+
+ sub_8032AA8(a, b);
+ gBattlePartyID[a] = gBattleBufferA[a][1];
+ species = GetMonData(&gEnemyParty[gBattlePartyID[a]], MON_DATA_SPECIES);
+ gUnknown_0300434C[a] = CreateInvisibleSpriteWithCallback(sub_80312F0);
+ sub_8031794(&gEnemyParty[gBattlePartyID[a]], a);
+ GetMonSpriteTemplate_803C56C(species, GetBankIdentity(a));
+ gObjectBankIDs[a] = CreateSprite(
+ &gUnknown_02024E8C,
+ sub_8077ABC(a, 2),
+ sub_8077F68(a),
+ sub_8079E90(a));
+ gSprites[gUnknown_0300434C[a]].data1 = gObjectBankIDs[a];
+ gSprites[gObjectBankIDs[a]].data0 = a;
+ gSprites[gObjectBankIDs[a]].data2 = species;
+ gSprites[gObjectBankIDs[a]].oam.paletteNum = a;
+ StartSpriteAnim(&gSprites[gObjectBankIDs[a]], gBattleMonForms[a]);
+ gSprites[gObjectBankIDs[a]].invisible = TRUE;
+ gSprites[gObjectBankIDs[a]].callback = SpriteCallbackDummy;
+ gSprites[gUnknown_0300434C[a]].data0 = sub_8046400(0, 0xFE);
+}
+
+void sub_80395B4(void)
+{
+ if (gBattleBufferA[gActiveBank][1] == 0)
+ {
+ ewram17810[gActiveBank].unk4 = 0;
+ gBattleBankFunc[gActiveBank] = sub_8039648;
+ }
+ else
+ {
+ FreeSpriteOamMatrix(&gSprites[gObjectBankIDs[gActiveBank]]);
+ DestroySprite(&gSprites[gObjectBankIDs[gActiveBank]]);
+ sub_8032A08(gActiveBank);
+ sub_8043DB0(gHealthboxIDs[gActiveBank]);
+ dp01_tbl4_exec_completed();
+ }
+}
+
+void sub_8039648(void)
+{
+ switch (ewram17810[gActiveBank].unk4)
+ {
+ case 0:
+ if (ewram17800[gActiveBank].unk0_2)
+ move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5);
+ ewram17810[gActiveBank].unk4 = 1;
+ break;
+ case 1:
+ if (!ewram17810[gActiveBank].unk0_6)
+ {
+ ewram17810[gActiveBank].unk4 = 0;
+ move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 2);
+ gBattleBankFunc[gActiveBank] = sub_8037BBC;
+ }
+ break;
+ }
+}
+
+void sub_80396D0(void)
+{
+ s16 xOffset;
+ u32 gender;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ if (GetBankIdentity(gActiveBank) & 2)
+ xOffset = -16;
+ else
+ xOffset = 16;
+ gender = gLinkPlayers[sub_803FC34(gActiveBank)].gender;
+ }
+ else
+ {
+ xOffset = 0;
+ gender = gLinkPlayers[GetMultiplayerId() ^ 1].gender;
+ }
+ sub_8031A6C(gender, gActiveBank);
+ GetMonSpriteTemplate_803C5A0(gender, GetBankIdentity(gActiveBank));
+ gObjectBankIDs[gActiveBank] = CreateSprite(
+ &gUnknown_02024E8C,
+ 176 + xOffset, 40 + 4 * (8 - gTrainerFrontPicCoords[gender].coords),
+ sub_8079E90(gActiveBank));
+ gSprites[gObjectBankIDs[gActiveBank]].pos2.x = -240;
+ gSprites[gObjectBankIDs[gActiveBank]].data0 = 2;
+ gSprites[gObjectBankIDs[gActiveBank]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[gender].tag);
+ gSprites[gObjectBankIDs[gActiveBank]].data5 = gSprites[gObjectBankIDs[gActiveBank]].oam.tileNum;
+ gSprites[gObjectBankIDs[gActiveBank]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[gender].tag);
+ gSprites[gObjectBankIDs[gActiveBank]].oam.affineParam = gender;
+ gSprites[gObjectBankIDs[gActiveBank]].callback = sub_80313A0;
+ gBattleBankFunc[gActiveBank] = sub_803757C;
+}
+
+void sub_80398A4(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_80398B0(void)
+{
+ oamt_add_pos2_onto_pos1(&gSprites[gObjectBankIDs[gActiveBank]]);
+ gSprites[gObjectBankIDs[gActiveBank]].data0 = 35;
+ gSprites[gObjectBankIDs[gActiveBank]].data2 = 280;
+ gSprites[gObjectBankIDs[gActiveBank]].data4 = gSprites[gObjectBankIDs[gActiveBank]].pos1.y;
+ gSprites[gObjectBankIDs[gActiveBank]].callback = sub_8078B34;
+ oamt_set_x3A_32(&gSprites[gObjectBankIDs[gActiveBank]], SpriteCallbackDummy);
+ gBattleBankFunc[gActiveBank] = sub_80375B4;
+}
+
+void sub_803995C(void)
+{
+ if (ewram17810[gActiveBank].unk4 == 0)
+ {
+ if (ewram17800[gActiveBank].unk0_2)
+ move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5);
+ ewram17810[gActiveBank].unk4++;
+ }
+ else if (!ewram17810[gActiveBank].unk0_6)
+ {
+ ewram17810[gActiveBank].unk4 = 0;
+ PlaySE12WithPanning(SE_POKE_DEAD, 63);
+ gSprites[gObjectBankIDs[gActiveBank]].callback = sub_8010384;
+ gBattleBankFunc[gActiveBank] = sub_8037B78;
+ }
+}
+
+void sub_8039A00(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039A0C(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039A18(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039A24(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039A30(void)
+{
+ if (!mplay_80342A4(gActiveBank))
+ {
+ u32 r0 = gBattleBufferA[gActiveBank][1]
+ | (gBattleBufferA[gActiveBank][2] << 8);
+
+ gUnknown_0202F7C4 = gBattleBufferA[gActiveBank][3];
+ gMovePowerMoveAnim = gBattleBufferA[gActiveBank][4]
+ | (gBattleBufferA[gActiveBank][5] << 8);
+ gMoveDmgMoveAnim = gBattleBufferA[gActiveBank][6]
+ | (gBattleBufferA[gActiveBank][7] << 8)
+ | (gBattleBufferA[gActiveBank][8] << 16)
+ | (gBattleBufferA[gActiveBank][9] << 24);
+ gHappinessMoveAnim = gBattleBufferA[gActiveBank][10];
+ gWeatherMoveAnim = gBattleBufferA[gActiveBank][12]
+ | (gBattleBufferA[gActiveBank][13] << 8);
+ gDisableStructMoveAnim = (u32 *)&gBattleBufferA[gActiveBank][16];
+ gPID_perBank[gActiveBank] = *gDisableStructMoveAnim;
+
+ if (sub_8031720(r0, gUnknown_0202F7C4) != 0)
+ {
+ dp01_tbl4_exec_completed();
+ }
+ else
+ {
+ ewram17810[gActiveBank].unk4 = 0;
+ gBattleBankFunc[gActiveBank] = sub_8039B64;
+ }
+ }
+}
+
+void sub_8039B64(void)
+{
+ u16 r4 = gBattleBufferA[gActiveBank][1]
+ | (gBattleBufferA[gActiveBank][2] << 8);
+ u8 r7 = gBattleBufferA[gActiveBank][11];
+
+ switch (ewram17810[gActiveBank].unk4)
+ {
+ case 0:
+ if (ewram17800[gActiveBank].unk0_2 && !ewram17800[gActiveBank].unk0_3)
+ {
+ ewram17800[gActiveBank].unk0_3 = 1;
+ move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5);
+ }
+ ewram17810[gActiveBank].unk4 = 1;
+ break;
+ case 1:
+ if (!ewram17810[gActiveBank].unk0_6)
+ {
+ sub_80326EC(0);
+ ExecuteMoveAnim(r4);
+ ewram17810[gActiveBank].unk4 = 2;
+ }
+ break;
+ case 2:
+ gAnimScriptCallback();
+ if (!gAnimScriptActive)
+ {
+ sub_80326EC(1);
+ if ((ewram17800[gActiveBank].unk0_2) && r7 <= 1)
+ {
+ move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6);
+ ewram17800[gActiveBank].unk0_3 = 0;
+ }
+ ewram17810[gActiveBank].unk4 = 3;
+ }
+ break;
+ case 3:
+ if (!ewram17810[gActiveBank].unk0_6)
+ {
+ sub_8031F24();
+ sub_80324BC(
+ gActiveBank,
+ gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
+ ewram17810[gActiveBank].unk4 = 0;
+ dp01_tbl4_exec_completed();
+ }
+ break;
+ }
+}
+
+void sub_8039CC8(void)
+{
+ gUnknown_030042A4 = 0;
+ gUnknown_030042A0 = 0;
+ BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBank][2]);
+ sub_8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15);
+ gBattleBankFunc[gActiveBank] = sub_8037C2C;
+}
+
+void sub_8039D2C(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039D38(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039D44(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039D50(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039D5C(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039D68(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039D74(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039D80(void)
+{
+ s16 r7;
+
+ load_gfxc_health_bar(0);
+ r7 = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
+ if (r7 != 0x7FFF)
+ {
+ u32 maxHP = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_MAX_HP);
+ u32 hp = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_HP);
+
+ sub_8043D84(gActiveBank, gHealthboxIDs[gActiveBank], maxHP, hp, r7);
+ }
+ else
+ {
+ u32 maxHP = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_MAX_HP);
+
+ sub_8043D84(gActiveBank, gHealthboxIDs[gActiveBank], maxHP, 0, r7);
+ }
+ gBattleBankFunc[gActiveBank] = sub_8037B24;
+}
+
+void sub_8039E70(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039E7C(void)
+{
+ if (mplay_80342A4(gActiveBank) == 0)
+ {
+ sub_8045A5C(gHealthboxIDs[gActiveBank], &gEnemyParty[gBattlePartyID[gActiveBank]], 9);
+ ewram17810[gActiveBank].unk0_4 = 0;
+ gBattleBankFunc[gActiveBank] = sub_8037FAC;
+ }
+}
+
+void sub_8039EF0(void)
+{
+ if (mplay_80342A4(gActiveBank) == 0)
+ {
+ move_anim_start_t2_for_situation(
+ gBattleBufferA[gActiveBank][1],
+ gBattleBufferA[gActiveBank][2]
+ | (gBattleBufferA[gActiveBank][3] << 8)
+ | (gBattleBufferA[gActiveBank][4] << 16)
+ | (gBattleBufferA[gActiveBank][5] << 24));
+ gBattleBankFunc[gActiveBank] = sub_8037FAC;
+ }
+}
+
+void sub_8039F58(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039F64(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039F70(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039F7C(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039F88(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039F94(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039FA0(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039FAC(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039FB8(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039FC4(void)
+{
+ gUnknown_020238C8.unk0_0 = 0;
+ dp01_tbl4_exec_completed();
+}
+
+void sub_8039FE0(void)
+{
+ gUnknown_020238C8.unk0_0 = gBattleBufferA[gActiveBank][1];
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A018(void)
+{
+ gUnknown_020238C8.unk0_7 = 0;
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A030(void)
+{
+ gUnknown_020238C8.unk0_7 ^= 1;
+ dp01_tbl4_exec_completed();
+}
+
+void dp01t_29_4_blink(void)
+{
+ if (gSprites[gObjectBankIDs[gActiveBank]].invisible == TRUE)
+ {
+ dp01_tbl4_exec_completed();
+ }
+ else
+ {
+ gDoingBattleAnim = TRUE;
+ gSprites[gObjectBankIDs[gActiveBank]].data1 = 0;
+ sub_8047858(gActiveBank);
+ gBattleBankFunc[gActiveBank] = dp01t_0F_4_move_anim;
+ }
+}
+
+void sub_803A0C8(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A0D4(void)
+{
+ s8 pan;
+
+ if (GetBankSide(gActiveBank) == 0)
+ pan = -64;
+ else
+ pan = 63;
+ PlaySE12WithPanning(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8), pan);
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A118(void)
+{
+ PlayFanfare(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A148(void)
+{
+ PlayCry3(
+ GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES),
+ 25, 5);
+ dp01_tbl4_exec_completed();
+}
+
+void dp01t_2E_4_battle_intro(void)
+{
+ sub_80E43C0(gBattleBufferA[gActiveBank][1]);
+ gUnknown_02024DE8 |= 1;
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A1B8(void)
+{
+ u8 taskId;
+
+ oamt_add_pos2_onto_pos1(&gSprites[gObjectBankIDs[gActiveBank]]);
+ gSprites[gObjectBankIDs[gActiveBank]].data0 = 35;
+ gSprites[gObjectBankIDs[gActiveBank]].data2 = 280;
+ gSprites[gObjectBankIDs[gActiveBank]].data4 = gSprites[gObjectBankIDs[gActiveBank]].pos1.y;
+ gSprites[gObjectBankIDs[gActiveBank]].callback = sub_8078B34;
+ oamt_set_x3A_32(&gSprites[gObjectBankIDs[gActiveBank]], sub_803A3A8);
+ taskId = CreateTask(sub_803A2C4, 5);
+ gTasks[taskId].data[0] = gActiveBank;
+ if (ewram17810[gActiveBank].unk0_0)
+ gTasks[gUnknown_02024E68[gActiveBank]].func = sub_8044CA0;
+ ewram17840.unk9_0 = 1;
+ gBattleBankFunc[gActiveBank] = nullsub_47;
+}
+
+void sub_803A2C4(u8 taskId)
+{
+ u8 r9;
+
+ r9 = gActiveBank;
+ gActiveBank = gTasks[taskId].data[0];
+ if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI))
+ {
+ gBattleBufferA[gActiveBank][1] = gBattlePartyID[gActiveBank];
+ sub_8039430(gActiveBank, 0);
+ }
+ else
+ {
+ gBattleBufferA[gActiveBank][1] = gBattlePartyID[gActiveBank];
+ sub_8039430(gActiveBank, 0);
+ gActiveBank ^= 2;
+ gBattleBufferA[gActiveBank][1] = gBattlePartyID[gActiveBank];
+ sub_8039430(gActiveBank, 0);
+ gActiveBank ^= 2;
+ }
+ gBattleBankFunc[gActiveBank] = sub_8037840;
+ gActiveBank = r9;
+ DestroyTask(taskId);
+}
+
+void sub_803A3A8(struct Sprite *sprite)
+{
+ sub_8031B74(sprite->oam.affineParam);
+ sprite->oam.tileNum = sprite->data5;
+ FreeSpriteOamMatrix(sprite);
+ DestroySprite(sprite);
+}
+
+void sub_803A3DC(void)
+{
+ if (gBattleBufferA[gActiveBank][1] != 0 && GetBankSide(gActiveBank) == 0)
+ {
+ dp01_tbl4_exec_completed();
+ return;
+ }
+
+ ewram17810[gActiveBank].unk0_0 = 1;
+ if (gBattleBufferA[gActiveBank][2] != 0)
+ {
+ if (ewram17810[gActiveBank].unk1_1 < 2)
+ {
+ ewram17810[gActiveBank].unk1_1++;
+ return;
+ }
+ else
+ {
+ ewram17810[gActiveBank].unk1_1 = 0;
+ }
+ }
+ gUnknown_02024E68[gActiveBank] = sub_8044804(
+ gActiveBank,
+ (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBank][4],
+ gBattleBufferA[gActiveBank][1],
+ gBattleBufferA[gActiveBank][2]);
+ ewram17810[gActiveBank].unk5 = 0;
+ if (gBattleBufferA[gActiveBank][2] != 0)
+ ewram17810[gActiveBank].unk5 = 0x5D;
+ gBattleBankFunc[gActiveBank] = sub_803A4E0;
+}
+
+void sub_803A4E0(void)
+{
+ if (ewram17810[gActiveBank].unk5++ >= 93)
+ {
+ ewram17810[gActiveBank].unk5 = 0;
+ dp01_tbl4_exec_completed();
+ }
+}
+
+void sub_803A520(void)
+{
+ if (ewram17810[gActiveBank].unk0_0)
+ gTasks[gUnknown_02024E68[gActiveBank]].func = sub_8044CA0;
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A56C(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A578(void)
+{
+ if (sub_8078874(gActiveBank) != 0)
+ {
+ gSprites[gObjectBankIDs[gActiveBank]].invisible = gBattleBufferA[gActiveBank][1];
+ sub_8031F88(gActiveBank);
+ }
+ dp01_tbl4_exec_completed();
+}
+
+void bx_exec_buffer_A_ch0_tbl4(void)
+{
+ if (mplay_80342A4(gActiveBank) == 0)
+ {
+ u8 r3 = gBattleBufferA[gActiveBank][1];
+ u16 r4 = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
+
+ if (move_anim_start_t3(gActiveBank, gActiveBank, gActiveBank, r3, r4) != 0)
+ dp01_tbl4_exec_completed();
+ else
+ gBattleBankFunc[gActiveBank] = sub_8037FD8;
+ }
+}
+
+void sub_803A640(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A64C(void)
+{
+ dp01_tbl4_exec_completed();
+}
+
+void sub_803A658(void)
+{
+ if (gBattleBufferA[gActiveBank][1] == 3)
+ gBattleOutcome = gBattleBufferA[gActiveBank][1];
+ else
+ gBattleOutcome = gBattleBufferA[gActiveBank][1] ^ 3;
+ FadeOutMapMusic(5);
+ BeginFastPaletteFade(3);
+ dp01_tbl4_exec_completed();
+ gBattleBankFunc[gActiveBank] = sub_8037F34;
+}
+
+void nullsub_48(void)
+{
+}
diff --git a/src/battle_2.c b/src/battle_2.c
index 2b13fc45d..d08f2b8df 100644
--- a/src/battle_2.c
+++ b/src/battle_2.c
@@ -26,6 +26,9 @@
#include "trig.h"
#include "unknown_task.h"
#include "util.h"
+#include "items.h"
+#include "hold_effects.h"
+#include "battle_move_effects.h"
struct UnknownStruct6
{
@@ -70,30 +73,6 @@ struct UnknownStruct12
u8 filler4[0x54];
};
-struct UnknownStruct13
-{
- u32 unk0_0:1;
- u32 unk0_1:1;
- u32 unk0_2:1;
- u32 unk0_3:1;
- u32 unk0_4:1;
- u32 unk0_5:1;
- u32 unk0_6:1;
- u32 unk0_7:1;
- u32 unk1_0:1;
- u32 unk1_1:1;
- u32 unk1_2:1;
- u32 unk1_3:2;
- u32 unk1_5:1;
- u32 unk1_6:1;
- u32 unk1_7:1;
- u32 unk2_0:1;
- u32 unk2_1:1;
- u32 unk2_2:1;
- u32 unk2_3:1;
- u8 filler4[12];
-};
-
extern const u16 gUnknown_08D004E0[];
extern const struct MonCoords gCastformFrontSpriteCoords[];
@@ -166,7 +145,6 @@ extern u16 gChosenMovesByBanks[];
extern u32 gHitMarker;
extern u8 gUnknown_02024C70[];
extern u16 gSideAffecting[];
-extern u8 gSideTimer[][12];
extern u32 gStatuses3[];
//extern u8 gDisableStructs[][0x1C];
extern u16 gPauseCounterBattle;
@@ -175,8 +153,6 @@ extern u16 gRandomTurnNumber;
extern u8 gBattleCommunication[];
extern u8 gUnknown_02024D1F[]; // I don't actually know what type this is.
extern u8 gBattleOutcome;
-extern struct UnknownStruct13 gProtectStructs[];
-extern u8 gWishFutureKnock[];
extern u16 gUnknown_02024DE8;
extern u8 gActionSelectionCursor[];
extern u8 gMoveSelectionCursor[];
@@ -199,7 +175,6 @@ extern u16 gUnknown_030042C0;
extern u16 gUnknown_030042C4;
extern MainCallback gPreBattleCallback1;
extern void (*gBattleMainFunc)(void);
-extern struct Struct30042E0 gBattleResults;
extern u8 gLeveledUpInBattle;
extern void (*gBattleBankFunc[])(void);
extern u8 gHealthboxIDs[];
@@ -219,6 +194,7 @@ extern u32 gBattleMoveDamage;
extern struct BattlePokemon gBattleMons[];
extern u8 gBattleMoveFlags;
+static void BattlePrepIntroSlide(void);
void sub_800E7C4(void)
{
@@ -1495,43 +1471,43 @@ void sub_80105EC(struct Sprite *sprite)
}
}
-void dp11b_obj_instanciate(u8 a, u8 b, s8 c, s8 d)
+void dp11b_obj_instanciate(u8 bank, u8 b, s8 c, s8 d)
{
u8 spriteId;
- u8 r7;
+ u8 objectID;
if (b)
{
- if (ewram17810[a].unk0_1)
+ if (ewram17810[bank].unk0_1)
return;
}
else
{
- if (ewram17810[a].unk0_2)
+ if (ewram17810[bank].unk0_2)
return;
}
spriteId = CreateInvisibleSpriteWithCallback(objc_dp11b_pingpong);
if (b == TRUE)
{
- r7 = gHealthboxIDs[a];
- ewram17810[a].unk2 = spriteId;
- ewram17810[a].unk0_1 = 1;
+ objectID = gHealthboxIDs[bank];
+ ewram17810[bank].unk2 = spriteId;
+ ewram17810[bank].unk0_1 = 1;
gSprites[spriteId].data0 = 0x80;
}
else
{
- r7 = gObjectBankIDs[a];
- ewram17810[a].unk3 = spriteId;
- ewram17810[a].unk0_2 = 1;
+ objectID = gObjectBankIDs[bank];
+ ewram17810[bank].unk3 = spriteId;
+ ewram17810[bank].unk0_2 = 1;
gSprites[spriteId].data0 = 0xC0;
}
gSprites[spriteId].data1 = c;
gSprites[spriteId].data2 = d;
- gSprites[spriteId].data3 = r7;
+ gSprites[spriteId].data3 = objectID;
gSprites[spriteId].data4 = b;
- gSprites[r7].pos2.x = 0;
- gSprites[r7].pos2.y = 0;
+ gSprites[objectID].pos2.x = 0;
+ gSprites[objectID].pos2.y = 0;
}
void dp11b_obj_free(u8 a, u8 b)
@@ -1586,7 +1562,6 @@ void sub_8010800(void)
void sub_8010824(void)
{
gBattleMainFunc();
- gActiveBank = 0;
for (gActiveBank = 0; gActiveBank < gNoOfAllBanks; gActiveBank++)
gBattleBankFunc[gActiveBank]();
@@ -1595,7 +1570,7 @@ void sub_8010824(void)
void sub_8010874(void)
{
s32 i;
- s32 j;
+ u32 j;
u8 *r4;
TurnValuesCleanUp(0);
@@ -1609,7 +1584,7 @@ void sub_8010874(void)
for (j = 0; j < (u32)0x1C; j++)
r4[j] = 0;
- gDisableStructs[i].unk16 = 2;
+ gDisableStructs[i].IsFirstTurn = 2;
gUnknown_02024C70[i] = 0;
gLastUsedMove[i] = 0;
gMoveHitWith[i] = 0;
@@ -1626,7 +1601,7 @@ void sub_8010874(void)
gSideAffecting[i] = 0;
r4 = (u8 *)&gSideTimer[i];
- for (j = 0; j < (u32)12; j++)
+ for (j = 0; j < 12; j++)
r4[j] = 0;
}
@@ -1639,8 +1614,8 @@ void sub_8010874(void)
r4[i] = 0;
gHitMarker = 0;
- if ((gBattleTypeFlags & 2) == 0 && gSaveBlock2.optionsBattleSceneOff == TRUE)
- gHitMarker = 0x80;
+ if ((gBattleTypeFlags & BATTLE_TYPE_LINK) == 0 && gSaveBlock2.optionsBattleSceneOff == TRUE)
+ gHitMarker = HITMARKER_NO_ANIMATIONS;
ewram16084 = gSaveBlock2.optionsBattleStyle;
gMultiHitCounter = 0;
gBattleOutcome = 0;
@@ -1680,36 +1655,36 @@ void sub_8010874(void)
ewram16113 = 0;
for (i = 0; i < 11; i++)
gBattleResults.unk36[i] = 0;
- gBattleResults.unk13 = 0;
- gBattleResults.unk0 = 0;
- gBattleResults.unk1 = 0;
+ gBattleResults.BattleTurnCounter = 0;
+ gBattleResults.PlayerFaintCounter = 0;
+ gBattleResults.OpponentFaintCounter = 0;
gBattleResults.unk2 = 0;
gBattleResults.unk3 = 0;
gBattleResults.unk4 = 0;
gBattleResults.unk5_0 = 0;
gBattleResults.unk5_1 = 0;
- gBattleResults.unk20 = 0;
- gBattleResults.unk22 = 0;
- gBattleResults.unk24 = 0;
- gBattleResults.unk6 = 0;
- gBattleResults.unk26 = 0;
- gBattleResults.unk28 = 0;
+ gBattleResults.LastOpponentSpecies = 0;
+ gBattleResults.LastUsedMove = 0;
+ gBattleResults.OpponentMove = 0;
+ gBattleResults.Poke1Species = 0;
+ gBattleResults.OpponentSpecies = 0;
+ gBattleResults.CaughtPoke = 0;
for (i = 0; i < 10; i++)
{
- gBattleResults.unk8[i] = 0;
- gBattleResults.unk14[i] = 0;
- gBattleResults.unk2A[i] = 0;
+ gBattleResults.PokeString1[i] = 0;
+ gBattleResults.PokeString2[i] = 0;
+ gBattleResults.CaughtNick[i] = 0;
}
}
-void sub_8010B88(void)
+void SwitchInClearStructs(void)
{
- struct UnkBattleStruct4 sp0 = gDisableStructs[gActiveBank];
+ struct DisableStruct sp0 = gDisableStructs[gActiveBank];
s32 i;
u8 *ptr;
u32 *ptr2;
- if (gBattleMoves[gCurrentMove].effect != 0x7F)
+ if (gBattleMoves[gCurrentMove].effect != EFFECT_BATON_PASS)
{
for (i = 0; i < 8; i++)
gBattleMons[gActiveBank].statStages[i] = 6;
@@ -1717,27 +1692,27 @@ void sub_8010B88(void)
{
struct UnknownStruct12 *sp20 = &gUnknown_02024AD0[i];
- if ((sp20->unk0 & 0x04000000) && gDisableStructs[i].unk14 == gActiveBank)
+ if ((sp20->unk0 & 0x04000000) && gDisableStructs[i].BankPreventingEscape == gActiveBank)
sp20->unk0 &= ~0x04000000;
- if ((gStatuses3[i] & 0x18) && gDisableStructs[i].unk15 == gActiveBank)
+ if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].BankWithSureHit == gActiveBank)
{
- gStatuses3[i] &= ~0x18;
- gDisableStructs[i].unk15 = 0;
+ gStatuses3[i] &= ~STATUS3_ALWAYS_HITS;
+ gDisableStructs[i].BankWithSureHit = 0;
}
}
}
- if (gBattleMoves[gCurrentMove].effect == 0x7F)
+ if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS)
{
- gBattleMons[gActiveBank].status2 &= 0x15100007;
- gStatuses3[gActiveBank] &= 0x3043F;
+ gBattleMons[gActiveBank].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED);
+ gStatuses3[gActiveBank] &= (STATUS3_LEECHSEED_RECEIVER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED | STATUS3_MUDSPORT | STATUS3_WATERSPORT);
for (i = 0; i < gNoOfAllBanks; i++)
{
if (GetBankSide(gActiveBank) != GetBankSide(i)
- && (gStatuses3[i] & 0x18) != 0
- && (gDisableStructs[i].unk15 == gActiveBank))
+ && (gStatuses3[i] & STATUS3_ALWAYS_HITS) != 0
+ && (gDisableStructs[i].BankWithSureHit == gActiveBank))
{
- gStatuses3[i] &= ~0x18;
+ gStatuses3[i] &= ~STATUS3_ALWAYS_HITS;
gStatuses3[i] |= 0x10;
}
}
@@ -1763,15 +1738,15 @@ void sub_8010B88(void)
for (i = 0; i < (u32)0x1C; i++)
ptr[i] = 0;
- if (gBattleMoves[gCurrentMove].effect == 0x7F)
+ if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS)
{
- gDisableStructs[gActiveBank].unkA = sp0.unkA;
- gDisableStructs[gActiveBank].unk15 = sp0.unk15;
+ gDisableStructs[gActiveBank].SubstituteHP = sp0.SubstituteHP;
+ gDisableStructs[gActiveBank].BankWithSureHit = sp0.BankWithSureHit;
gDisableStructs[gActiveBank].unkF_0 = sp0.unkF_0;
gDisableStructs[gActiveBank].unkF_4 = sp0.unkF_4;
}
- gDisableStructs[gActiveBank].unk16 = 2;
+ gDisableStructs[gActiveBank].IsFirstTurn = 2;
gLastUsedMove[gActiveBank] = 0;
gMoveHitWith[gActiveBank] = 0;
gUnknown_02024C44[gActiveBank] = 0;
@@ -1806,12 +1781,12 @@ void UndoEffectsAfterFainting(void)
gStatuses3[gActiveBank] = 0;
for (i = 0; i < gNoOfAllBanks; i++)
{
- if ((gBattleMons[i].status2 & 0x4000000) && gDisableStructs[i].unk14 == gActiveBank)
- gBattleMons[i].status2 &= ~0x4000000;
+ if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].BankPreventingEscape == gActiveBank)
+ gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION;
if (gBattleMons[i].status2 & (gBitTable[gActiveBank] << 16))
gBattleMons[i].status2 &= ~(gBitTable[gActiveBank] << 16);
- if ((gBattleMons[i].status2 & 0xE000) && ewram[0x16020 + i] == gActiveBank)
- gBattleMons[i].status2 &= ~0xE000;
+ if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && ewram[0x16020 + i] == gActiveBank)
+ gBattleMons[i].status2 &= ~STATUS2_WRAPPED;
}
gActionSelectionCursor[gActiveBank] = 0;
gMoveSelectionCursor[gActiveBank] = 0;
@@ -1819,27 +1794,27 @@ void UndoEffectsAfterFainting(void)
ptr = (u8 *)&gDisableStructs[gActiveBank];
for (i = 0; i < (u32)0x1C; i++)
ptr[i] = 0;
- gProtectStructs[gActiveBank].unk0_0 = 0;
- gProtectStructs[gActiveBank].unk0_1 = 0;
- gProtectStructs[gActiveBank].unk0_2 = 0;
- gProtectStructs[gActiveBank].unk0_3 = 0;
- gProtectStructs[gActiveBank].unk0_4 = 0;
- gProtectStructs[gActiveBank].unk0_5 = 0;
- gProtectStructs[gActiveBank].unk0_6 = 0;
- gProtectStructs[gActiveBank].unk0_7 = 0;
- gProtectStructs[gActiveBank].unk1_0 = 0;
- gProtectStructs[gActiveBank].unk1_1 = 0;
- gProtectStructs[gActiveBank].unk1_2 = 0;
- gProtectStructs[gActiveBank].unk1_3 = 0;
- gProtectStructs[gActiveBank].unk1_5 = 0;
- gProtectStructs[gActiveBank].unk1_6 = 0;
- gProtectStructs[gActiveBank].unk1_7 = 0;
- gProtectStructs[gActiveBank].unk2_0 = 0;
- gProtectStructs[gActiveBank].unk2_1 = 0;
- gProtectStructs[gActiveBank].unk2_2 = 0;
- gProtectStructs[gActiveBank].unk2_3 = 0;
-
- gDisableStructs[gActiveBank].unk16 = 2;
+ gProtectStructs[gActiveBank].Protected = 0;
+ gProtectStructs[gActiveBank].Endured = 0;
+ gProtectStructs[gActiveBank].OnlyStruggle = 0;
+ gProtectStructs[gActiveBank].HelpingHand = 0;
+ gProtectStructs[gActiveBank].BounceMove = 0;
+ gProtectStructs[gActiveBank].StealMove = 0;
+ gProtectStructs[gActiveBank].Flag0Unknown = 0;
+ gProtectStructs[gActiveBank].PrlzImmobility = 0;
+ gProtectStructs[gActiveBank].ConfusionSelfDmg = 0;
+ gProtectStructs[gActiveBank].NotEffective = 0;
+ gProtectStructs[gActiveBank].ChargingTurn = 0;
+ gProtectStructs[gActiveBank].FleeFlag = 0;
+ gProtectStructs[gActiveBank].UsedImprisionedMove = 0;
+ gProtectStructs[gActiveBank].LoveImmobility = 0;
+ gProtectStructs[gActiveBank].UsedDisabledMove = 0;
+ gProtectStructs[gActiveBank].UsedTauntedMove = 0;
+ gProtectStructs[gActiveBank].Flag2Unknown = 0;
+ gProtectStructs[gActiveBank].FlinchImmobility = 0;
+ gProtectStructs[gActiveBank].NotFirstStrike = 0;
+
+ gDisableStructs[gActiveBank].IsFirstTurn = 2;
gLastUsedMove[gActiveBank] = 0;
gMoveHitWith[gActiveBank] = 0;
gUnknown_02024C44[gActiveBank] = 0;
@@ -1878,7 +1853,7 @@ void bc_8012FAC(void)
{
gBattleCommunication[1]++;
if (gBattleCommunication[1] == gNoOfAllBanks)
- gBattleMainFunc = bc_load_battlefield;
+ gBattleMainFunc = BattlePrepIntroSlide;
else
gBattleCommunication[0] = 0;
}
@@ -1886,7 +1861,7 @@ void bc_8012FAC(void)
}
}
-void bc_load_battlefield(void)
+static void BattlePrepIntroSlide(void)
{
if (gBattleExecBuffer == 0)
{
@@ -2294,7 +2269,7 @@ void BattleTurnPassed(void)
if (sub_80170DC() != 0)
return;
TurnValuesCleanUp(0);
- gHitMarker &= ~0x200;
+ gHitMarker &= ~HITMARKER_NO_ATTACKSTRING;
gHitMarker &= ~0x80000;
gHitMarker &= ~0x400000;
gHitMarker &= ~0x100000;
@@ -2311,8 +2286,8 @@ void BattleTurnPassed(void)
gBattleMainFunc = sub_80138F0;
return;
}
- if (gBattleResults.unk13 < 0xFF)
- gBattleResults.unk13++;
+ if (gBattleResults.BattleTurnCounter < 0xFF)
+ gBattleResults.BattleTurnCounter++;
for (i = 0; i < gNoOfAllBanks; i++)
{
gActionForBanks[i] = 0xFF;
@@ -2331,12 +2306,12 @@ u8 CanRunFromBattle(void)
u8 r6;
s32 i;
- if (gBattleMons[gActiveBank].item == 0xAF)
+ if (gBattleMons[gActiveBank].item == ITEM_ENIGMA_BERRY)
r2 = gEnigmaBerries[gActiveBank].holdEffect;
else
r2 = ItemId_GetHoldEffect(gBattleMons[gActiveBank].item);
gStringBank = gActiveBank;
- if (r2 == 0x25)
+ if (r2 == HOLD_EFFECT_CAN_ALWAYS_RUN)
return 0;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
return 0;
@@ -2346,7 +2321,7 @@ u8 CanRunFromBattle(void)
for (i = 0; i < gNoOfAllBanks; i++)
{
if (r6 != GetBankSide(i)
- && gBattleMons[i].ability == 0x17)
+ && gBattleMons[i].ability == ABILITY_SHADOW_TAG)
{
ewram16003 = i;
gLastUsedAbility = gBattleMons[i].ability;
@@ -2357,7 +2332,7 @@ u8 CanRunFromBattle(void)
&& gBattleMons[gActiveBank].ability != ABILITY_LEVITATE
&& gBattleMons[gActiveBank].type1 != 2
&& gBattleMons[gActiveBank].type2 != 2
- && gBattleMons[i].ability == 0x47)
+ && gBattleMons[i].ability == ABILITY_ARENA_TRAP)
{
ewram16003 = i;
gLastUsedAbility = gBattleMons[i].ability;
@@ -2365,7 +2340,7 @@ u8 CanRunFromBattle(void)
return 2;
}
}
- i = AbilityBattleEffects(15, gActiveBank, 0x2A, 0, 0);
+ i = AbilityBattleEffects(15, gActiveBank, ABILITY_MAGNET_PULL, 0, 0);
if (i != 0 && (gBattleMons[gActiveBank].type1 == 8 || gBattleMons[gActiveBank].type2 == 8))
{
ewram16003 = i - 1;
@@ -2373,7 +2348,7 @@ u8 CanRunFromBattle(void)
gBattleCommunication[5] = 2;
return 2;
}
- if ((gBattleMons[gActiveBank].status2 & 0x0400E000) || (gStatuses3[gActiveBank] & 0x400))
+ if ((gBattleMons[gActiveBank].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED)) || (gStatuses3[gActiveBank] & STATUS3_ROOTED))
{
gBattleCommunication[5] = 0;
return 1;
diff --git a/src/battle_811DA74.c b/src/battle_811DA74.c
index 42c700844..36a287efc 100644
--- a/src/battle_811DA74.c
+++ b/src/battle_811DA74.c
@@ -1163,7 +1163,7 @@ void sub_811FDF0(void)
void sub_811FDFC(void)
{
- if (mplay_80342A4(gActiveBank) == 0)
+ if (!mplay_80342A4(gActiveBank))
{
u32 r0 = gBattleBufferA[gActiveBank][1]
| (gBattleBufferA[gActiveBank][2] << 8);
@@ -1409,10 +1409,12 @@ void sub_81203FC(void)
void LinkPartnerHandleHitAnimation(void)
{
if (gSprites[gObjectBankIDs[gActiveBank]].invisible == TRUE)
+ {
LinkPartnerBufferExecCompleted();
+ }
else
{
- gDoingBattleAnim = 1;
+ gDoingBattleAnim = TRUE;
gSprites[gObjectBankIDs[gActiveBank]].data1 = 0;
sub_8047858(gActiveBank);
gBattleBankFunc[gActiveBank] = bx_blink_t3;
@@ -1572,9 +1574,8 @@ void sub_81209D8(void)
{
u8 r3 = gBattleBufferA[gActiveBank][1];
u16 r4 = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- u8 var = gActiveBank;
- if (move_anim_start_t3(var, var, var, r3, r4) != 0)
+ if (move_anim_start_t3(gActiveBank, gActiveBank, gActiveBank, r3, r4) != 0)
LinkPartnerBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = sub_811E3B8;
diff --git a/src/battle_ai.c b/src/battle_ai.c
index fabe0b61d..d262e69c8 100644
--- a/src/battle_ai.c
+++ b/src/battle_ai.c
@@ -15,7 +15,7 @@
extern u16 gBattleTypeFlags;
extern u16 gBattleWeather;
extern u8 gActiveBank;
-extern u8 gBattlePartyID[][2];
+extern u16 gBattlePartyID[MAX_BANKS_BATTLE];
extern u16 gCurrentMove;
extern int gBattleMoveDamage;
extern u8 gBankAttacker;
@@ -23,13 +23,10 @@ extern u8 gBankTarget;
extern u8 gAbsentBankFlags;
extern u8 gBattleMoveFlags;
extern u16 gDynamicBasePower;
-extern u16 gLastUsedMove[];
-extern u32 gUnknown_02024ACC[];
-extern u32 gStatuses3[];
-extern u16 gSideAffecting[];
-extern struct BattlePokemon gBattleMons[];
-extern struct BattlePokemon gUnknown_02024A8C[];
-extern u8 gBattleResults[];
+extern u16 gLastUsedMove[MAX_BANKS_BATTLE];
+extern u32 gStatuses3[MAX_BANKS_BATTLE];
+extern u16 gSideAffecting[2];
+extern struct BattlePokemon gBattleMons[MAX_BANKS_BATTLE];
extern u8 gCritMultiplier;
extern u16 gTrainerBattleOpponent;
extern u8 *BattleAIs[];
@@ -120,7 +117,7 @@ static void BattleAICmd_get_gender(void);
static void BattleAICmd_is_first_turn(void);
static void BattleAICmd_get_stockpile_count(void);
static void BattleAICmd_is_double_battle(void);
-static void BattleAICmd_get_item(void);
+static void BattleAICmd_get_used_item(void);
static void BattleAICmd_get_move_type_from_result(void);
static void BattleAICmd_get_move_power_from_result(void);
static void BattleAICmd_get_move_effect_from_result(void);
@@ -142,100 +139,100 @@ typedef void (*BattleAICmdFunc)(void);
static const BattleAICmdFunc sBattleAICmdTable[] =
{
- BattleAICmd_if_random_less_than,
- BattleAICmd_if_random_greater_than,
- BattleAICmd_if_random_equal,
- BattleAICmd_if_random_not_equal,
- BattleAICmd_score,
- BattleAICmd_if_hp_less_than,
- BattleAICmd_if_hp_more_than,
- BattleAICmd_if_hp_equal,
- BattleAICmd_if_hp_not_equal,
- BattleAICmd_if_status,
- BattleAICmd_if_not_status,
- BattleAICmd_if_status2,
- BattleAICmd_if_not_status2,
- BattleAICmd_if_status3,
- BattleAICmd_if_not_status3,
- BattleAICmd_if_status4,
- BattleAICmd_if_not_status4,
- BattleAICmd_if_less_than,
- BattleAICmd_if_more_than,
- BattleAICmd_if_equal,
- BattleAICmd_if_not_equal,
- BattleAICmd_if_less_than_32,
- BattleAICmd_if_more_than_32,
- BattleAICmd_if_equal_32,
- BattleAICmd_if_not_equal_32,
- BattleAICmd_if_move,
- BattleAICmd_if_not_move,
- BattleAICmd_if_in_bytes,
- BattleAICmd_if_not_in_bytes,
- BattleAICmd_if_in_words,
- BattleAICmd_if_not_in_words,
- BattleAICmd_if_user_can_damage,
- BattleAICmd_if_user_cant_damage,
- BattleAICmd_get_turn_count,
- BattleAICmd_get_type,
- BattleAICmd_get_move_power,
- BattleAICmd_is_most_powerful_move,
- BattleAICmd_get_move,
- BattleAICmd_if_arg_equal,
- BattleAICmd_if_arg_not_equal,
- BattleAICmd_if_would_go_first,
- BattleAICmd_if_would_not_go_first,
- BattleAICmd_nullsub_2A,
- BattleAICmd_nullsub_2B,
- BattleAICmd_count_alive_pokemon,
- BattleAICmd_get_considered_move,
- BattleAICmd_get_considered_move_effect,
- BattleAICmd_get_ability,
- BattleAICmd_get_highest_possible_damage,
- BattleAICmd_if_damage_bonus,
- BattleAICmd_nullsub_32,
- BattleAICmd_nullsub_33,
- BattleAICmd_if_status_in_party,
- BattleAICmd_if_status_not_in_party,
- BattleAICmd_get_weather,
- BattleAICmd_if_effect,
- BattleAICmd_if_not_effect,
- BattleAICmd_if_stat_level_less_than,
- BattleAICmd_if_stat_level_more_than,
- BattleAICmd_if_stat_level_equal,
- BattleAICmd_if_stat_level_not_equal,
- BattleAICmd_if_can_faint,
- BattleAICmd_if_cant_faint,
- BattleAICmd_if_has_move,
- BattleAICmd_if_dont_have_move,
- BattleAICmd_if_move_effect,
- BattleAICmd_if_not_move_effect,
- BattleAICmd_if_last_move_did_damage,
- BattleAICmd_if_encored,
- BattleAICmd_flee,
- BattleAICmd_if_random_100,
- BattleAICmd_watch,
- BattleAICmd_get_hold_effect,
- BattleAICmd_get_gender,
- BattleAICmd_is_first_turn,
- BattleAICmd_get_stockpile_count,
- BattleAICmd_is_double_battle,
- BattleAICmd_get_item,
- BattleAICmd_get_move_type_from_result,
- BattleAICmd_get_move_power_from_result,
- BattleAICmd_get_move_effect_from_result,
- BattleAICmd_get_protect_count,
- BattleAICmd_nullsub_52,
- BattleAICmd_nullsub_53,
- BattleAICmd_nullsub_54,
- BattleAICmd_nullsub_55,
- BattleAICmd_nullsub_56,
- BattleAICmd_nullsub_57,
- BattleAICmd_call,
- BattleAICmd_jump,
- BattleAICmd_end,
- BattleAICmd_if_level_compare,
- BattleAICmd_if_taunted,
- BattleAICmd_if_not_taunted,
+ BattleAICmd_if_random_less_than, // 0x0
+ BattleAICmd_if_random_greater_than, // 0x1
+ BattleAICmd_if_random_equal, // 0x2
+ BattleAICmd_if_random_not_equal, // 0x3
+ BattleAICmd_score, // 0x4
+ BattleAICmd_if_hp_less_than, // 0x5
+ BattleAICmd_if_hp_more_than, // 0x6
+ BattleAICmd_if_hp_equal, // 0x7
+ BattleAICmd_if_hp_not_equal, // 0x8
+ BattleAICmd_if_status, // 0x9
+ BattleAICmd_if_not_status, // 0xA
+ BattleAICmd_if_status2, // 0xB
+ BattleAICmd_if_not_status2, // 0xC
+ BattleAICmd_if_status3, // 0xD
+ BattleAICmd_if_not_status3, // 0xE
+ BattleAICmd_if_status4, // 0xF
+ BattleAICmd_if_not_status4, // 0x10
+ BattleAICmd_if_less_than, // 0x11
+ 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_move, // 0x19
+ BattleAICmd_if_not_move, // 0x1A
+ BattleAICmd_if_in_bytes, // 0x1B
+ BattleAICmd_if_not_in_bytes, // 0x1C
+ BattleAICmd_if_in_words, // 0x1D
+ BattleAICmd_if_not_in_words, // 0x1E
+ BattleAICmd_if_user_can_damage, // 0x1F
+ BattleAICmd_if_user_cant_damage, // 0x20
+ BattleAICmd_get_turn_count, // 0x21
+ BattleAICmd_get_type, // 0x22
+ BattleAICmd_get_move_power, // 0x23
+ BattleAICmd_is_most_powerful_move, // 0x24
+ BattleAICmd_get_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_nullsub_2A, // 0x2A
+ BattleAICmd_nullsub_2B, // 0x2B
+ BattleAICmd_count_alive_pokemon, // 0x2C
+ BattleAICmd_get_considered_move, // 0x2D
+ BattleAICmd_get_considered_move_effect, // 0x2E
+ BattleAICmd_get_ability, // 0x2F
+ BattleAICmd_get_highest_possible_damage, // 0x30
+ BattleAICmd_if_damage_bonus, // 0x31
+ BattleAICmd_nullsub_32, // 0x32
+ BattleAICmd_nullsub_33, // 0x33
+ BattleAICmd_if_status_in_party, // 0x34
+ BattleAICmd_if_status_not_in_party, // 0x35
+ BattleAICmd_get_weather, // 0x36
+ BattleAICmd_if_effect, // 0x37
+ BattleAICmd_if_not_effect, // 0x38
+ BattleAICmd_if_stat_level_less_than, // 0x39
+ BattleAICmd_if_stat_level_more_than, // 0x3A
+ BattleAICmd_if_stat_level_equal, // 0x3B
+ BattleAICmd_if_stat_level_not_equal, // 0x3C
+ 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_last_move_did_damage, // 0x43
+ BattleAICmd_if_encored, // 0x44
+ BattleAICmd_flee, // 0x45
+ BattleAICmd_if_random_100, // 0x46
+ BattleAICmd_watch, // 0x47
+ BattleAICmd_get_hold_effect, // 0x48
+ BattleAICmd_get_gender, // 0x49
+ BattleAICmd_is_first_turn, // 0x4A
+ BattleAICmd_get_stockpile_count, // 0x4B
+ BattleAICmd_is_double_battle, // 0x4C
+ BattleAICmd_get_used_item, // 0x4D
+ BattleAICmd_get_move_type_from_result, // 0x4E
+ BattleAICmd_get_move_power_from_result, // 0x4F
+ BattleAICmd_get_move_effect_from_result, // 0x50
+ BattleAICmd_get_protect_count, // 0x51
+ BattleAICmd_nullsub_52, // 0x52
+ BattleAICmd_nullsub_53, // 0x53
+ BattleAICmd_nullsub_54, // 0x54
+ BattleAICmd_nullsub_55, // 0x55
+ BattleAICmd_nullsub_56, // 0x56
+ BattleAICmd_nullsub_57, // 0x57
+ BattleAICmd_call, // 0x58
+ BattleAICmd_jump, // 0x59
+ BattleAICmd_end, // 0x5A
+ BattleAICmd_if_level_compare, // 0x5B
+ BattleAICmd_if_taunted, // 0x5C
+ BattleAICmd_if_not_taunted, // 0x5D
};
#ifdef NONMATCHING
@@ -449,13 +446,13 @@ void unref_sub_81074A0(u8 a)
UNK_2016A00_STRUCT->movesUsed[a / 2][i] = 0;
}
-void sub_81074C4(u8 a, u8 b)
+void RecordAbilityBattle(u8 a, u8 b)
{
if (GetBankSide(a) == 0)
UNK_2016A00_STRUCT->unk20[GetBankIdentity(a) & 1] = b;
}
-void sub_81074F8(u8 a, u8 b)
+void RecordItemBattle(u8 a, u8 b)
{
if (GetBankSide(a) == 0)
UNK_2016A00_STRUCT->unk22[GetBankIdentity(a) & 1] = b;
@@ -899,7 +896,7 @@ static void BattleAICmd_if_user_cant_damage(void)
static void BattleAICmd_get_turn_count(void)
{
- AI_THINKING_STRUCT->funcResult = gBattleResults[19];
+ AI_THINKING_STRUCT->funcResult = gBattleResults.BattleTurnCounter;
gAIScriptPtr += 1;
}
@@ -946,8 +943,8 @@ static void BattleAICmd_is_most_powerful_move(void)
&& sDiscouragedPowerfulMoveEffects[i] == 0xFFFF)
{
gDynamicBasePower = 0;
- unk_2000000[0x1601C] = 0; // why is this a manual array?
- unk_2000000[0x1601F] = 1;
+ ewram[0x1601C] = 0; // why is this a manual array?
+ ewram[0x1601F] = 1;
gBattleMoveFlags = 0;
gCritMultiplier = 1;
@@ -965,8 +962,8 @@ static void BattleAICmd_is_most_powerful_move(void)
&& gBattleMoves[gBattleMons[gBankAttacker].moves[i]].power > 1)
{
gCurrentMove = gBattleMons[gBankAttacker].moves[i];
- sub_801CAF8(gBankAttacker, gBankTarget);
- move_effectiveness_something(gCurrentMove, gBankAttacker, gBankTarget);
+ AI_CalcDmg(gBankAttacker, gBankTarget);
+ TypeCalc(gCurrentMove, gBankAttacker, gBankTarget);
damages[i] = (gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[i]) / 100;
if (damages[i] == 0) // moves always do at least 1 damage.
@@ -1135,11 +1132,11 @@ _081082BA:\n\
ldrb r0, [r7]\n\
ldr r4, _08108354 @ =gBankTarget\n\
ldrb r1, [r4]\n\
- bl sub_801CAF8\n\
+ bl AI_CalcDmg\n\
ldrh r0, [r5]\n\
ldrb r1, [r7]\n\
ldrb r2, [r4]\n\
- bl move_effectiveness_something\n\
+ bl TypeCalc\n\
mov r4, sp\n\
add r4, r8\n\
ldr r2, _08108358 @ =gBattleMoveDamage\n\
@@ -1312,14 +1309,14 @@ static void BattleAICmd_count_alive_pokemon(void)
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
u32 status;
- var = gBattlePartyID[index][0];
+ var = gBattlePartyID[index];
status = GetBankIdentity(index) ^ 2;
- var2 = gBattlePartyID[GetBankByPlayerAI(status)][0];
+ var2 = gBattlePartyID[GetBankByPlayerAI(status)];
}
else
{
- var = gBattlePartyID[index][0];
- var2 = gBattlePartyID[index][0];
+ var = gBattlePartyID[index];
+ var2 = gBattlePartyID[index];
}
for (i = 0; i < 6; i++)
@@ -1415,8 +1412,8 @@ static void BattleAICmd_get_highest_possible_damage(void)
s32 i;
gDynamicBasePower = 0;
- BATTLE_STRUCT->unk.unk1 = 0;
- BATTLE_STRUCT->unk.unk4 = 1;
+ BATTLE_STRUCT->DynamicMoveType = 0;
+ BATTLE_STRUCT->DmgMultiplier = 1;
gBattleMoveFlags = 0;
gCritMultiplier = 1;
AI_THINKING_STRUCT->funcResult = 0;
@@ -1428,7 +1425,7 @@ static void BattleAICmd_get_highest_possible_damage(void)
if (gCurrentMove)
{
- move_effectiveness_something(gCurrentMove, gBankAttacker, gBankTarget);
+ TypeCalc(gCurrentMove, gBankAttacker, gBankTarget);
// reduce by 1/3.
if (gBattleMoveDamage == 120)
@@ -1455,15 +1452,15 @@ static void BattleAICmd_if_damage_bonus(void)
u8 damageVar;
gDynamicBasePower = 0;
- BATTLE_STRUCT->unk.unk1 = 0;
- BATTLE_STRUCT->unk.unk4 = 1;
+ BATTLE_STRUCT->DynamicMoveType = 0;
+ BATTLE_STRUCT->DmgMultiplier = 1;
gBattleMoveFlags = 0;
gCritMultiplier = 1;
gBattleMoveDamage = 40;
gCurrentMove = AI_THINKING_STRUCT->moveConsidered;
- move_effectiveness_something(gCurrentMove, gBankAttacker, gBankTarget);
+ TypeCalc(gCurrentMove, gBankAttacker, gBankTarget);
if (gBattleMoveDamage == 120)
gBattleMoveDamage = 80;
@@ -1565,13 +1562,13 @@ static void BattleAICmd_if_status_not_in_party(void)
static void BattleAICmd_get_weather(void)
{
- if (gBattleWeather & 7)
+ if (gBattleWeather & WEATHER_RAINY)
AI_THINKING_STRUCT->funcResult = WEATHER_RAIN;
- if (gBattleWeather & 0x18)
+ if (gBattleWeather & WEATHER_SANDSTORMY)
AI_THINKING_STRUCT->funcResult = WEATHER_SANDSTORM;
- if (gBattleWeather & 0x60)
+ if (gBattleWeather & WEATHER_SUNNY)
AI_THINKING_STRUCT->funcResult = WEATHER_SUN;
- if (gBattleWeather & 0x80)
+ if (gBattleWeather & weather_hail)
AI_THINKING_STRUCT->funcResult = WEATHER_HAIL;
gAIScriptPtr += 1;
@@ -1662,13 +1659,13 @@ static void BattleAICmd_if_can_faint(void)
}
gDynamicBasePower = 0;
- BATTLE_STRUCT->unk.unk1 = 0;
- BATTLE_STRUCT->unk.unk4 = 1;
+ BATTLE_STRUCT->DynamicMoveType = 0;
+ BATTLE_STRUCT->DmgMultiplier = 1;
gBattleMoveFlags = 0;
gCritMultiplier = 1;
gCurrentMove = AI_THINKING_STRUCT->moveConsidered;
- sub_801CAF8(gBankAttacker, gBankTarget);
- move_effectiveness_something(gCurrentMove, gBankAttacker, gBankTarget);
+ AI_CalcDmg(gBankAttacker, gBankTarget);
+ TypeCalc(gCurrentMove, gBankAttacker, gBankTarget);
gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100;
@@ -1691,13 +1688,13 @@ static void BattleAICmd_if_cant_faint(void)
}
gDynamicBasePower = 0;
- BATTLE_STRUCT->unk.unk1 = 0;
- BATTLE_STRUCT->unk.unk4 = 1;
+ BATTLE_STRUCT->DynamicMoveType = 0;
+ BATTLE_STRUCT->DmgMultiplier = 1;
gBattleMoveFlags = 0;
gCritMultiplier = 1;
gCurrentMove = AI_THINKING_STRUCT->moveConsidered;
- sub_801CAF8(gBankAttacker, gBankTarget);
- move_effectiveness_something(gCurrentMove, gBankAttacker, gBankTarget);
+ AI_CalcDmg(gBankAttacker, gBankTarget);
+ TypeCalc(gCurrentMove, gBankAttacker, gBankTarget);
gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100;
@@ -1846,7 +1843,7 @@ static void BattleAICmd_if_last_move_did_damage(void)
if (gAIScriptPtr[2] == 0)
{
- if (gDisableStructs[index].unk4 == 0)
+ if (gDisableStructs[index].DisabledMove == 0)
{
gAIScriptPtr += 7;
return;
@@ -1859,7 +1856,7 @@ static void BattleAICmd_if_last_move_did_damage(void)
gAIScriptPtr += 7;
return;
}
- else if (gDisableStructs[index].unk6 != 0)
+ else if (gDisableStructs[index].EncoredMove != 0)
{
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
return;
@@ -1872,7 +1869,7 @@ static void BattleAICmd_if_encored(void)
switch (gAIScriptPtr[1])
{
case 0: // _08109348
- if (gDisableStructs[gActiveBank].unk4 == AI_THINKING_STRUCT->moveConsidered)
+ if (gDisableStructs[gActiveBank].DisabledMove == AI_THINKING_STRUCT->moveConsidered)
{
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
return;
@@ -1880,7 +1877,7 @@ static void BattleAICmd_if_encored(void)
gAIScriptPtr += 6;
return;
case 1: // _08109370
- if (gDisableStructs[gActiveBank].unk6 == AI_THINKING_STRUCT->moveConsidered)
+ if (gDisableStructs[gActiveBank].EncoredMove == AI_THINKING_STRUCT->moveConsidered)
{
gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
return;
@@ -1957,7 +1954,7 @@ static void BattleAICmd_is_first_turn(void)
else
index = gBankTarget;
- AI_THINKING_STRUCT->funcResult = gDisableStructs[index].unk16;
+ AI_THINKING_STRUCT->funcResult = gDisableStructs[index].IsFirstTurn;
gAIScriptPtr += 2;
}
@@ -1971,7 +1968,7 @@ static void BattleAICmd_get_stockpile_count(void)
else
index = gBankTarget;
- AI_THINKING_STRUCT->funcResult = gDisableStructs[index].unk9;
+ AI_THINKING_STRUCT->funcResult = gDisableStructs[index].StockpileCounter;
gAIScriptPtr += 2;
}
@@ -1983,7 +1980,7 @@ static void BattleAICmd_is_double_battle(void)
gAIScriptPtr += 1;
}
-static void BattleAICmd_get_item(void)
+static void BattleAICmd_get_used_item(void)
{
u8 index;
@@ -1993,7 +1990,7 @@ static void BattleAICmd_get_item(void)
index = gBankTarget;
// this hack and a half matches. whatever. i dont care. someone else fix this mess later. PS: still cant fix this.
- AI_THINKING_STRUCT->funcResult = ewram[0x160CC + (index * 2)];
+ AI_THINKING_STRUCT->funcResult = ewram[MULTI_DIM_ARR(index, B_16, 0x160CC)];
gAIScriptPtr += 2;
}
@@ -2028,7 +2025,7 @@ static void BattleAICmd_get_protect_count(void)
else
index = gBankTarget;
- AI_THINKING_STRUCT->funcResult = gDisableStructs[index].unk8;
+ AI_THINKING_STRUCT->funcResult = gDisableStructs[index].ProtectUses;
gAIScriptPtr += 2;
}
diff --git a/src/battle_anim_8137220.c b/src/battle_anim_8137220.c
index 42d6cb8da..bb181d5fb 100644
--- a/src/battle_anim_8137220.c
+++ b/src/battle_anim_8137220.c
@@ -12,6 +12,7 @@
#include "songs.h"
#include "sound.h"
#include "sprite.h"
+#include "item_use.h"
#include "string_util.h"
#include "task.h"
#include "text.h"
@@ -33,7 +34,6 @@ extern u8 gBattleBufferA[][0x200];
extern u8 gObjectBankIDs[];
extern MainCallback gPreBattleCallback1;
extern bool8 gDoingBattleAnim;
-extern u16 gScriptItemId;
extern u16 gBattlePartyID[];
extern u8 gHealthboxIDs[];
extern u16 gBattleTypeFlags;
diff --git a/src/battle_party_menu.c b/src/battle_party_menu.c
index cf572642e..73b847713 100644
--- a/src/battle_party_menu.c
+++ b/src/battle_party_menu.c
@@ -2,6 +2,7 @@
#include "battle_party_menu.h"
#include "battle.h"
#include "item_menu.h"
+#include "item_use.h"
#include "main.h"
#include "menu.h"
#include "menu_helpers.h"
@@ -55,7 +56,6 @@ extern void nullsub_14();
extern void OpenPartyMenu();
extern u8 sub_803FBBC(void);
-extern u16 gScriptItemId;
extern u8 gPlayerPartyCount;
extern u8 gNoOfAllBanks;
extern u16 gBattlePartyID[];
diff --git a/src/berry.c b/src/berry.c
index d6fbb955e..fa15672e7 100644
--- a/src/berry.c
+++ b/src/berry.c
@@ -5,6 +5,7 @@
#include "fieldmap.h"
#include "item.h"
#include "item_menu.h"
+#include "item_use.h"
#include "items.h"
#include "main.h"
#include "rng.h"
@@ -974,7 +975,6 @@ const struct Berry gBerries[] =
const struct BerryTree gBlankBerryTree = {0};
extern u8 BerryTreeScript;
-extern u16 gScriptItemId;
extern u16 gScriptLastTalked;
extern u16 gSpecialVar_0x8004;
extern u16 gSpecialVar_0x8005;
diff --git a/src/berry_tag_screen.c b/src/berry_tag_screen.c
index 116ca2cca..0e81e4fec 100644
--- a/src/berry_tag_screen.c
+++ b/src/berry_tag_screen.c
@@ -5,6 +5,7 @@
#include "field_map_obj.h"
#include "item_menu.h"
#include "items.h"
+#include "item_use.h"
#include "main.h"
#include "menu.h"
#include "menu_helpers.h"
@@ -35,7 +36,6 @@ struct BerryTagStatus
extern struct Struct2000000 unk_2000000;
extern u8 gUnknown_0203932C;
extern struct BerryTagStatus gUnknown_0203932E;
-extern u16 gScriptItemId;
extern u16 gUnknown_030041B4;
extern const struct CompressedSpriteSheet gUnknown_083C1F74;
diff --git a/src/calculate_base_damage.c b/src/calculate_base_damage.c
index ae60e30fe..0f2605e5b 100644
--- a/src/calculate_base_damage.c
+++ b/src/calculate_base_damage.c
@@ -35,7 +35,11 @@ extern struct PokemonStorage gPokemonStorage;
extern u8 gBadEggNickname[];
extern struct SpriteTemplate gSpriteTemplate_8208288[];
-extern u8 gSecretBaseTrainerClasses[];
+extern u8 gTrainerClassToPicIndex[];
+extern u8 gTrainerClassToNameIndex[];
+extern u8 gUnknown_08208238[];
+extern u8 gUnknown_0820823C[];
+extern u8 gStatStageRatios[];
extern u8 gHoldEffectToType[][2];
#define APPLY_STAT_MOD(var, mon, stat, statIndex) \
diff --git a/src/decoration.c b/src/decoration.c
index 9eba54ad7..e829cb072 100644..100755
--- a/src/decoration.c
+++ b/src/decoration.c
@@ -1396,7 +1396,7 @@ const u8 *const gUnknown_083EC624[] = {
gMenuText_GoBackToPrev
};
-const struct MenuAction3 gUnknown_083EC634[] = {
+const struct YesNoFuncTable gUnknown_083EC634[] = {
{sub_80FF5BC, sub_80FF058},
{sub_81017A0, sub_80FF058},
{sub_81017A0, sub_80FF058},
@@ -1871,16 +1871,16 @@ void sub_80FE948(u8 taskId)
gUnknown_020388F5 = gUnknown_020388F2 + gUnknown_020388F4;
if (gUnknown_020388F5 == gUnknown_020388D5)
{
- gUnknown_083EC634[gTasks[taskId].data[11]].func2(taskId);
+ gUnknown_083EC634[gTasks[taskId].data[11]].noFunc(taskId);
} else
{
- gUnknown_083EC634[gTasks[taskId].data[11]].func1(taskId);
+ gUnknown_083EC634[gTasks[taskId].data[11]].yesFunc(taskId);
}
} else if (gMain.newKeys & B_BUTTON)
{
HandleDestroyMenuCursors();
PlaySE(SE_SELECT);
- gUnknown_083EC634[gTasks[taskId].data[11]].func2(taskId);
+ gUnknown_083EC634[gTasks[taskId].data[11]].noFunc(taskId);
}
}
}
diff --git a/src/field_map_obj.c b/src/field_map_obj.c
index d94c97ff3..d94c97ff3 100755..100644
--- a/src/field_map_obj.c
+++ b/src/field_map_obj.c
diff --git a/src/field_map_obj_helpers.c b/src/field_map_obj_helpers.c
index 17584c96a..17584c96a 100755..100644
--- a/src/field_map_obj_helpers.c
+++ b/src/field_map_obj_helpers.c
diff --git a/src/field_special_scene.c b/src/field_special_scene.c
index c88ac8f65..82a7a13e3 100644
--- a/src/field_special_scene.c
+++ b/src/field_special_scene.c
@@ -229,7 +229,7 @@ void ExecuteTruckSequence(void)
CreateTask(Task_HandleTruckSequence, 0xA);
}
-void EndTruckSequence(void)
+void EndTruckSequence(u8 taskId)
{
if (!FuncIsActiveTask(Task_HandleTruckSequence))
{
diff --git a/src/field_tasks.c b/src/field_tasks.c
new file mode 100755
index 000000000..caf2ce6b9
--- /dev/null
+++ b/src/field_tasks.c
@@ -0,0 +1,859 @@
+//
+// Created by scott on 6/22/2017.
+//
+
+#include "global.h"
+#include "task.h"
+#include "main.h"
+#include "vars.h"
+#include "bike.h"
+#include "item.h"
+#include "items.h"
+#include "event_data.h"
+#include "rom4.h"
+#include "clock.h"
+#include "script.h"
+#include "field_special_scene.h"
+#include "field_effect_helpers.h"
+#include "secret_base.h"
+#include "metatile_behavior.h"
+#include "fieldmap.h"
+#include "field_player_avatar.h"
+#include "field_camera.h"
+#include "songs.h"
+#include "sound.h"
+#include "field_tasks.h"
+
+void DummyPerStepCallback(u8);
+void PerStepCallback_8069F64(u8);
+void PerStepCallback_8069AA0(u8);
+void PerStepCallback_8069864(u8);
+void PerStepCallback_8069DD4(u8);
+void PerStepCallback_806A07C(u8);
+
+void (*const gUnknown_08376364[])(u8) = {
+ DummyPerStepCallback,
+ PerStepCallback_8069F64,
+ PerStepCallback_8069AA0,
+ PerStepCallback_8069864,
+ PerStepCallback_8069DD4,
+ EndTruckSequence,
+ sub_80BCF1C,
+ PerStepCallback_806A07C
+};
+
+void Task_RunPerStepCallback(u8 taskId)
+{
+ int idx = gTasks[taskId].data[0];
+ gUnknown_08376364[idx](taskId);
+}
+
+static void RunTimeBasedEvents(s16 *taskData)
+{
+ switch (*taskData)
+ {
+ case 0:
+ if (gMain.vblankCounter1 & 0x1000)
+ {
+ DoTimeBasedEvents();
+ (*taskData)++;
+ }
+ break;
+ case 1:
+ if (!(gMain.vblankCounter1 & 0x1000))
+ {
+ (*taskData)--;
+ }
+ break;
+ }
+}
+
+void Task_RunTimeBasedEvents(u8 taskId)
+{
+ s16 *taskData = gTasks[taskId].data;
+ if (!ScriptContext2_IsEnabled())
+ {
+ RunTimeBasedEvents(taskData);
+ sub_80540D0(taskData + 1, taskData + 2);
+ }
+}
+
+void Task_MuddySlope(u8);
+
+void SetUpFieldTasks(void)
+{
+ if (!FuncIsActiveTask(Task_RunPerStepCallback))
+ {
+ u8 taskId = CreateTask(Task_RunPerStepCallback, 0x50);
+ gTasks[taskId].data[0] = 0;
+ }
+ if (!FuncIsActiveTask(Task_MuddySlope))
+ {
+ CreateTask(Task_MuddySlope, 0x50);
+ }
+ if (!FuncIsActiveTask(Task_RunTimeBasedEvents))
+ {
+ CreateTask(Task_RunTimeBasedEvents, 0x50);
+ }
+}
+
+void ActivatePerStepCallback(u8 callback)
+{
+ s16 *dataPointer;
+ s16 *dataStart;
+ s16 zero;
+ u8 taskId = FindTaskIdByFunc(Task_RunPerStepCallback);
+ if (taskId != 0xff)
+ {
+ dataStart = gTasks[taskId].data;
+ zero = 0;
+ dataPointer = &dataStart[15];
+ do
+ {
+ *dataPointer-- = zero;
+ } while ((int)dataPointer >= (int)dataStart);
+ if (callback >= ARRAY_COUNT(gUnknown_08376364))
+ {
+ *dataStart = 0;
+ }
+ else
+ {
+ *dataStart = callback;
+ }
+ }
+}
+
+void ResetFieldTasksArgs(void)
+{
+ u8 taskId;
+ s16 *taskData;
+ taskId = FindTaskIdByFunc(Task_RunPerStepCallback);
+ if (taskId != 0xff)
+ {
+ taskData = gTasks[taskId].data;
+ }
+ taskId = FindTaskIdByFunc(Task_RunTimeBasedEvents);
+ if (taskId != 0xff)
+ {
+ taskData = gTasks[taskId].data;
+ taskData[1] = 0;
+ taskData[2] = 0;
+ }
+}
+
+const struct MetatileOffset gUnknown_08376384[][2] = {
+ {{ 0, 0,0x259}, { 0, 1,0x261}},
+ {{ 0, -1,0x259}, { 0, 0,0x261}},
+ {{ 0, 0,0x252}, { 1, 0,0x253}},
+ {{ -1, 0,0x252}, { 0, 0,0x253}}
+};
+
+const struct MetatileOffset gUnknown_083763A4[][2] = {
+ {{ 0, 0,0x25A}, { 0, 1,0x262}},
+ {{ 0, -1,0x25A}, { 0, 0,0x262}},
+ {{ 0, 0,0x254}, { 1, 0,0x255}},
+ {{ -1, 0,0x254}, { 0, 0,0x255}}
+};
+
+const struct MetatileOffset gUnknown_083763C4[][2] = {
+ {{ 0, 0,0x258}, { 0, 1,0x260}},
+ {{ 0, -1,0x258}, { 0, 0,0x260}},
+ {{ 0, 0,0x250}, { 1, 0,0x251}},
+ {{ -1, 0,0x250}, { 0, 0,0x251}}
+};
+
+void DummyPerStepCallback(u8 taskId) {}
+
+const struct MetatileOffset *sub_80695E0(const struct MetatileOffset a0[][2], s8 a1)
+{
+ if (sub_80576A0(a1))
+ {
+ return a0[0];
+ }
+ else if (sub_80576B4(a1))
+ {
+ return a0[1];
+ }
+ else if (sub_80576C8(a1))
+ {
+ return a0[2];
+ }
+ else if (sub_80576DC(a1))
+ {
+ return a0[3];
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+#ifdef NONMATCHING
+void sub_8069638(const struct MetatileOffset offsets[][2], s16 x, s16 y, bool32 flag)
+{
+ const struct MetatileOffset *offsetData = sub_80695E0(offsets, MapGridGetMetatileBehaviorAt(x, y));
+ const struct MetatileOffset *offsetData2 = offsetData;
+ if (offsetData != NULL)
+ {
+ MapGridSetMetatileIdAt(x + offsetData[0].x, y + offsetData[0].y, offsetData[0].tileId);
+ if (flag)
+ {
+ CurrentMapDrawMetatileAt(x + offsetData[0].x, y + offsetData[0].y);
+ }
+ MapGridSetMetatileIdAt(x + offsetData2[1].x, y + offsetData2[1].y, offsetData2[1].tileId);
+ if (flag)
+ {
+ CurrentMapDrawMetatileAt(x + offsetData2[1].x, y + offsetData2[1].y);
+ }
+ }
+}
+#else
+__attribute__((naked))
+void sub_8069638(const struct MetatileOffset offsets[][2], s16 x, s16 y, bool32 flag)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r8\n"
+ "\tpush {r7}\n"
+ "\tadds r5, r0, 0\n"
+ "\tmov r8, r3\n"
+ "\tlsls r1, 16\n"
+ "\tasrs r6, r1, 16\n"
+ "\tlsls r2, 16\n"
+ "\tasrs r7, r2, 16\n"
+ "\tadds r0, r6, 0\n"
+ "\tadds r1, r7, 0\n"
+ "\tbl MapGridGetMetatileBehaviorAt\n"
+ "\tadds r1, r0, 0\n"
+ "\tlsls r1, 16\n"
+ "\tlsrs r1, 16\n"
+ "\tadds r0, r5, 0\n"
+ "\tbl sub_80695E0\n"
+ "\tadds r4, r0, 0\n"
+ "\tadds r5, r4, 0\n"
+ "\tcmp r4, 0\n"
+ "\tbeq _080696B6\n"
+ "\tmovs r0, 0\n"
+ "\tldrsb r0, [r4, r0]\n"
+ "\tadds r0, r6, r0\n"
+ "\tmovs r1, 0x1\n"
+ "\tldrsb r1, [r4, r1]\n"
+ "\tadds r1, r7, r1\n"
+ "\tldrh r2, [r4, 0x2]\n"
+ "\tbl MapGridSetMetatileIdAt\n"
+ "\tmov r0, r8\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0806968E\n"
+ "\tmovs r0, 0\n"
+ "\tldrsb r0, [r4, r0]\n"
+ "\tadds r0, r6, r0\n"
+ "\tmovs r1, 0x1\n"
+ "\tldrsb r1, [r4, r1]\n"
+ "\tadds r1, r7, r1\n"
+ "\tbl CurrentMapDrawMetatileAt\n"
+ "_0806968E:\n"
+ "\tmovs r0, 0x4\n"
+ "\tldrsb r0, [r5, r0]\n"
+ "\tadds r0, r6, r0\n"
+ "\tmovs r1, 0x5\n"
+ "\tldrsb r1, [r5, r1]\n"
+ "\tadds r1, r7, r1\n"
+ "\tldrh r2, [r5, 0x6]\n"
+ "\tbl MapGridSetMetatileIdAt\n"
+ "\tmov r0, r8\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080696B6\n"
+ "\tmovs r0, 0x4\n"
+ "\tldrsb r0, [r5, r0]\n"
+ "\tadds r0, r6, r0\n"
+ "\tmovs r1, 0x5\n"
+ "\tldrsb r1, [r5, r1]\n"
+ "\tadds r1, r7, r1\n"
+ "\tbl CurrentMapDrawMetatileAt\n"
+ "_080696B6:\n"
+ "\tpop {r3}\n"
+ "\tmov r8, r3\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0");
+}
+#endif
+
+void sub_80696C0(s16 x, s16 y, bool32 flag)
+{
+ sub_8069638(gUnknown_08376384, x, y, flag);
+}
+
+void sub_80696E4(s16 x, s16 y, bool32 flag)
+{
+ sub_8069638(gUnknown_083763A4, x, y, flag);
+}
+
+void sub_8069708(s16 x, s16 y, bool32 flag)
+{
+ sub_8069638(gUnknown_083763C4, x, y, flag);
+}
+
+bool32 sub_806972C(s16 x1, s16 y1, s16 x2, s16 y2)
+{
+ s8 metatileBehavior = MapGridGetMetatileBehaviorAt(x2, y2);
+ if (sub_80576A0(metatileBehavior))
+ {
+ if (y1 > y2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576B4(metatileBehavior))
+ {
+ if (y1 < y2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576C8(metatileBehavior))
+ {
+ if (x1 > x2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576DC(metatileBehavior))
+ {
+ if (x1 < x2)
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+bool32 sub_80697C8(s16 x1, s16 y1, s16 x2, s16 y2)
+{
+ s8 metatileBehavior = MapGridGetMetatileBehaviorAt(x1, y1);
+ if (sub_80576A0(metatileBehavior))
+ {
+ if (y1 < y2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576B4(metatileBehavior))
+ {
+ if (y1 > y2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576C8(metatileBehavior))
+ {
+ if (x1 < x2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576DC(metatileBehavior))
+ {
+ if (x1 > x2)
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void PerStepCallback_8069864(u8 taskId)
+{
+ s16 *data;
+ s16 x, y;
+ data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ switch (data[1])
+ {
+ case 0:
+ data[2] = x;
+ data[3] = y;
+ sub_80696E4(x, y, TRUE);
+ data[1] = 1;
+ break;
+ case 1:
+ if (x != data[2] || y != data[3])
+ {
+ if (sub_806972C(x, y, data[2], data[3]))
+ {
+ sub_80696C0(data[2], data[3], TRUE);
+ sub_8069708(data[2], data[3], FALSE);
+ data[4] = data[2];
+ data[5] = data[3];
+ data[1] = 2;
+ data[6] = 8;
+ }
+ else
+ {
+ data[4] = -1;
+ data[5] = -1;
+ }
+ if (sub_80697C8(x, y, data[2], data[3]))
+ {
+ sub_80696C0(x, y, TRUE);
+ data[1] = 2;
+ data[6] = 8;
+ }
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsPacifidlogLog(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ PlaySE(SE_MIZU);
+ }
+ }
+ break;
+ case 2:
+ if ((--data[6]) == 0)
+ {
+ sub_80696E4(x, y, TRUE);
+ if (data[4] != -1 && data[5] != -1)
+ {
+ sub_8069708(data[4], data[5], TRUE);
+ }
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+void sub_80699D8(s16 x, s16 y)
+{
+ u8 z = PlayerGetZCoord();
+ if (!(z & 0x01))
+ {
+ switch (MapGridGetMetatileIdAt(x, y))
+ {
+ case 0x24e:
+ MapGridSetMetatileIdAt(x, y, 0x24f);
+ break;
+ case 0x256:
+ MapGridSetMetatileIdAt(x, y, 0x257);
+ break;
+ }
+ }
+}
+
+void sub_8069A3C(s16 x, s16 y)
+{
+ u8 z = PlayerGetZCoord();
+ if (!(z & 0x01))
+ {
+ switch (MapGridGetMetatileIdAt(x, y))
+ {
+ case 0x24f:
+ MapGridSetMetatileIdAt(x, y, 0x24e);
+ break;
+ case 0x257:
+ MapGridSetMetatileIdAt(x, y, 0x256);
+ break;
+ }
+ }
+}
+
+void PerStepCallback_8069AA0(u8 taskId)
+{
+ bool8 isFortreeBridgeCur;
+ bool8 isFortreeBridgePrev;
+ u8 z, flag;
+ s16 x, y, x2, y2;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ switch (data[1])
+ {
+ default:
+ break;
+ case 0:
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsFortreeBridge(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ sub_80699D8(x, y);
+ CurrentMapDrawMetatileAt(x, y);
+ }
+ data[1] = 1;
+ break;
+ case 1:
+ x2 = data[2];
+ y2 = data[3];
+ if (x == x2 && y == y2)
+ {
+ break;
+ }
+ isFortreeBridgeCur = MetatileBehavior_IsFortreeBridge(MapGridGetMetatileBehaviorAt(x, y));
+ isFortreeBridgePrev = MetatileBehavior_IsFortreeBridge(MapGridGetMetatileBehaviorAt(x2, y2));
+ z = PlayerGetZCoord();
+ flag = 0;
+ if ((u8)(z & 1) == 0)
+ {
+ flag = 1;
+ }
+ if (flag && (isFortreeBridgeCur == 1 || isFortreeBridgePrev == 1))
+ {
+ PlaySE(SE_HASHI);
+ }
+ if (isFortreeBridgePrev)
+ {
+ sub_8069A3C(x2, y2);
+ CurrentMapDrawMetatileAt(x2, y2);
+ sub_80699D8(x, y);
+ CurrentMapDrawMetatileAt(x, y);
+ }
+ data[4] = x2;
+ data[5] = y2;
+ data[2] = x;
+ data[3] = y;
+ if (!isFortreeBridgePrev)
+ {
+ break;
+ }
+ data[6] = 16;
+ data[1] = 2;
+ // fallthrough
+ case 2:
+ data[6]--;
+ x2 = data[4];
+ y2 = data[5];
+ switch (data[6] % 7)
+ {
+ case 0:
+ CurrentMapDrawMetatileAt(x2, y2);
+ case 1:
+ case 2:
+ case 3:
+ break;
+ case 4:
+ sub_80699D8(x2, y2);
+ CurrentMapDrawMetatileAt(x2, y2);
+ sub_8069A3C(x2, y2);
+ case 5:
+ case 6:
+ case 7:
+ break;
+ }
+ if (data[6] == 0)
+ {
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+const u16 gUnknown_083763E4[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ VAR_0x4001,
+ VAR_0x4002,
+ VAR_0x4003,
+ VAR_0x4004,
+ 0,
+ 0,
+ VAR_0x4005,
+ VAR_0x4006,
+ VAR_0x4007,
+ 0,
+ 0,
+ VAR_0x4008,
+ VAR_0x4009,
+ VAR_0x400A,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+bool32 sub_8069CB8(s16 x, s16 y)
+{
+ if ((u16)(x - 3) < 11 && (u16)(y - 6) < 14 && gUnknown_083763E4[y])
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_8069CFC(s16 x, s16 y)
+{
+ if (sub_8069CB8(x, y))
+ {
+ *GetVarPointer(gUnknown_083763E4[y]) |= (1 << (x - 3));
+ }
+}
+
+bool32 sub_8069D34(s16 x, s16 y)
+{
+ u32 var;
+ if (!sub_8069CB8(x, y))
+ {
+ return FALSE;
+ }
+ var = VarGet(gUnknown_083763E4[y]) << 16;
+ if (((1 << 16) << (x - 3)) & var)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_8069D78(void)
+{
+ s32 x, y;
+ s32 width = gMapHeader.mapData->width;
+ s32 height = gMapHeader.mapData->height;
+ for (x=0; x<width; x++)
+ {
+ for (y=0; y<height; y++)
+ {
+ if (sub_8069D34(x, y) == TRUE)
+ {
+ MapGridSetMetatileIdAt(x + 7, y + 7, 0x20e);
+ }
+ }
+ }
+}
+
+void PerStepCallback_8069DD4(u8 taskId)
+{
+ s16 x, y;
+ u16 tileBehavior;
+ u16 *var;
+ s16 *data = gTasks[taskId].data;
+ switch (data[1])
+ {
+ case 0:
+ PlayerGetDestCoords(&x, &y);
+ data[2] = x;
+ data[3] = y;
+ data[1] = 1;
+ break;
+ case 1:
+ PlayerGetDestCoords(&x, &y);
+ if (x != data[2] || y != data[3])
+ {
+ data[2] = x;
+ data[3] = y;
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ var = GetVarPointer(VAR_ICE_STEP_COUNT);
+ if (MetatileBehavior_IsThinIce(tileBehavior) == TRUE)
+ {
+ (*var)++;
+ data[6] = 4;
+ data[1] = 2;
+ data[4] = x;
+ data[5] = y;
+ }
+ else if (MetatileBehavior_IsCrackedIce(tileBehavior) == TRUE)
+ {
+ *var = 0;
+ data[6] = 4;
+ data[1] = 3;
+ data[4] = x;
+ data[5] = y;
+ }
+ }
+ break;
+ case 2:
+ if (data[6] != 0)
+ {
+ data[6]--;
+ }
+ else
+ {
+ x = data[4];
+ y = data[5];
+ PlaySE(SE_RU_BARI);
+ MapGridSetMetatileIdAt(x, y, 0x20e);
+ CurrentMapDrawMetatileAt(x, y);
+ sub_8069CFC(x - 7, y - 7);
+ data[1] = 1;
+ }
+ break;
+ case 3:
+ if (data[6] != 0)
+ {
+ data[6]--;
+ }
+ else
+ {
+ x = data[4];
+ y = data[5];
+ PlaySE(SE_RU_GASYAN);
+ MapGridSetMetatileIdAt(x, y, 0x206);
+ CurrentMapDrawMetatileAt(x, y);
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+void PerStepCallback_8069F64(u8 taskId)
+{
+ s16 x, y;
+ u16 *var;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ if (x != data[1] || y != data[2])
+ {
+ data[1] = x;
+ data[2] = y;
+ if (MetatileBehavior_IsAshGrass(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ if (MapGridGetMetatileIdAt(x, y) == 0x20a)
+ {
+ ash(x, y, 0x212, 4);
+ }
+ else
+ {
+ ash(x, y, 0x206, 4);
+ }
+ if (CheckBagHasItem(ITEM_SOOT_SACK, 1))
+ {
+ var = GetVarPointer(VAR_ASH_GATHER_COUNT);
+ if (*var < 9999)
+ {
+ (*var)++;
+ }
+ }
+ }
+ }
+}
+
+void sub_806A040(s16 x, s16 y)
+{
+ MapGridSetMetatileIdAt(x, y, MapGridGetMetatileIdAt(x, y) == 0x22f ? 0x206 : 0x237);
+ CurrentMapDrawMetatileAt(x, y);
+}
+
+void PerStepCallback_806A07C(u8 taskId)
+{
+ s16 x, y;
+ u16 behavior;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ behavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (data[4] != 0 && (--data[4]) == 0)
+ {
+ sub_806A040(data[5], data[6]);
+ }
+ if (data[7] != 0 && (--data[7]) == 0)
+ {
+ sub_806A040(data[8], data[9]);
+ }
+ if (MetatileBehavior_IsCrackedFloorHole(behavior))
+ {
+ VarSet(VAR_ICE_STEP_COUNT, 0); // this var does double duty
+ }
+ if ((x != data[2] || y != data[3]))
+ {
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsCrackedFloor(behavior))
+ {
+ if (GetPlayerSpeed() != 4)
+ {
+ VarSet(VAR_ICE_STEP_COUNT, 0); // this var does double duty
+ }
+ if (data[4] == 0)
+ {
+ data[4] = 3;
+ data[5] = x;
+ data[6] = y;
+ }
+ else if (data[7] == 0)
+ {
+ data[7] = 3;
+ data[8] = x;
+ data[9] = y;
+ }
+ }
+ }
+}
+
+const u16 gUnknown_08376418[] = {0xe8, 0xeb, 0xea, 0xe9};
+
+void sub_806A18C(s16 *data, s16 x, s16 y)
+{
+ u16 tile;
+ if ((--data[0]) == 0)
+ {
+ tile = 0xe8;
+ }
+ else
+ {
+ tile = gUnknown_08376418[data[0] / 8];
+ }
+ MapGridSetMetatileIdAt(x, y, tile);
+ CurrentMapDrawMetatileAt(x, y);
+ MapGridSetMetatileIdAt(x, y, 0xe8);
+}
+
+void Task_MuddySlope(u8 taskId)
+{
+ s16 x, y, x2, y2;
+ int i;
+ u16 mapIndices;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ mapIndices = (gSaveBlock1.location.mapGroup << 8) | gSaveBlock1.location.mapNum;
+ switch (data[1])
+ {
+ case 0:
+ data[0] = mapIndices;
+ data[2] = x;
+ data[3] = y;
+ data[1] = 1;
+ data[4] = 0;
+ data[7] = 0;
+ data[10] = 0;
+ data[13] = 0;
+ break;
+ case 1:
+ if (data[2] != x || data[3] != y)
+ {
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsMuddySlope(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ for (i=4; i<14; i+=3)
+ {
+ if (data[i] == 0)
+ {
+ data[i] = 32;
+ data[i + 1] = x;
+ data[i + 2] = y;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ if (gUnknown_0202E844.field_0 && mapIndices != data[0])
+ {
+ data[0] = mapIndices;
+ x2 = gUnknown_0202E844.x;
+ y2 = gUnknown_0202E844.y;
+ }
+ else
+ {
+ x2 = 0;
+ y2 = 0;
+ }
+ for (i=4; i<14; i+=3)
+ {
+ if (data[i])
+ {
+ data[i + 1] -= x2;
+ data[i + 2] -= y2;
+ sub_806A18C(&data[i], data[i + 1], data[i + 2]);
+ }
+ }
+}
diff --git a/src/item_use.c b/src/item_use.c
index a92161e9a..b906f91ad 100644
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -50,7 +50,6 @@ extern u8 gUnknown_081A168F[];
extern u16 gBattlePartyID[];
-extern u16 gScriptItemId;
extern u16 gBattleTypeFlags;
static const u8 gSSTidalBetaString[] = _("この チケットで ふねに のりほうだい\nはやく のってみたいな");
diff --git a/src/link.c b/src/link.c
index 363a8b494..5858ad8bf 100644
--- a/src/link.c
+++ b/src/link.c
@@ -4,6 +4,7 @@
#include "berry.h"
#include "berry_blender.h"
#include "hall_of_fame.h"
+#include "item_use.h"
#include "main.h"
#include "menu.h"
#include "palette.h"
@@ -38,7 +39,6 @@ struct LinkTestBGInfo
extern u8 unk_2000000[];
extern u8 unk_2004000[];
extern u16 gBattleTypeFlags;
-extern u16 gScriptItemId;
extern u16 word_3004858;
diff --git a/src/menu.c b/src/menu.c
index 45cfbbc2f..d532fc602 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -571,7 +571,7 @@ void PrintMenuItems(u8 left, u8 top, u8 menuItemCount, const struct MenuAction m
MenuPrint(menuItems[i].text, left, top + 2 * i);
}
-void PrintMenuItemsReordered(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[], u8 *order)
+void PrintMenuItemsReordered(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[], const u8 *order)
{
u8 i;
diff --git a/src/mori_debug_menu.c b/src/mori_debug_menu.c
index ba79261c0..2d9e3fa6f 100644
--- a/src/mori_debug_menu.c
+++ b/src/mori_debug_menu.c
@@ -133,7 +133,7 @@ s8 MoriDebugMenu_PokeblockCase(void)
s32 loopCounter;
for (loopCounter = 0; loopCounter <= 39; loopCounter++)
- sub_810CA6C((u8)loopCounter);
+ sub_810CA6C(loopCounter);
CloseMenu();
return 1;
diff --git a/src/party_menu.c b/src/party_menu.c
index 99bbb5f83..1fcd2cdda 100644
--- a/src/party_menu.c
+++ b/src/party_menu.c
@@ -6,6 +6,7 @@
#include "data2.h"
#include "event_data.h"
#include "item.h"
+#include "item_use.h"
#include "mail_data.h"
#include "main.h"
#include "menu.h"
@@ -78,7 +79,6 @@ extern u16 gUnknown_0202E8F8;
extern u8 gUnknown_0202E8FA;
extern u8 gLastFieldPokeMenuOpened;
extern u8 gPlayerPartyCount;
-extern u16 gScriptItemId;
extern s32 gBattleMoveDamage;
//extern const u16 gUnknown_083769A8[][6];
diff --git a/src/player_pc.c b/src/player_pc.c
index 9cb395432..38e01b92e 100644
--- a/src/player_pc.c
+++ b/src/player_pc.c
@@ -26,7 +26,6 @@ extern void DoPlayerPCDecoration(u8);
extern void BuyMenuFreeMemory(void);
extern void DestroyVerticalScrollIndicator(u8);
extern void PauseVerticalScrollIndicator(u8);
-extern void StartVerticalScrollIndicators(int);
extern void LoadScrollIndicatorPalette(void);
extern void ClearMailStruct(struct MailStruct *);
extern u8 sub_807D770(void);
diff --git a/src/pokeblock.c b/src/pokeblock.c
new file mode 100755
index 000000000..b7fa5daa8
--- /dev/null
+++ b/src/pokeblock.c
@@ -0,0 +1,1116 @@
+//
+// Created by scott on 6/27/2017.
+//
+
+#include "global.h"
+#include "rom4.h"
+#include "sprite.h"
+#include "script.h"
+#include "strings.h"
+#include "task.h"
+#include "unknown_task.h"
+#include "text.h"
+#include "main.h"
+#include "menu.h"
+#include "field_fadetransition.h"
+#include "palette.h"
+#include "graphics.h"
+#include "decompress.h"
+#include "menu_helpers.h"
+#include "battle.h"
+#include "item_menu.h"
+#include "item_use.h"
+#include "item.h"
+#include "items.h"
+#include "sound.h"
+#include "songs.h"
+#include "safari_zone.h"
+#include "use_pokeblock.h"
+#include "pokeblock.h"
+
+// function declarations
+
+// gUnknown_083F7EF4
+static void sub_810C508(u8);
+static void sub_810C5C0(u8);
+static void sub_810C748(u8);
+static void sub_810C788(u8);
+static void sub_810C854(u8);
+
+// gUnknown_083F7F24
+static void sub_810C610(u8);
+static void sub_810C668(u8);
+
+// sub_810B6C0
+static bool8 sub_810B998(void);
+static void sub_810BC98(void);
+static void sub_810BD08(void);
+static void sub_810BB0C(void);
+static void sub_810BB30(void);
+static void sub_810BC84(u8);
+
+// sub_810B96C
+static void sub_810BF7C(u8);
+
+// sub_810BC84
+static void sub_810BDAC(bool8);
+
+// sub_810BF38
+static void sub_810C8D4(struct Sprite *);
+
+// sub_810BF7C
+static void sub_810C0C8(u8);
+static void sub_810C31C(u8);
+static void sub_810C368(u8);
+
+// sub_810C0C8
+static void sub_810C1C8(u8, u8);
+static void sub_810C23C(u8);
+
+// sub_810C368
+static void sub_810C40C(u8);
+
+// sub_810C540
+static void sub_810C5EC(u8);
+
+// sub_810C610
+static void sub_810C704(u8);
+
+// rodata
+
+#define GFX_TAG_POKEBLOCK_CASE 14800
+
+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
+};
+
+void (*const gUnknown_083F7EA8[])(void) = {
+ sub_80A5B40,
+ c2_exit_to_overworld_2_switch,
+ sub_802E424,
+ c2_exit_to_overworld_2_switch
+};
+
+const u8 *const gPokeblockNames[] = {
+ NULL,
+ ContestStatsText_RedPokeBlock,
+ ContestStatsText_BluePokeBlock,
+ ContestStatsText_PinkPokeBlock,
+ ContestStatsText_GreenPokeBlock,
+ ContestStatsText_YellowPokeBlock,
+ ContestStatsText_PurplePokeBlock,
+ ContestStatsText_IndigoPokeBlock,
+ ContestStatsText_BrownPokeBlock,
+ ContestStatsText_LiteBluePokeBlock,
+ ContestStatsText_OlivePokeBlock,
+ ContestStatsText_GrayPokeBlock,
+ ContestStatsText_BlackPokeBlock,
+ ContestStatsText_WhitePokeBlock,
+ ContestStatsText_GoldPokeBlock
+};
+
+const struct MenuAction2 gUnknown_083F7EF4[] = {
+ {OtherText_Use, sub_810C508},
+ {OtherText_Toss, sub_810C5C0},
+ {gOtherText_CancelNoTerminator, sub_810C748},
+ {OtherText_Use, sub_810C788},
+ {OtherText_Use, sub_810C854},
+};
+
+const u8 gUnknown_083F7F1C[] = {0, 1, 2};
+const u8 gUnknown_083F7F1F[] = {3, 2};
+const u8 gUnknown_083F7F21[] = {4, 2};
+
+const struct YesNoFuncTable gUnknown_083F7F24 = {sub_810C610, sub_810C668};
+
+const u8 UnreferencedData_083F7F2C[] = {0x16, 0x17, 0x18, 0x21, 0x2f};
+
+const struct OamData gOamData_83F7F34 = {
+ .size = 3,
+ .priority = 2
+};
+
+const union AnimCmd gSpriteAnim_83F7F3C[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 0),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gSpriteAnimTable_83F7F44[] = {
+ gSpriteAnim_83F7F3C
+};
+
+const union AffineAnimCmd gSpriteAffineAnim_83F7F48[] = {
+ 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
+};
+
+const union AffineAnimCmd *const gSpriteAffineAnimTable_83F7F70[] = {
+ gSpriteAffineAnim_83F7F48
+};
+
+const struct CompressedSpriteSheet gUnknown_083F7F74 = {
+ gMenuPokeblockDevice_Gfx,
+ 0x800,
+ GFX_TAG_POKEBLOCK_CASE
+};
+
+const struct CompressedSpritePalette gUnknown_083F7F7C = {
+ gMenuPokeblockDevice_Pal,
+ GFX_TAG_POKEBLOCK_CASE
+};
+
+const struct SpriteTemplate gSpriteTemplate_83F7F84 = {
+ GFX_TAG_POKEBLOCK_CASE,
+ GFX_TAG_POKEBLOCK_CASE,
+ &gOamData_83F7F34,
+ gSpriteAnimTable_83F7F44,
+ NULL,
+ gDummySpriteAffineAnimTable,
+ SpriteCallbackDummy
+};
+
+const struct Pokeblock gUnknown_083F7F9C[] = {
+ { 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}
+};
+
+// text
+
+static void sub_810B674(void)
+{
+ AnimateSprites();
+ BuildOamBuffer();
+ RunTasks();
+ UpdatePaletteFade();
+}
+
+static void sub_810B68C(void)
+{
+ u16 *src;
+ vu16 *dest;
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+ src = gBGTilemapBuffers[2];
+ dest = (vu16 *)(VRAM + 0x7800);
+ DmaCopy16(3, src, dest, sizeof gBGTilemapBuffers[2]);
+}
+
+static bool8 sub_810B6C0(void)
+{
+ u16 ime;
+ switch (gMain.state)
+ {
+ case 0:
+ sub_80F9438();
+ sub_80F9368();
+ REG_BG2CNT = BGCNT_SCREENBASE(15) | BGCNT_CHARBASE(2) | BGCNT_PRIORITY(2);
+ REG_BLDCNT = 0;
+ gMain.state++;
+ break;
+ case 1:
+ remove_some_task();
+ gMain.state++;
+ break;
+ case 2:
+ ResetPaletteFade();
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ gMain.state++;
+ break;
+ case 3:
+ ResetSpriteData();
+ gMain.state++;
+ break;
+ case 4:
+ if (gUnknown_02039244 != 2)
+ {
+ ResetTasks();
+ }
+ gMain.state++;
+ break;
+ case 5:
+ SetUpWindowConfig(&gWindowConfig_81E6E34);
+ gMain.state++;
+ break;
+ case 6:
+ SetUpWindowConfig(&gWindowConfig_81E6E50);
+ gMain.state++;
+ break;
+ case 7:
+ MultistepInitMenuWindowBegin(&gWindowConfig_81E6E34);
+ gMain.state++;
+ break;
+ case 8:
+ if (MultistepInitMenuWindowContinue())
+ {
+ gMain.state++;
+ }
+ break;
+ case 9:
+ MultistepInitMenuWindowBegin(&gWindowConfig_81E6E50);
+ gMain.state++;
+ break;
+ case 10:
+ if (MultistepInitMenuWindowContinue())
+ {
+ ewram[0x1ffff] = 0;
+ gMain.state++;
+ }
+ break;
+ case 11:
+ if (sub_810B998())
+ {
+ gMain.state++;
+ }
+ break;
+ case 12:
+ sub_80F944C();
+ LoadScrollIndicatorPalette();
+ CreateVerticalScrollIndicators(0, 0xb0, 0x08);
+ CreateVerticalScrollIndicators(1, 0xb0, 0x98);
+ gMain.state++;
+ break;
+ case 13:
+ ewram[0x1fffe] = sub_810BA50(0x38, 0x40, 0);
+ gMain.state++;
+ break;
+ case 14:
+ sub_810BC98();
+ sub_810BD08();
+ gMain.state++;
+ break;
+ case 15:
+ sub_810BB0C();
+ sub_810BB30();
+ sub_810BC84(gUnknown_02039248[1]);
+ gMain.state++;
+ break;
+ case 16:
+ ime = REG_IME;
+ REG_IME = 0;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = ime;
+ REG_DISPSTAT |= DISPSTAT_VBLANK_INTR;
+ SetVBlankCallback(sub_810B68C);
+ REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG2_ON | DISPCNT_BG1_ON | DISPCNT_BG0_ON | DISPCNT_OBJ_1D_MAP;
+ gMain.state++;
+ break;
+ case 17:
+ if (sub_8055870() != TRUE)
+ {
+ gMain.state++;
+ }
+ break;
+ case 18:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gPaletteFade.bufferTransferDisabled = FALSE;
+ SetMainCallback2(sub_810B674);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_810B96C(void)
+{
+ do {
+ if (sub_810B6C0() == TRUE)
+ {
+ CreateTask(sub_810BF7C, 0);
+ break;
+ }
+ } while (sub_80F9344() != TRUE);
+}
+
+static bool8 sub_810B998(void)
+{
+ switch (ewram[0x1ffff])
+ {
+ case 0:
+ LZDecompressVram(gMenuPokeblock_Gfx, (u8 *)BG_CHAR_ADDR(2));
+ ewram[0x1ffff]++;
+ break;
+ case 1:
+ sub_800D238(gMenuPokeblock_Tilemap, gBGTilemapBuffers[2]);
+ ewram[0x1ffff]++;
+ break;
+ case 2:
+ LoadCompressedPalette(gMenuPokeblock_Pal, 0, 0xc0);
+ ewram[0x1ffff]++;
+ break;
+ case 3:
+ LoadCompressedObjectPic(&gUnknown_083F7F74);
+ ewram[0x1ffff]++;
+ break;
+ case 4:
+ LoadCompressedObjectPalette(&gUnknown_083F7F7C);
+ ewram[0x1ffff] = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+u8 sub_810BA50(s16 x, s16 y, u8 subpriority)
+{
+ return CreateSprite(&gSpriteTemplate_83F7F84, x, y, subpriority);
+}
+
+void sub_810BA7C(u8 a0)
+{
+ gUnknown_02039244 = a0;
+ switch (gUnknown_02039244)
+ {
+ default:
+ gUnknown_03000758 = gUnknown_083F7F1C;
+ gUnknown_0203924C = sizeof gUnknown_083F7F1C;
+ break;
+ case 2:
+ gUnknown_03000758 = gUnknown_083F7F1F;
+ gUnknown_0203924C = sizeof gUnknown_083F7F1F;
+ break;
+ case 3:
+ gUnknown_03000758 = gUnknown_083F7F21;
+ gUnknown_0203924C = sizeof gUnknown_083F7F21;
+ break;
+ }
+}
+
+void sub_810BADC(void)
+{
+ sub_810BA7C(2);
+ SetMainCallback2(sub_810B96C);
+}
+
+void sub_810BAF4(void)
+{
+ sub_810BA7C(3);
+ SetMainCallback2(sub_810B96C);
+}
+
+#ifdef DEBUG
+void debug_sub_8120F98(void)
+{
+ u8 i;
+ for (i=0; i<40 && gUnknown_083F7F9C[i].color != 0; i++)
+ {
+ gSaveBlock1.pokeblocks[i] = gUnknown_083F7F9C[i];
+ }
+}
+#endif
+
+static void sub_810BB0C(void)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ sub_8072BD8(ItemId_GetItem(ITEM_POKEBLOCK_CASE)->name, 2, 1, 0x48);
+}
+
+static void sub_810BB30(void)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ MenuPrint(gContestStatsText_Spicy, 2, 13);
+ MenuPrint(gContestStatsText_Dry, 2, 15);
+ MenuPrint(gContestStatsText_Sweet, 2, 17);
+ MenuPrint(gContestStatsText_Bitter, 8, 13);
+ MenuPrint(gContestStatsText_Sour, 8, 15);
+}
+
+static void sub_810BB88(u8 a0)
+{
+ u8 i;
+ u8 y;
+ u8 *buf;
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ for (i=a0; i<=a0+8; i++)
+ {
+ y = (i - a0) << 1;
+ if (i == gUnknown_02039248[2])
+ {
+ buf = sub_8072C74(gStringVar1, gContestStatsText_StowCase, 0x78, 0);
+ MenuPrint(gStringVar1, 15, y + 1);
+ if (i != a0 + 8)
+ {
+ MenuZeroFillWindowRect(15, y + 3, 29, 18);
+ }
+ break;
+ }
+ buf = sub_8072C74(gStringVar1, gPokeblockNames[gSaveBlock1.pokeblocks[i].color], 0x5e, 0);
+ buf[0] = EXT_CTRL_CODE_BEGIN;
+ buf[1] = 0x14;
+ buf[2] = 0x06;
+ buf += 3;
+ ConvertIntToDecimalStringN(buf, sub_810C9B0(&gSaveBlock1.pokeblocks[i]), STR_CONV_MODE_RIGHT_ALIGN, 3);
+ MenuPrint(gStringVar1, 15, y + 1);
+ }
+}
+
+static void sub_810BC84(u8 a0)
+{
+ sub_810BB88(a0);
+ sub_810BDAC(FALSE);
+}
+
+static void sub_810BC98(void)
+{
+ u16 i, j;
+ struct Pokeblock buf;
+ for (i=0; i<39; i++)
+ {
+ for (j=i+1; j<40; j++)
+ {
+ if (gSaveBlock1.pokeblocks[i].color == 0)
+ {
+ buf = gSaveBlock1.pokeblocks[i];
+ gSaveBlock1.pokeblocks[i] = gSaveBlock1.pokeblocks[j];
+ gSaveBlock1.pokeblocks[j] = buf;
+ }
+ }
+ }
+}
+
+static void sub_810BD08(void)
+{
+ u8 i;
+ gUnknown_02039248[2] = 0;
+ for (i=0; i<40; i++)
+ {
+ if (gSaveBlock1.pokeblocks[i].color != 0)
+ gUnknown_02039248[2]++;
+ }
+ if (gUnknown_02039248[2] < 8)
+ {
+ gUnknown_02039248[3] = gUnknown_02039248[2];
+ }
+ else
+ {
+ gUnknown_02039248[3] = 8;
+ }
+ if (gUnknown_02039248[1] + 8 > gUnknown_02039248[2] && gUnknown_02039248[1] != 0)
+ {
+ gUnknown_02039248[1]--;
+ }
+}
+
+static void sub_810BD64(u16 a0, u16 a1)
+{
+ u8 i;
+ int y;
+ for (i=0; i<14; i++)
+ {
+ gBGTilemapBuffers[2][(2 * gUnknown_02039248[0] + 1) * 32 + (y = i + 15)] = a0;
+ gBGTilemapBuffers[2][(2 * gUnknown_02039248[0] + 2) * 32 + y] = a0;
+ }
+}
+
+static void sub_810BDAC(bool8 flag)
+{
+ u8 i;
+ u16 v0;
+ if (!flag)
+ {
+ sub_810BD64(0x1005, 0x1014);
+ }
+ else
+ {
+ sub_810BD64(0x2005, 0x2014);
+ }
+ if (gUnknown_02039248[1])
+ {
+ sub_80F979C(0, 0);
+ }
+ else
+ {
+ sub_80F979C(0, 1);
+ }
+ if (gUnknown_02039248[2] > gUnknown_02039248[3] && gUnknown_02039248[1] + gUnknown_02039248[3] != gUnknown_02039248[2])
+ {
+ sub_80F979C(1, 0);
+ }
+ else
+ {
+ sub_80F979C(1, 1);
+ }
+ for (i=0; i<5; i++)
+ {
+ v0 = ((i % 3) << 6) + 0x1a1 + (i / 3) * 6;
+ if (gUnknown_02039248[0] + gUnknown_02039248[1] != gUnknown_02039248[2])
+ {
+ if (sub_810CA9C(&gSaveBlock1.pokeblocks[gUnknown_02039248[0] + gUnknown_02039248[1]], i + 1) > 0)
+ {
+ gBGTilemapBuffers[2][v0] = (i << 12) + 23;
+ gBGTilemapBuffers[2][v0 + 32] = (i << 12) + 24;
+ }
+ else
+ {
+ gBGTilemapBuffers[2][v0] = 15;
+ gBGTilemapBuffers[2][v0 + 32] = 15;
+ }
+ }
+ else
+ {
+ gBGTilemapBuffers[2][v0] = 15;
+ gBGTilemapBuffers[2][v0 + 32] = 15;
+ }
+ }
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ if (gUnknown_02039248[0] + gUnknown_02039248[1] != gUnknown_02039248[2])
+ {
+ sub_8072C14(gStringVar1, sub_810C9E8(&gSaveBlock1.pokeblocks[gUnknown_02039248[0] + gUnknown_02039248[1]]), 16, 1);
+ MenuPrint(gStringVar1, 11, 17);
+ }
+ else
+ {
+ MenuZeroFillWindowRect(11, 17, 12, 18);
+ }
+}
+
+static void sub_810BF38(bool8 flag)
+{
+ PlaySE(SE_SELECT);
+ gSprites[ewram[0x1fffe]].callback = sub_810C8D4;
+ sub_810BDAC(flag);
+}
+
+static void sub_810BF7C(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if (gUnknown_02039248[0] != 0)
+ {
+ sub_810BD64(5, 20);
+ gUnknown_02039248[0]--;
+ sub_810BF38(FALSE);
+ }
+ else if (gUnknown_02039248[1] != 0)
+ {
+ gUnknown_02039248[1]--;
+ sub_810BB88(gUnknown_02039248[1]);
+ sub_810BF38(FALSE);
+ }
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if (gUnknown_02039248[0] != gUnknown_02039248[3])
+ {
+ sub_810BD64(5, 20);
+ gUnknown_02039248[0]++;
+ sub_810BF38(FALSE);
+ }
+ else if (gUnknown_02039248[1] + gUnknown_02039248[0] != gUnknown_02039248[2])
+ {
+ gUnknown_02039248[1]++;
+ sub_810BB88(gUnknown_02039248[1]);
+ sub_810BF38(FALSE);
+ }
+ }
+ else if (gMain.newKeys & SELECT_BUTTON)
+ {
+ if (gUnknown_02039248[1] + gUnknown_02039248[0] != gUnknown_02039248[2])
+ {
+ PlaySE(SE_SELECT);
+ sub_810BDAC(TRUE);
+ gTasks[taskId].data[0] = gUnknown_02039248[1] + gUnknown_02039248[0];
+ gTasks[taskId].func = sub_810C0C8;
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ if (gUnknown_02039248[1] + gUnknown_02039248[0] == gUnknown_02039248[2])
+ {
+ gScriptResult = 0xffff;
+ sub_810C31C(taskId);
+ }
+ else
+ {
+ sub_810C368(taskId);
+ }
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gScriptResult = 0xffff;
+ sub_810C31C(taskId);
+ }
+ }
+}
+
+static void sub_810C0C8(u8 taskId)
+{
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if (gUnknown_02039248[0] != 0)
+ {
+ sub_810BD64(5, 20);
+ gUnknown_02039248[0]--;
+ sub_810BF38(TRUE);
+ sub_810C1C8(taskId, 1);
+ }
+ else if (gUnknown_02039248[1] != 0)
+ {
+ sub_810C1C8(taskId, 0);
+ gUnknown_02039248[1]--;
+ sub_810BB88(gUnknown_02039248[1]);
+ sub_810BF38(TRUE);
+ sub_810C1C8(taskId, 1);
+ }
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if (gUnknown_02039248[0] != gUnknown_02039248[3])
+ {
+ sub_810BD64(5, 20);
+ gUnknown_02039248[0]++;
+ sub_810BF38(TRUE);
+ sub_810C1C8(taskId, 1);
+ }
+ else if (gUnknown_02039248[1] + gUnknown_02039248[0] != gUnknown_02039248[2])
+ {
+ sub_810C1C8(taskId, 0);
+ gUnknown_02039248[1]++;
+ sub_810BB88(gUnknown_02039248[1]);
+ sub_810BF38(TRUE);
+ sub_810C1C8(taskId, 1);
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON || gMain.newKeys & SELECT_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_810C1C8(taskId, 0);
+ sub_810C23C(taskId);
+ gTasks[taskId].func = sub_810BF7C;
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_810C1C8(taskId, 0);
+ sub_810BDAC(0);
+ gTasks[taskId].func = sub_810BF7C;
+ }
+}
+
+static void sub_810C1C8(u8 taskId, u8 flag)
+{
+ u8 i;
+ u32 x;
+ s16 y;
+ u16 v0 = 0x1005;
+ if (!flag)
+ {
+ v0 = 0x0005;
+ }
+ y = gTasks[taskId].data[0] - gUnknown_02039248[1];
+ if ((u16)y <= 8 && y != gUnknown_02039248[0])
+ {
+ for (i=0; i<14; i++)
+ {
+ gBGTilemapBuffers[2][(2 * y + 1) * 32 + (x = i + 15)] = v0;
+ gBGTilemapBuffers[2][(2 * y + 2) * 32 + x] = v0;
+ }
+ }
+}
+
+static void sub_810C23C(u8 taskId)
+{
+ struct Pokeblock buf;
+ u8 selidx = gUnknown_02039248[1] + gUnknown_02039248[0];
+ if (selidx == gUnknown_02039248[2])
+ {
+ sub_810BDAC(FALSE);
+ }
+ else
+ {
+ buf = gSaveBlock1.pokeblocks[selidx];
+ gSaveBlock1.pokeblocks[selidx] = gSaveBlock1.pokeblocks[gTasks[taskId].data[0]];
+ gSaveBlock1.pokeblocks[gTasks[taskId].data[0]] = buf;
+ sub_810BB88(gUnknown_02039248[1]);
+ sub_810BDAC(FALSE);
+ }
+}
+
+static void sub_810C2B0(void)
+{
+ DestroyVerticalScrollIndicator(0);
+ DestroyVerticalScrollIndicator(1);
+ BuyMenuFreeMemory();
+}
+
+static void sub_810C2C8(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gUnknown_02039244 == 3)
+ {
+ gFieldCallback = sub_8080990;
+ }
+ sub_810C2B0();
+ SetMainCallback2(gUnknown_083F7EA8[gUnknown_02039244]);
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_810C31C(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ if (gUnknown_02039244 > 1)
+ {
+ gScriptItemId = ITEM_NONE;
+ }
+ gTasks[taskId].func = sub_810C2C8;
+}
+
+static void sub_810C368(u8 taskId)
+{
+ int v0 = 0;
+ if (gUnknown_02039244 > 1)
+ v0 = 2;
+ sub_80F98A4(0);
+ sub_80F98A4(1);
+ BasicInitMenuWindow(&gWindowConfig_81E6E50);
+ MenuDrawTextWindow(7, v0 + 4, 13, 11);
+ PrintMenuItemsReordered(8, v0 + 5, gUnknown_0203924C, (const struct MenuAction *)gUnknown_083F7EF4, gUnknown_03000758);
+ InitMenu(0, 8, v0 + 5, gUnknown_0203924C, 0, 5);
+ gScriptItemId = gUnknown_02039248[0] + gUnknown_02039248[1];
+ gTasks[taskId].func = sub_810C40C;
+}
+
+static void sub_810C40C(u8 taskId)
+{
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if (GetMenuCursorPos())
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ }
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if (GetMenuCursorPos() != gUnknown_0203924C - 1)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(+1);
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_083F7EF4[gUnknown_03000758[GetMenuCursorPos()]].func(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_810C748(taskId);
+ }
+}
+
+static void sub_810C4C4(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ sub_810C2B0();
+ sub_8136130(&gSaveBlock1.pokeblocks[gScriptItemId], sub_810B96C);
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_810C508(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_810C4C4;
+}
+
+static void sub_810C540(u8 taskId)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E6E50);
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(7, 4, 13, 11);
+ StringCopy(gStringVar1, gPokeblockNames[gSaveBlock1.pokeblocks[gUnknown_02039248[0] + gUnknown_02039248[1]].color]);
+ StringExpandPlaceholders(gStringVar4, gContestStatsText_ThrowAwayPrompt);
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_810C5EC, 0);
+}
+
+static void sub_810C5C0(u8 taskId)
+{
+ sub_80F979C(1, 1);
+ gTasks[taskId].func = sub_810C540;
+}
+
+static void sub_810C5EC(u8 taskId)
+{
+ DisplayYesNoMenu(7, 6, 1);
+ DoYesNoFuncWithChoice(taskId, &gUnknown_083F7F24);
+}
+
+static void sub_810C610(u8 taskId)
+{
+ MenuZeroFillWindowRect(7, 6, 13, 11);
+ sub_810CA6C((gUnknown_02039248[0] + gUnknown_02039248[1]));
+ StringExpandPlaceholders(gStringVar4, gContestStatsText_WasThrownAway);
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_810C704, 0);
+ sub_810BC98();
+ sub_810BD08();
+}
+
+static void sub_810C668(u8 taskId)
+{
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ if (gUnknown_02039248[2] > gUnknown_02039248[3] && gUnknown_02039248[1] + gUnknown_02039248[3] != gUnknown_02039248[2])
+ {
+ sub_80F979C(1, 0);
+ }
+ BasicInitMenuWindow(&gWindowConfig_81E6E50);
+ MenuZeroFillWindowRect(7, 6, 13, 11);
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ gTasks[taskId].func = sub_810BF7C;
+}
+
+static void sub_810C6DC(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
+ {
+ sub_810C668(taskId);
+ }
+}
+
+static void sub_810C704(u8 taskId)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ sub_810BC84(gUnknown_02039248[1]);
+ sub_80F979C(1, 1);
+ gTasks[taskId].func = sub_810C6DC;
+}
+
+static void sub_810C748(u8 taskId)
+{
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(7, 4, 13, 11);
+ gTasks[taskId].func = sub_810BF7C;
+}
+
+static void sub_810C788(u8 taskId)
+{
+ s16 v0 = sub_810CAE4(GetNature(&gEnemyParty[0]), &gSaveBlock1.pokeblocks[gScriptItemId]);
+ StringCopy(gBattleTextBuff1, gPokeblockNames[gSaveBlock1.pokeblocks[gScriptItemId].color]);
+ sub_810CA6C(gScriptItemId);
+ gScriptItemId = gSaveBlock1.pokeblocks[gScriptItemId].color << 8;
+ if (v0 == 0)
+ {
+ gScriptItemId += 1;
+ }
+ if (v0 > 0)
+ {
+ gScriptItemId += 2;
+ }
+ if (v0 < 0)
+ {
+ gScriptItemId += 3;
+ }
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_810C2C8;
+}
+
+static void sub_810C854(u8 taskId)
+{
+ SafariZoneActivatePokeblockFeeder(gScriptItemId);
+ StringCopy(gStringVar1, gPokeblockNames[gSaveBlock1.pokeblocks[gScriptItemId].color]);
+ gScriptResult = gScriptItemId;
+ sub_810CA6C(gScriptItemId);
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_810C2C8;
+}
+
+static void sub_810C8D4(struct Sprite *sprite)
+{
+ if (sprite->data0 > 1)
+ {
+ sprite->data0 = 0;
+ }
+ switch (sprite->data0)
+ {
+ case 0:
+ sprite->oam.affineMode = 1;
+ sprite->affineAnims = gSpriteAffineAnimTable_83F7F70;
+ InitSpriteAffineAnim(sprite);
+ sprite->data0 = 1;
+ sprite->data1 = 0;
+ break;
+ case 1:
+ if (++sprite->data1 > 11)
+ {
+ sprite->oam.affineMode = 0;
+ sprite->data0 = 0;
+ sprite->data1 = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->callback = SpriteCallbackDummy;
+ }
+ break;
+ }
+}
+
+static void ClearPokeblock(u8 pokeblockIdx)
+{
+ gSaveBlock1.pokeblocks[pokeblockIdx].color = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].spicy = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].dry = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].sweet = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].bitter = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].sour = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].feel = 0;
+}
+
+void ClearPokeblocks(void)
+{
+ u8 pokeblockIdx;
+ for (pokeblockIdx=0; pokeblockIdx<ARRAY_COUNT(gSaveBlock1.pokeblocks); pokeblockIdx++)
+ {
+ ClearPokeblock(pokeblockIdx);
+ }
+}
+
+u8 sub_810C9B0(struct Pokeblock *pokeblock)
+{
+ u8 contestStat;
+ u8 maxRating;
+ u8 rating = sub_810CA9C(pokeblock, 1);
+ for (contestStat=1; contestStat<5; contestStat++)
+ {
+ maxRating = sub_810CA9C(pokeblock, contestStat + 1);
+ if (rating < maxRating)
+ {
+ rating = maxRating;
+ }
+ }
+ return rating;
+}
+
+u8 sub_810C9E8(struct Pokeblock *pokeblock)
+{
+ u8 feel = sub_810CA9C(pokeblock, 6);
+ if (feel > 99)
+ feel = 99;
+ return feel;
+}
+
+s8 sub_810CA00(void)
+{
+ u8 i;
+ for (i=0; i<ARRAY_COUNT(gSaveBlock1.pokeblocks); i++)
+ {
+ if (gSaveBlock1.pokeblocks[i].color == 0)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool8 sub_810CA34(struct Pokeblock *pokeblock)
+{
+ s8 idx = sub_810CA00();
+ if (idx == -1)
+ {
+ return FALSE;
+ }
+ gSaveBlock1.pokeblocks[idx] = *pokeblock;
+ return TRUE;
+}
+
+bool8 sub_810CA6C(u8 pokeblockIdx)
+{
+ if (gSaveBlock1.pokeblocks[pokeblockIdx].color == 0)
+ {
+ return FALSE;
+ }
+ ClearPokeblock(pokeblockIdx);
+ return TRUE;
+}
+
+s16 sub_810CA9C(const struct Pokeblock *pokeblock, u8 field)
+{
+ if (field == 0)
+ return pokeblock->color;
+ if (field == 1)
+ return pokeblock->spicy;
+ if (field == 2)
+ return pokeblock->dry;
+ if (field == 3)
+ return pokeblock->sweet;
+ if (field == 4)
+ return pokeblock->bitter;
+ if (field == 5)
+ return pokeblock->sour;
+ if (field == 6)
+ return pokeblock->feel;
+ return 0;
+}
+
+s16 sub_810CAE4(u8 nature, const struct Pokeblock *pokeblock)
+{
+ u8 flavor;
+ s16 curGain;
+ s16 totalGain = 0;
+ for (flavor=0; flavor<5; flavor++)
+ {
+ curGain = sub_810CA9C(pokeblock, flavor + 1);
+ if (curGain > 0)
+ {
+ totalGain += curGain * gPokeblockFlavorCompatibilityTable[5 * nature + flavor];
+ }
+ }
+ return totalGain;
+}
+
+void sub_810CB44(struct Pokeblock *pokeblock, u8 *dest)
+{
+ u8 color = sub_810CA9C(pokeblock, 0);
+ StringCopy(dest, gPokeblockNames[color]);
+}
+
+bool8 sub_810CB68(u8 nature, u8 *dest)
+{
+ u8 flavor;
+ for (flavor=0; flavor<5; flavor++)
+ {
+ if (sub_810CAE4(nature, &gUnknown_083F7F9C[flavor]) > 0)
+ {
+ StringCopy(dest, gPokeblockNames[flavor + 1]);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
diff --git a/src/pokemon_2.c b/src/pokemon_2.c
index 5acdae4d3..543b032e2 100644
--- a/src/pokemon_2.c
+++ b/src/pokemon_2.c
@@ -38,7 +38,12 @@ extern struct PokemonStorage gPokemonStorage;
extern u8 gBadEggNickname[];
extern const struct SpriteTemplate gSpriteTemplate_8208288[];
//array of pointers to arrays of pointers to union AnimCmd (We probably need to typedef this.)
-extern u8 gSecretBaseTrainerClasses[];
+extern u8 gTrainerClassToPicIndex[];
+extern u8 gTrainerClassToNameIndex[];
+extern u8 gSecretBaseTrainerClasses[][5];
+extern u8 gUnknown_08208238[];
+extern u8 gUnknown_0820823C[];
+extern u8 gStatStageRatios[][2];
extern u8 gHoldEffectToType[][2];
u8 CountAliveMons(u8 a1)
@@ -1184,13 +1189,13 @@ void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord)
u8 GetSecretBaseTrainerPicIndex(void)
{
- u8 trainerClass = gSecretBaseTrainerClasses[(gSecretBaseRecord.trainerId[0] % 5) + (5 * gSecretBaseRecord.gender)];
+ u8 trainerClass = gSecretBaseTrainerClasses[gSecretBaseRecord.gender][gSecretBaseRecord.trainerId[0] % 5];
return gTrainerClassToPicIndex[trainerClass];
}
u8 GetSecretBaseTrainerNameIndex(void)
{
- u8 trainerClass = gSecretBaseTrainerClasses[(gSecretBaseRecord.trainerId[0] % 5) + (5 * gSecretBaseRecord.gender)];
+ u8 trainerClass = gSecretBaseTrainerClasses[gSecretBaseRecord.gender][gSecretBaseRecord.trainerId[0] % 5];
return gTrainerClassToNameIndex[trainerClass];
}
diff --git a/src/pokemon_3.c b/src/pokemon_3.c
index cb8eb2a46..3d85a1c8f 100644
--- a/src/pokemon_3.c
+++ b/src/pokemon_3.c
@@ -23,28 +23,6 @@
#include "text.h"
#include "util.h"
-#define EVO_FRIENDSHIP 0x0001 // Pokémon levels up with friendship ≥ 220
-#define EVO_FRIENDSHIP_DAY 0x0002 // Pokémon levels up during the day with friendship ≥ 220
-#define EVO_FRIENDSHIP_NIGHT 0x0003 // Pokémon levels up at night with friendship ≥ 220
-#define EVO_LEVEL 0x0004 // Pokémon reaches the specified level
-#define EVO_TRADE 0x0005 // Pokémon is traded
-#define EVO_TRADE_ITEM 0x0006 // Pokémon is traded while it's holding the specified item
-#define EVO_ITEM 0x0007 // specified item is used on Pokémon
-#define EVO_LEVEL_ATK_GT_DEF 0x0008 // Pokémon reaches the specified level with attack > defense
-#define EVO_LEVEL_ATK_EQ_DEF 0x0009 // Pokémon reaches the specified level with attack = defense
-#define EVO_LEVEL_ATK_LT_DEF 0x000a // Pokémon reaches the specified level with attack < defense
-#define EVO_LEVEL_SILCOON 0x000b // Pokémon reaches the specified level with a Silcoon personality value
-#define EVO_LEVEL_CASCOON 0x000c // Pokémon reaches the specified level with a Cascoon personality value
-#define EVO_LEVEL_NINJASK 0x000d // Pokémon reaches the specified level (special value for Ninjask)
-#define EVO_LEVEL_SHEDINJA 0x000e // Pokémon reaches the specified level (special value for Shedinja)
-#define EVO_BEAUTY 0x000f // Pokémon levels up with beauty ≥ specified value
-
-struct SpindaSpot
-{
- u8 x, y;
- u16 image[16];
-};
-
extern u8 gPlayerPartyCount;
extern u8 gEnemyPartyCount;
extern struct BattlePokemon gBattleMons[4];
@@ -70,7 +48,7 @@ extern u32 gTMHMLearnsets[][2];
extern u8 gBattleMonForms[];
extern const u8 BattleText_Wally[];
extern const u16 gHMMoves[];
-extern s8 gUnknown_083F7E28[];
+extern s8 gPokeblockFlavorCompatibilityTable[];
extern u8 gLastUsedAbility;
extern const u8 BattleText_PreventedSwitch[];
extern u16 gBattlePartyID[];
@@ -103,8 +81,8 @@ bool8 HealStatusConditions(struct Pokemon *mon, u32 unused, u32 healMask, u8 bat
u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
{
- u8 *temp;
- u8 *itemEffect;
+ const u8 *temp;
+ const u8 *itemEffect;
u8 offset;
int i;
u8 j;
@@ -112,7 +90,7 @@ u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
offset = 6;
- temp = (u8 *) gItemEffectTable[itemId - 13];
+ temp = gItemEffectTable[itemId - 13];
if (!temp && itemId != ITEM_ENIGMA_BERRY)
return 0;
@@ -1238,13 +1216,13 @@ bool8 sub_8040A3C(u16 species)
s8 sub_8040A54(struct Pokemon *mon, u8 a2)
{
u8 nature = GetNature(mon);
- return gUnknown_083F7E28[nature * 5 + a2];
+ return gPokeblockFlavorCompatibilityTable[nature * 5 + a2];
}
s8 sub_8040A7C(u32 personality, u8 a2)
{
u8 nature = GetNatureFromPersonality(personality);
- return gUnknown_083F7E28[nature * 5 + a2];
+ return gPokeblockFlavorCompatibilityTable[nature * 5 + a2];
}
bool8 IsTradedMon(struct Pokemon *mon)
@@ -1296,15 +1274,15 @@ void BoxMonRestorePP(struct BoxPokemon *boxMon)
void sub_8040B8C(void)
{
- gLastUsedAbility = BATTLE_STRUCT->filler1_2[0x37];
+ gLastUsedAbility = BATTLE_STRUCT->unk160C0;;
gBattleTextBuff1[0] = 0xFD;
gBattleTextBuff1[1] = 4;
- gBattleTextBuff1[2] = BATTLE_STRUCT->filler1[0x34];
+ gBattleTextBuff1[2] = BATTLE_STRUCT->unk16054;
gBattleTextBuff1[4] = EOS;
- if (!GetBankSide(BATTLE_STRUCT->filler1[0x34]))
- gBattleTextBuff1[3] = pokemon_order_func(gBattlePartyID[BATTLE_STRUCT->filler1[0x34]]);
+ if (!GetBankSide(BATTLE_STRUCT->unk16054))
+ gBattleTextBuff1[3] = pokemon_order_func(gBattlePartyID[BATTLE_STRUCT->unk16054]);
else
- gBattleTextBuff1[3] = gBattlePartyID[BATTLE_STRUCT->filler1[0x34]];
+ gBattleTextBuff1[3] = gBattlePartyID[BATTLE_STRUCT->unk16054];
gBattleTextBuff2[0] = 0xFD;
gBattleTextBuff2[1] = 4;
gBattleTextBuff2[2] = gBankInMenu;
diff --git a/src/pokemon_data.c b/src/pokemon_data.c
new file mode 100644
index 000000000..6414134fb
--- /dev/null
+++ b/src/pokemon_data.c
@@ -0,0 +1,128 @@
+#include "global.h"
+#include "pokemon.h"
+#include "species.h"
+#include "trainer.h"
+#include "abilities.h"
+#include "moves.h"
+#include "hold_effects.h"
+#include "items.h"
+#include "sprite.h"
+#include "data2.h"
+
+#include "data/pokemon/dex_order.h"
+#include "data/pokemon/spinda_spots.h"
+#include "data/pokemon/item_effects.h"
+#include "data/pokemon/nature_stats.h"
+#include "data/pokemon/tmhm_learnsets.h"
+#include "data/pokemon/trainer_class_lookups.h"
+#include "data/pokemon/cry_ids.h"
+#include "data/pokemon/experience_tables.h"
+#include "data/pokemon/base_stats.h"
+#include "data/pokemon/level_up_learnsets.h"
+#include "data/pokemon/evolution.h"
+#include "data/pokemon/level_up_learnset_pointers.h"
+
+const u8 gUnknown_08208238[] = { // Masks for getting PP Up count, also PP Max values
+ 0x03, 0x0c, 0x30, 0xc0
+};
+
+const u8 gUnknown_0820823C[] = { // Masks for setting PP Up count
+ 0xFC, 0xF3, 0xCF, 0x3F
+};
+
+const u8 gUnknown_08208240[] = { // Values added to PP Up count
+ 0x01, 0x04, 0x10, 0x40
+};
+
+const u8 gStatStageRatios[][2] = {
+ {10, 40}, // -6
+ {10, 35}, // -5
+ {10, 30}, // -4
+ {10, 25}, // -3
+ {10, 20}, // -2
+ {10, 15}, // -1
+ {10, 10}, // 0
+ {15, 10}, // 1
+ {20, 10}, // 2
+ {25, 10}, // 3
+ {30, 10}, // 4
+ {35, 10}, // 5
+ {40, 10} // 6
+};
+
+const u8 unknownGameFreakAbbrev_820825E[] = _("ゲーフリ");
+
+const u8 gHoldEffectToType[][2] = {
+ {HOLD_EFFECT_BUG_POWER, TYPE_BUG},
+ {HOLD_EFFECT_STEEL_POWER, TYPE_STEEL},
+ {HOLD_EFFECT_GROUND_POWER, TYPE_GROUND},
+ {HOLD_EFFECT_ROCK_POWER, TYPE_ROCK},
+ {HOLD_EFFECT_GRASS_POWER, TYPE_GRASS},
+ {HOLD_EFFECT_DARK_POWER, TYPE_DARK},
+ {HOLD_EFFECT_FIGHTING_POWER, TYPE_FIGHTING},
+ {HOLD_EFFECT_ELECTRIC_POWER, TYPE_ELECTRIC},
+ {HOLD_EFFECT_WATER_POWER, TYPE_WATER},
+ {HOLD_EFFECT_FLYING_POWER, TYPE_FLYING},
+ {HOLD_EFFECT_POISON_POWER, TYPE_POISON},
+ {HOLD_EFFECT_ICE_POWER, TYPE_ICE},
+ {HOLD_EFFECT_GHOST_POWER, TYPE_GHOST},
+ {HOLD_EFFECT_PSYCHIC_POWER, TYPE_PSYCHIC},
+ {HOLD_EFFECT_FIRE_POWER, TYPE_FIRE},
+ {HOLD_EFFECT_DRAGON_POWER, TYPE_DRAGON},
+ {HOLD_EFFECT_NORMAL_POWER, TYPE_NORMAL}
+};
+
+extern void sub_80105A0(struct Sprite *);
+extern void oac_poke_opponent(struct Sprite *);
+
+const struct SpriteTemplate gSpriteTemplate_8208288[] = {
+ {0xFFFF, 0, &gOamData_81F96F0, NULL, gSpriteImageTable_81E7A10, gSpriteAffineAnimTable_81E7B70, sub_80105A0},
+ {0xFFFF, 0, &gOamData_81F96E8, NULL, gSpriteImageTable_81E7A30, gSpriteAffineAnimTable_81E7BEC, oac_poke_opponent},
+ {0xFFFF, 0, &gOamData_81F96F0, NULL, gSpriteImageTable_81E7A50, gSpriteAffineAnimTable_81E7B70, sub_80105A0},
+ {0xFFFF, 0, &gOamData_81F96E8, NULL, gSpriteImageTable_81E7A70, gSpriteAffineAnimTable_81E7BEC, oac_poke_opponent},
+};
+
+const u8 gSecretBaseTrainerClasses[][5] = {
+ // male
+ {TRAINER_CLASS_YOUNGSTER, TRAINER_CLASS_BUG_CATCHER, TRAINER_CLASS_RICH_BOY, TRAINER_CLASS_CAMPER, TRAINER_CLASS_COOL_TRAINER_M},
+ // female
+ {TRAINER_CLASS_LASS, TRAINER_CLASS_SCHOOL_KID_F, TRAINER_CLASS_LADY, TRAINER_CLASS_PICNICKER, TRAINER_CLASS_COOL_TRAINER_F}
+};
+
+const u8 gUnknown_082082F2[] = {
+ MON_DATA_HP_EV,
+ MON_DATA_ATK_EV,
+ MON_DATA_DEF_EV,
+ MON_DATA_SPD_EV,
+ MON_DATA_SPDEF_EV,
+ MON_DATA_SPATK_EV
+};
+
+const u8 gUnknown_082082F8[] = {1, 1, 3, 2, 4, 6};
+
+const s8 gUnknown_082082FE[][3] = {
+ // Happiness deltas
+ { 5, 3, 2},
+ { 5, 3, 2},
+ { 1, 1, 0},
+ { 3, 2, 1},
+ { 1, 1, 0},
+ { 1, 1, 1},
+ {-1, -1, -1},
+ {-5, -5, -10},
+ {-5, -5, -10}
+};
+
+const u16 gHMMoves[] = {
+ MOVE_CUT,
+ MOVE_FLY,
+ MOVE_SURF,
+ MOVE_STRENGTH,
+ MOVE_FLASH,
+ MOVE_ROCK_SMASH,
+ MOVE_WATERFALL,
+ MOVE_DIVE,
+ 0xffff
+};
+
+const u8 gJapaneseNidoranNames[][11] = {_("ニドラン♂"), _("ニドラン♀")};
diff --git a/src/rom4.c b/src/rom4.c
index 2ddd5ed9f..bfc8e0e44 100644
--- a/src/rom4.c
+++ b/src/rom4.c
@@ -1672,7 +1672,7 @@ void mli4_mapscripts_and_other(void)
void sub_8054E20(void)
{
sub_805B710(0, 0);
- sub_80C8080();
+ RotatingGate_InitPuzzleAndGraphics();
}
void sub_8054E34(void)
diff --git a/src/rotating_gate.c b/src/rotating_gate.c
new file mode 100644
index 000000000..d12a21240
--- /dev/null
+++ b/src/rotating_gate.c
@@ -0,0 +1,1228 @@
+#include "global.h"
+#include "bike.h"
+#include "event_data.h"
+#include "field_map_obj.h"
+#include "fieldmap.h"
+#include "map_constants.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+
+#define ROTATING_GATE_TILE_TAG 0x1300
+#define ROTATING_GATE_PUZZLE_MAX 14
+#define GATE_ARM_MAX_LENGTH 2
+
+#define GATE_ROTATION(rotationDirection, arm, longArm) \
+ ((rotationDirection & 15) << 4) | ((arm & 7) << 1) | (longArm & 1)
+#define GATE_ROTATION_CLOCKWISE(arm, longArm) GATE_ROTATION(ROTATE_CLOCKWISE, arm, longArm)
+#define GATE_ROTATION_ANTICLOCKWISE(arm, longArm) GATE_ROTATION(ROTATE_ANTICLOCKWISE, arm, longArm)
+#define GATE_ROTATION_NONE 255
+
+static void SpriteCallback_RotatingGate(struct Sprite *sprite);
+static u8 RotatingGate_CreateGate(u8 gateId, s16 deltaX, s16 deltaY);
+static void RotatingGate_HideGatesOutsideViewport(struct Sprite *sprite);
+
+enum
+{
+ /*
+ * |
+ * +--
+ */
+ GATE_SHAPE_L1,
+
+ /*
+ * |
+ * |
+ * +--
+ */
+ GATE_SHAPE_L2,
+
+ /*
+ * |
+ * +----
+ */
+ GATE_SHAPE_L3,
+
+ /*
+ * |
+ * |
+ * +----
+ */
+ GATE_SHAPE_L4,
+
+ /*
+ * |
+ * +--
+ * |
+ */
+ GATE_SHAPE_T1,
+
+ /*
+ * |
+ * |
+ * +--
+ * |
+ */
+ GATE_SHAPE_T2,
+
+ /*
+ * |
+ * +----
+ * |
+ */
+ GATE_SHAPE_T3,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * +--
+ * |
+ * |
+ */
+ GATE_SHAPE_T4,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * |
+ * +----
+ * |
+ */
+ GATE_SHAPE_UNUSED_T1,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * |
+ * +--
+ * |
+ * |
+ */
+ GATE_SHAPE_UNUSED_T2,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * +----
+ * |
+ * |
+ */
+ GATE_SHAPE_UNUSED_T3,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * |
+ * +----
+ * |
+ * |
+ */
+ GATE_SHAPE_UNUSED_T4,
+};
+
+enum
+{
+ /*
+ * 0 degrees (clockwise)
+ * |
+ * +--
+ * |
+ */
+ GATE_ORIENTATION_0,
+
+ /*
+ * 90 degress (clockwise)
+ * --+--
+ * |
+ */
+ GATE_ORIENTATION_90,
+
+ /*
+ * 180 degrees (clockwise)
+ * |
+ * --+
+ * |
+ */
+ GATE_ORIENTATION_180,
+
+ /*
+ * 270 degrees (clockwise)
+ * |
+ * --+--
+ */
+ GATE_ORIENTATION_270,
+
+ GATE_ORIENTATION_MAX,
+};
+
+// Describes the location of the gates "arms" when the gate has not
+// been rotated (i.e. rotated 0 degrees)
+enum
+{
+ GATE_ARM_NORTH,
+ GATE_ARM_EAST,
+ GATE_ARM_SOUTH,
+ GATE_ARM_WEST,
+};
+
+enum
+{
+ ROTATE_NONE,
+ ROTATE_ANTICLOCKWISE,
+ ROTATE_CLOCKWISE,
+};
+
+enum
+{
+ PUZZLE_NONE,
+ PUZZLE_FORTREE_CITY_GYM,
+ PUZZLE_ROUTE110_TRICK_HOUSE_PUZZLE6,
+};
+
+struct RotatingGatePuzzle
+{
+ struct Coords16 pos;
+ u8 shape;
+ u8 orientation;
+};
+
+struct Coords8
+{
+ s8 deltaX;
+ s8 deltaY;
+};
+
+// Fortree
+static const struct RotatingGatePuzzle sRotatingGate_FortreePuzzleConfig[] = {
+ { { 12, 5 }, GATE_SHAPE_L4, GATE_ORIENTATION_0 },
+ { { 14, 7 }, GATE_SHAPE_L4, GATE_ORIENTATION_270 },
+ { { 16, 4 }, GATE_SHAPE_T2, GATE_ORIENTATION_90 },
+ { { 15, 14 }, GATE_SHAPE_L2, GATE_ORIENTATION_0 },
+ { { 18, 13 }, GATE_SHAPE_T1, GATE_ORIENTATION_180 },
+ { { 8, 20 }, GATE_SHAPE_T1, GATE_ORIENTATION_180 },
+ { { 16, 20 }, GATE_SHAPE_T4, GATE_ORIENTATION_90 },
+};
+
+// Trickhouse
+static const struct RotatingGatePuzzle sRotatingGate_TrickHousePuzzleConfig[] = {
+ { { 13, 3 }, GATE_SHAPE_T1, GATE_ORIENTATION_270 },
+ { { 12, 6 }, GATE_SHAPE_T1, GATE_ORIENTATION_180 },
+ { { 3, 6 }, GATE_SHAPE_T1, GATE_ORIENTATION_180 },
+ { { 3, 9 }, GATE_SHAPE_T2, GATE_ORIENTATION_270 },
+ { { 8, 8 }, GATE_SHAPE_L1, GATE_ORIENTATION_90 },
+ { { 2, 12 }, GATE_SHAPE_T3, GATE_ORIENTATION_180 },
+ { { 9, 13 }, GATE_SHAPE_L2, GATE_ORIENTATION_0 },
+ { { 3, 14 }, GATE_SHAPE_L3, GATE_ORIENTATION_90 },
+ { { 9, 15 }, GATE_SHAPE_L4, GATE_ORIENTATION_180 },
+ { { 3, 18 }, GATE_SHAPE_T2, GATE_ORIENTATION_180 },
+ { { 2, 19 }, GATE_SHAPE_T1, GATE_ORIENTATION_0 },
+ { { 5, 21 }, GATE_SHAPE_L1, GATE_ORIENTATION_0 },
+ { { 9, 19 }, GATE_SHAPE_L4, GATE_ORIENTATION_270 },
+ { { 12, 20 }, GATE_SHAPE_T1, GATE_ORIENTATION_90 },
+};
+
+static const u8 sRotatingGateTiles_1[] = INCBIN_U8("graphics/rotating_gates/1.4bpp");
+static const u8 sRotatingGateTiles_2[] = INCBIN_U8("graphics/rotating_gates/2.4bpp");
+static const u8 sRotatingGateTiles_3[] = INCBIN_U8("graphics/rotating_gates/3.4bpp");
+static const u8 sRotatingGateTiles_5[] = INCBIN_U8("graphics/rotating_gates/5.4bpp");
+static const u8 sRotatingGateTiles_6[] = INCBIN_U8("graphics/rotating_gates/6.4bpp");
+static const u8 sRotatingGateTiles_7[] = INCBIN_U8("graphics/rotating_gates/7.4bpp");
+static const u8 sRotatingGateTiles_0[] = INCBIN_U8("graphics/rotating_gates/0.4bpp");
+static const u8 sRotatingGateTiles_4[] = INCBIN_U8("graphics/rotating_gates/4.4bpp");
+
+static const struct OamData sOamData_RotatingGateLarge = {
+ .y = 0,
+ .affineMode = ST_OAM_AFFINE_NORMAL,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = ST_OAM_4BPP,
+ .shape = ST_OAM_SQUARE,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 5,
+ .affineParam = 0,
+};
+
+static const struct OamData sOamData_RotatingGateRegular = {
+ .y = 0,
+ .affineMode = ST_OAM_AFFINE_NORMAL,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = ST_OAM_4BPP,
+ .shape = ST_OAM_SQUARE,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 5,
+ .affineParam = 0,
+};
+
+static const struct SpriteSheet sRotatingGatesGraphicsTable[] = {
+ { sRotatingGateTiles_0, 0x200, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L1 },
+ { sRotatingGateTiles_1, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L2 },
+ { sRotatingGateTiles_2, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L3 },
+ { sRotatingGateTiles_3, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L4 },
+ { sRotatingGateTiles_4, 0x200, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T1 },
+ { sRotatingGateTiles_5, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T2 },
+ { sRotatingGateTiles_6, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T3 },
+ { sRotatingGateTiles_7, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T4 },
+ { NULL },
+};
+
+static const union AnimCmd sSpriteAnim_RotatingGateLarge[] = {
+ ANIMCMD_FRAME(0, 0), ANIMCMD_END,
+};
+
+static const union AnimCmd sSpriteAnim_RotatingGateRegular[] = {
+ ANIMCMD_FRAME(0, 0), ANIMCMD_END,
+};
+
+static const union AnimCmd *const sSpriteAnimTable_RotatingGateLarge[] = {
+ sSpriteAnim_RotatingGateLarge,
+};
+
+static const union AnimCmd *const sSpriteAnimTable_RotatingGateRegular[] = {
+ sSpriteAnim_RotatingGateRegular,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_Rotated0[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_Rotated90[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0), AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_Rotated180[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0), AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_Rotated270[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0), AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise0to90[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise90to180[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise180to270[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise270to360[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise360to270[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise270to180[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise180to90[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise90to0[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise0to90Faster[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise90to180Faster[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise180to270Faster[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise270to360Faster[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise360to270Faster[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 8), AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise270to180Faster[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise180to90Faster[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise90to0Faster[] = {
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_RotatingGate[] = {
+ sSpriteAffineAnim_Rotated0,
+ sSpriteAffineAnim_Rotated90,
+ sSpriteAffineAnim_Rotated180,
+ sSpriteAffineAnim_Rotated270,
+ sSpriteAffineAnim_RotatingAnticlockwise360to270,
+ sSpriteAffineAnim_RotatingAnticlockwise90to0,
+ sSpriteAffineAnim_RotatingAnticlockwise180to90,
+ sSpriteAffineAnim_RotatingAnticlockwise270to180,
+ sSpriteAffineAnim_RotatingClockwise0to90,
+ sSpriteAffineAnim_RotatingClockwise90to180,
+ sSpriteAffineAnim_RotatingClockwise180to270,
+ sSpriteAffineAnim_RotatingClockwise270to360,
+ sSpriteAffineAnim_RotatingAnticlockwise360to270Faster,
+ sSpriteAffineAnim_RotatingAnticlockwise90to0Faster,
+ sSpriteAffineAnim_RotatingAnticlockwise180to90Faster,
+ sSpriteAffineAnim_RotatingAnticlockwise270to180Faster,
+ sSpriteAffineAnim_RotatingClockwise0to90Faster,
+ sSpriteAffineAnim_RotatingClockwise90to180Faster,
+ sSpriteAffineAnim_RotatingClockwise180to270Faster,
+ sSpriteAffineAnim_RotatingClockwise270to360Faster,
+};
+
+static const struct SpriteTemplate sSpriteTemplate_RotatingGateLarge = {
+ .tileTag = ROTATING_GATE_TILE_TAG,
+ .paletteTag = 0xFFFF,
+ .oam = &sOamData_RotatingGateLarge,
+ .anims = sSpriteAnimTable_RotatingGateLarge,
+ .images = NULL,
+ .affineAnims = sSpriteAffineAnimTable_RotatingGate,
+ .callback = SpriteCallback_RotatingGate,
+};
+
+static const struct SpriteTemplate sSpriteTemplate_RotatingGateRegular = {
+ .tileTag = ROTATING_GATE_TILE_TAG,
+ .paletteTag = 0xFFFF,
+ .oam = &sOamData_RotatingGateRegular,
+ .anims = sSpriteAnimTable_RotatingGateRegular,
+ .images = NULL,
+ .affineAnims = sSpriteAffineAnimTable_RotatingGate,
+ .callback = SpriteCallback_RotatingGate,
+};
+
+// These structures describe what happens to the gate if you hit it at
+// a given coordinate in a 4x4 grid when walking in the specified
+// direction. Either the gate does not rotate, or it rotates in the
+// given direction. This information is compared against the gate
+// "arm" layout to see if there is an arm at the position in order to
+// produce the final rotation.
+static const u8 sRotatingGate_RotationInfoNorth[4][4] = {
+ { GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE },
+ { GATE_ROTATION_CLOCKWISE(GATE_ARM_WEST, 1),
+ GATE_ROTATION_CLOCKWISE(GATE_ARM_WEST, 0),
+ GATE_ROTATION_ANTICLOCKWISE(GATE_ARM_EAST, 0),
+ GATE_ROTATION_ANTICLOCKWISE(GATE_ARM_EAST, 1) },
+ { GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE },
+ { GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE },
+};
+
+static const u8 sRotatingGate_RotationInfoSouth[4][4] = {
+ { GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE },
+ { GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE },
+ { GATE_ROTATION_ANTICLOCKWISE(GATE_ARM_WEST, 1),
+ GATE_ROTATION_ANTICLOCKWISE(GATE_ARM_WEST, 0),
+ GATE_ROTATION_CLOCKWISE(GATE_ARM_EAST, 0),
+ GATE_ROTATION_CLOCKWISE(GATE_ARM_EAST, 1) },
+ { GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE, GATE_ROTATION_NONE },
+};
+
+static const u8 sRotatingGate_RotationInfoWest[4][4] = {
+ { GATE_ROTATION_NONE,
+ GATE_ROTATION_ANTICLOCKWISE(GATE_ARM_NORTH, 1),
+ GATE_ROTATION_NONE,
+ GATE_ROTATION_NONE },
+ { GATE_ROTATION_NONE,
+ GATE_ROTATION_ANTICLOCKWISE(GATE_ARM_NORTH, 0),
+ GATE_ROTATION_NONE,
+ GATE_ROTATION_NONE },
+ { GATE_ROTATION_NONE,
+ GATE_ROTATION_CLOCKWISE(GATE_ARM_SOUTH, 0),
+ GATE_ROTATION_NONE,
+ GATE_ROTATION_NONE },
+ { GATE_ROTATION_NONE,
+ GATE_ROTATION_CLOCKWISE(GATE_ARM_SOUTH, 1),
+ GATE_ROTATION_NONE,
+ GATE_ROTATION_NONE },
+};
+
+static const u8 sRotatingGate_RotationInfoEast[4][4] = {
+ { GATE_ROTATION_NONE,
+ GATE_ROTATION_NONE,
+ GATE_ROTATION_CLOCKWISE(GATE_ARM_NORTH, 1),
+ GATE_ROTATION_NONE },
+ { GATE_ROTATION_NONE,
+ GATE_ROTATION_NONE,
+ GATE_ROTATION_CLOCKWISE(GATE_ARM_NORTH, 0),
+ GATE_ROTATION_NONE },
+ { GATE_ROTATION_NONE,
+ GATE_ROTATION_NONE,
+ GATE_ROTATION_ANTICLOCKWISE(GATE_ARM_SOUTH, 0),
+ GATE_ROTATION_NONE },
+ { GATE_ROTATION_NONE,
+ GATE_ROTATION_NONE,
+ GATE_ROTATION_ANTICLOCKWISE(GATE_ARM_SOUTH, 1),
+ GATE_ROTATION_NONE },
+};
+
+// These tables describe the relative coordinate positions the arms
+// must move through in order to be rotated.
+static const struct Coords8 sRotatingGate_ArmPositionsClockwiseRotation[] = {
+ { 0, -1 }, { 1, -2 }, { 0, 0 }, { 1, 0 }, { -1, 0 }, { -1, 1 }, { -1, -1 }, { -2, -1 },
+};
+
+static const struct Coords8 sRotatingGate_ArmPositionsAntiClockwiseRotation[] = {
+ { -1, -1 }, { -1, -2 }, { 0, -1 }, { 1, -1 }, { 0, 0 }, { 0, 1 }, { -1, 0 }, { -2, 0 },
+};
+
+// Describes where the gates "arms" are in the order north, east, south, west.
+// These are adjusted using the current orientation to perform collision checking
+static const u8 sRotatingGate_ArmLayout[][GATE_ARM_WEST + 1][GATE_ARM_MAX_LENGTH] = {
+ // L-shape gates
+ {
+ { 1, 0 }, { 1, 0 }, { 0, 0 }, { 0, 0 },
+ },
+ {
+ { 1, 1 }, { 1, 0 }, { 0, 0 }, { 0, 0 },
+ },
+ {
+ { 1, 0 }, { 1, 1 }, { 0, 0 }, { 0, 0 },
+ },
+ {
+ { 1, 1 }, { 1, 1 }, { 0, 0 }, { 0, 0 },
+ },
+
+ // T-shape gates
+ {
+ { 1, 0 }, { 1, 0 }, { 1, 0 }, { 0, 0 },
+ },
+ {
+ { 1, 1 }, { 1, 0 }, { 1, 0 }, { 0, 0 },
+ },
+ {
+ { 1, 0 }, { 1, 1 }, { 1, 0 }, { 0, 0 },
+ },
+ {
+ { 1, 0 }, { 1, 0 }, { 1, 1 }, { 0, 0 },
+ },
+
+ // Unused T-shape gates
+ // These have 2-3 long arms and cannot actually be used anywhere
+ // since configuration for them is missing from the other tables.
+ {
+ { 1, 1 }, { 1, 1 }, { 1, 0 }, { 0, 0 },
+ },
+ {
+ { 1, 1 }, { 1, 0 }, { 1, 1 }, { 0, 0 },
+ },
+ {
+ { 1, 0 }, { 1, 1 }, { 1, 1 }, { 0, 0 },
+ },
+ {
+ { 1, 1 }, { 1, 1 }, { 1, 1 }, { 0, 0 },
+ },
+};
+
+extern u8 gRotatingGate_GateSpriteIds[ROTATING_GATE_PUZZLE_MAX];
+extern const struct RotatingGatePuzzle *gRotatingGate_PuzzleConfig;
+extern u8 gRotatingGate_PuzzleCount;
+
+static int GetCurrentMapRotatingGatePuzzleType(void)
+{
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_FORTREE_CITY_GYM &&
+ gSaveBlock1.location.mapNum == MAP_ID_FORTREE_CITY_GYM)
+ {
+ return PUZZLE_FORTREE_CITY_GYM;
+ }
+
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_ROUTE110_TRICK_HOUSE_PUZZLE6 &&
+ gSaveBlock1.location.mapNum == MAP_ID_ROUTE110_TRICK_HOUSE_PUZZLE6)
+ {
+ return PUZZLE_ROUTE110_TRICK_HOUSE_PUZZLE6;
+ }
+
+ return PUZZLE_NONE;
+}
+
+static void RotatingGate_ResetAllGateOrientations(void)
+{
+ int i;
+ u8 *ptr;
+
+ ptr = (u8 *)GetVarPointer(0x4000);
+
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ ptr[i] = gRotatingGate_PuzzleConfig[i].orientation;
+ }
+}
+
+static int RotatingGate_GetGateOrientation(u8 gateId)
+{
+ return ((u8 *)GetVarPointer(0x4000))[gateId];
+}
+
+static void RotatingGate_SetGateOrientation(u8 gateId, u8 orientation)
+{
+ ((u8 *)GetVarPointer(0x4000))[gateId] = orientation;
+}
+
+static void RotatingGate_RotateInDirection(u8 gateId, u32 rotationDirection)
+{
+ u8 orientation = RotatingGate_GetGateOrientation(gateId);
+
+ if (rotationDirection == ROTATE_ANTICLOCKWISE)
+ {
+ if (orientation)
+ {
+ orientation--;
+ }
+ else
+ {
+ orientation = GATE_ORIENTATION_270;
+ }
+ }
+ else
+ {
+ orientation = ++orientation % GATE_ORIENTATION_MAX;
+ }
+
+ RotatingGate_SetGateOrientation(gateId, orientation);
+}
+
+static void RotatingGate_LoadPuzzleConfig(void)
+{
+ int puzzleType = GetCurrentMapRotatingGatePuzzleType();
+ u32 i;
+
+ switch (puzzleType)
+ {
+ case PUZZLE_FORTREE_CITY_GYM:
+ gRotatingGate_PuzzleConfig = sRotatingGate_FortreePuzzleConfig;
+ gRotatingGate_PuzzleCount =
+ sizeof(sRotatingGate_FortreePuzzleConfig) / sizeof(struct RotatingGatePuzzle);
+ break;
+ case PUZZLE_ROUTE110_TRICK_HOUSE_PUZZLE6:
+ gRotatingGate_PuzzleConfig = sRotatingGate_TrickHousePuzzleConfig;
+ gRotatingGate_PuzzleCount =
+ sizeof(sRotatingGate_TrickHousePuzzleConfig) / sizeof(struct RotatingGatePuzzle);
+ break;
+ case PUZZLE_NONE:
+ default:
+ return;
+ }
+
+ for (i = 0; i < ROTATING_GATE_PUZZLE_MAX; i++)
+ {
+ gRotatingGate_GateSpriteIds[i] = MAX_SPRITES;
+ }
+}
+
+static void RotatingGate_CreateGatesWithinViewport(s16 deltaX, s16 deltaY)
+{
+ u8 i;
+
+ // Calculate the bounding box of the camera
+ // Same as RotatingGate_DestroyGatesOutsideViewport
+ s16 x = gSaveBlock1.pos.x - 2;
+ s16 x2 = gSaveBlock1.pos.x + 0x11;
+ s16 y = gSaveBlock1.pos.y - 2;
+ s16 y2 = gSaveBlock1.pos.y + 0xe;
+
+ s16 x3, y3;
+
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ x3 = gRotatingGate_PuzzleConfig[i].pos.x + 7;
+ y3 = gRotatingGate_PuzzleConfig[i].pos.y + 7;
+
+ if (y <= y3 && y2 >= y3 && x <= x3 && x2 >= x3 &&
+ gRotatingGate_GateSpriteIds[i] == MAX_SPRITES)
+ {
+ gRotatingGate_GateSpriteIds[i] = RotatingGate_CreateGate(i, deltaX, deltaY);
+ }
+ }
+}
+
+static u8 RotatingGate_CreateGate(u8 gateId, s16 deltaX, s16 deltaY)
+{
+ struct Sprite *sprite;
+ struct SpriteTemplate template;
+ const struct RotatingGatePuzzle *gate;
+ u8 spriteId;
+ s16 x, y;
+
+ gate = &gRotatingGate_PuzzleConfig[gateId];
+
+ if (gate->shape == GATE_SHAPE_L1 || gate->shape == GATE_SHAPE_T1)
+ {
+ template = sSpriteTemplate_RotatingGateRegular;
+ }
+ else
+ {
+ template = sSpriteTemplate_RotatingGateLarge;
+ }
+
+ template.tileTag = gate->shape + ROTATING_GATE_TILE_TAG;
+
+ spriteId = CreateSprite(&template, 0, 0, 0x94);
+ if (spriteId == MAX_SPRITES)
+ {
+ return MAX_SPRITES;
+ }
+
+ x = gate->pos.x + 7;
+ y = gate->pos.y + 7;
+
+ sprite = &gSprites[spriteId];
+ sprite->data0 = gateId;
+ sprite->coordOffsetEnabled = 1;
+
+ sub_8060388(x + deltaX, y + deltaY, &sprite->pos1.x, &sprite->pos1.y);
+ RotatingGate_HideGatesOutsideViewport(sprite);
+ StartSpriteAffineAnim(sprite, RotatingGate_GetGateOrientation(gateId));
+
+ return spriteId;
+}
+
+static void SpriteCallback_RotatingGate(struct Sprite *sprite)
+{
+ u8 rotationDirection;
+ u8 orientation;
+ u8 affineAnimation;
+
+ rotationDirection = sprite->data1;
+ orientation = sprite->data2;
+
+ RotatingGate_HideGatesOutsideViewport(sprite);
+
+ if (rotationDirection == ROTATE_ANTICLOCKWISE)
+ {
+ affineAnimation = orientation + 4;
+
+ if (GetPlayerSpeed() != 1)
+ affineAnimation += 8;
+
+ PlaySE(SE_HI_TURUN);
+ StartSpriteAffineAnim(sprite, affineAnimation);
+ }
+ else if (rotationDirection == ROTATE_CLOCKWISE)
+ {
+ affineAnimation = orientation + 8;
+
+ if (GetPlayerSpeed() != 1)
+ affineAnimation += 8;
+
+ PlaySE(SE_HI_TURUN);
+ StartSpriteAffineAnim(sprite, affineAnimation);
+ }
+
+ sprite->data1 = ROTATE_NONE;
+}
+
+static void RotatingGate_HideGatesOutsideViewport(struct Sprite *sprite)
+{
+ u16 x;
+ s16 x2;
+ u16 y;
+ s16 y2;
+
+ sprite->invisible = 0;
+ x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX + gSpriteCoordOffsetX;
+ y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY;
+
+ x2 = x + 0x40; // Dimensions of the rotating gate
+ y2 = y + 0x40;
+
+ if ((s16)x > DISPLAY_WIDTH + 0x10 - 1 || x2 < -0x10)
+ {
+ sprite->invisible = 1;
+ }
+
+ if ((s16)y > DISPLAY_HEIGHT + 0x10 - 1 || y2 < -0x10)
+ {
+ sprite->invisible = 1;
+ }
+}
+
+static void LoadRotatingGatePics(void)
+{
+ LoadSpriteSheets(sRotatingGatesGraphicsTable);
+}
+
+static void RotatingGate_DestroyGatesOutsideViewport(void)
+{
+ s16 x;
+ s16 x2;
+ s16 y;
+ s16 y2;
+ s16 xGate;
+ s16 yGate;
+ int i;
+ struct Sprite *sprite;
+
+ // Same as RotatingGate_CreateGatesWithinViewport
+ x = gSaveBlock1.pos.x - 2;
+ x2 = gSaveBlock1.pos.x + 0x11;
+ y = gSaveBlock1.pos.y - 2;
+ y2 = gSaveBlock1.pos.y + 0xe;
+
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ xGate = gRotatingGate_PuzzleConfig[i].pos.x + 7;
+ yGate = gRotatingGate_PuzzleConfig[i].pos.y + 7;
+
+ if (gRotatingGate_GateSpriteIds[i] == MAX_SPRITES)
+ continue;
+
+ if (xGate < x || xGate > x2 || yGate < y || yGate > y2)
+ {
+ sprite = &gSprites[gRotatingGate_GateSpriteIds[i]];
+ FreeSpriteOamMatrix(sprite);
+ DestroySprite(sprite);
+ gRotatingGate_GateSpriteIds[i] = MAX_SPRITES;
+ }
+ }
+}
+
+#ifdef NONMATCHING
+static int RotatingGate_CanRotate(u8 gateId, int rotationDirection)
+{
+ const struct Coords8 *armPos;
+ u8 orientation;
+ s16 x;
+ s16 y;
+ int shape;
+ int i;
+ int j;
+ int armOrientation;
+ const u8 *gateArmCollisionData;
+ u8 armIndex;
+
+ if (rotationDirection == ROTATE_ANTICLOCKWISE)
+ armPos = sRotatingGate_ArmPositionsAntiClockwiseRotation;
+ else if (rotationDirection == ROTATE_CLOCKWISE)
+ armPos = sRotatingGate_ArmPositionsClockwiseRotation;
+ else
+ return 0;
+
+ orientation = RotatingGate_GetGateOrientation(gateId);
+
+ shape = gRotatingGate_PuzzleConfig[gateId].shape;
+ x = gRotatingGate_PuzzleConfig[gateId].pos.x + 7;
+ y = gRotatingGate_PuzzleConfig[gateId].pos.y + 7;
+
+ // Loop through the gate's "arms" clockwise (north, south, east, west)
+ for (i = GATE_ARM_NORTH; i <= GATE_ARM_WEST; i++)
+ {
+ armOrientation = orientation + i;
+ gateArmCollisionData = sRotatingGate_ArmLayout[shape][i];
+
+ // Ensure that no part of the arm collides with the map
+ for (j = 0; j < GATE_ARM_MAX_LENGTH; j++)
+ {
+ armIndex = 2 * (armOrientation % 4) + j;
+
+ if (*gateArmCollisionData)
+ {
+ if (MapGridIsImpassableAt(
+ armPos[armIndex].deltaX + x, armPos[armIndex].deltaY + y) == 1)
+ return 0;
+ }
+ gateArmCollisionData++;
+ }
+ }
+
+ return 1;
+}
+#else
+__attribute__((naked)) static int RotatingGate_CanRotate(u8 a, int puzzleType)
+{
+ 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\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ cmp r1, 0x1\n\
+ bne _080C7EAC\n\
+ ldr r0, _080C7EA8 @ =sRotatingGate_ArmPositionsAntiClockwiseRotation\n\
+ mov r10, r0\n\
+ b _080C7EB8\n\
+ .align 2, 0\n\
+_080C7EA8: .4byte sRotatingGate_ArmPositionsAntiClockwiseRotation\n\
+_080C7EAC:\n\
+ cmp r1, 0x2\n\
+ beq _080C7EB4\n\
+_080C7EB0:\n\
+ movs r0, 0\n\
+ b _080C7F48\n\
+_080C7EB4:\n\
+ ldr r1, _080C7F58 @ =sRotatingGate_ArmPositionsClockwiseRotation\n\
+ mov r10, r1\n\
+_080C7EB8:\n\
+ adds r0, r4, 0\n\
+ bl RotatingGate_GetGateOrientation\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ str r0, [sp]\n\
+ ldr r0, _080C7F5C @ =gRotatingGate_PuzzleConfig\n\
+ ldr r1, [r0]\n\
+ lsls r0, r4, 3\n\
+ adds r0, r1\n\
+ ldrb r2, [r0, 0x4]\n\
+ ldrh r1, [r0]\n\
+ adds r1, 0x7\n\
+ ldrh r0, [r0, 0x2]\n\
+ adds r0, 0x7\n\
+ movs r3, 0\n\
+ lsls r2, 3\n\
+ str r2, [sp, 0x4]\n\
+ lsls r1, 16\n\
+ asrs r1, 16\n\
+ mov r9, r1\n\
+ lsls r0, 16\n\
+ asrs r0, 16\n\
+ mov r8, r0\n\
+_080C7EE8:\n\
+ movs r6, 0\n\
+ ldr r2, [sp]\n\
+ adds r7, r2, r3\n\
+ lsls r0, r3, 1\n\
+ adds r5, r7, 0\n\
+ ldr r1, [sp, 0x4]\n\
+ adds r0, r1\n\
+ ldr r2, _080C7F60 @ =sRotatingGate_ArmLayout\n\
+ adds r4, r0, r2\n\
+_080C7EFA:\n\
+ adds r0, r5, 0\n\
+ cmp r5, 0\n\
+ bge _080C7F02\n\
+ adds r0, r7, 0x3\n\
+_080C7F02:\n\
+ asrs r0, 2\n\
+ lsls r0, 2\n\
+ subs r0, r5, r0\n\
+ lsls r0, 1\n\
+ adds r0, r6\n\
+ lsls r0, 24\n\
+ lsrs r1, r0, 24\n\
+ ldrb r0, [r4]\n\
+ cmp r0, 0\n\
+ beq _080C7F38\n\
+ lsls r1, 2\n\
+ add r1, r10\n\
+ movs r0, 0\n\
+ ldrsb r0, [r1, r0]\n\
+ add r0, r9\n\
+ ldrb r1, [r1, 0x1]\n\
+ lsls r1, 24\n\
+ asrs r1, 24\n\
+ add r1, r8\n\
+ str r3, [sp, 0x8]\n\
+ bl MapGridIsImpassableAt\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ ldr r3, [sp, 0x8]\n\
+ cmp r0, 0x1\n\
+ beq _080C7EB0\n\
+_080C7F38:\n\
+ adds r4, 0x1\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x1\n\
+ ble _080C7EFA\n\
+ adds r3, 0x1\n\
+ cmp r3, 0x3\n\
+ ble _080C7EE8\n\
+ movs r0, 0x1\n\
+_080C7F48:\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 {r1}\n\
+ bx r1\n\
+ .align 2, 0\n\
+_080C7F58: .4byte sRotatingGate_ArmPositionsClockwiseRotation\n\
+_080C7F5C: .4byte gRotatingGate_PuzzleConfig\n\
+_080C7F60: .4byte sRotatingGate_ArmLayout\n\
+.syntax divided\n");
+}
+#endif
+
+#ifdef NONMATCHING
+static int RotatingGate_HasArm(u8 gateId, u8 armInfo)
+{
+ int isLongArm;
+ s8 armOrientation;
+ int arm;
+ int shape;
+
+ arm = armInfo >> 1;
+ isLongArm = armInfo & 1;
+
+ armOrientation = (arm - RotatingGate_GetGateOrientation(gateId) + 4) % 4;
+ shape = gRotatingGate_PuzzleConfig[gateId].shape;
+ return sRotatingGate_ArmLayout[shape][armOrientation][isLongArm];
+}
+#else
+__attribute__((naked)) static int RotatingGate_HasArm(u8 a, u8 b)
+{
+ asm(".syntax unified\n\
+ push {r4-r6,lr}\n\
+ adds r4, r1, 0\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ adds r6, r0, 0\n\
+ lsls r4, 24\n\
+ lsrs r5, r4, 24\n\
+ lsrs r4, 25\n\
+ movs r0, 0x1\n\
+ ands r5, r0\n\
+ adds r0, r6, 0\n\
+ bl RotatingGate_GetGateOrientation\n\
+ subs r4, r0\n\
+ adds r1, r4, 0x4\n\
+ adds r0, r1, 0\n\
+ cmp r1, 0\n\
+ bge _080C7F8A\n\
+ adds r0, r4, 0x7\n\
+_080C7F8A:\n\
+ asrs r0, 2\n\
+ lsls r0, 2\n\
+ subs r0, r1, r0\n\
+ ldr r1, _080C7FB0 @ =gRotatingGate_PuzzleConfig\n\
+ ldr r2, [r1]\n\
+ lsls r1, r6, 3\n\
+ adds r1, r2\n\
+ ldrb r1, [r1, 0x4]\n\
+ ldr r2, _080C7FB4 @ =sRotatingGate_ArmLayout\n\
+ lsls r0, 24\n\
+ asrs r0, 23\n\
+ adds r0, r5\n\
+ lsls r1, 3\n\
+ adds r0, r1\n\
+ adds r0, r2\n\
+ ldrb r0, [r0]\n\
+ pop {r4-r6}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .align 2, 0\n\
+_080C7FB0: .4byte gRotatingGate_PuzzleConfig\n\
+_080C7FB4: .4byte sRotatingGate_ArmLayout\n\
+.syntax divided\n");
+}
+#endif
+
+static void RotatingGate_TriggerRotationAnimation(u8 gateId, int rotationDirection)
+{
+ struct Sprite *sprite;
+
+ if (gRotatingGate_GateSpriteIds[gateId] != MAX_SPRITES)
+ {
+ sprite = &gSprites[gRotatingGate_GateSpriteIds[gateId]];
+ sprite->data1 = rotationDirection;
+ sprite->data2 = RotatingGate_GetGateOrientation(gateId);
+ }
+}
+
+#ifdef NONMATCHING
+static u8 RotatingGate_GetRotationInfo(u8 direction, s16 x, s16 y)
+{
+ register const u8(*ptr)[][4] asm("r3");
+
+ if (direction == DIR_NORTH)
+ ptr = &sRotatingGate_RotationInfoNorth;
+ else if (direction == DIR_SOUTH)
+ ptr = &sRotatingGate_RotationInfoSouth;
+ else if (direction == DIR_WEST)
+ ptr = &sRotatingGate_RotationInfoWest;
+ else if (direction == DIR_EAST)
+ ptr = &sRotatingGate_RotationInfoEast;
+ else
+ return GATE_ROTATION_NONE;
+
+ return (*ptr)[y][x];
+}
+#else
+__attribute__((naked)) static u8 RotatingGate_GetRotationInfo(u8 a, s16 b, s16 c)
+{
+ asm(".syntax unified\n\
+ push {lr}\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ adds r3, r0, 0\n\
+ lsls r1, 16\n\
+ lsrs r1, 16\n\
+ lsls r2, 16\n\
+ lsrs r2, 16\n\
+ cmp r0, 0x2\n\
+ bne _080C8008\n\
+ ldr r3, _080C8004 @ =sRotatingGate_RotationInfoNorth\n\
+ b _080C802A\n\
+ .align 2, 0\n\
+_080C8004: .4byte sRotatingGate_RotationInfoNorth\n\
+_080C8008:\n\
+ cmp r0, 0x1\n\
+ bne _080C8014\n\
+ ldr r3, _080C8010 @ =sRotatingGate_RotationInfoSouth\n\
+ b _080C802A\n\
+ .align 2, 0\n\
+_080C8010: .4byte sRotatingGate_RotationInfoSouth\n\
+_080C8014:\n\
+ cmp r0, 0x3\n\
+ bne _080C8020\n\
+ ldr r3, _080C801C @ =sRotatingGate_RotationInfoWest\n\
+ b _080C802A\n\
+ .align 2, 0\n\
+_080C801C: .4byte sRotatingGate_RotationInfoWest\n\
+_080C8020:\n\
+ cmp r3, 0x4\n\
+ beq _080C8028\n\
+ movs r0, 0xFF\n\
+ b _080C8038\n\
+_080C8028:\n\
+ ldr r3, _080C803C @ =sRotatingGate_RotationInfoEast\n\
+_080C802A:\n\
+ lsls r0, r2, 16\n\
+ lsls r1, 16\n\
+ asrs r1, 16\n\
+ asrs r0, 14\n\
+ adds r0, r1\n\
+ adds r0, r3, r0\n\
+ ldrb r0, [r0]\n\
+_080C8038:\n\
+ pop {r1}\n\
+ bx r1\n\
+ .align 2, 0\n\
+_080C803C: .4byte sRotatingGate_RotationInfoEast\n\
+.syntax divided\n");
+}
+#endif
+
+void RotatingGate_InitPuzzle(void)
+{
+ if (GetCurrentMapRotatingGatePuzzleType())
+ {
+ RotatingGate_LoadPuzzleConfig();
+ RotatingGate_ResetAllGateOrientations();
+ }
+}
+
+void RotatingGatePuzzleCameraUpdate(u16 deltaX, u16 deltaY)
+{
+ if (GetCurrentMapRotatingGatePuzzleType())
+ {
+ RotatingGate_CreateGatesWithinViewport(deltaX, deltaY);
+ RotatingGate_DestroyGatesOutsideViewport();
+ }
+}
+
+void RotatingGate_InitPuzzleAndGraphics(void)
+{
+ if (GetCurrentMapRotatingGatePuzzleType())
+ {
+ LoadRotatingGatePics();
+ RotatingGate_LoadPuzzleConfig();
+ RotatingGate_CreateGatesWithinViewport(0, 0);
+ }
+}
+
+bool8 CheckForRotatingGatePuzzleCollision(u8 direction, s16 x, s16 y)
+{
+ int i;
+ s16 gateX;
+ s16 gateY;
+ register u32 rotationInfo asm("r0");
+ int rotationDirection;
+ int armInfo;
+ s16 centerX;
+ s16 centerY;
+
+ if (!GetCurrentMapRotatingGatePuzzleType())
+ {
+ return 0;
+ }
+
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ gateX = gRotatingGate_PuzzleConfig[i].pos.x + 7;
+ gateY = gRotatingGate_PuzzleConfig[i].pos.y + 7;
+
+ if (gateX - 2 <= x && x <= gateX + 1 && gateY - 2 <= y && y <= gateY + 1)
+ {
+ centerX = x - gateX + 2;
+ centerY = y - gateY + 2;
+ rotationInfo = RotatingGate_GetRotationInfo(direction, centerX, centerY);
+
+ if (rotationInfo != GATE_ROTATION_NONE)
+ {
+ rotationDirection = rotationInfo >> 4;
+ armInfo = rotationInfo & 0xF;
+
+ asm("" ::"r"(armInfo));
+
+ if (RotatingGate_HasArm(i, armInfo))
+ {
+ if (RotatingGate_CanRotate(i, rotationDirection))
+ {
+ RotatingGate_TriggerRotationAnimation(i, rotationDirection);
+ RotatingGate_RotateInDirection(i, rotationDirection);
+ return 0;
+ }
+
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/src/sound_check_menu.c b/src/sound_check_menu.c
new file mode 100755
index 000000000..13a6f6f3e
--- /dev/null
+++ b/src/sound_check_menu.c
@@ -0,0 +1,2198 @@
+#include "global.h"
+#include "sprite.h"
+#include "palette.h"
+#include "task.h"
+#include "m4a.h"
+#include "main.h"
+#include "text.h"
+#include "menu.h"
+#include "songs.h"
+#include "title_screen.h"
+#include "sound.h"
+#include "pokedex_cry_screen.h"
+
+// local task defines
+#define WINDOW_SELECTED data[0]
+#define BGM_INDEX data[1]
+#define SE_INDEX data[2]
+#define UNK_DATA3 data[3]
+#define UNK_DATA4 data[4]
+// data 5-7 are not used
+// i dont have a define for data 8 yet because its used in a nonmatching and I can't be sure yet its actually used.
+
+// window selections
+enum
+{
+ BGM_WINDOW,
+ SE_WINDOW
+};
+
+// driver test cry enums
+enum
+{
+ CRY_TEST_UNK0,
+ CRY_TEST_VOLUME,
+ CRY_TEST_PANPOT,
+ CRY_TEST_PITCH,
+ CRY_TEST_LENGTH,
+ CRY_TEST_RELEASE,
+ CRY_TEST_PROGRESS,
+ CRY_TEST_CHORUS,
+ CRY_TEST_PRIORITY
+};
+
+// minmax range enums
+enum
+{
+ MIN,
+ MAX
+};
+
+extern struct ToneData voicegroup_84537C0[];
+extern struct ToneData voicegroup_8452590[];
+extern struct ToneData voicegroup_8453DC0[];
+extern struct ToneData voicegroup_8452B90[];
+extern struct ToneData voicegroup_84543C0[];
+extern struct ToneData voicegroup_8453190[];
+extern struct ToneData voicegroup_84549C0[];
+extern struct ToneData voicegroup_8453790[];
+
+extern int gUnknown_020387B4[9];
+
+extern s8 gUnknown_020387B3;
+extern u8 gUnknown_020387B1;
+extern u8 gUnknown_020387B2;
+extern u8 gUnknown_020387D8;
+extern u8 gUnknown_020387D9;
+extern u8 gUnknown_020387B0;
+extern u16 gUnknown_03005D34;
+extern u8 gUnknown_03005E98;
+
+extern struct MusicPlayerInfo *gUnknown_03005D30;
+extern struct MusicPlayerInfo gMPlay_BGM;
+
+void sub_80BA258(u8);
+void sub_80BA384(u8);
+void sub_80BA65C(u8);
+void sub_80BA68C(u8);
+void sub_80BA6B8(u8);
+void sub_80BA700(u16, u16, u16);
+void sub_80BA79C(const u8 *const, u16, u16);
+void sub_80BA800(u8);
+void sub_80BAA48(u8);
+void sub_80BACDC(s8);
+void sub_80BAD5C(void);
+void sub_80BAE10(u8, u8);
+void sub_80BAE78(int, u16, u16, u8);
+void sub_80BAF84(u8);
+void sub_80BB038(u8);
+void sub_80BB1D4(void);
+void sub_80BB25C(u8);
+void sub_80BB3B4(u8);
+void sub_80BB494(void);
+
+static const u8 gDebugText_SoundCheckJap[] = _("サウンドチェック");
+static const u8 gDebugText_BGM[] = _("BGM");
+static const u8 gDebugText_SE[] = _("SE ");
+static const u8 gDebugText_ABDesc[] = _("A‥さいせい B‥おわり");
+static const u8 gDebugText_UpDown[] = _("L‥UP R‥DOWN");
+static const u8 gDebugText_DriverTest[] = _("R‥DRIVER-TEST");
+
+// ideally this should be a multi Coords8 struct, but it wont match when its treated like a struct.
+static const u8 gUnknown_083D0300[] = { 1, 1, 1, 3, 1, 5, 1, 7, 1, 9, 1, 11, 1, 13, 1, 15, 1, 17 };
+
+static const u8 gDebugText_BBack[] = _("Bぼたんで もどる");
+static const u8 gDebugText_APlay[] = _("Aぼたんで さいせい");
+static const u8 gDebugText_Voice[] = _("VOICE‥‥‥‥");
+static const u8 gDebugText_Volume[] = _("VOLUME‥‥‥");
+static const u8 gDebugText_Panpot[] = _("PANPOT‥‥‥");
+static const u8 gDebugText_Pitch[] = _("PITCH‥‥‥‥");
+static const u8 gDebugText_Length[] = _("LENGTH‥‥‥");
+static const u8 gDebugText_Release[] = _("RELEASE‥‥");
+static const u8 gDebugText_Progress[] = _("PROGRESS‥");
+static const u8 gDebugText_Chorus[] = _("CHORUS‥‥‥");
+static const u8 gDebugText_Priority[] = _("PRIORITY‥");
+static const u8 gDebugText_Playing[] = _("さいせいちゆう‥"); // 再生中 (playing)
+static const u8 gDebugText_Reverse[] = _("はんてん‥‥‥‥"); // 反転 (reverse)
+static const u8 gDebugText_Stereo[] = _("すてれお‥‥‥‥"); // stereo
+
+// also ideally should be a MinMax struct, but any attempt to make this into a struct causes it to not match due to the weird multi dim access.
+static const int gUnknown_083D039C[16] =
+{
+ 0, 387,
+ 0, 127,
+ -127, 127,
+ -128, 32639,
+ 0, 65535,
+ 0, 255,
+ 0, 65535,
+ -64, 63
+};
+
+static const u8 gUnknown_083D03DC[] = _("▶");
+static const u8 gUnknown_083D03DE[] = _(" ");
+
+// why not just use Powers of ten from string_util?
+static const int gUnknown_083D03E0[6] =
+{
+ 1,
+ 10,
+ 100,
+ 1000,
+ 10000,
+ 100000
+};
+
+static const s8 gUnknown_083D03F8[5] = { 0x3F, 0x00, 0xC0, 0x7F, 0x80 };
+
+static const u8 gOtherText_SE[] = _("SE");
+static const u8 gOtherText_Pan[] = _("PAN");
+static const u8 gOtherText_LR[] = _(" LR");
+static const u8 gOtherText_RL[] = _(" RL");
+
+// bgm names
+static const u8 BGMName_STOP[] = _("STOP");
+static const u8 BGMName_TETSUJI[] = _("TETSUJI");
+static const u8 BGMName_FIELD13[] = _("FIELD13");
+static const u8 BGMName_KACHI22[] = _("KACHI22");
+static const u8 BGMName_KACHI2[] = _("KACHI2");
+static const u8 BGMName_KACHI3[] = _("KACHI3");
+static const u8 BGMName_KACHI5[] = _("KACHI5");
+static const u8 BGMName_PCC[] = _("PCC");
+static const u8 BGMName_NIBI[] = _("NIBI");
+static const u8 BGMName_SUIKUN[] = _("SUIKUN");
+static const u8 BGMName_DOORO1[] = _("DOORO1");
+static const u8 BGMName_DOORO_X1[] = _("DOORO-X1");
+static const u8 BGMName_DOORO_X3[] = _("DOORO-X3");
+static const u8 BGMName_MACHI_S2[] = _("MACHI-S2");
+static const u8 BGMName_MACHI_S4[] = _("MACHI-S4");
+static const u8 BGMName_GIM[] = _("GIM");
+static const u8 BGMName_NAMINORI[] = _("NAMINORI");
+static const u8 BGMName_DAN01[] = _("DAN01");
+static const u8 BGMName_FANFA1[] = _("FANFA1");
+static const u8 BGMName_ME_ASA[] = _("ME-ASA");
+static const u8 BGMName_ME_BACHI[] = _("ME-BACHI");
+static const u8 BGMName_FANFA4[] = _("FANFA4");
+static const u8 BGMName_FANFA5[] = _("FANFA5");
+static const u8 BGMName_ME_WAZA[] = _("ME-WAZA");
+static const u8 BGMName_BIJYUTU[] = _("BIJYUTU");
+static const u8 BGMName_DOORO_X4[] = _("DOORO-X4");
+static const u8 BGMName_FUNE_KAN[] = _("FUNE-KAN");
+static const u8 BGMName_ME_SHINKA[] = _("ME-SHINKA");
+static const u8 BGMName_SHINKA[] = _("SHINKA");
+static const u8 BGMName_ME_WASURE[] = _("ME-WASURE");
+static const u8 BGMName_SYOUJOEYE[] = _("SYOUJOEYE");
+static const u8 BGMName_BOYEYE[] = _("BOYEYE");
+static const u8 BGMName_DAN02[] = _("DAN02");
+static const u8 BGMName_MACHI_S3[] = _("MACHI-S3");
+static const u8 BGMName_ODAMAKI[] = _("ODAMAKI");
+static const u8 BGMName_B_TOWER[] = _("B-TOWER");
+static const u8 BGMName_SWIMEYE[] = _("SWIMEYE");
+static const u8 BGMName_DAN03[] = _("DAN03");
+static const u8 BGMName_ME_KINOMI[] = _("ME-KINOMI");
+static const u8 BGMName_ME_TAMA[] = _("ME-TAMA");
+static const u8 BGMName_ME_B_BIG[] = _("ME-B-BIG");
+static const u8 BGMName_ME_B_SMALL[] = _("ME-B-SMALL");
+static const u8 BGMName_ME_ZANNEN[] = _("ME-ZANNEN");
+static const u8 BGMName_BD_TIME[] = _("BD-TIME");
+static const u8 BGMName_TEST1[] = _("TEST1");
+static const u8 BGMName_TEST2[] = _("TEST2");
+static const u8 BGMName_TEST3[] = _("TEST3");
+static const u8 BGMName_TEST4[] = _("TEST4");
+static const u8 BGMName_TEST[] = _("TEST");
+static const u8 BGMName_GOMACHI0[] = _("GOMACHI0");
+static const u8 BGMName_GOTOWN[] = _("GOTOWN");
+static const u8 BGMName_POKECEN[] = _("POKECEN");
+static const u8 BGMName_NEXTROAD[] = _("NEXTROAD");
+static const u8 BGMName_GRANROAD[] = _("GRANROAD");
+static const u8 BGMName_CYCLING[] = _("CYCLING");
+static const u8 BGMName_FRIENDLY[] = _("FRIENDLY");
+static const u8 BGMName_MISHIRO[] = _("MISHIRO");
+static const u8 BGMName_TOZAN[] = _("TOZAN");
+static const u8 BGMName_GIRLEYE[] = _("GIRLEYE");
+static const u8 BGMName_MINAMO[] = _("MINAMO");
+static const u8 BGMName_ASHROAD[] = _("ASHROAD");
+static const u8 BGMName_EVENT0[] = _("EVENT0");
+static const u8 BGMName_DEEPDEEP[] = _("DEEPDEEP");
+static const u8 BGMName_KACHI1[] = _("KACHI1");
+static const u8 BGMName_TITLE3[] = _("TITLE3");
+static const u8 BGMName_DEMO1[] = _("DEMO1");
+static const u8 BGMName_GIRL_SUP[] = _("GIRL-SUP");
+static const u8 BGMName_HAGESHII[] = _("HAGESHII");
+static const u8 BGMName_KAKKOII[] = _("KAKKOII");
+static const u8 BGMName_KAZANBAI[] = _("KAZANBAI");
+static const u8 BGMName_AQA_0[] = _("AQA-0");
+static const u8 BGMName_TSURETEK[] = _("TSURETEK");
+static const u8 BGMName_BOY_SUP[] = _("BOY-SUP");
+static const u8 BGMName_RAINBOW[] = _("RAINBOW");
+static const u8 BGMName_AYASII[] = _("AYASII");
+static const u8 BGMName_KACHI4[] = _("KACHI4");
+static const u8 BGMName_ROPEWAY[] = _("ROPEWAY");
+static const u8 BGMName_CASINO[] = _("CASINO");
+static const u8 BGMName_HIGHTOWN[] = _("HIGHTOWN");
+static const u8 BGMName_SAFARI[] = _("SAFARI");
+static const u8 BGMName_C_ROAD[] = _("C-ROAD");
+static const u8 BGMName_AJITO[] = _("AJITO");
+static const u8 BGMName_M_BOAT[] = _("M-BOAT");
+static const u8 BGMName_M_DUNGON[] = _("M-DUNGON");
+static const u8 BGMName_FINECITY[] = _("FINECITY");
+static const u8 BGMName_MACHUPI[] = _("MACHUPI");
+static const u8 BGMName_P_SCHOOL[] = _("P-SCHOOL");
+static const u8 BGMName_DENDOU[] = _("DENDOU");
+static const u8 BGMName_TONEKUSA[] = _("TONEKUSA");
+static const u8 BGMName_MABOROSI[] = _("MABOROSI");
+static const u8 BGMName_CON_FAN[] = _("CON-FAN");
+static const u8 BGMName_CONTEST0[] = _("CONTEST0");
+static const u8 BGMName_MGM0[] = _("MGM0");
+static const u8 BGMName_T_BATTLE[] = _("T-BATTLE");
+static const u8 BGMName_OOAME[] = _("OOAME");
+static const u8 BGMName_HIDERI[] = _("HIDERI");
+static const u8 BGMName_RUNECITY[] = _("RUNECITY");
+static const u8 BGMName_CON_K[] = _("CON-K");
+static const u8 BGMName_EIKOU_R[] = _("EIKOU-R");
+static const u8 BGMName_KARAKURI[] = _("KARAKURI");
+static const u8 BGMName_HUTAGO[] = _("HUTAGO");
+static const u8 BGMName_SITENNOU[] = _("SITENNOU");
+static const u8 BGMName_YAMA_EYE[] = _("YAMA-EYE");
+static const u8 BGMName_CONLOBBY[] = _("CONLOBBY");
+static const u8 BGMName_INTER_V[] = _("INTER-V");
+static const u8 BGMName_DAIGO[] = _("DAIGO");
+static const u8 BGMName_THANKFOR[] = _("THANKFOR");
+static const u8 BGMName_END[] = _("END");
+static const u8 BGMName_BATTLE27[] = _("BATTLE27");
+static const u8 BGMName_BATTLE31[] = _("BATTLE31");
+static const u8 BGMName_BATTLE20[] = _("BATTLE20");
+static const u8 BGMName_BATTLE32[] = _("BATTLE32");
+static const u8 BGMName_BATTLE33[] = _("BATTLE33");
+static const u8 BGMName_BATTLE36[] = _("BATTLE36");
+static const u8 BGMName_BATTLE34[] = _("BATTLE34");
+static const u8 BGMName_BATTLE35[] = _("BATTLE35");
+static const u8 BGMName_BATTLE38[] = _("BATTLE38");
+static const u8 BGMName_BATTLE30[] = _("BATTLE30");
+
+static const u8 *const gBGMNames[] =
+{
+ BGMName_STOP,
+ BGMName_TETSUJI,
+ BGMName_FIELD13,
+ BGMName_KACHI22,
+ BGMName_KACHI2,
+ BGMName_KACHI3,
+ BGMName_KACHI5,
+ BGMName_PCC,
+ BGMName_NIBI,
+ BGMName_SUIKUN,
+ BGMName_DOORO1,
+ BGMName_DOORO_X1,
+ BGMName_DOORO_X3,
+ BGMName_MACHI_S2,
+ BGMName_MACHI_S4,
+ BGMName_GIM,
+ BGMName_NAMINORI,
+ BGMName_DAN01,
+ BGMName_FANFA1,
+ BGMName_ME_ASA,
+ BGMName_ME_BACHI,
+ BGMName_FANFA4,
+ BGMName_FANFA5,
+ BGMName_ME_WAZA,
+ BGMName_BIJYUTU,
+ BGMName_DOORO_X4,
+ BGMName_FUNE_KAN,
+ BGMName_ME_SHINKA,
+ BGMName_SHINKA,
+ BGMName_ME_WASURE,
+ BGMName_SYOUJOEYE,
+ BGMName_BOYEYE,
+ BGMName_DAN02,
+ BGMName_MACHI_S3,
+ BGMName_ODAMAKI,
+ BGMName_B_TOWER,
+ BGMName_SWIMEYE,
+ BGMName_DAN03,
+ BGMName_ME_KINOMI,
+ BGMName_ME_TAMA,
+ BGMName_ME_B_BIG,
+ BGMName_ME_B_SMALL,
+ BGMName_ME_ZANNEN,
+ BGMName_BD_TIME,
+ BGMName_TEST1,
+ BGMName_TEST2,
+ BGMName_TEST3,
+ BGMName_TEST4,
+ BGMName_TEST,
+ BGMName_GOMACHI0,
+ BGMName_GOTOWN,
+ BGMName_POKECEN,
+ BGMName_NEXTROAD,
+ BGMName_GRANROAD,
+ BGMName_CYCLING,
+ BGMName_FRIENDLY,
+ BGMName_MISHIRO,
+ BGMName_TOZAN,
+ BGMName_GIRLEYE,
+ BGMName_MINAMO,
+ BGMName_ASHROAD,
+ BGMName_EVENT0,
+ BGMName_DEEPDEEP,
+ BGMName_KACHI1,
+ BGMName_TITLE3,
+ BGMName_DEMO1,
+ BGMName_GIRL_SUP,
+ BGMName_HAGESHII,
+ BGMName_KAKKOII,
+ BGMName_KAZANBAI,
+ BGMName_AQA_0,
+ BGMName_TSURETEK,
+ BGMName_BOY_SUP,
+ BGMName_RAINBOW,
+ BGMName_AYASII,
+ BGMName_KACHI4,
+ BGMName_ROPEWAY,
+ BGMName_CASINO,
+ BGMName_HIGHTOWN,
+ BGMName_SAFARI,
+ BGMName_C_ROAD,
+ BGMName_AJITO,
+ BGMName_M_BOAT,
+ BGMName_M_DUNGON,
+ BGMName_FINECITY,
+ BGMName_MACHUPI,
+ BGMName_P_SCHOOL,
+ BGMName_DENDOU,
+ BGMName_TONEKUSA,
+ BGMName_MABOROSI,
+ BGMName_CON_FAN,
+ BGMName_CONTEST0,
+ BGMName_MGM0,
+ BGMName_T_BATTLE,
+ BGMName_OOAME,
+ BGMName_HIDERI,
+ BGMName_RUNECITY,
+ BGMName_CON_K,
+ BGMName_EIKOU_R,
+ BGMName_KARAKURI,
+ BGMName_HUTAGO,
+ BGMName_SITENNOU,
+ BGMName_YAMA_EYE,
+ BGMName_CONLOBBY,
+ BGMName_INTER_V,
+ BGMName_DAIGO,
+ BGMName_THANKFOR,
+ BGMName_END,
+ BGMName_BATTLE27,
+ BGMName_BATTLE31,
+ BGMName_BATTLE20,
+ BGMName_BATTLE32,
+ BGMName_BATTLE33,
+ BGMName_BATTLE36,
+ BGMName_BATTLE34,
+ BGMName_BATTLE35,
+ BGMName_BATTLE38,
+ BGMName_BATTLE30
+};
+
+// SE names
+static const u8 SEName_STOP[] = _("STOP");
+static const u8 SEName_KAIFUKU[] = _("KAIFUKU");
+static const u8 SEName_PC_LOGON[] = _("PC-LOGON");
+static const u8 SEName_PC_OFF[] = _("PC-OFF");
+static const u8 SEName_PC_ON[] = _("PC-ON");
+static const u8 SEName_SELECT[] = _("SELECT");
+static const u8 SEName_WIN_OPEN[] = _("WIN-OPEN");
+static const u8 SEName_WALL_HIT[] = _("WALL-HIT");
+static const u8 SEName_DOOR[] = _("DOOR");
+static const u8 SEName_KAIDAN[] = _("KAIDAN");
+static const u8 SEName_DANSA[] = _("DANSA");
+static const u8 SEName_JITENSYA[] = _("JITENSYA");
+static const u8 SEName_KOUKA_L[] = _("KOUKA-L");
+static const u8 SEName_KOUKA_M[] = _("KOUKA-M");
+static const u8 SEName_KOUKA_H[] = _("KOUKA-H");
+static const u8 SEName_BOWA2[] = _("BOWA2");
+static const u8 SEName_POKE_DEAD[] = _("POKE-DEAD");
+static const u8 SEName_NIGERU[] = _("NIGERU");
+static const u8 SEName_JIDO_DOA[] = _("JIDO-DOA");
+static const u8 SEName_NAMINORI[] = _("NAMINORI");
+static const u8 SEName_BAN[] = _("BAN");
+static const u8 SEName_PIN[] = _("PIN");
+static const u8 SEName_BOO[] = _("BOO");
+static const u8 SEName_BOWA[] = _("BOWA");
+static const u8 SEName_JYUNI[] = _("JYUNI");
+static const u8 SEName_A[] = _("A");
+static const u8 SEName_I[] = _("I");
+static const u8 SEName_U[] = _("U");
+static const u8 SEName_E[] = _("E");
+static const u8 SEName_O[] = _("O");
+static const u8 SEName_N[] = _("N");
+static const u8 SEName_SEIKAI[] = _("SEIKAI");
+static const u8 SEName_HAZURE[] = _("HAZURE");
+static const u8 SEName_EXP[] = _("EXP");
+static const u8 SEName_JITE_PYOKO[] = _("JITE-PYOKO");
+static const u8 SEName_MU_PACHI[] = _("MU-PACHI");
+static const u8 SEName_TK_KASYA[] = _("TK-KASYA");
+static const u8 SEName_FU_ZAKU[] = _("FU-ZAKU");
+static const u8 SEName_FU_ZAKU2[] = _("FU-ZAKU2");
+static const u8 SEName_FU_ZUZUZU[] = _("FU-ZUZUZU");
+static const u8 SEName_RU_GASHIN[] = _("RU-GASHIN");
+static const u8 SEName_RU_GASYAN[] = _("RU-GASYAN");
+static const u8 SEName_RU_BARI[] = _("RU-BARI");
+static const u8 SEName_RU_HYUU[] = _("RU-HYUU");
+static const u8 SEName_KI_GASYAN[] = _("KI-GASYAN");
+static const u8 SEName_TK_WARPIN[] = _("TK-WARPIN");
+static const u8 SEName_TK_WARPOUT[] = _("TK-WARPOUT");
+static const u8 SEName_TU_SAA[] = _("TU-SAA");
+static const u8 SEName_HI_TURUN[] = _("HI-TURUN");
+static const u8 SEName_TRACK_MOVE[] = _("TRACK-MOVE");
+static const u8 SEName_TRACK_STOP[] = _("TRACK-STOP");
+static const u8 SEName_TRACK_HAIK[] = _("TRACK-HAIK");
+static const u8 SEName_TRACK_DOOR[] = _("TRACK-DOOR");
+static const u8 SEName_MOTER[] = _("MOTER");
+static const u8 SEName_CARD[] = _("CARD");
+static const u8 SEName_SAVE[] = _("SAVE");
+static const u8 SEName_KON[] = _("KON");
+static const u8 SEName_KON2[] = _("KON2");
+static const u8 SEName_KON3[] = _("KON3");
+static const u8 SEName_KON4[] = _("KON4");
+static const u8 SEName_SUIKOMU[] = _("SUIKOMU");
+static const u8 SEName_NAGERU[] = _("NAGERU");
+static const u8 SEName_TOY_C[] = _("TOY-C");
+static const u8 SEName_TOY_D[] = _("TOY-D");
+static const u8 SEName_TOY_E[] = _("TOY-E");
+static const u8 SEName_TOY_F[] = _("TOY-F");
+static const u8 SEName_TOY_G[] = _("TOY-G");
+static const u8 SEName_TOY_A[] = _("TOY-A");
+static const u8 SEName_TOY_B[] = _("TOY-B");
+static const u8 SEName_TOY_C1[] = _("TOY-C1");
+static const u8 SEName_MIZU[] = _("MIZU");
+static const u8 SEName_HASHI[] = _("HASHI");
+static const u8 SEName_DAUGI[] = _("DAUGI");
+static const u8 SEName_PINPON[] = _("PINPON");
+static const u8 SEName_FUUSEN1[] = _("FUUSEN1");
+static const u8 SEName_FUUSEN2[] = _("FUUSEN2");
+static const u8 SEName_FUUSEN3[] = _("FUUSEN3");
+static const u8 SEName_TOY_KABE[] = _("TOY-KABE");
+static const u8 SEName_TOY_DANGO[] = _("TOY-DANGO");
+static const u8 SEName_DOKU[] = _("DOKU");
+static const u8 SEName_ESUKA[] = _("ESUKA");
+static const u8 SEName_T_AME[] = _("T-AME");
+static const u8 SEName_T_AME_E[] = _("T-AME-E");
+static const u8 SEName_T_OOAME[] = _("T-OOAME");
+static const u8 SEName_T_OOAME_E[] = _("T-OOAME-E");
+static const u8 SEName_T_KOAME[] = _("T-KOAME");
+static const u8 SEName_T_KOAME_E[] = _("T-KOAME-E");
+static const u8 SEName_T_KAMI[] = _("T-KAMI");
+static const u8 SEName_T_KAMI2[] = _("T-KAMI2");
+static const u8 SEName_ELEBETA[] = _("ELEBETA");
+static const u8 SEName_HINSI[] = _("HINSI");
+static const u8 SEName_EXPMAX[] = _("EXPMAX");
+static const u8 SEName_TAMAKORO[] = _("TAMAKORO");
+static const u8 SEName_TAMAKORO_E[] = _("TAMAKORO-E");
+static const u8 SEName_BASABASA[] = _("BASABASA");
+static const u8 SEName_REGI[] = _("REGI");
+static const u8 SEName_C_GAJI[] = _("C-GAJI");
+static const u8 SEName_C_MAKU_U[] = _("C-MAKU-U");
+static const u8 SEName_C_MAKU_D[] = _("C-MAKU-D");
+static const u8 SEName_C_PASI[] = _("C-PASI");
+static const u8 SEName_C_SYU[] = _("C-SYU");
+static const u8 SEName_C_PIKON[] = _("C-PIKON");
+static const u8 SEName_REAPOKE[] = _("REAPOKE");
+static const u8 SEName_OP_BASYU[] = _("OP-BASYU");
+static const u8 SEName_BT_START[] = _("BT-START");
+static const u8 SEName_DENDOU[] = _("DENDOU");
+static const u8 SEName_JIHANKI[] = _("JIHANKI");
+static const u8 SEName_TAMA[] = _("TAMA");
+static const u8 SEName_Z_SCROLL[] = _("Z-SCROLL");
+static const u8 SEName_Z_PAGE[] = _("Z-PAGE");
+static const u8 SEName_PN_ON[] = _("PN-ON");
+static const u8 SEName_PN_OFF[] = _("PN-OFF");
+static const u8 SEName_Z_SEARCH[] = _("Z-SEARCH");
+static const u8 SEName_TAMAGO[] = _("TAMAGO");
+static const u8 SEName_TB_START[] = _("TB-START");
+static const u8 SEName_TB_KON[] = _("TB-KON");
+static const u8 SEName_TB_KARA[] = _("TB-KARA");
+static const u8 SEName_BIDORO[] = _("BIDORO");
+static const u8 SEName_W085[] = _("W085");
+static const u8 SEName_W085B[] = _("W085B");
+static const u8 SEName_W231[] = _("W231");
+static const u8 SEName_W171[] = _("W171");
+static const u8 SEName_W233[] = _("W233");
+static const u8 SEName_W233B[] = _("W233B");
+static const u8 SEName_W145[] = _("W145");
+static const u8 SEName_W145B[] = _("W145B");
+static const u8 SEName_W145C[] = _("W145C");
+static const u8 SEName_W240[] = _("W240");
+static const u8 SEName_W015[] = _("W015");
+static const u8 SEName_W081[] = _("W081");
+static const u8 SEName_W081B[] = _("W081B");
+static const u8 SEName_W088[] = _("W088");
+static const u8 SEName_W016[] = _("W016");
+static const u8 SEName_W016B[] = _("W016B");
+static const u8 SEName_W003[] = _("W003");
+static const u8 SEName_W104[] = _("W104");
+static const u8 SEName_W013[] = _("W013");
+static const u8 SEName_W196[] = _("W196");
+static const u8 SEName_W086[] = _("W086");
+static const u8 SEName_W004[] = _("W004");
+static const u8 SEName_W025[] = _("W025");
+static const u8 SEName_W025B[] = _("W025B");
+static const u8 SEName_W152[] = _("W152");
+static const u8 SEName_W026[] = _("W026");
+static const u8 SEName_W172[] = _("W172");
+static const u8 SEName_W172B[] = _("W172B");
+static const u8 SEName_W053[] = _("W053");
+static const u8 SEName_W007[] = _("W007");
+static const u8 SEName_W092[] = _("W092");
+static const u8 SEName_W221[] = _("W221");
+static const u8 SEName_W221B[] = _("W221B");
+static const u8 SEName_W052[] = _("W052");
+static const u8 SEName_W036[] = _("W036");
+static const u8 SEName_W059[] = _("W059");
+static const u8 SEName_W059B[] = _("W059B");
+static const u8 SEName_W010[] = _("W010");
+static const u8 SEName_W011[] = _("W011");
+static const u8 SEName_W017[] = _("W017");
+static const u8 SEName_W019[] = _("W019");
+static const u8 SEName_W028[] = _("W028");
+static const u8 SEName_W013B[] = _("W013B");
+static const u8 SEName_W044[] = _("W044");
+static const u8 SEName_W029[] = _("W029");
+static const u8 SEName_W057[] = _("W057");
+static const u8 SEName_W056[] = _("W056");
+static const u8 SEName_W250[] = _("W250");
+static const u8 SEName_W030[] = _("W030");
+static const u8 SEName_W039[] = _("W039");
+static const u8 SEName_W054[] = _("W054");
+static const u8 SEName_W077[] = _("W077");
+static const u8 SEName_W020[] = _("W020");
+static const u8 SEName_W082[] = _("W082");
+static const u8 SEName_W047[] = _("W047");
+static const u8 SEName_W195[] = _("W195");
+static const u8 SEName_W006[] = _("W006");
+static const u8 SEName_W091[] = _("W091");
+static const u8 SEName_W146[] = _("W146");
+static const u8 SEName_W120[] = _("W120");
+static const u8 SEName_W153[] = _("W153");
+static const u8 SEName_W071B[] = _("W071B");
+static const u8 SEName_W071[] = _("W071");
+static const u8 SEName_W103[] = _("W103");
+static const u8 SEName_W062[] = _("W062");
+static const u8 SEName_W062B[] = _("W062B");
+static const u8 SEName_W048[] = _("W048");
+static const u8 SEName_W187[] = _("W187");
+static const u8 SEName_W118[] = _("W118");
+static const u8 SEName_W155[] = _("W155");
+static const u8 SEName_W122[] = _("W122");
+static const u8 SEName_W060[] = _("W060");
+static const u8 SEName_W185[] = _("W185");
+static const u8 SEName_W014[] = _("W014");
+static const u8 SEName_W043[] = _("W043");
+static const u8 SEName_W207[] = _("W207");
+static const u8 SEName_W207B[] = _("W207B");
+static const u8 SEName_W215[] = _("W215");
+static const u8 SEName_W109[] = _("W109");
+static const u8 SEName_W173[] = _("W173");
+static const u8 SEName_W280[] = _("W280");
+static const u8 SEName_W202[] = _("W202");
+static const u8 SEName_W060B[] = _("W060B");
+static const u8 SEName_W076[] = _("W076");
+static const u8 SEName_W080[] = _("W080");
+static const u8 SEName_W100[] = _("W100");
+static const u8 SEName_W107[] = _("W107");
+static const u8 SEName_W166[] = _("W166");
+static const u8 SEName_W129[] = _("W129");
+static const u8 SEName_W115[] = _("W115");
+static const u8 SEName_W112[] = _("W112");
+static const u8 SEName_W197[] = _("W197");
+static const u8 SEName_W199[] = _("W199");
+static const u8 SEName_W236[] = _("W236");
+static const u8 SEName_W204[] = _("W204");
+static const u8 SEName_W268[] = _("W268");
+static const u8 SEName_W070[] = _("W070");
+static const u8 SEName_W063[] = _("W063");
+static const u8 SEName_W127[] = _("W127");
+static const u8 SEName_W179[] = _("W179");
+static const u8 SEName_W151[] = _("W151");
+static const u8 SEName_W201[] = _("W201");
+static const u8 SEName_W161[] = _("W161");
+static const u8 SEName_W161B[] = _("W161B");
+static const u8 SEName_W227[] = _("W227");
+static const u8 SEName_W227B[] = _("W227B");
+static const u8 SEName_W226[] = _("W226");
+static const u8 SEName_W208[] = _("W208");
+static const u8 SEName_W213[] = _("W213");
+static const u8 SEName_W213B[] = _("W213B");
+static const u8 SEName_W234[] = _("W234");
+static const u8 SEName_W260[] = _("W260");
+static const u8 SEName_W328[] = _("W328");
+static const u8 SEName_W320[] = _("W320");
+static const u8 SEName_W255[] = _("W255");
+static const u8 SEName_W291[] = _("W291");
+static const u8 SEName_W089[] = _("W089");
+static const u8 SEName_W239[] = _("W239");
+static const u8 SEName_W230[] = _("W230");
+static const u8 SEName_W281[] = _("W281");
+static const u8 SEName_W327[] = _("W327");
+static const u8 SEName_W287[] = _("W287");
+static const u8 SEName_W257[] = _("W257");
+static const u8 SEName_W253[] = _("W253");
+static const u8 SEName_W258[] = _("W258");
+static const u8 SEName_W322[] = _("W322");
+static const u8 SEName_W298[] = _("W298");
+static const u8 SEName_W287B[] = _("W287B");
+static const u8 SEName_W114[] = _("W114");
+static const u8 SEName_W063B[] = _("W063B");
+
+static const u8 *const gSENames[] =
+{
+ SEName_STOP,
+ SEName_KAIFUKU,
+ SEName_PC_LOGON,
+ SEName_PC_OFF,
+ SEName_PC_ON,
+ SEName_SELECT,
+ SEName_WIN_OPEN,
+ SEName_WALL_HIT,
+ SEName_DOOR,
+ SEName_KAIDAN,
+ SEName_DANSA,
+ SEName_JITENSYA,
+ SEName_KOUKA_L,
+ SEName_KOUKA_M,
+ SEName_KOUKA_H,
+ SEName_BOWA2,
+ SEName_POKE_DEAD,
+ SEName_NIGERU,
+ SEName_JIDO_DOA,
+ SEName_NAMINORI,
+ SEName_BAN,
+ SEName_PIN,
+ SEName_BOO,
+ SEName_BOWA,
+ SEName_JYUNI,
+ SEName_A,
+ SEName_I,
+ SEName_U,
+ SEName_E,
+ SEName_O,
+ SEName_N,
+ SEName_SEIKAI,
+ SEName_HAZURE,
+ SEName_EXP,
+ SEName_JITE_PYOKO,
+ SEName_MU_PACHI,
+ SEName_TK_KASYA,
+ SEName_FU_ZAKU,
+ SEName_FU_ZAKU2,
+ SEName_FU_ZUZUZU,
+ SEName_RU_GASHIN,
+ SEName_RU_GASYAN,
+ SEName_RU_BARI,
+ SEName_RU_HYUU,
+ SEName_KI_GASYAN,
+ SEName_TK_WARPIN,
+ SEName_TK_WARPOUT,
+ SEName_TU_SAA,
+ SEName_HI_TURUN,
+ SEName_TRACK_MOVE,
+ SEName_TRACK_STOP,
+ SEName_TRACK_HAIK,
+ SEName_TRACK_DOOR,
+ SEName_MOTER,
+ SEName_CARD,
+ SEName_SAVE,
+ SEName_KON,
+ SEName_KON2,
+ SEName_KON3,
+ SEName_KON4,
+ SEName_SUIKOMU,
+ SEName_NAGERU,
+ SEName_TOY_C,
+ SEName_TOY_D,
+ SEName_TOY_E,
+ SEName_TOY_F,
+ SEName_TOY_G,
+ SEName_TOY_A,
+ SEName_TOY_B,
+ SEName_TOY_C1,
+ SEName_MIZU,
+ SEName_HASHI,
+ SEName_DAUGI,
+ SEName_PINPON,
+ SEName_FUUSEN1,
+ SEName_FUUSEN2,
+ SEName_FUUSEN3,
+ SEName_TOY_KABE,
+ SEName_TOY_DANGO,
+ SEName_DOKU,
+ SEName_ESUKA,
+ SEName_T_AME,
+ SEName_T_AME_E,
+ SEName_T_OOAME,
+ SEName_T_OOAME_E,
+ SEName_T_KOAME,
+ SEName_T_KOAME_E,
+ SEName_T_KAMI,
+ SEName_T_KAMI2,
+ SEName_ELEBETA,
+ SEName_HINSI,
+ SEName_EXPMAX,
+ SEName_TAMAKORO,
+ SEName_TAMAKORO_E,
+ SEName_BASABASA,
+ SEName_REGI,
+ SEName_C_GAJI,
+ SEName_C_MAKU_U,
+ SEName_C_MAKU_D,
+ SEName_C_PASI,
+ SEName_C_SYU,
+ SEName_C_PIKON,
+ SEName_REAPOKE,
+ SEName_OP_BASYU,
+ SEName_BT_START,
+ SEName_DENDOU,
+ SEName_JIHANKI,
+ SEName_TAMA,
+ SEName_Z_SCROLL,
+ SEName_Z_PAGE,
+ SEName_PN_ON,
+ SEName_PN_OFF,
+ SEName_Z_SEARCH,
+ SEName_TAMAGO,
+ SEName_TB_START,
+ SEName_TB_KON,
+ SEName_TB_KARA,
+ SEName_BIDORO,
+ SEName_W085,
+ SEName_W085B,
+ SEName_W231,
+ SEName_W171,
+ SEName_W233,
+ SEName_W233B,
+ SEName_W145,
+ SEName_W145B,
+ SEName_W145C,
+ SEName_W240,
+ SEName_W015,
+ SEName_W081,
+ SEName_W081B,
+ SEName_W088,
+ SEName_W016,
+ SEName_W016B,
+ SEName_W003,
+ SEName_W104,
+ SEName_W013,
+ SEName_W196,
+ SEName_W086,
+ SEName_W004,
+ SEName_W025,
+ SEName_W025B,
+ SEName_W152,
+ SEName_W026,
+ SEName_W172,
+ SEName_W172B,
+ SEName_W053,
+ SEName_W007,
+ SEName_W092,
+ SEName_W221,
+ SEName_W221B,
+ SEName_W052,
+ SEName_W036,
+ SEName_W059,
+ SEName_W059B,
+ SEName_W010,
+ SEName_W011,
+ SEName_W017,
+ SEName_W019,
+ SEName_W028,
+ SEName_W013B,
+ SEName_W044,
+ SEName_W029,
+ SEName_W057,
+ SEName_W056,
+ SEName_W250,
+ SEName_W030,
+ SEName_W039,
+ SEName_W054,
+ SEName_W077,
+ SEName_W020,
+ SEName_W082,
+ SEName_W047,
+ SEName_W195,
+ SEName_W006,
+ SEName_W091,
+ SEName_W146,
+ SEName_W120,
+ SEName_W153,
+ SEName_W071B,
+ SEName_W071,
+ SEName_W103,
+ SEName_W062,
+ SEName_W062B,
+ SEName_W048,
+ SEName_W187,
+ SEName_W118,
+ SEName_W155,
+ SEName_W122,
+ SEName_W060,
+ SEName_W185,
+ SEName_W014,
+ SEName_W043,
+ SEName_W207,
+ SEName_W207B,
+ SEName_W215,
+ SEName_W109,
+ SEName_W173,
+ SEName_W280,
+ SEName_W202,
+ SEName_W060B,
+ SEName_W076,
+ SEName_W080,
+ SEName_W100,
+ SEName_W107,
+ SEName_W166,
+ SEName_W129,
+ SEName_W115,
+ SEName_W112,
+ SEName_W197,
+ SEName_W199,
+ SEName_W236,
+ SEName_W204,
+ SEName_W268,
+ SEName_W070,
+ SEName_W063,
+ SEName_W127,
+ SEName_W179,
+ SEName_W151,
+ SEName_W201,
+ SEName_W161,
+ SEName_W161B,
+ SEName_W227,
+ SEName_W227B,
+ SEName_W226,
+ SEName_W208,
+ SEName_W213,
+ SEName_W213B,
+ SEName_W234,
+ SEName_W260,
+ SEName_W328,
+ SEName_W320,
+ SEName_W255,
+ SEName_W291,
+ SEName_W089,
+ SEName_W239,
+ SEName_W230,
+ SEName_W281,
+ SEName_W327,
+ SEName_W287,
+ SEName_W257,
+ SEName_W253,
+ SEName_W258,
+ SEName_W322,
+ SEName_W298,
+ SEName_W287B,
+ SEName_W114,
+ SEName_W063B
+};
+
+void sub_80BA0A8(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+void sub_80BA0C0(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+
+ if(gUnknown_020387B0 != 0)
+ {
+ m4aSoundMain();
+ m4aSoundMain();
+ m4aSoundMain();
+ }
+}
+
+// unused
+void CB2_StartSoundCheckMenu(void)
+{
+ u8 taskId;
+
+ SetVBlankCallback(NULL);
+ REG_DISPCNT = 0;
+ REG_BG2CNT = 0;
+ REG_BG1CNT = 0;
+ REG_BG0CNT = 0;
+ REG_BG2HOFS = 0;
+ REG_BG2VOFS = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1VOFS = 0;
+ REG_BG0HOFS = 0;
+ REG_BG0VOFS = 0;
+ DmaFill16(3, 0, VRAM, VRAM_SIZE);
+ DmaFill32(3, 0, OAM, OAM_SIZE);
+ DmaFill16(3, 0, PLTT, PLTT_SIZE);
+ ResetPaletteFade();
+ ResetTasks();
+ ResetSpriteData();
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0);
+ REG_WIN0H = WIN_RANGE(0, 0);
+ REG_WIN0V = WIN_RANGE(0, 0);
+ REG_WIN1H = WIN_RANGE(0, 0);
+ REG_WIN1V = WIN_RANGE(0, 0);
+ REG_WININ = 0x1111;
+ REG_WINOUT = 0x31;
+ REG_BLDCNT = 0xE1;
+ REG_BLDALPHA = 0;
+ REG_BLDY = 7;
+ REG_IE = 1; // could be a typo of REG_IME
+ REG_IE |= 1;
+ REG_DISPSTAT |= 8;
+ SetVBlankCallback(sub_80BA0C0);
+ SetMainCallback2(sub_80BA0A8);
+ REG_DISPCNT = 0x7140;
+ taskId = CreateTask(sub_80BA258, 0);
+ TASK.WINDOW_SELECTED = BGM_WINDOW;
+ TASK.BGM_INDEX = 0;
+ TASK.SE_INDEX = 0;
+ TASK.UNK_DATA3 = 0;
+ gUnknown_020387B0 = 0;
+ TASK.UNK_DATA3 = 0; // why?
+ m4aSoundInit();
+}
+
+// Task_InitSoundCheckMenu
+void sub_80BA258(u8 taskId)
+{
+ u8 soundcheckStr[sizeof(gDebugText_SoundCheckJap)];
+ u8 bgmStr[sizeof(gDebugText_BGM)];
+ u8 seStr[sizeof(gDebugText_SE)];
+ u8 abDescStr[sizeof(gDebugText_ABDesc)];
+ u8 upDownStr[sizeof(gDebugText_UpDown)];
+ u8 driverStr[sizeof(gDebugText_DriverTest)];
+
+ memcpy(soundcheckStr, gDebugText_SoundCheckJap, sizeof(gDebugText_SoundCheckJap));
+ memcpy(bgmStr, gDebugText_BGM, sizeof(gDebugText_BGM));
+ memcpy(seStr, gDebugText_SE, sizeof(gDebugText_SE));
+ memcpy(abDescStr, gDebugText_ABDesc, sizeof(gDebugText_ABDesc));
+ memcpy(upDownStr, gDebugText_UpDown, sizeof(gDebugText_UpDown));
+ memcpy(driverStr, gDebugText_DriverTest, sizeof(gDebugText_DriverTest));
+
+ if(!gPaletteFade.active)
+ {
+ MenuDrawTextWindow(0x2, 0, 0x1B, 0x3);
+ MenuDrawTextWindow(0x2, 0x5, 0x1B, 0xA);
+ MenuDrawTextWindow(0x2, 0xC, 0x1B, 0x11);
+ MenuPrint(soundcheckStr, 4, 1);
+ MenuPrint(abDescStr, 14, 1);
+ MenuPrint(bgmStr, 4, 6);
+ MenuPrint(upDownStr, 14, 6);
+ MenuPrint(seStr, 4, 13);
+ MenuPrint(upDownStr, 14, 13);
+ MenuPrint(driverStr, 14, 18);
+ TASK.FUNC = sub_80BA384;
+ REG_WIN0H = WIN_RANGE(17, 223);
+ REG_WIN0V = WIN_RANGE(1, 31);
+ }
+}
+
+void sub_80BA384(u8 taskId) // Task_HandleDrawingSoundCheckMenuText
+{
+ sub_80BA6B8(TASK.WINDOW_SELECTED);
+ sub_80BA700(TASK.BGM_INDEX + BGM_STOP, 7, 8); // print by BGM index
+ sub_80BA79C(gBGMNames[TASK.BGM_INDEX], 11, 8);
+ sub_80BA700(TASK.SE_INDEX, 7, 15);
+ sub_80BA79C(gSENames[TASK.SE_INDEX], 11, 15);
+ TASK.FUNC = sub_80BA65C;
+}
+
+#ifdef NONMATCHING
+bool8 sub_80BA400(u8 taskId) // Task_ProcessSoundCheckMenuInput
+{
+ if(gMain.newKeys & R_BUTTON) // driver test
+ {
+ TASK.FUNC = sub_80BA800;
+ return FALSE;
+ }
+ if(gMain.newKeys & L_BUTTON)
+ {
+ TASK.FUNC = sub_80BAF84;
+ return FALSE;
+ }
+ if(gMain.newKeys & START_BUTTON)
+ {
+ TASK.FUNC = sub_80BB25C;
+ return FALSE;
+ }
+ if(gMain.newKeys & A_BUTTON) // both these cases insist on non reuses of certain data variables and cause the function to not match.
+ {
+ if(TASK.WINDOW_SELECTED != 0) // is playing?
+ {
+ if(TASK.UNK_DATA4 != 0)
+ {
+ if(TASK.SE_INDEX != 0) // why are you insiting on a non signed halfword?
+ {
+ m4aSongNumStop(TASK.UNK_DATA4);
+ }
+ else
+ {
+ m4aSongNumStop(TASK.SE_INDEX);
+ TASK.UNK_DATA4 = TASK.SE_INDEX;
+ return FALSE;
+ }
+ }
+ else if(TASK.SE_INDEX == 0) // _080BA4BA
+ {
+ return FALSE;
+ }
+ // _080BA4C4
+ m4aSongNumStart(TASK.SE_INDEX);
+ TASK.UNK_DATA4 = TASK.SE_INDEX;
+ return FALSE;
+ }
+ else // _080BA4D0
+ {
+ if(TASK.UNK_DATA3 != 0)
+ {
+ if(TASK.BGM_INDEX != 0)
+ {
+ m4aSongNumStop(TASK.UNK_DATA3 + BGM_STOP);
+ }
+ else // _080BA500
+ {
+ m4aSongNumStop(TASK.UNK_DATA3 + BGM_STOP);
+ TASK.UNK_DATA3 = TASK.BGM_INDEX;
+ return FALSE;
+ }
+ }
+ else if(TASK.BGM_INDEX == 0) // _080BA514
+ return FALSE;
+
+ m4aSongNumStart(TASK.BGM_INDEX + BGM_STOP);
+ TASK.UNK_DATA3 = TASK.BGM_INDEX;
+ }
+ return FALSE;
+ }
+ if(gMain.newKeys & B_BUTTON)
+ {
+ m4aSongNumStart(5);
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ TASK.FUNC = sub_80BA68C;
+ return FALSE;
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ TASK.data[8] ^= A_BUTTON; // huh?
+ return TRUE;
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ TASK.data[8] ^= A_BUTTON; // huh?
+ return TRUE;
+ }
+ else
+ {
+ u16 keys = gMain.newAndRepeatedKeys & DPAD_RIGHT;
+ if(keys)
+ {
+ if(TASK.WINDOW_SELECTED != 0)
+ {
+ if(TASK.SE_INDEX > 0)
+ {
+ TASK.SE_INDEX--;
+ }
+ else
+ {
+ TASK.SE_INDEX = 0xF7;
+ }
+ }
+ else if(TASK.BGM_INDEX > 0)
+ {
+ TASK.BGM_INDEX--;
+ }
+ else
+ {
+ TASK.BGM_INDEX = 0x75;
+ }
+ return TRUE;
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_LEFT)
+ {
+ if(TASK.WINDOW_SELECTED != 0)
+ {
+ if(TASK.SE_INDEX < 0xF7)
+ {
+ TASK.SE_INDEX++;
+ }
+ else
+ {
+ TASK.SE_INDEX = keys; // ??
+ }
+ }
+ else if(TASK.BGM_INDEX < 0x75)
+ {
+ TASK.BGM_INDEX++;
+ return TRUE;
+ }
+ else
+ {
+ TASK.BGM_INDEX = TASK.SE_INDEX;
+ return TRUE;
+ }
+ return TRUE;
+ }
+ if(gMain.heldKeys & SELECT_BUTTON)
+ {
+ gUnknown_020387B0 = A_BUTTON;
+ return FALSE;
+ }
+ else
+ {
+ gUnknown_020387B0 = (gMain.heldKeys & SELECT_BUTTON);
+ return FALSE;
+ }
+ }
+}
+#else
+__attribute__((naked))
+bool8 sub_80BA400(u8 taskId)
+{
+ asm(".syntax unified\n\
+ push {r4-r6,lr}\n\
+ sub sp, 0x4\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ ldr r2, _080BA428 @ =gMain\n\
+ ldrh r1, [r2, 0x2E]\n\
+ movs r0, 0x80\n\
+ lsls r0, 1\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _080BA434\n\
+ ldr r0, _080BA42C @ =gTasks\n\
+ lsls r1, r4, 2\n\
+ adds r1, r4\n\
+ lsls r1, 3\n\
+ adds r1, r0\n\
+ ldr r0, _080BA430 @ =sub_80BA800\n\
+ str r0, [r1]\n\
+ b _080BA64C\n\
+ .align 2, 0\n\
+_080BA428: .4byte gMain\n\
+_080BA42C: .4byte gTasks\n\
+_080BA430: .4byte sub_80BA800\n\
+_080BA434:\n\
+ movs r0, 0x80\n\
+ lsls r0, 2\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _080BA458\n\
+ ldr r0, _080BA450 @ =gTasks\n\
+ lsls r1, r4, 2\n\
+ adds r1, r4\n\
+ lsls r1, 3\n\
+ adds r1, r0\n\
+ ldr r0, _080BA454 @ =sub_80BAF84\n\
+ str r0, [r1]\n\
+ b _080BA64C\n\
+ .align 2, 0\n\
+_080BA450: .4byte gTasks\n\
+_080BA454: .4byte sub_80BAF84\n\
+_080BA458:\n\
+ movs r0, 0x8\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _080BA478\n\
+ ldr r0, _080BA470 @ =gTasks\n\
+ lsls r1, r4, 2\n\
+ adds r1, r4\n\
+ lsls r1, 3\n\
+ adds r1, r0\n\
+ ldr r0, _080BA474 @ =sub_80BB25C\n\
+ str r0, [r1]\n\
+ b _080BA64C\n\
+ .align 2, 0\n\
+_080BA470: .4byte gTasks\n\
+_080BA474: .4byte sub_80BB25C\n\
+_080BA478:\n\
+ movs r6, 0x1\n\
+ movs r5, 0x1\n\
+ ands r5, r1\n\
+ cmp r5, 0\n\
+ beq _080BA538\n\
+ ldr r0, _080BA4AC @ =gTasks\n\
+ lsls r1, r4, 2\n\
+ adds r1, r4\n\
+ lsls r1, 3\n\
+ adds r5, r1, r0\n\
+ movs r1, 0x8\n\
+ ldrsh r0, [r5, r1]\n\
+ cmp r0, 0\n\
+ beq _080BA4D0\n\
+ movs r2, 0x10\n\
+ ldrsh r0, [r5, r2]\n\
+ cmp r0, 0\n\
+ beq _080BA4BA\n\
+ movs r3, 0xC\n\
+ ldrsh r4, [r5, r3]\n\
+ cmp r4, 0\n\
+ beq _080BA4B0\n\
+ ldrh r0, [r5, 0x10]\n\
+ bl m4aSongNumStop\n\
+ b _080BA4C4\n\
+ .align 2, 0\n\
+_080BA4AC: .4byte gTasks\n\
+_080BA4B0:\n\
+ ldrh r0, [r5, 0x10]\n\
+ bl m4aSongNumStop\n\
+ strh r4, [r5, 0x10]\n\
+ b _080BA64C\n\
+_080BA4BA:\n\
+ movs r4, 0xC\n\
+ ldrsh r0, [r5, r4]\n\
+ cmp r0, 0\n\
+ bne _080BA4C4\n\
+ b _080BA64C\n\
+_080BA4C4:\n\
+ ldrh r0, [r5, 0xC]\n\
+ bl m4aSongNumStart\n\
+ ldrh r0, [r5, 0xC]\n\
+ strh r0, [r5, 0x10]\n\
+ b _080BA64C\n\
+_080BA4D0:\n\
+ ldrh r1, [r5, 0xE]\n\
+ movs r2, 0xE\n\
+ ldrsh r0, [r5, r2]\n\
+ cmp r0, 0\n\
+ beq _080BA514\n\
+ movs r3, 0xA\n\
+ ldrsh r4, [r5, r3]\n\
+ cmp r4, 0\n\
+ beq _080BA500\n\
+ ldr r0, _080BA4FC @ =0x0000015d\n\
+ adds r4, r0, 0\n\
+ adds r0, r1, r4\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ bl m4aSongNumStop\n\
+ ldrh r1, [r5, 0xA]\n\
+ adds r4, r1\n\
+ lsls r4, 16\n\
+ lsrs r4, 16\n\
+ adds r0, r4, 0\n\
+ b _080BA528\n\
+ .align 2, 0\n\
+_080BA4FC: .4byte 0x0000015d\n\
+_080BA500:\n\
+ ldr r2, _080BA510 @ =0x0000015d\n\
+ adds r0, r1, r2\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ bl m4aSongNumStop\n\
+ strh r4, [r5, 0xE]\n\
+ b _080BA64C\n\
+ .align 2, 0\n\
+_080BA510: .4byte 0x0000015d\n\
+_080BA514:\n\
+ ldrh r1, [r5, 0xA]\n\
+ movs r3, 0xA\n\
+ ldrsh r0, [r5, r3]\n\
+ cmp r0, 0\n\
+ bne _080BA520\n\
+ b _080BA64C\n\
+_080BA520:\n\
+ ldr r4, _080BA534 @ =0x0000015d\n\
+ adds r0, r1, r4\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+_080BA528:\n\
+ bl m4aSongNumStart\n\
+ ldrh r0, [r5, 0xA]\n\
+ strh r0, [r5, 0xE]\n\
+ b _080BA64C\n\
+ .align 2, 0\n\
+_080BA534: .4byte 0x0000015d\n\
+_080BA538:\n\
+ movs r0, 0x2\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _080BA570\n\
+ movs r0, 0x5\n\
+ bl m4aSongNumStart\n\
+ movs r0, 0x1\n\
+ negs r0, r0\n\
+ str r5, [sp]\n\
+ movs r1, 0\n\
+ movs r2, 0\n\
+ movs r3, 0x10\n\
+ bl BeginNormalPaletteFade\n\
+ ldr r1, _080BA568 @ =gTasks\n\
+ lsls r0, r4, 2\n\
+ adds r0, r4\n\
+ lsls r0, 3\n\
+ adds r0, r1\n\
+ ldr r1, _080BA56C @ =sub_80BA68C\n\
+ str r1, [r0]\n\
+ b _080BA64C\n\
+ .align 2, 0\n\
+_080BA568: .4byte gTasks\n\
+_080BA56C: .4byte sub_80BA68C\n\
+_080BA570:\n\
+ ldrh r1, [r2, 0x30]\n\
+ movs r0, 0x40\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _080BA582\n\
+ movs r0, 0x80\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _080BA59C\n\
+_080BA582:\n\
+ ldr r0, _080BA598 @ =gTasks\n\
+ lsls r1, r4, 2\n\
+ adds r1, r4\n\
+ lsls r1, 3\n\
+ adds r1, r0\n\
+ ldrh r0, [r1, 0x8]\n\
+ eors r0, r6\n\
+ strh r0, [r1, 0x8]\n\
+_080BA592:\n\
+ movs r0, 0x1\n\
+ b _080BA64E\n\
+ .align 2, 0\n\
+_080BA598: .4byte gTasks\n\
+_080BA59C:\n\
+ movs r0, 0x10\n\
+ ands r0, r1\n\
+ lsls r0, 16\n\
+ lsrs r3, r0, 16\n\
+ cmp r3, 0\n\
+ beq _080BA5EA\n\
+ ldr r0, _080BA5CC @ =gTasks\n\
+ lsls r1, r4, 2\n\
+ adds r1, r4\n\
+ lsls r1, 3\n\
+ adds r1, r0\n\
+ movs r2, 0x8\n\
+ ldrsh r0, [r1, r2]\n\
+ cmp r0, 0\n\
+ beq _080BA5D6\n\
+ ldrh r2, [r1, 0xC]\n\
+ movs r3, 0xC\n\
+ ldrsh r0, [r1, r3]\n\
+ cmp r0, 0\n\
+ ble _080BA5D0\n\
+ subs r0, r2, 0x1\n\
+ strh r0, [r1, 0xC]\n\
+ b _080BA592\n\
+ .align 2, 0\n\
+_080BA5CC: .4byte gTasks\n\
+_080BA5D0:\n\
+ movs r0, 0xF7\n\
+ strh r0, [r1, 0xC]\n\
+ b _080BA592\n\
+_080BA5D6:\n\
+ ldrh r2, [r1, 0xA]\n\
+ movs r4, 0xA\n\
+ ldrsh r0, [r1, r4]\n\
+ cmp r0, 0\n\
+ ble _080BA5E4\n\
+ subs r0, r2, 0x1\n\
+ b _080BA5E6\n\
+_080BA5E4:\n\
+ movs r0, 0x75\n\
+_080BA5E6:\n\
+ strh r0, [r1, 0xA]\n\
+ b _080BA592\n\
+_080BA5EA:\n\
+ movs r0, 0x20\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _080BA630\n\
+ ldr r1, _080BA614 @ =gTasks\n\
+ lsls r0, r4, 2\n\
+ adds r0, r4\n\
+ lsls r0, 3\n\
+ adds r1, r0, r1\n\
+ movs r0, 0x8\n\
+ ldrsh r2, [r1, r0]\n\
+ cmp r2, 0\n\
+ beq _080BA61C\n\
+ ldrh r2, [r1, 0xC]\n\
+ movs r4, 0xC\n\
+ ldrsh r0, [r1, r4]\n\
+ cmp r0, 0xF6\n\
+ bgt _080BA618\n\
+ adds r0, r2, 0x1\n\
+ strh r0, [r1, 0xC]\n\
+ b _080BA592\n\
+ .align 2, 0\n\
+_080BA614: .4byte gTasks\n\
+_080BA618:\n\
+ strh r3, [r1, 0xC]\n\
+ b _080BA592\n\
+_080BA61C:\n\
+ ldrh r3, [r1, 0xA]\n\
+ movs r4, 0xA\n\
+ ldrsh r0, [r1, r4]\n\
+ cmp r0, 0x74\n\
+ bgt _080BA62C\n\
+ adds r0, r3, 0x1\n\
+ strh r0, [r1, 0xA]\n\
+ b _080BA592\n\
+_080BA62C:\n\
+ strh r2, [r1, 0xA]\n\
+ b _080BA592\n\
+_080BA630:\n\
+ ldrh r1, [r2, 0x2C]\n\
+ movs r0, 0x4\n\
+ ands r0, r1\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ cmp r1, 0\n\
+ beq _080BA648\n\
+ ldr r0, _080BA644 @ =gUnknown_020387B0\n\
+ strb r6, [r0]\n\
+ b _080BA64C\n\
+ .align 2, 0\n\
+_080BA644: .4byte gUnknown_020387B0\n\
+_080BA648:\n\
+ ldr r0, _080BA658 @ =gUnknown_020387B0\n\
+ strb r1, [r0]\n\
+_080BA64C:\n\
+ movs r0, 0\n\
+_080BA64E:\n\
+ add sp, 0x4\n\
+ pop {r4-r6}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .align 2, 0\n\
+_080BA658: .4byte gUnknown_020387B0\n\
+ .syntax divided");
+}
+#endif
+
+void sub_80BA65C(u8 taskId)
+{
+ if(sub_80BA400(taskId) != FALSE)
+ TASK.FUNC = sub_80BA384;
+}
+
+void sub_80BA68C(u8 taskId)
+{
+ if(!gPaletteFade.active)
+ {
+ DestroyTask(taskId);
+ SetMainCallback2(CB2_InitTitleScreen);
+ }
+}
+
+void sub_80BA6B8(u8 windowType)
+{
+ switch(windowType)
+ {
+ case BGM_WINDOW:
+ default:
+ REG_WIN1H = WIN_RANGE(17, 223);
+ REG_WIN1V = WIN_RANGE(41, 87);
+ break;
+ case SE_WINDOW:
+ REG_WIN1H = WIN_RANGE(17, 223);
+ REG_WIN1V = WIN_RANGE(97, 143);
+ break;
+ }
+}
+
+void sub_80BA700(u16 soundIndex, u16 x, u16 y) // PrintSoundNumber ?
+{
+ u8 i;
+ u8 str[5];
+ bool8 someBool;
+ u8 divisorValue;
+
+ for(i = 0; i < 3; i++)
+ str[i] = 0; // initialize array
+
+ str[3] = CHAR_ELLIPSIS;
+ str[4] = EOS;
+ someBool = FALSE;
+
+ divisorValue = soundIndex / 100;
+ if(divisorValue)
+ {
+ str[0] = divisorValue + CHAR_0;
+ someBool = TRUE;
+ }
+
+ divisorValue = (soundIndex % 100) / 10;
+ if(divisorValue || someBool != FALSE)
+ str[1] = divisorValue + CHAR_0;
+
+ str[2] = ((soundIndex % 100) % 10) + CHAR_0;
+ MenuPrint(str, x, y);
+}
+
+void sub_80BA79C(const u8 *const string, u16 x, u16 y)
+{
+ u8 i;
+ u8 str[11];
+
+ for(i = 0; i < 11; i++)
+ str[i] = 0; // format string.
+
+ str[10] = EOS; // the above for loop formats the last element of the array unnecessarily.
+
+ for(i = 0; string[i] != EOS && i < 10; i++)
+ str[i] = string[i];
+
+ MenuPrint(str, x, y);
+}
+
+void sub_80BA800(u8 taskId) // Task_DrawDriverTestMenu
+{
+ u8 bbackStr[sizeof(gDebugText_BBack)];
+ u8 aplayStr[sizeof(gDebugText_APlay)];
+ u8 voiceStr[sizeof(gDebugText_Voice)];
+ u8 volumeStr[sizeof(gDebugText_Volume)];
+ u8 panpotStr[sizeof(gDebugText_Panpot)];
+ u8 pitchStr[sizeof(gDebugText_Pitch)];
+ u8 lengthStr[sizeof(gDebugText_Length)];
+ u8 releaseStr[sizeof(gDebugText_Release)];
+ u8 progressStr[sizeof(gDebugText_Progress)];
+ u8 chorusStr[sizeof(gDebugText_Chorus)];
+ u8 priorityStr[sizeof(gDebugText_Priority)];
+ u8 playingStr[sizeof(gDebugText_Playing)];
+ u8 reverseStr[sizeof(gDebugText_Reverse)];
+ u8 stereoStr[sizeof(gDebugText_Stereo)];
+
+ memcpy(bbackStr, gDebugText_BBack, sizeof(gDebugText_BBack));
+ memcpy(aplayStr, gDebugText_APlay, sizeof(gDebugText_APlay));
+ memcpy(voiceStr, gDebugText_Voice, sizeof(gDebugText_Voice));
+ memcpy(volumeStr, gDebugText_Volume, sizeof(gDebugText_Volume));
+ memcpy(panpotStr, gDebugText_Panpot, sizeof(gDebugText_Panpot));
+ memcpy(pitchStr, gDebugText_Pitch, sizeof(gDebugText_Pitch));
+ memcpy(lengthStr, gDebugText_Length, sizeof(gDebugText_Length));
+ memcpy(releaseStr, gDebugText_Release, sizeof(gDebugText_Release));
+ memcpy(progressStr, gDebugText_Progress, sizeof(gDebugText_Progress));
+ memcpy(chorusStr, gDebugText_Chorus, sizeof(gDebugText_Chorus));
+ memcpy(priorityStr, gDebugText_Priority, sizeof(gDebugText_Priority));
+ memcpy(playingStr, gDebugText_Playing, sizeof(gDebugText_Playing));
+ memcpy(reverseStr, gDebugText_Reverse, sizeof(gDebugText_Reverse));
+ memcpy(stereoStr, gDebugText_Stereo, sizeof(gDebugText_Stereo));
+
+ REG_DISPCNT = 0x3140;
+ MenuDrawTextWindow(0, 0, 0x1D, 0x13);
+ MenuPrint(bbackStr, 0x13, 0x4);
+ MenuPrint(aplayStr, 0x13, 0x2);
+ MenuPrint(voiceStr, 0x2, 0x1);
+ MenuPrint(volumeStr, 0x2, 0x3);
+ MenuPrint(panpotStr, 0x2, 0x5);
+ MenuPrint(pitchStr, 0x2, 0x7);
+ MenuPrint(lengthStr, 0x2, 0x9);
+ MenuPrint(releaseStr, 0x2, 0xB);
+ MenuPrint(progressStr, 0x2, 0xD);
+ MenuPrint(chorusStr, 0x2, 0xF);
+ MenuPrint(priorityStr, 0x2, 0x11);
+ MenuPrint(playingStr, 0x13, 0x10);
+ MenuPrint(reverseStr, 0x13, 0xE);
+ MenuPrint(stereoStr, 0x13, 0xC);
+ REG_WIN0H = WIN_RANGE(0, 240);
+ REG_WIN0V = WIN_RANGE(0, 160);
+ gUnknown_020387B3 = 0;
+ gUnknown_020387B1 = 0;
+ gUnknown_020387B2 = 0;
+ gUnknown_03005D30 = NULL;
+ gUnknown_020387D8 = 0;
+ gUnknown_020387D9 = 1;
+ gUnknown_020387B4[CRY_TEST_UNK0] = 0;
+ gUnknown_020387B4[CRY_TEST_VOLUME] = 0x78;
+ gUnknown_020387B4[CRY_TEST_PANPOT] = 0;
+ gUnknown_020387B4[CRY_TEST_PITCH] = 0x3C00;
+ gUnknown_020387B4[CRY_TEST_LENGTH] = 0xB4;
+ gUnknown_020387B4[CRY_TEST_PROGRESS] = 0;
+ gUnknown_020387B4[CRY_TEST_RELEASE] = 0;
+ gUnknown_020387B4[CRY_TEST_CHORUS] = 0;
+ gUnknown_020387B4[CRY_TEST_PRIORITY] = 2;
+ sub_80BAD5C();
+ sub_80BAE10(0, 0);
+ TASK.FUNC = sub_80BAA48;
+}
+
+void sub_80BAA48(u8 taskId) // Task_ProcessDriverTestInput
+{
+ if(gMain.newKeys & B_BUTTON)
+ {
+ REG_DISPCNT = 0x7140;
+ REG_WIN0H = WIN_RANGE(17, 223);
+ REG_WIN0V = WIN_RANGE(1, 31);
+ MenuZeroFillWindowRect(0, 0, 0x1D, 0x13);
+ TASK.FUNC = sub_80BA258;
+ return;
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_UP) // _080BAAA8
+ {
+ u8 backupVar = gUnknown_020387B3;
+ if(--gUnknown_020387B3 < 0)
+ gUnknown_020387B3 = 8;
+
+ sub_80BAE10(backupVar, gUnknown_020387B3);
+ return;
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_DOWN) // _080BAAD0
+ {
+ u8 backupVar = gUnknown_020387B3;
+ if(++gUnknown_020387B3 > 8)
+ gUnknown_020387B3 = 0;
+
+ sub_80BAE10(backupVar, gUnknown_020387B3);
+ return;
+ }
+ if(gMain.newKeys & START_BUTTON) // _080BAAF8
+ {
+ gUnknown_020387D8 ^= 1;
+ sub_80BAD5C();
+ return;
+ }
+ if(gMain.newKeys & SELECT_BUTTON) // _080BAB14
+ {
+ gUnknown_020387D9 ^= 1;
+ sub_80BAD5C();
+ SetPokemonCryStereo(gUnknown_020387D9);
+ return;
+ }
+ if(gMain.newAndRepeatedKeys & R_BUTTON) // _080BAB38
+ {
+ sub_80BACDC(10);
+ sub_80BAD5C();
+ return;
+ }
+ if(gMain.newAndRepeatedKeys & L_BUTTON) // _080BAB46
+ {
+ sub_80BACDC(-10);
+ sub_80BAD5C();
+ return;
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_LEFT) // _080BAB56
+ {
+ sub_80BACDC(-1);
+ sub_80BAD5C();
+ return;
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_RIGHT) // _080BAB64
+ {
+ sub_80BACDC(1);
+ sub_80BAD5C();
+ return;
+ }
+ if(gMain.newKeys & A_BUTTON) // _080BAB78
+ {
+ u8 divide, remaining;
+
+ SetPokemonCryVolume(gUnknown_020387B4[CRY_TEST_VOLUME]);
+ SetPokemonCryPanpot(gUnknown_020387B4[CRY_TEST_PANPOT]);
+ SetPokemonCryPitch(gUnknown_020387B4[CRY_TEST_PITCH]);
+ SetPokemonCryLength(gUnknown_020387B4[CRY_TEST_LENGTH]);
+ SetPokemonCryProgress(gUnknown_020387B4[CRY_TEST_PROGRESS]);
+ SetPokemonCryRelease(gUnknown_020387B4[CRY_TEST_RELEASE]);
+ SetPokemonCryChorus(gUnknown_020387B4[CRY_TEST_CHORUS]);
+ SetPokemonCryPriority(gUnknown_020387B4[CRY_TEST_PRIORITY]);
+
+ remaining = gUnknown_020387B4[CRY_TEST_UNK0] % 128;
+ divide = gUnknown_020387B4[CRY_TEST_UNK0] / 128;
+
+ switch(divide)
+ {
+ case 0:
+ if(gUnknown_020387D8)
+ gUnknown_03005D30 = SetPokemonCryTone(&voicegroup_84537C0[remaining]);
+ else
+ gUnknown_03005D30 = SetPokemonCryTone(&voicegroup_8452590[remaining]);
+ break;
+ case 1:
+ if(gUnknown_020387D8)
+ gUnknown_03005D30 = SetPokemonCryTone(&voicegroup_8453DC0[remaining]);
+ else
+ gUnknown_03005D30 = SetPokemonCryTone(&voicegroup_8452B90[remaining]);
+ break;
+ case 2:
+ if(gUnknown_020387D8)
+ gUnknown_03005D30 = SetPokemonCryTone(&voicegroup_84543C0[remaining]);
+ else
+ gUnknown_03005D30 = SetPokemonCryTone(&voicegroup_8453190[remaining]);
+ break;
+ case 3:
+ if(gUnknown_020387D8)
+ gUnknown_03005D30 = SetPokemonCryTone(&voicegroup_84549C0[remaining]);
+ else
+ gUnknown_03005D30 = SetPokemonCryTone(&voicegroup_8453790[remaining]);
+ break;
+ }
+ }
+
+ // _080BACA2
+ if(gUnknown_03005D30 != NULL)
+ {
+ gUnknown_020387B1 = IsPokemonCryPlaying(gUnknown_03005D30);
+
+ if(gUnknown_020387B1 != gUnknown_020387B2)
+ sub_80BAD5C();
+
+ gUnknown_020387B2 = gUnknown_020387B1;
+ }
+}
+
+void sub_80BACDC(s8 var)
+{
+ int minMaxArray[ARRAY_COUNT(gUnknown_083D039C)];
+
+ memcpy(minMaxArray, gUnknown_083D039C, sizeof(gUnknown_083D039C));
+ gUnknown_020387B4[gUnknown_020387B3] += var;
+
+ if(gUnknown_020387B4[gUnknown_020387B3] > minMaxArray[MULTI_DIM_ARR(gUnknown_020387B3, B_16, MAX)])
+ gUnknown_020387B4[gUnknown_020387B3] = minMaxArray[MULTI_DIM_ARR(gUnknown_020387B3, B_16, MIN)];
+
+ if(gUnknown_020387B4[gUnknown_020387B3] < minMaxArray[MULTI_DIM_ARR(gUnknown_020387B3, B_16, MIN)])
+ gUnknown_020387B4[gUnknown_020387B3] = minMaxArray[MULTI_DIM_ARR(gUnknown_020387B3, B_16, MAX)];
+}
+
+void sub_80BAD5C(void)
+{
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_UNK0] + 1, 0xB, 0x1, 0x5);
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_VOLUME], 0xB, 0x3, 0x5);
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_PANPOT], 0xB, 0x5, 0x5);
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_PITCH], 0xB, 0x7, 0x5);
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_LENGTH], 0xB, 0x9, 0x5);
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_RELEASE], 0xB, 0xB, 0x5);
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_PROGRESS], 0xB, 0xD, 0x5);
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_CHORUS], 0xB, 0xF, 0x5);
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_PRIORITY], 0xB, 0x11, 0x5);
+ sub_80BAE78(gUnknown_020387B1, 0x1B, 0x10, 0x1);
+ sub_80BAE78(gUnknown_020387D8, 0x1B, 0xE, 0x1);
+ sub_80BAE78(gUnknown_020387D9, 0x1B, 0xC, 0x1);
+}
+
+void sub_80BAE10(u8 var1, u8 var2)
+{
+ u8 str1[sizeof(gUnknown_083D03DC)];
+ u8 str2[sizeof(gUnknown_083D03DE)];
+
+ memcpy(str1, gUnknown_083D03DC, sizeof(gUnknown_083D03DC));
+ memcpy(str2, gUnknown_083D03DE, sizeof(gUnknown_083D03DE));
+
+ MenuPrint(str2, gUnknown_083D0300[MULTI_DIM_ARR(var1, B_16, 0)], gUnknown_083D0300[MULTI_DIM_ARR(var1, B_16, 1)]);
+ MenuPrint(str1, gUnknown_083D0300[MULTI_DIM_ARR(var2, B_16, 0)], gUnknown_083D0300[MULTI_DIM_ARR(var2, B_16, 1)]);
+}
+
+/*void sub_80BAE78(int var1, u16 var2, u16 var3, u8 var4)
+{
+ u32 powers[6];
+ u8 str[8];
+ u8 i;
+ u8 someVar, someVar2;
+
+ memcpy(powers, gUnknown_083D03E0, sizeof(powers);
+
+ for(i = 0; i < var4; i++)
+ str[i] = 0;
+
+ str[var4 + 1] = CHAR_0;
+ someVar = 0;
+
+ if(var1 < 0) // make absolute value? wtf
+ {
+ var1 = -var1; // just use abs?
+ someVar = 1;
+ }
+
+ // _080BAED6
+ someVar2 = 0;
+ if(var4 == 1)
+ someVar2 = 1;
+
+ // _080BAEE2
+ for(;;)
+ {
+
+ }
+}*/
+
+// no.
+__attribute__((naked))
+void sub_80BAE78(int var1, u16 var2, u16 var3, u8 var4)
+{
+ 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, 0x2C\n\
+ mov r8, r0\n\
+ lsls r1, 16\n\
+ lsrs r6, r1, 16\n\
+ lsls r2, 16\n\
+ lsrs r2, 16\n\
+ lsls r3, 24\n\
+ lsrs r7, r3, 24\n\
+ mov r1, sp\n\
+ ldr r0, _080BAF80 @ =gUnknown_083D03E0\n\
+ ldm r0!, {r3-r5}\n\
+ stm r1!, {r3-r5}\n\
+ ldm r0!, {r3-r5}\n\
+ stm r1!, {r3-r5}\n\
+ movs r5, 0\n\
+ add r0, sp, 0x18\n\
+ mov r9, r0\n\
+ cmp r5, r7\n\
+ bgt _080BAEC0\n\
+ mov r4, r9\n\
+ movs r3, 0\n\
+_080BAEAC:\n\
+ lsls r0, r5, 24\n\
+ asrs r0, 24\n\
+ adds r1, r4, r0\n\
+ strb r3, [r1]\n\
+ adds r0, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r5, r0, 24\n\
+ asrs r0, 24\n\
+ cmp r0, r7\n\
+ ble _080BAEAC\n\
+_080BAEC0:\n\
+ adds r0, r7, 0x1\n\
+ add r0, r9\n\
+ movs r1, 0xFF\n\
+ strb r1, [r0]\n\
+ movs r1, 0\n\
+ mov r3, r8\n\
+ cmp r3, 0\n\
+ bge _080BAED6\n\
+ negs r3, r3\n\
+ mov r8, r3\n\
+ movs r1, 0x1\n\
+_080BAED6:\n\
+ movs r4, 0\n\
+ mov r10, r4\n\
+ cmp r7, 0x1\n\
+ bne _080BAEE2\n\
+ movs r5, 0x1\n\
+ mov r10, r5\n\
+_080BAEE2:\n\
+ subs r0, r7, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r5, r0, 24\n\
+ lsls r0, r5, 24\n\
+ lsls r6, 24\n\
+ str r6, [sp, 0x24]\n\
+ lsls r2, 24\n\
+ str r2, [sp, 0x28]\n\
+ cmp r0, 0\n\
+ blt _080BAF62\n\
+ str r1, [sp, 0x20]\n\
+_080BAEF8:\n\
+ asrs r6, r0, 24\n\
+ lsls r0, r6, 2\n\
+ add r0, sp\n\
+ ldr r1, [r0]\n\
+ mov r0, r8\n\
+ bl __divsi3\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+ cmp r0, 0\n\
+ bne _080BAF1A\n\
+ mov r0, r10\n\
+ cmp r0, 0\n\
+ bne _080BAF1A\n\
+ lsls r4, r5, 24\n\
+ cmp r6, 0\n\
+ bne _080BAF46\n\
+_080BAF1A:\n\
+ lsls r4, r5, 24\n\
+ ldr r3, [sp, 0x20]\n\
+ cmp r3, 0\n\
+ beq _080BAF34\n\
+ mov r5, r10\n\
+ cmp r5, 0\n\
+ bne _080BAF34\n\
+ asrs r0, r4, 24\n\
+ subs r0, r7, r0\n\
+ subs r0, 0x1\n\
+ add r0, r9\n\
+ movs r1, 0xAE\n\
+ strb r1, [r0]\n\
+_080BAF34:\n\
+ asrs r1, r4, 24\n\
+ subs r1, r7, r1\n\
+ add r1, r9\n\
+ lsls r0, r2, 24\n\
+ asrs r0, 24\n\
+ subs r0, 0x5F\n\
+ strb r0, [r1]\n\
+ movs r0, 0x1\n\
+ mov r10, r0\n\
+_080BAF46:\n\
+ asrs r4, 24\n\
+ lsls r0, r4, 2\n\
+ add r0, sp\n\
+ ldr r1, [r0]\n\
+ mov r0, r8\n\
+ bl __modsi3\n\
+ mov r8, r0\n\
+ subs r4, 0x1\n\
+ lsls r4, 24\n\
+ lsrs r5, r4, 24\n\
+ lsls r0, r5, 24\n\
+ cmp r0, 0\n\
+ bge _080BAEF8\n\
+_080BAF62:\n\
+ ldr r3, [sp, 0x24]\n\
+ lsrs r1, r3, 24\n\
+ ldr r4, [sp, 0x28]\n\
+ lsrs r2, r4, 24\n\
+ mov r0, r9\n\
+ bl MenuPrint\n\
+ add sp, 0x2C\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\
+ .align 2, 0\n\
+_080BAF80: .4byte gUnknown_083D03E0\n\
+ .syntax divided");
+}
+
+void sub_80BAF84(u8 taskId)
+{
+ u8 seStr[sizeof(gOtherText_SE)];
+ u8 panStr[sizeof(gOtherText_Pan)];
+ u8 playingStr[sizeof(gDebugText_Playing)];
+
+ memcpy(seStr, gOtherText_SE, sizeof(gOtherText_SE));
+ memcpy(panStr, gOtherText_Pan, sizeof(gOtherText_Pan));
+ memcpy(playingStr, gDebugText_Playing, sizeof(gDebugText_Playing));
+
+ REG_DISPCNT = 0x3140;
+ MenuDrawTextWindow(0, 0, 0x1D, 0x13);
+ MenuPrint(seStr, 3, 2);
+ MenuPrint(panStr, 3, 4);
+ MenuPrint(playingStr, 3, 8);
+ REG_WIN0H = WIN_RANGE(0, 240);
+ REG_WIN0V = WIN_RANGE(0, 160);
+ gUnknown_020387B4[CRY_TEST_UNK0] = 1;
+ gUnknown_020387B4[CRY_TEST_PANPOT] = 0;
+ gUnknown_020387B4[CRY_TEST_CHORUS] = 0;
+ gUnknown_020387B4[CRY_TEST_PROGRESS] = 0;
+ gUnknown_020387B4[CRY_TEST_RELEASE] = 0;
+ sub_80BB1D4();
+ TASK.FUNC = sub_80BB038;
+}
+
+void sub_80BB038(u8 taskId)
+{
+ sub_80BB1D4();
+ if(gUnknown_020387B4[CRY_TEST_PROGRESS])
+ {
+ if(gUnknown_020387B4[CRY_TEST_RELEASE])
+ {
+ gUnknown_020387B4[CRY_TEST_RELEASE]--;
+ }
+ else // _080BB05C
+ {
+ s8 panpot = gUnknown_083D03F8[gUnknown_020387B4[CRY_TEST_PANPOT]];
+ if(panpot != -128)
+ {
+ if(panpot == 0x7F)
+ {
+ gUnknown_020387B4[CRY_TEST_CHORUS] += 2;
+ if(gUnknown_020387B4[CRY_TEST_CHORUS] < 0x3F)
+ SE12PanpotControl(gUnknown_020387B4[CRY_TEST_CHORUS]);
+ }
+ }
+ else // _080BB08C
+ {
+ gUnknown_020387B4[CRY_TEST_CHORUS] -= 2;
+ if(gUnknown_020387B4[CRY_TEST_CHORUS] > -0x40)
+ SE12PanpotControl(gUnknown_020387B4[CRY_TEST_CHORUS]);
+ }
+ }
+ }
+ // _080BB0A2
+ if(gMain.newKeys & B_BUTTON)
+ {
+ REG_DISPCNT = 0x7140;
+ REG_WIN0H = WIN_RANGE(17, 223);
+ REG_WIN0V = WIN_RANGE(1, 31);
+ MenuZeroFillWindowRect(0, 0, 0x1D, 0x13);
+ TASK.FUNC = sub_80BA258;
+ return;
+ }
+ if(gMain.newKeys & A_BUTTON) // _080BB104
+ {
+ s8 panpot = gUnknown_083D03F8[gUnknown_020387B4[CRY_TEST_PANPOT]];
+ if(panpot != -128)
+ {
+ if(panpot == 0x7F)
+ {
+ PlaySE12WithPanning(gUnknown_020387B4[CRY_TEST_UNK0], -0x40);
+ gUnknown_020387B4[CRY_TEST_CHORUS] = -0x40;
+ gUnknown_020387B4[CRY_TEST_PROGRESS] = 1;
+ gUnknown_020387B4[CRY_TEST_RELEASE] = 0x1E;
+ return;
+ }
+ }
+ else // _080BB140
+ {
+ PlaySE12WithPanning(gUnknown_020387B4[CRY_TEST_UNK0], 0x3F);
+ gUnknown_020387B4[CRY_TEST_CHORUS] = 0x3F;
+ gUnknown_020387B4[CRY_TEST_PROGRESS] = 1;
+ gUnknown_020387B4[CRY_TEST_RELEASE] = 0x1E;
+ return;
+ }
+ // _080BB154
+ PlaySE12WithPanning(gUnknown_020387B4[CRY_TEST_UNK0], panpot);
+ gUnknown_020387B4[CRY_TEST_PROGRESS] = 0;
+ return;
+ }
+ if(gMain.newKeys & L_BUTTON) // _080BB15E
+ {
+ gUnknown_020387B4[CRY_TEST_PANPOT]++;
+ if(gUnknown_020387B4[CRY_TEST_PANPOT] > 4)
+ gUnknown_020387B4[CRY_TEST_PANPOT] = 0;
+ }
+ if(gMain.newKeys & R_BUTTON) // _080BB176
+ {
+ gUnknown_020387B4[CRY_TEST_PANPOT]--;
+ if(gUnknown_020387B4[CRY_TEST_PANPOT] < 0)
+ gUnknown_020387B4[CRY_TEST_PANPOT] = 4;
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_RIGHT) // _080BB192
+ {
+ gUnknown_020387B4[CRY_TEST_UNK0]++;
+ if(gUnknown_020387B4[CRY_TEST_UNK0] > 0xF7)
+ gUnknown_020387B4[CRY_TEST_UNK0] = 0;
+ }
+ else if(gMain.newAndRepeatedKeys & DPAD_LEFT) // _080BB1B0
+ {
+ gUnknown_020387B4[CRY_TEST_UNK0]--;
+ if(gUnknown_020387B4[CRY_TEST_UNK0] < 0)
+ gUnknown_020387B4[CRY_TEST_UNK0] = 0xF7;
+ }
+}
+
+void sub_80BB1D4(void)
+{
+ u8 lrStr[sizeof(gOtherText_LR)];
+ u8 rlStr[sizeof(gOtherText_RL)];
+
+ memcpy(lrStr, gOtherText_LR, sizeof(lrStr));
+ memcpy(rlStr, gOtherText_RL, sizeof(rlStr));
+
+ sub_80BAE78(gUnknown_020387B4[CRY_TEST_UNK0], 7, 2, 3);
+
+ switch(gUnknown_083D03F8[gUnknown_020387B4[CRY_TEST_PANPOT]])
+ {
+ case 0x7F:
+ MenuPrint(lrStr, 7, 4);
+ break;
+ case -0x80:
+ MenuPrint(rlStr, 7, 4);
+ break;
+ default:
+ sub_80BAE78(gUnknown_083D03F8[gUnknown_020387B4[CRY_TEST_PANPOT]], 7, 4, 3);
+ break;
+ }
+ sub_80BAE78(IsSEPlaying(), 12, 8, 1);
+}
+
+void sub_80BB25C(u8 taskId)
+{
+ struct CryRelatedStruct cryStruct, cryStruct2;
+ u8 zero;
+
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ gUnknown_03005D34 = 1;
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+
+ cryStruct.unk0 = 0x2000;
+ cryStruct.unk2 = 29;
+ cryStruct.paletteNo = 12;
+ cryStruct.yPos = 30;
+ cryStruct.xPos = 4;
+
+ zero = 0; // wtf?
+ gUnknown_03005E98 = 0;
+
+ while(sub_8119E3C(&cryStruct, 3) == FALSE);
+
+ cryStruct2.unk0 = 0;
+ cryStruct2.unk2 = 15;
+ cryStruct2.paletteNo = 13;
+ cryStruct2.xPos = 12;
+ cryStruct2.yPos = 12;
+
+ zero = 0; // wtf?
+ gUnknown_03005E98 = 0;
+
+ while(ShowPokedexCryScreen(&cryStruct2, 2) == FALSE);
+
+ MenuDrawTextWindow(0, 16, 5, 19);
+ sub_80BB494();
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0);
+ REG_BG2HOFS = 0;
+ REG_BG2VOFS = 0;
+ REG_BG2CNT = 0xF01;
+ REG_BG3CNT = 0x1D03;
+ REG_DISPCNT = 0x1d40;
+ m4aMPlayFadeOutTemporarily(&gMPlay_BGM, 2);
+ TASK.FUNC = sub_80BB3B4;
+}
+
+void sub_80BB3B4(u8 taskId)
+{
+ sub_8119F88(3);
+
+ if(gMain.newKeys & A_BUTTON)
+ {
+ sub_811A050(gUnknown_03005D34);
+ }
+ if(gMain.newKeys & R_BUTTON)
+ {
+ StopCryAndClearCrySongs();
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if(--gUnknown_03005D34 == 0)
+ gUnknown_03005D34 = 384; // total species
+ sub_80BB494();
+ }
+ if(gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if(++gUnknown_03005D34 > 384)
+ gUnknown_03005D34 = 1;
+ sub_80BB494();
+ }
+ if(gMain.newKeys & B_BUTTON)
+ {
+ REG_DISPCNT = 0x7140;
+ REG_WIN0H = WIN_RANGE(17, 223);
+ REG_WIN0V = WIN_RANGE(1, 31);
+ MenuZeroFillWindowRect(0, 0, 0x1D, 0x13);
+ TASK.FUNC = sub_80BA258;
+ DestroyCryMeterNeedleSprite();
+ }
+}
+
+void sub_80BB494(void)
+{
+ sub_80BAE78(gUnknown_03005D34, 1, 17, 3);
+}
diff --git a/src/tv.c b/src/tv.c
index 4bd11a9b9..27fe9b84c 100644
--- a/src/tv.c
+++ b/src/tv.c
@@ -44,7 +44,6 @@ struct UnkTvStruct
s8 var0;
};
-extern struct Struct30042E0 gBattleResults;
extern u8 gUnknown_0300430A[11];
struct OutbreakPokemon
@@ -430,15 +429,15 @@ void TakeTVShowInSearchOfTrainersOffTheAir(void);
void GabbyAndTyBeforeInterview(void)
{
u8 i;
- gSaveBlock1.gabbyAndTyData.mon1 = gBattleResults.unk6;
- gSaveBlock1.gabbyAndTyData.mon2 = gBattleResults.unk26;
- gSaveBlock1.gabbyAndTyData.lastMove = gBattleResults.unk22;
+ gSaveBlock1.gabbyAndTyData.mon1 = gBattleResults.Poke1Species;
+ gSaveBlock1.gabbyAndTyData.mon2 = gBattleResults.OpponentSpecies;
+ gSaveBlock1.gabbyAndTyData.lastMove = gBattleResults.LastUsedMove;
if (gSaveBlock1.gabbyAndTyData.battleNum != 0xff)
{
gSaveBlock1.gabbyAndTyData.battleNum ++;
}
gSaveBlock1.gabbyAndTyData.valA_0 = gBattleResults.unk5_0;
- if (gBattleResults.unk0)
+ if (gBattleResults.PlayerFaintCounter)
{
gSaveBlock1.gabbyAndTyData.valA_1 = 1;
} else
@@ -612,11 +611,11 @@ void sub_80BDEC8(void) {
total = 0;
sub_80BEB20();
sub_80BE778();
- if (gBattleResults.unk28 == 0) {
+ if (gBattleResults.CaughtPoke == 0) {
sub_80BE074();
} else {
sub_80BE028();
- if (sub_80BF77C(0xffff) == 0 && StringCompareWithoutExtCtrlCodes(gSpeciesNames[gBattleResults.unk28], gBattleResults.unk2A) != 0) {
+ if (sub_80BF77C(0xffff) == 0 && StringCompareWithoutExtCtrlCodes(gSpeciesNames[gBattleResults.CaughtPoke], gBattleResults.CaughtNick) != 0) {
gUnknown_03005D38.var0 = sub_80BF74C(gSaveBlock1.tvShows);
if (gUnknown_03005D38.var0 != -1 && sub_80BF1B4(TVSHOW_POKEMON_TODAY_CAUGHT) != 1) {
for (i=0; i<11; i++) {
@@ -642,8 +641,8 @@ void sub_80BDEC8(void) {
show->pokemonToday.var12 = total;
show->pokemonToday.ball = item;
StringCopy(show->pokemonToday.playerName, gSaveBlock2.playerName);
- StringCopy(show->pokemonToday.nickname, gBattleResults.unk2A);
- show->pokemonToday.species = gBattleResults.unk28;
+ StringCopy(show->pokemonToday.nickname, gBattleResults.CaughtNick);
+ show->pokemonToday.species = gBattleResults.CaughtPoke;
sub_80BE138(show);
show->pokemonToday.language = GAME_LANGUAGE;
show->pokemonToday.language2 = sub_80BDEAC(show->pokemonToday.nickname);
@@ -663,8 +662,8 @@ void sub_80BE028(void) {
buffer->worldOfMasters.var00 = TVSHOW_WORLD_OF_MASTERS;
}
buffer->worldOfMasters.var02++;
- buffer->worldOfMasters.var04 = gBattleResults.unk28;
- buffer->worldOfMasters.var08 = gBattleResults.unk6;
+ buffer->worldOfMasters.var04 = gBattleResults.CaughtPoke;
+ buffer->worldOfMasters.var08 = gBattleResults.Poke1Species;
buffer->worldOfMasters.var0a = gMapHeader.name;
}
@@ -689,7 +688,7 @@ void sub_80BE074(void) {
asm_comment("Here the wrong registers are used to hold the show ID and flag.");
show->pokemonTodayFailed.var00 = TVSHOW_POKEMON_TODAY_FAILED;
show->pokemonTodayFailed.var01 = flag;
- show->pokemonTodayFailed.species = gBattleResults.unk6;
+ show->pokemonTodayFailed.species = gBattleResults.Poke1Species;
show->pokemonTodayFailed.species2 = gBattleResults.unk20;
show->pokemonTodayFailed.var10 = total;
show->pokemonTodayFailed.var11 = gBattleOutcome;