summaryrefslogtreecommitdiff
path: root/src/misc
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc')
-rw-r--r--src/misc/de_rom_8040FE0.c272
-rw-r--r--src/misc/rom3.c1393
-rw-r--r--src/misc/rom4.c2573
-rw-r--r--src/misc/rom6.c202
-rw-r--r--src/misc/rom_800D42C.c118
-rw-r--r--src/misc/rom_8077ABC.c2055
-rw-r--r--src/misc/script_pokemon_util_80C4BF0.c716
-rw-r--r--src/misc/script_pokemon_util_80F99CC.c445
-rw-r--r--src/misc/unknown_task.c255
-rw-r--r--src/misc/unused_8124F94.c126
10 files changed, 8155 insertions, 0 deletions
diff --git a/src/misc/de_rom_8040FE0.c b/src/misc/de_rom_8040FE0.c
new file mode 100644
index 000000000..c618ebdb2
--- /dev/null
+++ b/src/misc/de_rom_8040FE0.c
@@ -0,0 +1,272 @@
+#include "global.h"
+#include "battle.h"
+
+#if GERMAN
+
+enum {
+ TRAINER_CLASS_NAME_LEADER = 25,
+ TRAINER_CLASS_NAME_SCHOOL_KID = 26,
+ TRAINER_CLASS_NAME_EXPERT = 30,
+ TRAINER_CLASS_NAME_POKEMON_TRAINER_3 = 46,
+};
+
+enum {
+ TRAINER_CLASS_LEADER_F = 26,
+ TRAINER_CLASS_ELITE_FOUR_F = 25,
+ TRAINER_CLASS_SCHOOL_KID_F = 30,
+ TRAINER_CLASS_BIRD_KEEPER = 46,
+ TRAINER_CLASS_MAY_1 = 61,
+ TRAINER_CLASS_MAY_2 = 62,
+ TRAINER_CLASS_MAY_3 = 63,
+};
+
+extern struct SecretBaseRecord gSecretBaseRecord;
+
+extern u8 gTrainerClassNames[][13];
+extern struct Trainer gTrainers[];
+
+u8 *de_sub_8040FE0(u8 gender) {
+ if (gender)
+ {
+ gender++;
+
+ }
+
+ gender = TRAINER_CLASS_NAME_SCHOOL_KID;
+ return gTrainerClassNames[gender];
+}
+
+u8 *de_sub_8040FF4(u8 gender) {
+ if (gender) {
+ gender++;
+ }
+
+ gender = TRAINER_CLASS_NAME_POKEMON_TRAINER_3;
+ return gTrainerClassNames[gender];
+}
+
+u8 *de_sub_804100C(u8 gender) {
+ if (gender) {
+ gender++;
+ }
+
+ gender = TRAINER_CLASS_NAME_LEADER;
+ return gTrainerClassNames[gender];
+}
+
+#ifdef NONMATCHING
+
+u8 de_sub_81364AC(void);
+u8 get_trainer_class_name_index(void);
+u8 de_sub_81364F8(void);
+u8 sub_8135FD8(void);
+
+u8 *de_sub_8041024(s32 arg0, u32 arg1) {
+ u8 nameIndex, trainerClass, gender;
+ struct Trainer *trainer;
+ u8 local2;
+
+ switch (arg0)
+ {
+ case 0x400:
+ nameIndex = GetSecretBaseTrainerNameIndex();
+ gender = gSecretBaseRecord.gender;
+ if (nameIndex == TRAINER_CLASS_NAME_SCHOOL_KID)
+ {
+ return de_sub_8040FE0(gender);
+ }
+
+ return gTrainerClassNames[nameIndex];
+
+ case 0x100:
+ trainerClass = de_sub_81364AC();
+ nameIndex = get_trainer_class_name_index();
+ if (trainerClass == TRAINER_CLASS_SCHOOL_KID_F)
+ {
+ return de_sub_8040FE0(FEMALE);
+ }
+ if (trainerClass == TRAINER_CLASS_MAY_1 || trainerClass == TRAINER_CLASS_MAY_2 || trainerClass == TRAINER_CLASS_MAY_3)
+ {
+ return de_sub_8040FF4(FEMALE);
+ }
+
+ return gTrainerClassNames[nameIndex];
+
+ case 0x800:
+ trainerClass = de_sub_81364F8();
+ nameIndex = sub_8135FD8();
+ if (trainerClass == TRAINER_CLASS_SCHOOL_KID_F)
+ {
+ return de_sub_8040FE0(FEMALE);
+ }
+ if (trainerClass == TRAINER_CLASS_MAY_1 || trainerClass == TRAINER_CLASS_MAY_2 || trainerClass == TRAINER_CLASS_MAY_3)
+ {
+ return de_sub_8040FF4(FEMALE);
+ }
+
+ return gTrainerClassNames[nameIndex];
+
+ default:
+ trainer = &gTrainers[arg1];
+ trainerClass = trainer->trainerClass;
+ local2 = sub_803FC58(arg1);
+
+ if (trainerClass == TRAINER_CLASS_LEADER_F)
+ {
+ return de_sub_8040FE0(local2);
+ }
+
+ if (trainerClass == TRAINER_CLASS_BIRD_KEEPER && local2 == FEMALE)
+ {
+ return de_sub_8040FF4(FEMALE);
+ }
+
+ if (trainerClass == TRAINER_CLASS_ELITE_FOUR_F)
+ {
+ if (gTrainers[arg1].doubleBattle == TRUE)
+ {
+ return de_sub_804100C(FEMALE);
+ }
+ else
+ {
+ return de_sub_804100C(MALE);
+ }
+ }
+
+
+ return gTrainerClassNames[trainerClass];
+ }
+}
+#else
+
+__attribute__((naked))
+void de_sub_8041024(void) {
+ asm(".syntax unified\n\
+ push {r4-r6,lr}\n\
+ adds r2, r0, 0\n\
+ adds r6, r1, 0\n\
+ movs r0, 0x80\n\
+ lsls r0, 3\n\
+ cmp r2, r0\n\
+ beq _0804104A\n\
+ cmp r2, r0\n\
+ bgt _08041040\n\
+ movs r0, 0x80\n\
+ lsls r0, 1\n\
+ cmp r2, r0\n\
+ beq _08041064\n\
+ b _0804109C\n\
+_08041040:\n\
+ movs r0, 0x80\n\
+ lsls r0, 4\n\
+ cmp r2, r0\n\
+ beq _08041086\n\
+ b _0804109C\n\
+_0804104A:\n\
+ bl GetSecretBaseTrainerNameIndex\n\
+ lsls r0, 24\n\
+ lsrs r5, r0, 24\n\
+ ldr r0, _08041060 @ =0x02017000\n\
+ ldrb r0, [r0, 0x1]\n\
+ lsls r0, 27\n\
+ lsrs r2, r0, 31\n\
+ cmp r5, 0x1A\n\
+ beq _080410B8\n\
+ b _080410F8\n\
+ .align 2, 0\n\
+_08041060: .4byte 0x02017000\n\
+_08041064:\n\
+ bl de_sub_81364AC\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ bl get_trainer_class_name_index\n\
+_08041070:\n\
+ lsls r0, 24\n\
+ lsrs r5, r0, 24\n\
+ cmp r4, 0x1E\n\
+ beq _08041094\n\
+ adds r0, r4, 0\n\
+ subs r0, 0x3D\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0x2\n\
+ bls _080410CC\n\
+ b _080410F8\n\
+_08041086:\n\
+ bl de_sub_81364F8\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ bl sub_8135FD8\n\
+ b _08041070\n\
+_08041094:\n\
+ movs r0, 0x1\n\
+ bl de_sub_8040FE0\n\
+ b _08041102\n\
+_0804109C:\n\
+ ldr r1, _080410C0 @ =gTrainers\n\
+ lsls r4, r6, 2\n\
+ adds r0, r4, r6\n\
+ lsls r0, 3\n\
+ adds r0, r1\n\
+ ldrb r5, [r0, 0x1]\n\
+ lsls r0, r6, 16\n\
+ lsrs r0, 16\n\
+ bl sub_803FC58\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+ cmp r5, 0x1A\n\
+ bne _080410C4\n\
+_080410B8:\n\
+ adds r0, r2, 0\n\
+ bl de_sub_8040FE0\n\
+ b _08041102\n\
+ .align 2, 0\n\
+_080410C0: .4byte gTrainers\n\
+_080410C4:\n\
+ cmp r5, 0x2E\n\
+ bne _080410D4\n\
+ cmp r2, 0x1\n\
+ bne _080410D4\n\
+_080410CC:\n\
+ movs r0, 0x1\n\
+ bl de_sub_8040FF4\n\
+ b _08041102\n\
+_080410D4:\n\
+ cmp r5, 0x19\n\
+ bne _080410F8\n\
+ ldr r0, _080410F4 @ =gTrainers\n\
+ adds r1, r4, r6\n\
+ lsls r1, 3\n\
+ adds r1, r0\n\
+ ldrb r0, [r1, 0x18]\n\
+ movs r2, 0\n\
+ cmp r0, 0x1\n\
+ bne _080410EA\n\
+ movs r2, 0x1\n\
+_080410EA:\n\
+ adds r0, r2, 0\n\
+ bl de_sub_804100C\n\
+ b _08041102\n\
+ .align 2, 0\n\
+_080410F4: .4byte gTrainers\n\
+_080410F8:\n\
+ movs r0, 0xD\n\
+ adds r1, r5, 0\n\
+ muls r1, r0\n\
+ ldr r0, _08041108 @ =gTrainerClassNames\n\
+ adds r0, r1, r0\n\
+_08041102:\n\
+ pop {r4-r6}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .align 2, 0\n\
+_08041108: .4byte gTrainerClassNames\n\
+ .syntax divided\n");
+}
+#endif
+
+u32 de_sub_804110C(u32 arg0, u32 arg1) {
+ return arg1;
+}
+
+#endif
diff --git a/src/misc/rom3.c b/src/misc/rom3.c
new file mode 100644
index 000000000..803bbf943
--- /dev/null
+++ b/src/misc/rom3.c
@@ -0,0 +1,1393 @@
+#include "global.h"
+#include "battle.h"
+#include "battle_811DA74.h"
+#include "battle_ai.h"
+#include "battle_anim.h"
+#include "battle_anim_81258BC.h"
+#include "battle_anim_8137220.h"
+#include "cable_club.h"
+#include "items.h"
+#include "link.h"
+#include "pokemon.h"
+#include "rom3.h"
+#include "rom_8094928.h"
+#include "species.h"
+#include "task.h"
+#include "util.h"
+
+extern u8 unk_2000000[];
+
+#define EWRAM_14000 ((u8 *)(unk_2000000 + 0x14000))
+#define EWRAM_15000 ((u8 *)(unk_2000000 + 0x15000))
+
+extern u16 gBattleTypeFlags;
+extern u16 gBattleWeather;
+extern struct BattlePokemon gBattleMons[];
+
+static EWRAM_DATA u8 gUnknown_020238C4 = 0;
+static EWRAM_DATA u8 gUnknown_020238C5 = 0;
+static EWRAM_DATA u8 gUnknown_020238C6 = 0;
+
+extern u32 gUnknown_020239FC;
+extern u8 gBattleBufferA[][0x200];
+extern u8 gBattleBufferB[][0x200];
+extern u8 gActiveBank;
+extern u32 gBattleExecBuffer;
+extern u8 gNoOfAllBanks;
+extern u16 gBattlePartyID[];
+extern u8 gBanksBySide[];
+extern u16 gCurrentMove;
+extern u16 gUnknown_02024BE8;
+extern u16 gLastUsedItem;
+extern u8 gLastUsedAbility;
+extern u8 gBankAttacker;
+extern u8 gBankTarget;
+extern u8 gEffectBank;
+extern u8 gStringBank;
+extern u8 gAbsentBankFlags;
+extern u8 gMultiHitCounter;
+extern u8 gUnknown_02024C78;
+extern u8 gBattleOutcome;
+extern u8 gActionSelectionCursor[];
+extern u8 gMoveSelectionCursor[];
+extern u8 gBattleTextBuff1[];
+extern u8 gBattleTextBuff2[];
+extern u8 gBattleTextBuff3[];
+extern void (*gBattleMainFunc)(void);
+extern void (*gBattleBankFunc[])(void);
+
+u8 gBattleBuffersTransferData[0x170];
+
+void sub_800B858(void)
+{
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ OpenLink();
+ CreateTask(sub_8083C50, 0);
+ sub_800BF28();
+ }
+}
+
+void setup_poochyena_battle(void)
+{
+ s32 i;
+
+ gBattleMainFunc = nullsub_41;
+ for (i = 0; i < 4; i++)
+ {
+ gBattleBankFunc[i] = nullsub_91;
+ gBanksBySide[i] = 0xFF;
+ gActionSelectionCursor[i] = 0;
+ gMoveSelectionCursor[i] = 0;
+ }
+ sub_800B858();
+ gBattleExecBuffer = 0;
+ battle_anim_clear_some_data();
+ ClearBattleMonForms();
+ BattleAI_HandleItemUseBeforeAISetup();
+ if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE)
+ {
+ ZeroEnemyPartyMons();
+ CreateMon(&gEnemyParty[0], SPECIES_POOCHYENA, 2, 32, 0, 0, 0, 0);
+ i = ITEM_NONE;
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, (u8 *)&i);
+ }
+ gUnknown_020239FC = 0;
+ gUnknown_02024C78 = 0;
+}
+
+void sub_800B950(void)
+{
+ s32 i;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ sub_800BA78();
+ else
+ sub_800B9A8();
+ sub_800BD54();
+ if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
+ {
+ for (i = 0; i < gNoOfAllBanks; i++)
+ sub_8094978(i, 0);
+ }
+}
+
+void sub_800B9A8(void)
+{
+ if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
+ {
+ gBattleMainFunc = sub_8010800;
+ if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
+ gBattleBankFunc[0] = SetBankFuncToSafariBufferRunCommand;
+ else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL)
+ gBattleBankFunc[0] = SetBankFuncToWallyBufferRunCommand;
+ else
+ gBattleBankFunc[0] = SetBankFuncToPlayerBufferRunCommand;
+ gBanksBySide[0] = 0;
+ gBattleBankFunc[1] = SetBankFuncToOpponentBufferRunCommand;
+ gBanksBySide[1] = 1;
+ gNoOfAllBanks = 2;
+ }
+ else
+ {
+ gBattleMainFunc = sub_8010800;
+ gBattleBankFunc[0] = SetBankFuncToPlayerBufferRunCommand;
+ gBanksBySide[0] = 0;
+ gBattleBankFunc[1] = SetBankFuncToOpponentBufferRunCommand;
+ gBanksBySide[1] = 1;
+ gBattleBankFunc[2] = SetBankFuncToPlayerBufferRunCommand;
+ gBanksBySide[2] = 2;
+ gBattleBankFunc[3] = SetBankFuncToOpponentBufferRunCommand;
+ gBanksBySide[3] = 3;
+ gNoOfAllBanks = 4;
+ }
+}
+
+void sub_800BA78(void)
+{
+ u8 multiplayerId;
+ int i;
+
+ if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_WILD)
+ {
+ gBattleMainFunc = sub_8010800;
+ gBattleBankFunc[0] = SetBankFuncToPlayerBufferRunCommand;
+ gBanksBySide[0] = 0;
+ gBattleBankFunc[1] = SetBankFuncToLinkOpponentBufferRunCommand;
+ gBanksBySide[1] = 1;
+ gNoOfAllBanks = 2;
+ }
+ else
+ {
+ gBattleBankFunc[1] = SetBankFuncToPlayerBufferRunCommand;
+ gBanksBySide[1] = 0;
+ gBattleBankFunc[0] = SetBankFuncToLinkOpponentBufferRunCommand;
+ gBanksBySide[0] = 1;
+ gNoOfAllBanks = 2;
+ }
+ return;
+ }
+ if ((gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_DOUBLE)) == BATTLE_TYPE_DOUBLE)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_WILD)
+ {
+ gBattleMainFunc = sub_8010800;
+ gBattleBankFunc[0] = SetBankFuncToPlayerBufferRunCommand;
+ gBanksBySide[0] = 0;
+ gBattleBankFunc[1] = SetBankFuncToLinkOpponentBufferRunCommand;
+ gBanksBySide[1] = 1;
+ gBattleBankFunc[2] = SetBankFuncToPlayerBufferRunCommand;
+ gBanksBySide[2] = 2;
+ gBattleBankFunc[3] = SetBankFuncToLinkOpponentBufferRunCommand;
+ gBanksBySide[3] = 3;
+ gNoOfAllBanks = 4;
+ }
+ else
+ {
+ gBattleBankFunc[1] = SetBankFuncToPlayerBufferRunCommand;
+ gBanksBySide[1] = 0;
+ gBattleBankFunc[0] = SetBankFuncToLinkOpponentBufferRunCommand;
+ gBanksBySide[0] = 1;
+ gBattleBankFunc[3] = SetBankFuncToPlayerBufferRunCommand;
+ gBanksBySide[3] = 2;
+ gBattleBankFunc[2] = SetBankFuncToLinkOpponentBufferRunCommand;
+ gBanksBySide[2] = 3;
+ gNoOfAllBanks = 4;
+
+ }
+ return;
+ }
+ multiplayerId = GetMultiplayerId();
+ if (gBattleTypeFlags & BATTLE_TYPE_WILD)
+ gBattleMainFunc = sub_8010800;
+ for (i = 0; i < 4; i++)
+ {
+ switch (gLinkPlayers[i].lp_field_18)
+ {
+ case 0:
+ case 3:
+ sub_8094978(gLinkPlayers[i].lp_field_18, 0);
+ break;
+ case 1:
+ case 2:
+ sub_8094978(gLinkPlayers[i].lp_field_18, 1);
+ break;
+ }
+
+ if (i == multiplayerId)
+ {
+ gBattleBankFunc[gLinkPlayers[i].lp_field_18] = SetBankFuncToPlayerBufferRunCommand;
+ switch (gLinkPlayers[i].lp_field_18)
+ {
+ case 0:
+ case 3:
+ gBanksBySide[gLinkPlayers[i].lp_field_18] = 0;
+ gBattlePartyID[gLinkPlayers[i].lp_field_18] = 0;
+ break;
+ case 1:
+ case 2:
+ gBanksBySide[gLinkPlayers[i].lp_field_18] = 2;
+ gBattlePartyID[gLinkPlayers[i].lp_field_18] = 3;
+ break;
+ }
+ }
+ else
+ {
+ if ((!(gLinkPlayers[i].lp_field_18 & 1) && !(gLinkPlayers[multiplayerId].lp_field_18 & 1))
+ || ((gLinkPlayers[i].lp_field_18 & 1) && (gLinkPlayers[multiplayerId].lp_field_18 & 1)))
+ {
+ gBattleBankFunc[gLinkPlayers[i].lp_field_18] = SetBankFuncToLinkPartnerBufferRunCommand;
+ switch (gLinkPlayers[i].lp_field_18)
+ {
+ case 0:
+ case 3:
+ gBanksBySide[gLinkPlayers[i].lp_field_18] = 0;
+ gBattlePartyID[gLinkPlayers[i].lp_field_18] = 0;
+ break;
+ case 1:
+ case 2:
+ gBanksBySide[gLinkPlayers[i].lp_field_18] = 2;
+ gBattlePartyID[gLinkPlayers[i].lp_field_18] = 3;
+ break;
+ }
+ }
+ else
+ {
+ gBattleBankFunc[gLinkPlayers[i].lp_field_18] = SetBankFuncToLinkOpponentBufferRunCommand;
+ switch (gLinkPlayers[i].lp_field_18)
+ {
+ case 0:
+ case 3:
+ gBanksBySide[gLinkPlayers[i].lp_field_18] = 1;
+ gBattlePartyID[gLinkPlayers[i].lp_field_18] = 0;
+ break;
+ case 1:
+ case 2:
+ gBanksBySide[gLinkPlayers[i].lp_field_18] = 3;
+ gBattlePartyID[gLinkPlayers[i].lp_field_18] = 3;
+ break;
+ }
+ }
+ }
+ }
+ gNoOfAllBanks = 4;
+}
+
+void sub_800BD54(void)
+{
+ int i;
+ int j;
+
+ if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
+ {
+ for (i = 0; i < gNoOfAllBanks; i++)
+ {
+ for (j = 0; j < 6; j++)
+ {
+ if (i < 2)
+ {
+ if (!(gBanksBySide[i] & 1))
+ {
+ if (GetMonData(&gPlayerParty[j], MON_DATA_HP) != 0
+ && GetMonData(&gPlayerParty[j], MON_DATA_SPECIES2) != 0
+ && GetMonData(&gPlayerParty[j], MON_DATA_SPECIES2) != SPECIES_EGG
+ && GetMonData(&gPlayerParty[j], MON_DATA_IS_EGG) == 0)
+ {
+ gBattlePartyID[i] = j;
+ break;
+ }
+ }
+ else
+ {
+ if (GetMonData(&gEnemyParty[j], MON_DATA_HP) != 0
+ && GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != 0
+ && GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_EGG
+ && GetMonData(&gEnemyParty[j], MON_DATA_IS_EGG) == 0)
+ {
+ gBattlePartyID[i] = j;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (!(gBanksBySide[i] & 1))
+ {
+ if (GetMonData(&gPlayerParty[j], MON_DATA_HP) != 0
+ && GetMonData(&gPlayerParty[j], MON_DATA_SPECIES) != 0 //Probably a typo by Game Freak. The rest use SPECIES2
+ && GetMonData(&gPlayerParty[j], MON_DATA_SPECIES2) != SPECIES_EGG
+ && GetMonData(&gPlayerParty[j], MON_DATA_IS_EGG) == 0
+ && gBattlePartyID[i - 2] != j)
+ {
+ gBattlePartyID[i] = j;
+ break;
+ }
+ }
+ else
+ {
+ if (GetMonData(&gEnemyParty[j], MON_DATA_HP) != 0
+ && GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != 0
+ && GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_EGG
+ && GetMonData(&gEnemyParty[j], MON_DATA_IS_EGG) == 0
+ && gBattlePartyID[i - 2] != j)
+ {
+ gBattlePartyID[i] = j;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void dp01_prepare_buffer(u8 a, u8 *b, u16 c)
+{
+ int i;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ dp01_prepare_buffer_wireless_probably(a, c, b);
+ }
+ else
+ {
+ switch (a)
+ {
+ case 0:
+ for (i = 0; i < c; i++)
+ {
+ gBattleBufferA[gActiveBank][i] = *b;
+ b++;
+ }
+ break;
+ case 1:
+ for (i = 0; i < c; i++)
+ {
+ gBattleBufferB[gActiveBank][i] = *b;
+ b++;
+ }
+ break;
+ }
+ }
+}
+
+void sub_800BF28(void)
+{
+ gUnknown_020238C4 = CreateTask(sub_800C1A8, 0);
+ gTasks[gUnknown_020238C4].data[11] = 0;
+ gTasks[gUnknown_020238C4].data[12] = 0;
+ gTasks[gUnknown_020238C4].data[13] = 0;
+ gTasks[gUnknown_020238C4].data[14] = 0;
+ gTasks[gUnknown_020238C4].data[15] = 0;
+ gUnknown_020238C5 = CreateTask(sub_800C47C, 0);
+ gTasks[gUnknown_020238C5].data[12] = 0;
+ gTasks[gUnknown_020238C5].data[13] = 0;
+ gTasks[gUnknown_020238C5].data[14] = 0;
+ gTasks[gUnknown_020238C5].data[15] = 0;
+ gUnknown_020238C6 = 0;
+ CpuFill16(0, EWRAM_14000, 0x2000);
+}
+
+void dp01_prepare_buffer_wireless_probably(u8 a, u16 b, u8 *c)
+{
+ s32 r9;
+ int i;
+
+ r9 = b - b % 4 + 4;
+ if (gTasks[gUnknown_020238C4].data[14] + r9 + 9 > 0x1000)
+ {
+ gTasks[gUnknown_020238C4].data[12] = gTasks[gUnknown_020238C4].data[14];
+ gTasks[gUnknown_020238C4].data[14] = 0;
+ }
+ unk_2000000[gTasks[gUnknown_020238C4].data[14] + 0x14000] = a;
+ unk_2000000[gTasks[gUnknown_020238C4].data[14] + 0x14001] = gActiveBank;
+ unk_2000000[gTasks[gUnknown_020238C4].data[14] + 0x14002] = gBankAttacker;
+ unk_2000000[gTasks[gUnknown_020238C4].data[14] + 0x14003] = gBankTarget;
+ unk_2000000[gTasks[gUnknown_020238C4].data[14] + 0x14004] = r9;
+ unk_2000000[gTasks[gUnknown_020238C4].data[14] + 0x14005] = (r9 & 0x0000FF00) >> 8;
+ unk_2000000[gTasks[gUnknown_020238C4].data[14] + 0x14006] = gAbsentBankFlags;
+ unk_2000000[gTasks[gUnknown_020238C4].data[14] + 0x14007] = gEffectBank;
+ for (i = 0; i < b; i++)
+ unk_2000000[gTasks[gUnknown_020238C4].data[14] + 0x14008 + i] = c[i];
+ gTasks[gUnknown_020238C4].data[14] = gTasks[gUnknown_020238C4].data[14] + r9 + 8;
+}
+
+void sub_800C1A8(u8 taskId)
+{
+ u16 var;
+
+ switch (gTasks[taskId].data[11])
+ {
+ case 0:
+ gTasks[taskId].data[10] = 100;
+ gTasks[taskId].data[11]++;
+ break;
+ case 1:
+ gTasks[taskId].data[10]--;
+ if (gTasks[taskId].data[10] == 0)
+ gTasks[taskId].data[11]++;
+ break;
+ case 2:
+ GetLinkPlayerCount_2();
+ if (IsLinkMaster())
+ {
+ sub_8007F4C();
+ gTasks[taskId].data[11]++;
+ break;
+ }
+ gTasks[taskId].data[11]++;
+ break;
+ case 3:
+ if (gTasks[taskId].data[15] != gTasks[taskId].data[14])
+ {
+ if (gTasks[taskId].data[13] == 0)
+ {
+ if (gTasks[taskId].data[15] > gTasks[taskId].data[14]
+ && gTasks[taskId].data[15] == gTasks[taskId].data[12])
+ {
+ gTasks[taskId].data[12] = 0;
+ gTasks[taskId].data[15] = 0;
+ }
+ var = (unk_2000000[gTasks[taskId].data[15] + 0x14004] | (unk_2000000[gTasks[taskId].data[15] + 0x14005] << 8)) + 8;
+ SendBlock(bitmask_all_link_players_but_self(), &unk_2000000[gTasks[taskId].data[15] + 0x14000], var);
+ gTasks[taskId].data[11]++;
+ }
+ else
+ {
+ gTasks[taskId].data[13]--;
+ break;
+ }
+ }
+ break;
+ case 4:
+ if (sub_8007ECC())
+ {
+ var = unk_2000000[gTasks[taskId].data[15] + 0x14004] | (unk_2000000[gTasks[taskId].data[15] + 0x14005] << 8);
+ gTasks[taskId].data[13] = 1;
+ gTasks[taskId].data[15] = gTasks[taskId].data[15] + var + 8;
+ gTasks[taskId].data[11] = 3;
+ }
+ break;
+ case 5:
+ gTasks[taskId].data[13]--;
+ if (gTasks[taskId].data[13] == 0)
+ {
+ gTasks[taskId].data[13] = 1;
+ gTasks[taskId].data[11] = 3;
+ }
+ break;
+ }
+}
+
+//fix me
+void sub_800C35C(void)
+{
+ u8 i; //r4
+ s32 j; //r2
+ u16 r6; //r6
+ u8 *recvBuffer; //r3
+ u8 *dest; //r5
+ u8 *src; //r4
+
+ if (gReceivedRemoteLinkPlayers != 0 && (gBattleTypeFlags & 0x20) && gLinkPlayers[0].linkType == 0x2211)
+ {
+ for (i = 0; i < GetLinkPlayerCount(); i++)
+ {
+ if (GetBlockReceivedStatus() & gBitTable[i])
+ {
+ ResetBlockReceivedFlag(i);
+ recvBuffer = (u8 *)&gBlockRecvBuffer[i];
+#ifndef NONMATCHING
+ asm("");
+ recvBuffer = (u8 *)&gBlockRecvBuffer[i];
+#endif
+ r6 = gBlockRecvBuffer[i][2];
+ if (gTasks[gUnknown_020238C5].data[14] + 9 + r6 > 0x1000)
+ {
+ gTasks[gUnknown_020238C5].data[12] = gTasks[gUnknown_020238C5].data[14];
+ gTasks[gUnknown_020238C5].data[14] = 0;
+ }
+ //_0800C402
+ dest = EWRAM_15000 + gTasks[gUnknown_020238C5].data[14];
+ src = recvBuffer;
+ for (j = 0; j < r6 + 8; j++)
+ dest[j] = src[j];
+ gTasks[gUnknown_020238C5].data[14] = gTasks[gUnknown_020238C5].data[14] + r6 + 8;
+ }
+ //_0800C446
+ }
+ }
+}
+
+void sub_800C47C(u8 taskId)
+{
+ u16 r7;
+ u8 r4;
+ u8 r2;
+
+ if (gTasks[taskId].data[15] != gTasks[taskId].data[14])
+ {
+ if (gTasks[taskId].data[15] > gTasks[taskId].data[14]
+ && gTasks[taskId].data[15] == gTasks[taskId].data[12])
+ {
+ gTasks[taskId].data[12] = 0;
+ gTasks[taskId].data[15] = 0;
+ }
+ r4 = unk_2000000[0x15000 + gTasks[taskId].data[15] + 1];
+ r7 = unk_2000000[0x15000 + gTasks[taskId].data[15] + 4] | (unk_2000000[0x15000 + gTasks[taskId].data[15] + 5] << 8);
+ switch (unk_2000000[0x15000 + gTasks[taskId].data[15] + 0])
+ {
+ case 0:
+ if (gBattleExecBuffer & gBitTable[r4])
+ return;
+ memcpy(gBattleBufferA[r4], &unk_2000000[0x15000 + gTasks[taskId].data[15] + 8], r7);
+ sub_80155A4(r4);
+ if (!(gBattleTypeFlags & BATTLE_TYPE_WILD))
+ {
+ gBankAttacker = unk_2000000[0x15000 + gTasks[taskId].data[15] + 2];
+ gBankTarget = unk_2000000[0x15000 + gTasks[taskId].data[15] + 3];
+ gAbsentBankFlags = unk_2000000[0x15000 + gTasks[taskId].data[15] + 6];
+ gEffectBank = unk_2000000[0x15000 + gTasks[taskId].data[15] + 7];
+ }
+ break;
+ case 1:
+ memcpy(gBattleBufferB[r4], &unk_2000000[0x15000 + gTasks[taskId].data[15] + 8], r7);
+ break;
+ case 2:
+ r2 = unk_2000000[0x15000 + gTasks[taskId].data[15] + 8];
+ gBattleExecBuffer &= ~(gBitTable[r4] << (r2 * 4));
+ break;
+ }
+ gTasks[taskId].data[15] = gTasks[taskId].data[15] + r7 + 8;
+ }
+}
+
+void EmitGetAttributes(u8 a, u8 b, u8 c)
+{
+ gBattleBuffersTransferData[0] = 0;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ gBattleBuffersTransferData[3] = 0;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x01_a_b_0(u8 a, u8 b, u8 c)
+{
+ gBattleBuffersTransferData[0] = 1;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ gBattleBuffersTransferData[3] = 0;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitSetAttributes(u8 a, u8 b, u8 c, u8 d, void *e)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 2;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ for (i = 0; i < d; i++)
+ gBattleBuffersTransferData[3 + i] = *(u8*)(e++);
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, d + 3);
+}
+
+void unref_sub_800C6A4(u8 a, u8 b, u8 c, u8 *d)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 3;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ for (i = 0; i < c; i++)
+ gBattleBuffersTransferData[3 + i] = *(d++);
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, c + 3);
+}
+
+void dp01_build_cmdbuf_x04_4_4_4(u8 a)
+{
+ gBattleBuffersTransferData[0] = 4;
+ gBattleBuffersTransferData[1] = 4;
+ gBattleBuffersTransferData[2] = 4;
+ gBattleBuffersTransferData[3] = 4;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitSwitchInAnim(u8 a, u8 b, u8 c)
+{
+ gBattleBuffersTransferData[0] = 5;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ gBattleBuffersTransferData[3] = 5;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitReturnPokeToBall(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 6;
+ gBattleBuffersTransferData[1] = b;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 2);
+}
+
+void dp01_build_cmdbuf_x07_7_7_7(u8 a)
+{
+ gBattleBuffersTransferData[0] = 7;
+ gBattleBuffersTransferData[1] = 7;
+ gBattleBuffersTransferData[2] = 7;
+ gBattleBuffersTransferData[3] = 7;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitTrainerSlide(u8 a)
+{
+ gBattleBuffersTransferData[0] = 8;
+ gBattleBuffersTransferData[1] = 8;
+ gBattleBuffersTransferData[2] = 8;
+ gBattleBuffersTransferData[3] = 8;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x09_9_9_9(u8 a)
+{
+ gBattleBuffersTransferData[0] = 9;
+ gBattleBuffersTransferData[1] = 9;
+ gBattleBuffersTransferData[2] = 9;
+ gBattleBuffersTransferData[3] = 9;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitFaintAnimation(u8 a)
+{
+ gBattleBuffersTransferData[0] = 10;
+ gBattleBuffersTransferData[1] = 10;
+ gBattleBuffersTransferData[2] = 10;
+ gBattleBuffersTransferData[3] = 10;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x0B_B_B_B(u8 a)
+{
+ gBattleBuffersTransferData[0] = 11;
+ gBattleBuffersTransferData[1] = 11;
+ gBattleBuffersTransferData[2] = 11;
+ gBattleBuffersTransferData[3] = 11;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x0C_C_C_C(u8 a)
+{
+ gBattleBuffersTransferData[0] = 12;
+ gBattleBuffersTransferData[1] = 12;
+ gBattleBuffersTransferData[2] = 12;
+ gBattleBuffersTransferData[3] = 12;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitBallThrowAnim(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 13;
+ gBattleBuffersTransferData[1] = b;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 2);
+}
+
+void unref_sub_800C828(u8 a, u8 b, u8 *c)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 14;
+ gBattleBuffersTransferData[1] = b;
+ for (i = 0; i < b * 3; i++)
+ gBattleBuffersTransferData[2 + i] = *(c++);
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, b * 3 + 2);
+}
+
+void EmitMoveAnimation(u8 a, u16 b, u8 c, u16 d, s32 e, u8 f, struct DisableStruct *g)
+{
+ gBattleBuffersTransferData[0] = 15;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8;
+ gBattleBuffersTransferData[3] = c;
+ gBattleBuffersTransferData[4] = d;
+ gBattleBuffersTransferData[5] = (d & 0xFF00) >> 8;
+ gBattleBuffersTransferData[6] = e;
+ gBattleBuffersTransferData[7] = (e & 0x0000FF00) >> 8;
+ gBattleBuffersTransferData[8] = (e & 0x00FF0000) >> 16;
+ gBattleBuffersTransferData[9] = (e & 0xFF000000) >> 24;
+ gBattleBuffersTransferData[10] = f;
+ gBattleBuffersTransferData[11] = gMultiHitCounter;
+ if (AbilityBattleEffects(14, 0, 13, 0, 0) == 0 && AbilityBattleEffects(14, 0, 0x4D, 0, 0) == 0)
+ {
+ gBattleBuffersTransferData[12] = gBattleWeather;
+ gBattleBuffersTransferData[13] = (gBattleWeather & 0xFF00) >> 8;
+ }
+ else
+ {
+ gBattleBuffersTransferData[12] = 0;
+ gBattleBuffersTransferData[13] = 0;
+ }
+ gBattleBuffersTransferData[14] = 0;
+ gBattleBuffersTransferData[15] = 0;
+ memcpy(&gBattleBuffersTransferData[16], g, sizeof(*g));
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 0x2C);
+}
+
+#ifdef NONMATCHING
+void EmitPrintString(u8 a, u16 b)
+{
+ int i;
+ //u16 *r12;
+
+ gBattleBuffersTransferData[0] = 16;
+ gBattleBuffersTransferData[1] = gBattleOutcome;
+ gBattleBuffersTransferData[2] = b;
+ gBattleBuffersTransferData[3] = (b & 0xFF00) >> 8;
+
+ *((u16 *)&gBattleBuffersTransferData[4]) = gCurrentMove;
+ *((u16 *)&gBattleBuffersTransferData[6]) = gUnknown_02024BE8;
+ *((u16 *)&gBattleBuffersTransferData[8]) = gLastUsedItem;
+
+ gBattleBuffersTransferData[10] = gLastUsedAbility;
+ gBattleBuffersTransferData[11] = unk_2000000[0x16000 + 3];
+ gBattleBuffersTransferData[12] = unk_2000000[0x16000 + 0x5E];
+ gBattleBuffersTransferData[13] = unk_2000000[0x16000 + 0xC1];
+ gBattleBuffersTransferData[14] = gStringBank;
+ gBattleBuffersTransferData[15] = gBattleMoves[gCurrentMove].type;
+ for (i = 0; i < 4; i++)
+ {
+ gBattleBuffersTransferData[16 + i] = gBattleMons[i].ability;
+ }
+ for (i = 0; i < 16; i++)
+ {
+ gBattleBuffersTransferData[20 + i] = gBattleTextBuff1[i];
+ gBattleBuffersTransferData[36 + i] = gBattleTextBuff2[i];
+ gBattleBuffersTransferData[52 + i] = gBattleTextBuff3[i];
+ }
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 0x44);
+}
+#else
+__attribute__((naked))
+void EmitPrintString(u8 a, u16 b)
+{
+ 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\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r10, r0\n\
+ lsls r1, 16\n\
+ lsrs r1, 16\n\
+ ldr r2, _0800CA2C @ =gBattleBuffersTransferData\n\
+ movs r0, 0x10\n\
+ strb r0, [r2]\n\
+ ldr r0, _0800CA30 @ =gBattleOutcome\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r2, 0x1]\n\
+ strb r1, [r2, 0x2]\n\
+ lsrs r1, 8\n\
+ strb r1, [r2, 0x3]\n\
+ adds r0, r2, 0x4\n\
+ mov r12, r0\n\
+ ldr r4, _0800CA34 @ =gCurrentMove\n\
+ ldrh r0, [r4]\n\
+ strh r0, [r2, 0x4]\n\
+ ldr r0, _0800CA38 @ =gUnknown_02024BE8\n\
+ ldrh r0, [r0]\n\
+ mov r1, r12\n\
+ strh r0, [r1, 0x2]\n\
+ ldr r0, _0800CA3C @ =gLastUsedItem\n\
+ ldrh r0, [r0]\n\
+ strh r0, [r1, 0x4]\n\
+ ldr r0, _0800CA40 @ =gLastUsedAbility\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1, 0x6]\n\
+ ldr r1, _0800CA44 @ =0x02000000\n\
+ ldr r3, _0800CA48 @ =0x00016003\n\
+ adds r0, r1, r3\n\
+ ldrb r0, [r0]\n\
+ mov r7, r12\n\
+ strb r0, [r7, 0x7]\n\
+ adds r3, 0x5B\n\
+ adds r0, r1, r3\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r7, 0x8]\n\
+ ldr r7, _0800CA4C @ =0x000160c1\n\
+ adds r1, r7\n\
+ ldrb r0, [r1]\n\
+ mov r1, r12\n\
+ strb r0, [r1, 0x9]\n\
+ ldr r0, _0800CA50 @ =gStringBank\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1, 0xA]\n\
+ ldr r3, _0800CA54 @ =gBattleMoves\n\
+ ldrh r1, [r4]\n\
+ lsls r0, r1, 1\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ adds r0, r3\n\
+ ldrb r0, [r0, 0x2]\n\
+ mov r3, r12\n\
+ strb r0, [r3, 0xB]\n\
+ movs r3, 0\n\
+ mov r9, r2\n\
+ ldr r7, _0800CA58 @ =gBattleTextBuff3\n\
+ mov r8, r7\n\
+ adds r2, 0x10\n\
+ ldr r0, _0800CA5C @ =gBattleMons\n\
+ adds r4, r0, 0\n\
+ adds r4, 0x20\n\
+_0800C9D2:\n\
+ adds r1, r2, r3\n\
+ ldrb r0, [r4]\n\
+ strb r0, [r1]\n\
+ adds r4, 0x58\n\
+ adds r3, 0x1\n\
+ cmp r3, 0x3\n\
+ ble _0800C9D2\n\
+ movs r3, 0\n\
+ mov r5, r12\n\
+ adds r5, 0x10\n\
+ mov r4, r12\n\
+ adds r4, 0x20\n\
+ ldr r6, _0800CA60 @ =gBattleTextBuff2\n\
+ mov r2, r12\n\
+ adds r2, 0x30\n\
+_0800C9F0:\n\
+ adds r1, r5, r3\n\
+ ldr r7, _0800CA64 @ =gBattleTextBuff1\n\
+ adds r0, r3, r7\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1]\n\
+ adds r1, r4, r3\n\
+ adds r0, r3, r6\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1]\n\
+ adds r1, r2, r3\n\
+ mov r7, r8\n\
+ adds r0, r3, r7\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1]\n\
+ adds r3, 0x1\n\
+ cmp r3, 0xF\n\
+ ble _0800C9F0\n\
+ mov r0, r10\n\
+ mov r1, r9\n\
+ movs r2, 0x44\n\
+ bl dp01_prepare_buffer\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\
+_0800CA2C: .4byte gBattleBuffersTransferData\n\
+_0800CA30: .4byte gBattleOutcome\n\
+_0800CA34: .4byte gCurrentMove\n\
+_0800CA38: .4byte gUnknown_02024BE8\n\
+_0800CA3C: .4byte gLastUsedItem\n\
+_0800CA40: .4byte gLastUsedAbility\n\
+_0800CA44: .4byte 0x02000000\n\
+_0800CA48: .4byte 0x00016003\n\
+_0800CA4C: .4byte 0x000160c1\n\
+_0800CA50: .4byte gStringBank\n\
+_0800CA54: .4byte gBattleMoves\n\
+_0800CA58: .4byte gBattleTextBuff3\n\
+_0800CA5C: .4byte gBattleMons\n\
+_0800CA60: .4byte gBattleTextBuff2\n\
+_0800CA64: .4byte gBattleTextBuff1\n\
+ .syntax divided\n");
+}
+#endif
+
+__attribute__((naked))
+void EmitPrintStringPlayerOnly(u8 a, u16 stringID)
+{
+ 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\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r10, r0\n\
+ lsls r1, 16\n\
+ lsrs r1, 16\n\
+ ldr r2, _0800CB28 @ =gBattleBuffersTransferData\n\
+ movs r0, 0x11\n\
+ strb r0, [r2]\n\
+ strb r0, [r2, 0x1]\n\
+ strb r1, [r2, 0x2]\n\
+ lsrs r1, 8\n\
+ strb r1, [r2, 0x3]\n\
+ adds r0, r2, 0x4\n\
+ mov r12, r0\n\
+ ldr r0, _0800CB2C @ =gCurrentMove\n\
+ ldrh r0, [r0]\n\
+ strh r0, [r2, 0x4]\n\
+ ldr r0, _0800CB30 @ =gUnknown_02024BE8\n\
+ ldrh r0, [r0]\n\
+ mov r1, r12\n\
+ strh r0, [r1, 0x2]\n\
+ ldr r0, _0800CB34 @ =gLastUsedItem\n\
+ ldrh r0, [r0]\n\
+ strh r0, [r1, 0x4]\n\
+ ldr r0, _0800CB38 @ =gLastUsedAbility\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1, 0x6]\n\
+ ldr r0, _0800CB3C @ =0x02000000\n\
+ ldr r3, _0800CB40 @ =0x00016003\n\
+ adds r1, r0, r3\n\
+ ldrb r1, [r1]\n\
+ mov r7, r12\n\
+ strb r1, [r7, 0x7]\n\
+ ldr r1, _0800CB44 @ =0x0001605e\n\
+ adds r0, r1\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r7, 0x8]\n\
+ movs r3, 0\n\
+ mov r9, r2\n\
+ ldr r7, _0800CB48 @ =gBattleTextBuff3\n\
+ mov r8, r7\n\
+ mov r4, r9\n\
+ adds r4, 0x10\n\
+ ldr r0, _0800CB4C @ =gBattleMons\n\
+ adds r2, r0, 0\n\
+ adds r2, 0x20\n\
+_0800CACE:\n\
+ adds r1, r4, r3\n\
+ ldrb r0, [r2]\n\
+ strb r0, [r1]\n\
+ adds r2, 0x58\n\
+ adds r3, 0x1\n\
+ cmp r3, 0x3\n\
+ ble _0800CACE\n\
+ movs r3, 0\n\
+ mov r5, r12\n\
+ adds r5, 0x10\n\
+ mov r4, r12\n\
+ adds r4, 0x20\n\
+ ldr r6, _0800CB50 @ =gBattleTextBuff2\n\
+ mov r2, r12\n\
+ adds r2, 0x30\n\
+_0800CAEC:\n\
+ adds r1, r5, r3\n\
+ ldr r7, _0800CB54 @ =gBattleTextBuff1\n\
+ adds r0, r3, r7\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1]\n\
+ adds r1, r4, r3\n\
+ adds r0, r3, r6\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1]\n\
+ adds r1, r2, r3\n\
+ mov r7, r8\n\
+ adds r0, r3, r7\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1]\n\
+ adds r3, 0x1\n\
+ cmp r3, 0xF\n\
+ ble _0800CAEC\n\
+ mov r0, r10\n\
+ mov r1, r9\n\
+ movs r2, 0x44\n\
+ bl dp01_prepare_buffer\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\
+_0800CB28: .4byte gBattleBuffersTransferData\n\
+_0800CB2C: .4byte gCurrentMove\n\
+_0800CB30: .4byte gUnknown_02024BE8\n\
+_0800CB34: .4byte gLastUsedItem\n\
+_0800CB38: .4byte gLastUsedAbility\n\
+_0800CB3C: .4byte 0x02000000\n\
+_0800CB40: .4byte 0x00016003\n\
+_0800CB44: .4byte 0x0001605e\n\
+_0800CB48: .4byte gBattleTextBuff3\n\
+_0800CB4C: .4byte gBattleMons\n\
+_0800CB50: .4byte gBattleTextBuff2\n\
+_0800CB54: .4byte gBattleTextBuff1\n\
+ .syntax divided\n");
+}
+
+void dp01_build_cmdbuf_x12_a_bb(u8 a, u8 b, u16 c)
+{
+ gBattleBuffersTransferData[0] = 18;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ gBattleBuffersTransferData[3] = (c & 0xFF00) >> 8;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void unref_sub_800CB84(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 19;
+ gBattleBuffersTransferData[1] = b;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 2);
+}
+
+void sub_800CBA4(u8 a, u8 b, u8 c, u8 *d)
+{
+ u32 i;
+
+ gBattleBuffersTransferData[0] = 20;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ gBattleBuffersTransferData[3] = 0;
+ for (i = 0; i < 20; i++)
+ gBattleBuffersTransferData[4 + i] = d[i];
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 24);
+}
+
+void sub_800CBE0(u8 a, u8 *b)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 21;
+ for (i = 0; i < 3; i++)
+ gBattleBuffersTransferData[1 + i] = b[i];
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitChoosePokemon(u8 a, u8 b, u8 c, u8 d, u8 *e)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 22;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ gBattleBuffersTransferData[3] = d;
+ for (i = 0; i < 3; i++)
+ gBattleBuffersTransferData[4 + i] = e[i];
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 8); //but only 7 bytes were written
+}
+
+void dp01_build_cmdbuf_x17_17_17_17(u8 a)
+{
+ gBattleBuffersTransferData[0] = 23;
+ gBattleBuffersTransferData[1] = 23;
+ gBattleBuffersTransferData[2] = 23;
+ gBattleBuffersTransferData[3] = 23;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+// FIXME: I think this function is supposed to take s16 as its second argument,
+// but battle_4.c expects u16
+void EmitHealthBarUpdate(u8 a, u16 b)
+{
+ gBattleBuffersTransferData[0] = 24;
+ gBattleBuffersTransferData[1] = 0;
+ gBattleBuffersTransferData[2] = (s16)b;
+ gBattleBuffersTransferData[3] = ((s16)b & 0xFF00) >> 8;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+// FIXME: I think this function is supposed to take s16 as its third argument,
+// but battle_4.c expects u16
+void EmitExpBarUpdate(u8 a, u8 b, u16 c)
+{
+ gBattleBuffersTransferData[0] = 25;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (s16)c;
+ gBattleBuffersTransferData[3] = ((s16)c & 0xFF00) >> 8;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitStatusIconUpdate(u8 a, u32 b, u32 c)
+{
+ gBattleBuffersTransferData[0] = 26;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (b & 0x0000FF00) >> 8;
+ gBattleBuffersTransferData[3] = (b & 0x00FF0000) >> 16;
+ gBattleBuffersTransferData[4] = (b & 0xFF000000) >> 24;
+ gBattleBuffersTransferData[5] = c;
+ gBattleBuffersTransferData[6] = (c & 0x0000FF00) >> 8;
+ gBattleBuffersTransferData[7] = (c & 0x00FF0000) >> 16;
+ gBattleBuffersTransferData[8] = (c & 0xFF000000) >> 24;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 9);
+}
+
+void EmitStatusAnimation(u8 a, u8 b, u32 c)
+{
+ gBattleBuffersTransferData[0] = 27;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ gBattleBuffersTransferData[3] = (c & 0x0000FF00) >> 8;
+ gBattleBuffersTransferData[4] = (c & 0x00FF0000) >> 16;
+ gBattleBuffersTransferData[5] = (c & 0xFF000000) >> 24;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 6);
+}
+
+void EmitStatusXor(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 28;
+ gBattleBuffersTransferData[1] = b;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 2);
+}
+
+void dp01_build_cmdbuf_x1D_1D_numargs_varargs(u8 a, u16 b, u8 *c)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 29;
+ gBattleBuffersTransferData[1] = 29;
+ gBattleBuffersTransferData[2] = b;
+ gBattleBuffersTransferData[3] = (b & 0xFF00) >> 8;
+ for (i = 0; i < b; i++)
+ gBattleBuffersTransferData[4 + i] = *(c++);
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, b + 4);
+}
+
+void unref_sub_800CDD4(u8 a, u32 b, u16 c, u8 *d)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 30;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (b & 0x0000FF00) >> 8;
+ gBattleBuffersTransferData[3] = (b & 0x00FF0000) >> 16;
+ gBattleBuffersTransferData[4] = (b & 0xFF000000) >> 24;
+ gBattleBuffersTransferData[5] = c;
+ gBattleBuffersTransferData[6] = (c & 0xFF00) >> 8;
+ for (i = 0; i < c; i++)
+ gBattleBuffersTransferData[7 + i] = *(d++);
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, c + 7);
+}
+
+void unref_sub_800CE3C(u8 a, u16 b, u8 *c)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 31;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8;
+ for (i = 0; i < b; i++)
+ gBattleBuffersTransferData[3 + i] = *(c++);
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, b + 3);
+}
+
+void unref_sub_800CE84(u8 a, u16 b, u8 *c)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 32;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8;
+ for (i = 0; i < b; i++)
+ gBattleBuffersTransferData[3 + i] = *(c++);
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, b + 3);
+}
+
+void dp01_build_cmdbuf_x21_a_bb(u8 a, u8 b, u16 c)
+{
+ gBattleBuffersTransferData[0] = 33;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ gBattleBuffersTransferData[3] = (c & 0xFF00) >> 8;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x22_a_three_bytes(u8 a, u8 b, u8 *c)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 34;
+ gBattleBuffersTransferData[1] = b;
+ for (i = 0; i < 3; i++)
+ gBattleBuffersTransferData[2 + i] = c[i];
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 5);
+}
+
+void dp01_build_cmdbuf_x23_aa_0(u8 a, u16 b)
+{
+ gBattleBuffersTransferData[0] = 35;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8;
+ gBattleBuffersTransferData[3] = 0;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x24_aa_0(u8 a, u16 b)
+{
+ gBattleBuffersTransferData[0] = 36;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8;
+ gBattleBuffersTransferData[3] = 0;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x25_25_25_25(u8 a)
+{
+ gBattleBuffersTransferData[0] = 37;
+ gBattleBuffersTransferData[1] = 37;
+ gBattleBuffersTransferData[2] = 37;
+ gBattleBuffersTransferData[3] = 37;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x26_a(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 38;
+ gBattleBuffersTransferData[1] = b;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 2);
+}
+
+void dp01_build_cmdbuf_x27_27_27_27(u8 a)
+{
+ gBattleBuffersTransferData[0] = 39;
+ gBattleBuffersTransferData[1] = 39;
+ gBattleBuffersTransferData[2] = 39;
+ gBattleBuffersTransferData[3] = 39;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x28_28_28_28(u8 a)
+{
+ gBattleBuffersTransferData[0] = 40;
+ gBattleBuffersTransferData[1] = 40;
+ gBattleBuffersTransferData[2] = 40;
+ gBattleBuffersTransferData[3] = 40;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitHitAnimation(u8 a)
+{
+ gBattleBuffersTransferData[0] = 41;
+ gBattleBuffersTransferData[1] = 41;
+ gBattleBuffersTransferData[2] = 41;
+ gBattleBuffersTransferData[3] = 41;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x2A_2A_2A_2A(u8 a)
+{
+ gBattleBuffersTransferData[0] = 42;
+ gBattleBuffersTransferData[1] = 42;
+ gBattleBuffersTransferData[2] = 42;
+ gBattleBuffersTransferData[3] = 42;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitEffectivenessSound(u8 a, u16 b)
+{
+ gBattleBuffersTransferData[0] = 43;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8;
+ gBattleBuffersTransferData[3] = 0;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitPlaySound(u8 a, u16 b)
+{
+ gBattleBuffersTransferData[0] = 44;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8;
+ gBattleBuffersTransferData[3] = 0;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitFaintingCry(u8 a)
+{
+ gBattleBuffersTransferData[0] = 45;
+ gBattleBuffersTransferData[1] = 45;
+ gBattleBuffersTransferData[2] = 45;
+ gBattleBuffersTransferData[3] = 45;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitBattleIntroSlide(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 46;
+ gBattleBuffersTransferData[1] = b;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 2);
+}
+
+void dp01_build_cmdbuf_x2F_2F_2F_2F(u8 a)
+{
+ gBattleBuffersTransferData[0] = 47;
+ gBattleBuffersTransferData[1] = 47;
+ gBattleBuffersTransferData[2] = 47;
+ gBattleBuffersTransferData[3] = 47;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x30_TODO(u8 a, u8 *b, u8 c)
+{
+ int i;
+
+ gBattleBuffersTransferData[0] = 48;
+ gBattleBuffersTransferData[1] = c & 0x7F;
+ gBattleBuffersTransferData[2] = (c & 0x80) >> 7;
+ gBattleBuffersTransferData[3] = 48;
+ for (i = 0; i < 48; i++)
+ gBattleBuffersTransferData[4 + i] = b[i];
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 52);
+}
+
+void dp01_build_cmdbuf_x31_31_31_31(u8 a)
+{
+ gBattleBuffersTransferData[0] = 49;
+ gBattleBuffersTransferData[1] = 49;
+ gBattleBuffersTransferData[2] = 49;
+ gBattleBuffersTransferData[3] = 49;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void dp01_build_cmdbuf_x32_32_32_32(u8 a)
+{
+ gBattleBuffersTransferData[0] = 50;
+ gBattleBuffersTransferData[1] = 50;
+ gBattleBuffersTransferData[2] = 50;
+ gBattleBuffersTransferData[3] = 50;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitSpriteInvisibility(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 51;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = 51;
+ gBattleBuffersTransferData[3] = 51;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitBattleAnimation(u8 a, u8 b, u16 c)
+{
+ gBattleBuffersTransferData[0] = 52;
+ gBattleBuffersTransferData[1] = b;
+ gBattleBuffersTransferData[2] = c;
+ gBattleBuffersTransferData[3] = (c & 0xFF00) >> 8;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 4);
+}
+
+void EmitLinkStandbyMsg(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 53;
+ gBattleBuffersTransferData[1] = b;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 2);
+}
+
+void EmitResetActionMoveSelection(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 54;
+ gBattleBuffersTransferData[1] = b;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 2);
+}
+
+void dp01_build_cmdbuf_x37_a(u8 a, u8 b)
+{
+ gBattleBuffersTransferData[0] = 55;
+ gBattleBuffersTransferData[1] = b;
+ dp01_prepare_buffer(a, gBattleBuffersTransferData, 2);
+}
diff --git a/src/misc/rom4.c b/src/misc/rom4.c
new file mode 100644
index 000000000..f9006efba
--- /dev/null
+++ b/src/misc/rom4.c
@@ -0,0 +1,2573 @@
+#include "global.h"
+#include "rom4.h"
+#include "battle_setup.h"
+#include "berry.h"
+#include "cable_club.h"
+#include "clock.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "field_control_avatar.h"
+#include "field_effect.h"
+#include "field_fadetransition.h"
+#include "field_ground_effect.h"
+#include "field_map_obj.h"
+#include "field_map_obj_helpers.h"
+#include "field_message_box.h"
+#include "field_player_avatar.h"
+#include "field_screen_effect.h"
+#include "field_special_scene.h"
+#include "field_specials.h"
+#include "field_tasks.h"
+#include "field_weather.h"
+#include "fieldmap.h"
+#include "fldeff_flash.h"
+#include "heal_location.h"
+#include "link.h"
+#include "load_save.h"
+#include "main.h"
+#include "map_name_popup.h"
+#include "menu.h"
+#include "metatile_behavior.h"
+#include "new_game.h"
+#include "palette.h"
+#include "play_time.h"
+#include "rng.h"
+#include "roamer.h"
+#include "rotating_gate.h"
+#include "safari_zone.h"
+#include "script.h"
+#include "script_pokemon_80C4.h"
+#include "secret_base.h"
+#include "songs.h"
+#include "sound.h"
+#include "start_menu.h"
+#include "task.h"
+#include "tileset_anim.h"
+#include "time_events.h"
+#include "tv.h"
+#include "unknown_task.h"
+#include "wild_encounter.h"
+
+#ifdef SAPPHIRE
+#define LEGENDARY_MUSIC BGM_OOAME // Heavy Rain
+#else
+#define LEGENDARY_MUSIC BGM_HIDERI // Drought
+#endif
+
+struct UnkTVStruct
+{
+ u32 tv_field_0;
+ u32 tv_field_4;
+};
+
+EWRAM_DATA struct WarpData gUnknown_020297F0 = {0};
+EWRAM_DATA struct WarpData gUnknown_020297F8 = {0};
+EWRAM_DATA struct WarpData gUnknown_02029800 = {0};
+EWRAM_DATA struct WarpData gUnknown_02029808 = {0};
+EWRAM_DATA struct UnkPlayerStruct gUnknown_02029810 = {0};
+EWRAM_DATA u16 gUnknown_02029814 = 0;
+EWRAM_DATA bool8 gUnknown_02029816 = FALSE;
+EWRAM_DATA struct LinkPlayerMapObject gLinkPlayerMapObjects[4] = {0};
+
+static u8 gUnknown_03000580[4];
+static u16 (*gUnknown_03000584)(u32);
+static u8 gUnknown_03000588;
+
+u16 word_3004858;
+void (*gFieldCallback)(void);
+u8 gUnknown_03004860;
+u8 gFieldLinkPlayerCount;
+
+extern u16 gUnknown_03004898;
+extern u16 gUnknown_0300489C;
+
+extern u8 EventScript_LeagueWhiteOut[];
+extern u8 gUnknown_0819FC9F[];
+extern u8 SingleBattleColosseum_EventScript_1A436F[];
+extern u8 SingleBattleColosseum_EventScript_1A4379[];
+extern u8 DoubleBattleColosseum_EventScript_1A4383[];
+extern u8 DoubleBattleColosseum_EventScript_1A439E[];
+extern u8 DoubleBattleColosseum_EventScript_1A43B9[];
+extern u8 DoubleBattleColosseum_EventScript_1A43D4[];
+extern u8 TradeCenter_EventScript_1A43F0[];
+extern u8 TradeCenter_EventScript_1A43FA[];
+extern u8 RecordCorner_EventScript_1A4418[];
+extern u8 RecordCorner_EventScript_1A442D[];
+extern u8 RecordCorner_EventScript_1A4442[];
+extern u8 RecordCorner_EventScript_1A4457[];
+extern u8 TradeRoom_ReadTrainerCard1[];
+extern u8 TradeRoom_ReadTrainerCard2[];
+extern u8 TradeRoom_TooBusyToNotice[];
+extern u8 TradeRoom_PromptToCancelLink[];
+extern u8 TradeRoom_TerminateLink[];
+extern u8 gUnknown_081A4508[];
+
+extern u8 (*gUnknown_082166A0[])(struct LinkPlayerMapObject *, struct MapObject *, u8);
+extern u8 (*gUnknown_082166AC[])(struct LinkPlayerMapObject *, struct MapObject *, u8);
+extern void (*gUnknown_082166D8[])(struct LinkPlayerMapObject *, struct MapObject *);
+
+extern struct MapData * const gMapAttributes[];
+extern struct MapHeader * const * const gMapGroups[];
+extern const struct WarpData gDummyWarpData;
+extern s32 gUnknown_0839ACE8;
+extern u32 gUnknown_08216694[];
+
+void DoWhiteOut(void)
+{
+ ScriptContext2_RunNewScript(EventScript_LeagueWhiteOut);
+ gSaveBlock1.money /= 2;
+ HealPlayerParty();
+ sub_8053050();
+ sub_8053570();
+ warp_in();
+}
+
+void flag_var_implications_of_teleport_(void)
+{
+ player_avatar_init_params_reset();
+ FlagReset(SYS_CYCLING_ROAD);
+ FlagReset(SYS_CRUISE_MODE);
+ FlagReset(SYS_SAFARI_MODE);
+ FlagReset(SYS_USE_STRENGTH);
+ FlagReset(SYS_USE_FLASH);
+}
+
+void new_game(void)
+{
+ player_avatar_init_params_reset();
+ FlagReset(SYS_CYCLING_ROAD);
+ FlagReset(SYS_CRUISE_MODE);
+ FlagReset(SYS_SAFARI_MODE);
+ FlagReset(SYS_USE_STRENGTH);
+ FlagReset(SYS_USE_FLASH);
+ ScriptContext2_RunNewScript(gUnknown_0819FC9F);
+}
+
+void sub_8053014(void)
+{
+ player_avatar_init_params_reset();
+ FlagReset(SYS_CYCLING_ROAD);
+ FlagReset(SYS_CRUISE_MODE);
+ FlagReset(SYS_SAFARI_MODE);
+ FlagReset(SYS_USE_STRENGTH);
+ FlagReset(SYS_USE_FLASH);
+}
+
+void sub_8053050(void)
+{
+ player_avatar_init_params_reset();
+ FlagReset(SYS_CYCLING_ROAD);
+ FlagReset(SYS_CRUISE_MODE);
+ FlagReset(SYS_SAFARI_MODE);
+ FlagReset(SYS_USE_STRENGTH);
+ FlagReset(SYS_USE_FLASH);
+}
+
+void sub_805308C(void)
+{
+ FlagReset(SYS_SAFARI_MODE);
+ sub_8054164();
+ ResetCyclingRoadChallengeData();
+ UpdateLocationHistoryForRoamer();
+ RoamerMoveToOtherLocationSet();
+}
+
+void ResetGameStats(void)
+{
+ s32 i;
+
+ for (i = 0; i < NUM_GAME_STATS; i++)
+ gSaveBlock1.gameStats[i] = 0;
+}
+
+void IncrementGameStat(u8 index)
+{
+ if (index < NUM_GAME_STATS)
+ {
+ if (gSaveBlock1.gameStats[index] < 0xFFFFFF)
+ gSaveBlock1.gameStats[index]++;
+ else
+ gSaveBlock1.gameStats[index] = 0xFFFFFF;
+ }
+}
+
+u32 GetGameStat(u8 index)
+{
+ if (index >= NUM_GAME_STATS)
+ return 0;
+
+ return gSaveBlock1.gameStats[index];
+}
+
+void SetGameStat(u8 index, u32 value)
+{
+ if (index < NUM_GAME_STATS)
+ gSaveBlock1.gameStats[index] = value;
+}
+
+void sub_8053154(void)
+{
+ CpuFill32(0, gSaveBlock1.mapObjectTemplates, sizeof(gSaveBlock1.mapObjectTemplates));
+ CpuCopy32(gMapHeader.events->mapObjects,
+ gSaveBlock1.mapObjectTemplates,
+ gMapHeader.events->mapObjectCount * sizeof(struct MapObjectTemplate));
+}
+
+void sub_8053198(void)
+{
+ struct MapObjectTemplate *mapObjectTemplates = gSaveBlock1.mapObjectTemplates;
+ s32 i;
+ for (i = 0; i < 64; i++)
+ mapObjectTemplates[i].script = gMapHeader.events->mapObjects[i].script;
+}
+
+void update_saveblock1_field_object_coords(u8 localId, s16 x, s16 y)
+{
+ s32 i;
+ for (i = 0; i < 64; i++)
+ {
+ struct MapObjectTemplate *mapObjectTemplate = &gSaveBlock1.mapObjectTemplates[i];
+ if (mapObjectTemplate->localId == localId)
+ {
+ mapObjectTemplate->x = x;
+ mapObjectTemplate->y = y;
+ break;
+ }
+ }
+}
+
+void update_saveblock1_field_object_movement_behavior(u8 localId, u8 movementType)
+{
+ s32 i = 0;
+ struct MapObjectTemplate *mapObjectTemplate = gSaveBlock1.mapObjectTemplates;
+ do
+ {
+ if (mapObjectTemplate->localId == localId)
+ {
+ mapObjectTemplate->movementType = movementType;
+ break;
+ }
+ mapObjectTemplate++;
+ i++;
+ } while (i < 64);
+}
+
+void mapdata_load_assets_to_gpu_and_full_redraw(void)
+{
+ move_tilemap_camera_to_upper_left_corner();
+ copy_map_tileset1_tileset2_to_vram(gMapHeader.mapData);
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ DrawWholeMapView();
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+}
+
+struct MapData *get_mapdata_header(void)
+{
+ u16 mapDataId = gSaveBlock1.mapDataId;
+ if (mapDataId)
+ return gMapAttributes[mapDataId - 1];
+ return NULL;
+}
+
+void warp_shift(void)
+{
+ gUnknown_020297F0 = gSaveBlock1.location;
+ gSaveBlock1.location = gUnknown_020297F8;
+ gUnknown_02029800 = gDummyWarpData;
+ gUnknown_02029808 = gDummyWarpData;
+}
+
+void warp_set(struct WarpData *warp, s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ warp->mapGroup = mapGroup;
+ warp->mapNum = mapNum;
+ warp->warpId = warpId;
+ warp->x = x;
+ warp->y = y;
+}
+
+bool32 warp_data_is_not_neg_1(struct WarpData *warp)
+{
+ if (warp->mapGroup != -1)
+ return FALSE;
+ if (warp->mapNum != -1)
+ return FALSE;
+ if (warp->warpId != -1)
+ return FALSE;
+ if (warp->x != -1)
+ return FALSE;
+ if (warp->y != -1)
+ return FALSE;
+ return TRUE;
+}
+
+struct MapHeader * const get_mapheader_by_bank_and_number(u16 mapGroup, u16 mapNum)
+{
+ return gMapGroups[mapGroup][mapNum];
+}
+
+struct MapHeader * const warp1_get_mapheader(void)
+{
+ return get_mapheader_by_bank_and_number(gUnknown_020297F8.mapGroup, gUnknown_020297F8.mapNum);
+}
+
+void set_current_map_header_from_sav1_save_old_name(void)
+{
+ struct MapHeader *dest = &gMapHeader;
+ struct MapHeader *src = get_mapheader_by_bank_and_number(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);
+ *dest = *src;
+ gSaveBlock1.mapDataId = dest->mapDataId;
+ dest->mapData = get_mapdata_header();
+}
+
+void sub_805338C(void)
+{
+ struct MapHeader *dest = &gMapHeader;
+ struct MapHeader *src = get_mapheader_by_bank_and_number(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);
+ *dest = *src;
+ dest->mapData = get_mapdata_header();
+}
+
+void sub_80533CC(void)
+{
+ if (gSaveBlock1.location.warpId >= 0 && gSaveBlock1.location.warpId < gMapHeader.events->warpCount)
+ {
+ gSaveBlock1.pos.x = gMapHeader.events->warps[gSaveBlock1.location.warpId].x;
+ gSaveBlock1.pos.y = gMapHeader.events->warps[gSaveBlock1.location.warpId].y;
+ }
+ else if (gSaveBlock1.location.x >= 0 && gSaveBlock1.location.y >= 0)
+ {
+ gSaveBlock1.pos.x = gSaveBlock1.location.x;
+ gSaveBlock1.pos.y = gSaveBlock1.location.y;
+ }
+ else
+ {
+ gSaveBlock1.pos.x = gMapHeader.mapData->width / 2;
+ gSaveBlock1.pos.y = gMapHeader.mapData->height / 2;
+ }
+}
+
+void warp_in(void)
+{
+ warp_shift();
+ set_current_map_header_from_sav1_save_old_name();
+ sub_80533CC();
+}
+
+void warp1_set(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ warp_set(&gUnknown_020297F8, mapGroup, mapNum, warpId, x, y);
+}
+
+void warp1_set_2(s8 mapGroup, s8 mapNum, s8 warpId)
+{
+ warp1_set(mapGroup, mapNum, warpId, -1, -1);
+}
+
+void saved_warp2_set(int unused, s8 mapGroup, s8 mapNum, s8 warpId)
+{
+ warp_set(&gSaveBlock1.warp2, mapGroup, mapNum, warpId, gSaveBlock1.pos.x, gSaveBlock1.pos.y);
+}
+
+void saved_warp2_set_2(int unused, s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ warp_set(&gSaveBlock1.warp2, mapGroup, mapNum, warpId, x, y);
+}
+
+void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused)
+{
+ gUnknown_020297F8 = gSaveBlock1.warp2;
+}
+
+void sub_8053538(u8 a1)
+{
+ const struct HealLocation *warp = GetHealLocation(a1);
+ if (warp)
+ warp1_set(warp->group, warp->map, -1, warp->x, warp->y);
+}
+
+void sub_8053570(void)
+{
+ gUnknown_020297F8 = gSaveBlock1.warp3;
+}
+
+void sub_8053588(u8 a1)
+{
+ const struct HealLocation *warp = GetHealLocation(a1);
+ if (warp)
+ warp_set(&gSaveBlock1.warp3, warp->group, warp->map, -1, warp->x, warp->y);
+}
+
+void sub_80535C4(s16 a1, s16 a2)
+{
+ u8 v4 = sav1_map_get_light_level();
+ u8 v5 = get_map_light_level_by_bank_and_number(gUnknown_020297F8.mapGroup, gUnknown_020297F8.mapNum);
+ if (is_light_level_1_2_3_5_or_6(v4) && is_light_level_1_2_3_5_or_6(v5) != TRUE)
+ sub_805363C(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum, -1, a1 - 7, a2 - 6);
+}
+
+void sub_805363C(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ warp_set(&gSaveBlock1.warp4, mapGroup, mapNum, warpId, x, y);
+}
+
+void sub_8053678(void)
+{
+ gUnknown_020297F8 = gSaveBlock1.warp4;
+}
+
+void sub_8053690(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ warp_set(&gUnknown_02029800, mapGroup, mapNum, warpId, x, y);
+}
+
+void warp1_set_to_warp2(void)
+{
+ gUnknown_020297F8 = gUnknown_02029800;
+}
+
+void sub_80536E4(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ warp_set(&gUnknown_02029808, mapGroup, mapNum, warpId, x, y);
+}
+
+void sub_8053720(s16 x, s16 y)
+{
+ if (warp_data_is_not_neg_1(&gUnknown_02029808) == TRUE)
+ {
+ gUnknown_020297F8 = gUnknown_020297F0;
+ }
+ else
+ {
+ warp1_set(gUnknown_02029808.mapGroup, gUnknown_02029808.mapNum, -1, x, y);
+ }
+}
+
+void sub_8053778(void)
+{
+ gUnknown_020297F8 = gSaveBlock1.warp1;
+}
+
+void unref_sub_8053790(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ warp_set(&gSaveBlock1.warp1, mapGroup, mapNum, warpId, x, y);
+}
+
+void sub_80537CC(u8 a1)
+{
+ const struct HealLocation *warp = GetHealLocation(a1);
+ if (warp)
+ warp_set(&gSaveBlock1.warp1, warp->group, warp->map, -1, warp->x, warp->y);
+}
+
+void gpu_sync_bg_hide()
+{
+ gSaveBlock1.warp1 = gSaveBlock1.warp2;
+}
+
+struct MapConnection *sub_8053818(u8 dir)
+{
+ s32 i;
+ s32 count = gMapHeader.connections->count;
+ struct MapConnection *connection = gMapHeader.connections->connections;
+
+ if (connection == NULL)
+ return NULL;
+
+ for(i = 0; i < count; i++, connection++)
+ if (connection->direction == dir)
+ return connection;
+
+ return NULL;
+}
+
+bool8 sub_8053850(u8 dir, u16 x, u16 y)
+{
+ struct MapConnection *connection = sub_8053818(dir);
+ if (connection)
+ {
+ warp1_set(connection->mapGroup, connection->mapNum, -1, x, y);
+ }
+ else
+ {
+ mapheader_run_script_with_tag_x6();
+ if (warp_data_is_not_neg_1(&gUnknown_02029800))
+ return FALSE;
+ warp1_set_to_warp2();
+ }
+ return TRUE;
+}
+
+bool8 sub_80538B0(u16 x, u16 y)
+{
+ return sub_8053850(CONNECTION_EMERGE, x, y);
+}
+
+bool8 sub_80538D0(u16 x, u16 y)
+{
+ return sub_8053850(CONNECTION_DIVE, x, y);
+}
+
+void sub_80538F0(u8 mapGroup, u8 mapNum)
+{
+ s32 i;
+
+ warp1_set(mapGroup, mapNum, -1, -1, -1);
+ sub_8053F0C();
+ warp_shift();
+ set_current_map_header_from_sav1_save_old_name();
+ sub_8053154();
+ ClearTempFieldEventData();
+ ResetCyclingRoadChallengeData();
+ prev_quest_postbuffer_cursor_backup_reset();
+ sub_8082BD0(mapGroup, mapNum);
+ DoTimeBasedEvents();
+ sub_80806E4();
+ sub_8054164();
+ sub_8053C98();
+ sav1_reset_battle_music_maybe();
+ mapheader_run_script_with_tag_x3();
+ not_trainer_hill_battle_pyramid();
+ sub_8056D38(gMapHeader.mapData);
+ apply_map_tileset2_palette(gMapHeader.mapData);
+
+ for (i = 6; i < 12; i++)
+ sub_807D874(i);
+
+ sub_8072ED0();
+ UpdateLocationHistoryForRoamer();
+ RoamerMove();
+ DoCurrentWeather();
+ ResetFieldTasksArgs();
+ mapheader_run_script_with_tag_x5();
+ ShowMapNamePopup();
+}
+
+void sub_8053994(u32 a1)
+{
+ bool8 v2;
+ bool8 v3;
+
+ set_current_map_header_from_sav1_save_old_name();
+ sub_8053154();
+ v2 = is_light_level_1_2_3_5_or_6(gMapHeader.mapType);
+ v3 = is_light_level_8_or_9(gMapHeader.mapType);
+ ClearTempFieldEventData();
+ ResetCyclingRoadChallengeData();
+ prev_quest_postbuffer_cursor_backup_reset();
+ sub_8082BD0(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);
+ if (a1 != 1)
+ DoTimeBasedEvents();
+ sub_80806E4();
+ sub_8054164();
+ if (v2)
+ FlagReset(SYS_USE_FLASH);
+ sub_8053C98();
+ sav1_reset_battle_music_maybe();
+ mapheader_run_script_with_tag_x3();
+ UpdateLocationHistoryForRoamer();
+ RoamerMoveToOtherLocationSet();
+ not_trainer_hill_battle_pyramid();
+ if (a1 != 1 && v3)
+ {
+ UpdateTVScreensOnMap(gUnknown_03004870.width, gUnknown_03004870.height);
+ sub_80BBCCC(1);
+ }
+}
+
+void player_avatar_init_params_reset(void)
+{
+ gUnknown_02029810.player_field_1 = 1;
+ gUnknown_02029810.player_field_0 = 1;
+}
+
+void walkrun_find_lowest_active_bit_in_bitfield(void)
+{
+ gUnknown_02029810.player_field_1 = player_get_direction_lower_nybble();
+
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE))
+ gUnknown_02029810.player_field_0 = 2;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ gUnknown_02029810.player_field_0 = 4;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ gUnknown_02029810.player_field_0 = 8;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_4))
+ gUnknown_02029810.player_field_0 = 16;
+ else
+ gUnknown_02029810.player_field_0 = 1;
+}
+
+struct UnkPlayerStruct *sub_8053AA8(void)
+{
+ struct UnkPlayerStruct playerStruct;
+ u8 light = sav1_map_get_light_level();
+ u16 v2 = cur_mapdata_block_role_at_screen_center_acc_to_sav1();
+ u8 v4 = sub_8053B00(&gUnknown_02029810, v2, light);
+ playerStruct.player_field_0 = v4;
+ playerStruct.player_field_1 = sub_8053B60(&gUnknown_02029810, v4, v2, light);
+ gUnknown_02029810 = playerStruct;
+ return &gUnknown_02029810;
+}
+
+u8 sub_8053B00(struct UnkPlayerStruct *playerStruct, u16 a2, u8 a3)
+{
+ if (a3 != 8 && FlagGet(SYS_CRUISE_MODE))
+ return 1;
+ if (a3 == 5)
+ return 16;
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(a2) == 1)
+ return 8;
+ if (IsBikingAllowedByMap() != TRUE)
+ return 1;
+ if (playerStruct->player_field_0 == 2)
+ return 2;
+ if (playerStruct->player_field_0 != 4)
+ return 1;
+ return 4;
+}
+
+u8 sub_8053B60(struct UnkPlayerStruct *playerStruct, u8 a2, u16 a3, u8 a4)
+{
+ if (FlagGet(SYS_CRUISE_MODE) && a4 == 6)
+ return 4;
+ if (MetatileBehavior_IsDeepSouthWarp(a3) == TRUE)
+ return 2;
+ if (MetatileBehavior_IsNonAnimDoor(a3) == TRUE || MetatileBehavior_IsDoor(a3) == TRUE)
+ return 1;
+ if (MetatileBehavior_IsSouthArrowWarp(a3) == TRUE)
+ return 2;
+ if (MetatileBehavior_IsNorthArrowWarp(a3) == TRUE)
+ return 1;
+ if (MetatileBehavior_IsWestArrowWarp(a3) == TRUE)
+ return 4;
+ if (MetatileBehavior_IsEastArrowWarp(a3) == TRUE)
+ return 3;
+ if ((playerStruct->player_field_0 == 16 && a2 == 8)
+ || (playerStruct->player_field_0 == 8 && a2 == 16))
+ return playerStruct->player_field_1;
+ if (MetatileBehavior_IsLadder(a3) == TRUE)
+ return playerStruct->player_field_1;
+ return 1;
+}
+
+u16 cur_mapdata_block_role_at_screen_center_acc_to_sav1(void)
+{
+ return MapGridGetMetatileBehaviorAt(gSaveBlock1.pos.x + 7, gSaveBlock1.pos.y + 7);
+}
+
+bool32 IsBikingAllowedByMap(void)
+{
+ // is player in cycling road entrance?
+ if (gSaveBlock1.location.mapGroup == 29 && (gSaveBlock1.location.mapNum == 11 || gSaveBlock1.location.mapNum == 12))
+ return TRUE;
+
+ // is player indoor, in a secret base, or underwater?
+ if (gMapHeader.mapType == MAP_TYPE_INDOOR)
+ return FALSE;
+ if (gMapHeader.mapType == MAP_TYPE_SECRET_BASE)
+ return FALSE;
+ if (gMapHeader.mapType == MAP_TYPE_UNDERWATER)
+ return FALSE;
+
+ // is player in SeafloorCavern_Room9?
+ if (gSaveBlock1.location.mapGroup == 24 && gSaveBlock1.location.mapNum == 36)
+ return FALSE;
+
+ // is player in CaveOfOrigin_B4F?
+ if (gSaveBlock1.location.mapGroup == 24 && gSaveBlock1.location.mapNum == 42)
+ return FALSE;
+
+ return TRUE;
+}
+
+void sub_8053C98(void)
+{
+ if (!gMapHeader.cave)
+ gSaveBlock1.flashUsed = 0;
+ else if (FlagGet(SYS_USE_FLASH))
+ gSaveBlock1.flashUsed = 1;
+ else
+ gSaveBlock1.flashUsed = gUnknown_0839ACE8;
+}
+
+void sub_8053CE4(s32 a1)
+{
+ if (a1 < 0 || a1 > gUnknown_0839ACE8)
+ a1 = 0;
+ gSaveBlock1.flashUsed = a1;
+}
+
+u8 sav1_get_flash_used_on_map(void)
+{
+ return gSaveBlock1.flashUsed;
+}
+
+void sub_8053D14(u16 mapDataId)
+{
+ gSaveBlock1.mapDataId = mapDataId;
+ gMapHeader.mapData = get_mapdata_header();
+}
+
+bool16 sub_8053D30(struct WarpData *warp)
+{
+ if (!FlagGet(SYS_WEATHER_CTRL))
+ return FALSE;
+ if (warp->mapGroup != 0)
+ return FALSE;
+ switch (warp->mapNum)
+ {
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ return TRUE;
+ case 39:
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool16 sub_8053D6C(struct WarpData *warp)
+{
+ if (VarGet(0x40B3))
+ return FALSE;
+ if (warp->mapGroup != 32)
+ return FALSE;
+ if (warp->mapNum == 0 || warp->mapNum == 1)
+ return TRUE;
+ return FALSE;
+}
+
+u16 sub_8053D9C(struct WarpData *warp)
+{
+ if (sub_8053D30(warp) == TRUE)
+ return LEGENDARY_MUSIC;
+ else if (sub_8053D6C(warp) == TRUE)
+ return BGM_TOZAN;
+ else
+ return get_mapheader_by_bank_and_number(warp->mapGroup, warp->mapNum)->music;
+}
+
+u16 sav1_map_get_music(void)
+{
+ u16 music;
+
+ if (gSaveBlock1.location.mapGroup == 0
+ && gSaveBlock1.location.mapNum == 26
+ && GetSav1Weather() == 8)
+ return BGM_ASHROAD;
+
+ music = sub_8053D9C(&gSaveBlock1.location);
+ if (music != 0x7FFF)
+ {
+ return music;
+ }
+ else
+ {
+ if (gSaveBlock1.pos.x < 24)
+ return BGM_DOORO_X1;
+ else
+ return BGM_GRANROAD;
+ }
+}
+
+u16 warp1_target_get_music(void)
+{
+ u16 music = sub_8053D9C(&gUnknown_020297F8);
+ if (music != 0x7FFF)
+ {
+ return music;
+ }
+ else
+ {
+ if (gSaveBlock1.location.mapGroup == 0 && gSaveBlock1.location.mapNum == 2)
+ return BGM_DOORO_X1;
+ else
+ return BGM_GRANROAD;
+ }
+}
+
+void call_map_music_set_to_zero(void)
+{
+ ResetMapMusic();
+}
+
+void sub_8053E90(void)
+{
+ u16 music = sav1_map_get_music();
+
+ if (music != LEGENDARY_MUSIC)
+ {
+ if (gSaveBlock1.battleMusic)
+ music = gSaveBlock1.battleMusic;
+ else if (sav1_map_get_light_level() == 5)
+ music = BGM_DEEPDEEP;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ music = BGM_NAMINORI;
+ }
+
+ if (music != GetCurrentMapMusic())
+ PlayNewMapMusic(music);
+}
+
+void sav1_set_battle_music_maybe(u16 songNum)
+{
+ gSaveBlock1.battleMusic = songNum;
+}
+
+void sav1_reset_battle_music_maybe(void)
+{
+ gSaveBlock1.battleMusic = 0;
+}
+
+void sub_8053F0C(void)
+{
+ if (FlagGet(SPECIAL_FLAG_1) != TRUE)
+ {
+ u16 newMusic = warp1_target_get_music();
+ u16 currentMusic = GetCurrentMapMusic();
+ if (newMusic != LEGENDARY_MUSIC)
+ {
+ if (currentMusic == BGM_DEEPDEEP || currentMusic == BGM_NAMINORI)
+ return;
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ newMusic = BGM_NAMINORI;
+ }
+ if (newMusic != currentMusic)
+ {
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ FadeOutAndFadeInNewMapMusic(newMusic, 4, 4);
+ else
+ FadeOutAndPlayNewMapMusic(newMusic, 8);
+ }
+ }
+}
+
+void sub_8053F84(void)
+{
+ u16 currentMusic = GetCurrentMapMusic();
+ if (currentMusic != sav1_map_get_music())
+ FadeOutAndPlayNewMapMusic(sav1_map_get_music(), 8);
+}
+
+void sub_8053FB0(u16 music)
+{
+ u16 currentMusic = GetCurrentMapMusic();
+ if (currentMusic != music && currentMusic != LEGENDARY_MUSIC)
+ FadeOutAndPlayNewMapMusic(music, 8);
+}
+
+u8 is_warp1_light_level_8_or_9(void)
+{
+ struct MapHeader *mapHeader = warp1_get_mapheader();
+ if (is_light_level_8_or_9(mapHeader->mapType) == TRUE)
+ return 2;
+ else
+ return 4;
+}
+
+void sub_8053FF8(void)
+{
+ u16 music = warp1_target_get_music();
+ if (FlagGet(SPECIAL_FLAG_1) != TRUE && music != GetCurrentMapMusic())
+ {
+ u8 speed = is_warp1_light_level_8_or_9();
+ FadeOutMapMusic(speed);
+ }
+}
+
+bool8 sub_8054034(void)
+{
+ return IsNotWaitingForBGMStop();
+}
+
+void sub_8054044(void)
+{
+ FadeOutMapMusic(4);
+}
+
+void sub_8054050(void)
+{
+ s16 x, y;
+ PlayerGetDestCoords((u16 *)&x, (u16 *)&y);
+ if (gUnknown_02029816 != TRUE
+ || MetatileBehavior_IsSurfableWaterOrUnderwater(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ s8 pan = (Random() % 88) + 212;
+ s8 volume = (Random() % 30) + 50;
+ PlayCry2(gUnknown_02029814, pan, volume, 1);
+ }
+}
+
+void sub_80540D0(s16 *a1, u16 *a2)
+{
+ switch (*a1)
+ {
+ case 0:
+ if (!gUnknown_02029814)
+ *a1 = 4;
+ else
+ *a1 = 1;
+ break;
+ case 1:
+ *a2 = (Random() % 2400) + 1200;
+ *a1 = 3;
+ break;
+ case 2:
+ *a2 = (Random() % 1200) + 1200;
+ *a1 = 3;
+ break;
+ case 3:
+ (*a2)--;
+ if (*a2 == 0)
+ {
+ sub_8054050();
+ *a1 = 2;
+ }
+ break;
+ case 4:
+ break;
+ }
+}
+
+void sub_8054164(void)
+{
+ if ((gSaveBlock1.location.mapGroup == 0 && gSaveBlock1.location.mapNum == 45) && !IsMirageIslandPresent())
+ {
+ gUnknown_02029816 = TRUE;
+ gUnknown_02029814 = GetMirageIslandMon();
+ }
+ else
+ {
+ gUnknown_02029814 = GetLocalWildMon(&gUnknown_02029816);
+ }
+}
+
+u8 get_map_light_level_by_bank_and_number(s8 mapGroup, s8 mapNum)
+{
+ return get_mapheader_by_bank_and_number(mapGroup, mapNum)->mapType;
+}
+
+u8 get_map_light_level_from_warp(struct WarpData *warp)
+{
+ return get_map_light_level_by_bank_and_number(warp->mapGroup, warp->mapNum);
+}
+
+u8 sav1_map_get_light_level(void)
+{
+ return get_map_light_level_from_warp(&gSaveBlock1.location);
+}
+
+u8 get_map_light_from_warp0(void)
+{
+ return get_map_light_level_from_warp(&gUnknown_020297F0);
+}
+
+bool8 is_light_level_1_2_3_5_or_6(u8 a1)
+{
+ if (a1 == 3 || a1 == 1 || a1 == 5 || a1 == 2 || a1 == 6)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 is_light_level_1_2_3_or_6(u8 a1)
+{
+ if (a1 == 3 || a1 == 1 || a1 == 6 || a1 == 2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 is_light_level_8_or_9(u8 a1)
+{
+ if (a1 == 8 || a1 == 9)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+u8 unref_sub_8054260(void)
+{
+ return get_mapheader_by_bank_and_number(gSaveBlock1.warp2.mapGroup, gSaveBlock1.warp2.mapNum)->regionMapSectionId;
+}
+
+u8 sav1_map_get_name(void)
+{
+ return get_mapheader_by_bank_and_number(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum)->regionMapSectionId;
+}
+
+u8 sav1_map_get_battletype(void)
+{
+ return get_mapheader_by_bank_and_number(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum)->battleType;
+}
+
+void ResetSafariZoneFlag_(void)
+{
+ ResetSafariZoneFlag();
+}
+
+bool32 is_c1_link_related_active(void)
+{
+ if (gMain.callback1 == sub_8055354)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void c1_overworld_normal(u16 newKeys, u16 heldKeys)
+{
+ struct FieldInput inputStruct;
+
+ sub_8059204();
+ FieldClearPlayerInput(&inputStruct);
+ FieldGetPlayerInput(&inputStruct, newKeys, heldKeys);
+ if (!ScriptContext2_IsEnabled())
+ {
+ if (sub_8068024(&inputStruct) == 1)
+ {
+ ScriptContext2_Enable();
+ HideMapNamePopup();
+ }
+ else
+ {
+ player_step(inputStruct.dpadDirection, newKeys, heldKeys);
+ }
+ }
+}
+
+void c1_overworld(void)
+{
+ if (gMain.callback2 == c2_overworld)
+ c1_overworld_normal(gMain.newKeys, gMain.heldKeys);
+}
+
+void c2_overworld_basic(void)
+{
+ ScriptContext2_RunScript();
+ RunTasks();
+ AnimateSprites();
+ CameraUpdate();
+ UpdateCameraPanning();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ sub_8072EDC();
+}
+
+void sub_8054398(void)
+{
+ c2_overworld_basic();
+}
+
+void c2_overworld(void)
+{
+ int fading = (gPaletteFade.active != 0);
+ if (fading)
+ SetVBlankCallback(NULL);
+ c2_overworld_basic();
+ if (fading)
+ SetFieldVBlankCallback();
+}
+
+void set_callback1(MainCallback cb)
+{
+ gMain.callback1 = cb;
+}
+
+void sub_80543DC(u16 (*a1)(u32))
+{
+ gUnknown_03000584 = a1;
+}
+
+void sub_80543E8(void)
+{
+ if (gFieldCallback)
+ gFieldCallback();
+ else
+ mapldr_default();
+ gFieldCallback = NULL;
+}
+
+void CB2_NewGame(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ ResetSafariZoneFlag_();
+ NewGameInitData();
+ player_avatar_init_params_reset();
+ PlayTimeCounter_Start();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ gFieldCallback = ExecuteTruckSequence;
+ do_load_map_stuff_loop(&gMain.state);
+ SetFieldVBlankCallback();
+ set_callback1(c1_overworld);
+ SetMainCallback2(c2_overworld);
+}
+
+void CB2_WhiteOut(void)
+{
+ u8 val;
+ gMain.state++;
+ if (gMain.state >= 120)
+ {
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ ResetSafariZoneFlag_();
+ DoWhiteOut();
+ player_avatar_init_params_reset();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ gFieldCallback = sub_8080B60;
+ val = 0;
+ do_load_map_stuff_loop(&val);
+ SetFieldVBlankCallback();
+ set_callback1(c1_overworld);
+ SetMainCallback2(c2_overworld);
+ }
+}
+
+void CB2_LoadMap(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ set_callback1(NULL);
+ SetMainCallback2(sub_810CC80);
+ gMain.savedCallback = CB2_LoadMap2;
+}
+
+void CB2_LoadMap2(void)
+{
+ do_load_map_stuff_loop(&gMain.state);
+ SetFieldVBlankCallback();
+ set_callback1(c1_overworld);
+ SetMainCallback2(c2_overworld);
+}
+
+void sub_8054534(void)
+{
+ if (!gMain.state)
+ {
+ FieldClearVBlankHBlankCallbacks();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ set_callback1(NULL);
+ }
+ if (sub_805493C(&gMain.state, 1))
+ {
+ SetFieldVBlankCallback();
+ set_callback1(c1_overworld);
+ SetMainCallback2(c2_overworld);
+ }
+}
+
+void sub_8054588(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_8080AC4;
+ SetMainCallback2(c2_80567AC);
+}
+
+void c2_80567AC(void)
+{
+ if (sub_805483C(&gMain.state))
+ {
+ SetFieldVBlankCallback();
+ set_callback1(sub_8055354);
+ sub_80543DC(sub_8055390);
+ SetMainCallback2(c2_overworld);
+ }
+}
+
+void c2_exit_to_overworld_2_switch(void)
+{
+ if (is_c1_link_related_active() == TRUE)
+ {
+ SetMainCallback2(c2_exit_to_overworld_2_link);
+ }
+ else
+ {
+ FieldClearVBlankHBlankCallbacks();
+ SetMainCallback2(c2_exit_to_overworld_2_local);
+ }
+}
+
+void c2_exit_to_overworld_2_local(void)
+{
+ if (sub_8054A4C(&gMain.state))
+ {
+ SetFieldVBlankCallback();
+ SetMainCallback2(c2_overworld);
+ }
+}
+
+void c2_exit_to_overworld_2_link(void)
+{
+ if (!sub_8055870() && sub_8054A9C(&gMain.state))
+ SetMainCallback2(c2_overworld);
+}
+
+void sub_805465C(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ sub_8054F70();
+ set_callback1(sub_8055354);
+ sub_80543DC(sub_8055390);
+ gFieldCallback = sub_8080A3C;
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ c2_exit_to_overworld_2_switch();
+}
+
+void sub_805469C(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = atk17_seteffectuser;
+ c2_exit_to_overworld_2_switch();
+}
+
+void sub_80546B8(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_80809B0;
+ c2_exit_to_overworld_2_switch();
+}
+
+void c2_exit_to_overworld_1_continue_scripts_restart_music(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_8080990;
+ c2_exit_to_overworld_2_switch();
+}
+
+void sub_80546F0(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_8080B60;
+ c2_exit_to_overworld_2_switch();
+}
+
+void sub_805470C(void)
+{
+ if (gMapHeader.flags == 1 && sub_80BBB24() == 1)
+ ShowMapNamePopup();
+ sub_8080B60();
+}
+
+void CB2_ContinueSavedGame(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ ResetSafariZoneFlag_();
+ sub_805338C();
+ sub_8053198();
+ UnfreezeMapObjects();
+ DoTimeBasedEvents();
+ sub_805308C();
+ sub_8055FC0();
+ PlayTimeCounter_Start();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ if (GetSecretBase2Field_9() == 1)
+ {
+ ClearSecretBase2Field_9();
+ sub_8053778();
+ warp_in();
+ SetMainCallback2(CB2_LoadMap);
+ }
+ else
+ {
+ gFieldCallback = sub_805470C;
+ set_callback1(c1_overworld);
+ c2_exit_to_overworld_2_switch();
+ }
+}
+
+void FieldClearVBlankHBlankCallbacks(void)
+{
+ u16 savedIme = REG_IME;
+ REG_IME = 0;
+ REG_IE &= ~INTR_FLAG_HBLANK;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = savedIme;
+ SetVBlankCallback(NULL);
+ SetHBlankCallback(NULL);
+}
+
+void SetFieldVBlankCallback(void)
+{
+ SetVBlankCallback(VBlankCB_Field);
+}
+
+void VBlankCB_Field(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ sub_8089668();
+ sub_8057A58();
+ TransferPlttBuffer();
+ sub_8072E74();
+}
+
+void sub_8054814(void)
+{
+ u8 val = sav1_get_flash_used_on_map();
+ if (val)
+ {
+ sub_80815E0(val);
+ sub_80895F8(gUnknown_08216694[0], gUnknown_08216694[1], gUnknown_08216694[2]);
+ }
+}
+
+bool32 sub_805483C(u8 *a1)
+{
+ switch (*a1)
+ {
+ case 0:
+ FieldClearVBlankHBlankCallbacks();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ sub_8054F70();
+ sub_8054BA8();
+ (*a1)++;
+ break;
+ case 1:
+ sub_8053994(1);
+ (*a1)++;
+ break;
+ case 2:
+ sub_8054D4C(1);
+ (*a1)++;
+ break;
+ case 3:
+ sub_8054E98();
+ sub_8054D90();
+ sub_8054EC8();
+ sub_8054E60();
+ (*a1)++;
+ break;
+ case 4:
+ sub_8054814();
+ sub_8054C54();
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ (*a1)++;
+ break;
+ case 5:
+ move_tilemap_camera_to_upper_left_corner();
+ (*a1)++;
+ break;
+ case 6:
+ sub_8056D28(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 7:
+ sub_8056D38(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 8:
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 9:
+ DrawWholeMapView();
+ (*a1)++;
+ break;
+ case 10:
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+ (*a1)++;
+ break;
+ case 12:
+ sub_80543E8();
+ (*a1)++;
+ break;
+ case 11:
+ (*a1)++;
+ break;
+ case 13:
+ return 1;
+ }
+ return 0;
+}
+
+bool32 sub_805493C(u8 *a1, u32 a2)
+{
+ switch (*a1)
+ {
+ case 0:
+ FieldClearVBlankHBlankCallbacks();
+ sub_8053994(a2);
+ (*a1)++;
+ break;
+ case 1:
+ sub_8054BA8();
+ (*a1)++;
+ break;
+ case 2:
+ sub_8054D4C(a2);
+ (*a1)++;
+ break;
+ case 3:
+ mli4_mapscripts_and_other();
+ sub_8054E34();
+ (*a1)++;
+ break;
+ case 4:
+ sub_8054814();
+ sub_8054C54();
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ (*a1)++;
+ break;
+ case 5:
+ move_tilemap_camera_to_upper_left_corner();
+ (*a1)++;
+ break;
+ case 6:
+ sub_8056D28(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 7:
+ sub_8056D38(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 8:
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 9:
+ DrawWholeMapView();
+ (*a1)++;
+ break;
+ case 10:
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+ (*a1)++;
+ break;
+ case 11:
+ if (gMapHeader.flags == 1 && sub_80BBB24() == 1)
+ ShowMapNamePopup();
+ (*a1)++;
+ break;
+ case 12:
+ sub_80543E8();
+ (*a1)++;
+ break;
+ case 13:
+ return 1;
+ }
+ return 0;
+}
+
+bool32 sub_8054A4C(u8 *a1)
+{
+ switch (*a1)
+ {
+ case 0:
+ sub_8054BA8();
+ sub_8054D4C(0);
+ sub_8054E20();
+ sub_8054E34();
+ (*a1)++;
+ break;
+ case 1:
+ sub_8054C2C();
+ (*a1)++;
+ break;
+ case 2:
+ sub_80543E8();
+ (*a1)++;
+ break;
+ case 3:
+ return 1;
+ }
+ return 0;
+}
+
+bool32 sub_8054A9C(u8 *a1)
+{
+ switch (*a1)
+ {
+ case 0:
+ FieldClearVBlankHBlankCallbacks();
+ sub_8054BA8();
+ (*a1)++;
+ break;
+ case 1:
+ sub_8054D4C(1);
+ (*a1)++;
+ break;
+ case 2:
+ sub_8054F48();
+ sub_8054E20();
+ sub_8054E7C();
+ (*a1)++;
+ break;
+ case 3:
+ sub_8054814();
+ sub_8054C54();
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ (*a1)++;
+ break;
+ case 4:
+ move_tilemap_camera_to_upper_left_corner();
+ (*a1)++;
+ break;
+ case 5:
+ sub_8056D28(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 6:
+ sub_8056D38(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 7:
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 8:
+ DrawWholeMapView();
+ (*a1)++;
+ break;
+ case 9:
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+ (*a1)++;
+ break;
+ case 12:
+ sub_80543E8();
+ (*a1)++;
+ break;
+ case 10:
+ case 11:
+ (*a1)++;
+ break;
+ case 13:
+ SetFieldVBlankCallback();
+ (*a1)++;
+ return 1;
+ }
+ return 0;
+}
+
+void do_load_map_stuff_loop(u8 *a1)
+{
+ while (!sub_805493C(a1, 0))
+ ;
+}
+
+void sub_8054BA8(void)
+{
+ u8 *addr;
+ u32 size;
+
+ REG_DISPCNT = 0;
+
+ remove_some_task();
+
+ DmaClear16(3, PLTT + 2, PLTT_SIZE - 2);
+
+ addr = (void *)VRAM;
+ size = 0x18000;
+ while (1)
+ {
+ DmaFill16(3, 0, addr, 0x1000);
+ addr += 0x1000;
+ size -= 0x1000;
+ if (size <= 0x1000)
+ {
+ DmaFill16(3, 0, addr, size);
+ break;
+ }
+ }
+
+ ResetOamRange(0, 128);
+ LoadOam();
+}
+
+void sub_8054C2C(void)
+{
+ sub_8054814();
+ sub_8054C54();
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ mapdata_load_assets_to_gpu_and_full_redraw();
+}
+
+void sub_8054C54(void)
+{
+ REG_MOSAIC = 0;
+ REG_WININ = 7967;
+ REG_WINOUT = 257;
+ REG_WIN0H = 255;
+ REG_WIN0V = 255;
+ REG_WIN1H = -1;
+ REG_WIN1V = -1;
+ REG_BLDCNT = gUnknown_081E29E0[1] | gUnknown_081E29E0[2] | gUnknown_081E29E0[3] | 0x1040;
+ REG_BLDALPHA = 1805;
+ *gBGHOffsetRegs[0] = 0;
+ *gBGVOffsetRegs[0] = 0;
+ *gBGControlRegs[0] = 0;
+ *gBGHOffsetRegs[1] = 0;
+ *gBGVOffsetRegs[1] = 0;
+ *gBGControlRegs[1] = 7489;
+ *gBGHOffsetRegs[2] = 0;
+ *gBGVOffsetRegs[2] = 0;
+ *gBGControlRegs[2] = 7234;
+ *gBGHOffsetRegs[3] = 0;
+ *gBGVOffsetRegs[3] = 0;
+ *gBGControlRegs[3] = 7747;
+ REG_DISPCNT = gUnknown_081E29D8[1] | 0x7060 | gUnknown_081E29D8[2] | gUnknown_081E29D8[0] | gUnknown_081E29D8[3];
+}
+
+void sub_8054D4C(u32 a1)
+{
+ ResetTasks();
+ ResetSpriteData();
+ ResetPaletteFade();
+ dp12_8087EA4();
+ ResetCameraUpdateInfo();
+ InstallCameraPanAheadCallback();
+ sub_805C7C4(0);
+ FieldEffectActiveListClear();
+ InitFieldMessageBox();
+ sub_807C828();
+ sub_8080750();
+ if (!a1)
+ SetUpFieldTasks();
+ mapheader_run_script_with_tag_x5();
+}
+
+void sub_8054D90(void)
+{
+ gUnknown_0300489C = 0;
+ gUnknown_03004898 = 0;
+ sub_805AA98();
+ sub_805B55C(0, 0);
+ mapheader_run_first_tag4_script_list_match();
+}
+
+void mli4_mapscripts_and_other(void)
+{
+ s16 x, y;
+ struct UnkPlayerStruct *player;
+ gUnknown_0300489C = 0;
+ gUnknown_03004898 = 0;
+ sub_805AA98();
+ sav1_camera_get_focus_coords(&x, &y);
+ player = sub_8053AA8();
+ InitPlayerAvatar(x, y, player->player_field_1, gSaveBlock2.playerGender);
+ SetPlayerAvatarTransitionFlags(player->player_field_0);
+ player_avatar_init_params_reset();
+ sub_805B55C(0, 0);
+ ResetBerryTreeSparkleFlags();
+ mapheader_run_first_tag4_script_list_match();
+}
+
+void sub_8054E20(void)
+{
+ sub_805B710(0, 0);
+ RotatingGate_InitPuzzleAndGraphics();
+}
+
+void sub_8054E34(void)
+{
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_15 = 1;
+ InitCameraUpdateCallback(gPlayerAvatar.spriteId);
+}
+
+void sub_8054E60(void)
+{
+ InitCameraUpdateCallback(sub_8055AE8(gUnknown_03004860));
+}
+
+void sub_8054E7C(void)
+{
+ InitCameraUpdateCallback(sub_8055AE8(gUnknown_03004860));
+}
+
+void sub_8054E98(void)
+{
+ u16 x, y;
+ sav1_camera_get_focus_coords(&x, &y);
+ sub_8056C50(x + gUnknown_03004860, y);
+}
+
+void sub_8054EC8(void)
+{
+ u16 i;
+ u16 x, y;
+
+ sav1_camera_get_focus_coords(&x, &y);
+ x -= gUnknown_03004860;
+
+ for (i = 0; i < gFieldLinkPlayerCount; i++)
+ {
+ SpawnLinkPlayerMapObject(i, i + x, y, gLinkPlayers[i].gender);
+ CreateLinkPlayerSprite(i);
+ }
+
+ sub_8055340(word_3002910);
+}
+
+void sub_8054F48(void)
+{
+ u16 i;
+ for (i = 0; i < gFieldLinkPlayerCount; i++)
+ CreateLinkPlayerSprite(i);
+}
+
+void sub_8054F70(void)
+{
+ int i;
+ for (i = 0; i < 4; i++)
+ gUnknown_03000580[i] = 0x80;
+}
+
+bool32 sub_8054F88(u16 a1)
+{
+ int i;
+ int count = gFieldLinkPlayerCount;
+
+ for (i = 0; i < count; i++)
+ if (gUnknown_03000580[i] != a1)
+ return FALSE;
+ return TRUE;
+}
+
+bool32 sub_8054FC0(u16 a1)
+{
+ int i;
+ int count = gFieldLinkPlayerCount;
+
+ for (i = 0; i < count; i++)
+ if (gUnknown_03000580[i] == a1)
+ return TRUE;
+ return FALSE;
+}
+
+void sub_8054FF8(u32 a1, u16 a2, struct UnkStruct_8054FF8 *a3, u16 *a4)
+{
+ u8 *script;
+
+ if (gUnknown_03000580[a1] == 0x80)
+ {
+ script = sub_8055648(a3);
+ if (script)
+ {
+ *a4 = sub_8055758(script);
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_8055808(script);
+ }
+ return;
+ }
+ if (sub_8054FC0(0x83) == 1)
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_805585C();
+ }
+ return;
+ }
+ switch (a2)
+ {
+ case 24:
+ if (sub_8055630(a3))
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_80557F4();
+ }
+ }
+ break;
+ case 18:
+ if (sub_8055660(a3) == 1)
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_8055824();
+ }
+ }
+ break;
+ case 25:
+ script = sub_805568C(a3);
+ if (script)
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_8055840(script);
+ }
+ }
+ break;
+ case 27:
+ if (sub_8055618(a3))
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_8055408);
+ sub_80557E8();
+ }
+ }
+ break;
+ case 28:
+ if (sub_8055618(a3))
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_8055438);
+ sub_80557E8();
+ }
+ }
+ break;
+ }
+ }
+
+ switch (a2)
+ {
+ case 23:
+ gUnknown_03000580[a1] = 0x83;
+ break;
+ case 22:
+ gUnknown_03000580[a1] = 0x82;
+ break;
+ case 26:
+ gUnknown_03000580[a1] = 0x80;
+ if (a3->b)
+ sub_80543DC(sub_8055390);
+ break;
+ case 29:
+ if (gUnknown_03000580[a1] == 0x82)
+ gUnknown_03000580[a1] = 0x81;
+ break;
+ }
+}
+
+void sub_8055218(u16 *a1, int a2)
+{
+ struct UnkStruct_8054FF8 st;
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ u16 v5 = a1[i];
+ u16 v8 = 0;
+ sub_80555B0(i, a2, &st);
+ sub_8054FF8(i, v5, &st, &v8);
+ if (gUnknown_03000580[i] == 0x80)
+ v8 = sub_805530C(v5);
+ sub_8055BFC(i, v8);
+ }
+}
+
+void sub_8055280(u16 a1)
+{
+ if (a1 >= 17 && a1 < 30)
+ word_3004858 = a1;
+ else
+ word_3004858 = 17;
+}
+
+u16 sub_80552B0(u32 a1)
+{
+ if (gMain.heldKeys & 0x40)
+ {
+ return 19;
+ }
+ else if (gMain.heldKeys & 0x80)
+ {
+ return 18;
+ }
+ else if (gMain.heldKeys & 0x20)
+ {
+ return 20;
+ }
+ else if (gMain.heldKeys & 0x10)
+ {
+ return 21;
+ }
+ else if (gMain.newKeys & 8)
+ {
+ return 24;
+ }
+ else if (gMain.newKeys & 1)
+ {
+ return 25;
+ }
+ else
+ {
+ return 17;
+ }
+}
+
+u16 sub_805530C(u16 a1)
+{
+ switch (a1)
+ {
+ case 21:
+ return 4;
+ case 20:
+ return 3;
+ case 19:
+ return 1;
+ case 18:
+ return 2;
+ default:
+ return 0;
+ }
+}
+
+void sub_8055340(u16 *a1)
+{
+ int i;
+ for (i = 0; i < 4; i++)
+ a1[i] = 17;
+}
+
+void sub_8055354(void)
+{
+ u8 val = gUnknown_03004860;
+ sub_8055218(word_3002910, val);
+ sub_8055280(gUnknown_03000584(val));
+ sub_8055340(word_3002910);
+}
+
+u16 sub_8055390(u32 a1)
+{
+ if (ScriptContext2_IsEnabled() == 1)
+ return 17;
+ if (gLink.recvQueue.count > 4)
+ return 27;
+ if (gLink.sendQueue.count <= 4)
+ return sub_80552B0(a1);
+ return 28;
+}
+
+u16 sub_80553E0(u32 a1)
+{
+ return 17;
+}
+
+u16 sub_80553E4(u32 a1)
+{
+ u16 retVal;
+ if (ScriptContext2_IsEnabled() == 1)
+ {
+ retVal = 17;
+ }
+ else
+ {
+ retVal = 26;
+ sub_80543DC(sub_80553E0);
+ }
+ return retVal;
+}
+
+u16 sub_8055408(u32 a1)
+{
+ u16 retVal;
+ if (gLink.recvQueue.count > 2)
+ {
+ retVal = 17;
+ }
+ else
+ {
+ retVal = 26;
+ ScriptContext2_Disable();
+ sub_80543DC(sub_80553E0);
+ }
+ return retVal;
+}
+
+u16 sub_8055438(u32 a1)
+{
+ u16 retVal;
+ if (gLink.sendQueue.count > 2)
+ {
+ retVal = 17;
+ }
+ else
+ {
+ retVal = 26;
+ ScriptContext2_Disable();
+ sub_80543DC(sub_80553E0);
+ }
+ return retVal;
+}
+
+u16 sub_8055468(u32 a1)
+{
+ return 17;
+}
+
+u16 sub_805546C(u32 linkPlayerId)
+{
+ if (gUnknown_03000580[linkPlayerId] == 0x82 && (gMain.newKeys & B_BUTTON))
+ {
+ sub_80543DC(sub_8055468);
+ return 29;
+ }
+ else
+ {
+ return 17;
+ }
+}
+
+u16 sub_80554A4(u32 a1)
+{
+ sub_80543DC(sub_805546C);
+ return 22;
+}
+
+u16 sub_80554B8(u32 a1)
+{
+ return 17;
+}
+
+u16 sub_80554BC(u32 a1)
+{
+ if (sub_8054F88(0x83) == TRUE)
+ {
+ ScriptContext1_SetupScript(gUnknown_081A4508);
+ sub_80543DC(sub_80554B8);
+ }
+ return 17;
+}
+
+u16 sub_80554E4(u32 a1)
+{
+ sub_80543DC(sub_80554BC);
+ return 23;
+}
+
+u32 sub_80554F8(void)
+{
+ if (sub_8054FC0(0x83) == TRUE)
+ return 2;
+ if (gUnknown_03000584 == sub_805546C && gUnknown_03000580[gUnknown_03004860] != 0x82)
+ return 0;
+ if (gUnknown_03000584 == sub_8055468 && gUnknown_03000580[gUnknown_03004860] == 0x81)
+ return 2;
+ return sub_8054F88(0x82);
+}
+
+bool32 unref_sub_8055568(void)
+{
+ return sub_8054FC0(0x83);
+}
+
+u16 sub_8055574(void)
+{
+ sub_80543DC(sub_80554A4);
+ return 0;
+}
+
+u16 sub_8055588(void)
+{
+ sub_80543DC(sub_80553E4);
+ return 0;
+}
+
+u16 sub_805559C(void)
+{
+ sub_80543DC(sub_80554E4);
+ return 0;
+}
+
+void sub_80555B0(int linkPlayerId, int a2, struct UnkStruct_8054FF8 *a3)
+{
+ s16 x, y;
+
+ a3->a = linkPlayerId;
+ a3->b = (linkPlayerId == a2) ? 1 : 0;
+ a3->c = gLinkPlayerMapObjects[linkPlayerId].mode;
+ a3->d = sub_8055B30(linkPlayerId);
+ sub_8055B08(linkPlayerId, &x, &y);
+ a3->sub.x = x;
+ a3->sub.y = y;
+ a3->sub.height = sub_8055B50(linkPlayerId);
+ a3->field_C = MapGridGetMetatileBehaviorAt(x, y);
+}
+
+bool32 sub_8055618(struct UnkStruct_8054FF8 *a1)
+{
+ u8 v1 = a1->c;
+ if (v1 == 2 || v1 == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool32 sub_8055630(struct UnkStruct_8054FF8 *a1)
+{
+ u8 v1 = a1->c;
+ if (v1 == 2 || v1 == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+u8 *sub_8055648(struct UnkStruct_8054FF8 *a1)
+{
+ if (a1->c != 2)
+ return 0;
+ return sub_8068E24(&a1->sub);
+}
+
+bool32 sub_8055660(struct UnkStruct_8054FF8 *a1)
+{
+ if (a1->c != 2 && a1->c != 0)
+ return FALSE;
+ if (!MetatileBehavior_IsSouthArrowWarp(a1->field_C))
+ return FALSE;
+ if (a1->d != 1)
+ return FALSE;
+ return TRUE;
+}
+
+u8 *sub_805568C(struct UnkStruct_8054FF8 *a1)
+{
+ struct MapPosition unkStruct;
+ u8 linkPlayerId;
+
+ if (a1->c && a1->c != 2)
+ return 0;
+
+ unkStruct = a1->sub;
+ unkStruct.x += gUnknown_0821664C[a1->d].x;
+ unkStruct.y += gUnknown_0821664C[a1->d].y;
+ unkStruct.height = 0;
+ linkPlayerId = GetLinkPlayerIdAt(unkStruct.x, unkStruct.y);
+
+ if (linkPlayerId != 4)
+ {
+ if (!a1->b)
+ return TradeRoom_TooBusyToNotice;
+ if (gUnknown_03000580[linkPlayerId] != 0x80)
+ return TradeRoom_TooBusyToNotice;
+ if (!sub_8083BF4(linkPlayerId))
+ return TradeRoom_ReadTrainerCard1;
+ else
+ return TradeRoom_ReadTrainerCard2;
+ }
+
+ return sub_80682A8(&unkStruct, a1->field_C, a1->d);
+}
+
+u16 sub_8055758(u8 *script)
+{
+ if (script == DoubleBattleColosseum_EventScript_1A4383)
+ return 10;
+ if (script == DoubleBattleColosseum_EventScript_1A439E)
+ return 9;
+ if (script == DoubleBattleColosseum_EventScript_1A43B9)
+ return 10;
+ if (script == DoubleBattleColosseum_EventScript_1A43D4)
+ return 9;
+ if (script == RecordCorner_EventScript_1A4418)
+ return 10;
+ if (script == RecordCorner_EventScript_1A442D)
+ return 9;
+ if (script == RecordCorner_EventScript_1A4442)
+ return 10;
+ if (script == RecordCorner_EventScript_1A4457)
+ return 9;
+ if (script == SingleBattleColosseum_EventScript_1A436F)
+ return 10;
+ if (script == SingleBattleColosseum_EventScript_1A4379)
+ return 9;
+ if (script == TradeCenter_EventScript_1A43F0)
+ return 10;
+ if (script == TradeCenter_EventScript_1A43FA)
+ return 9;
+ return 0;
+}
+
+void sub_80557E8(void)
+{
+ ScriptContext2_Enable();
+}
+
+void sub_80557F4(void)
+{
+ PlaySE(SE_WIN_OPEN);
+ sub_8071310();
+ ScriptContext2_Enable();
+}
+
+void sub_8055808(u8 *script)
+{
+ PlaySE(SE_SELECT);
+ ScriptContext1_SetupScript(script);
+ ScriptContext2_Enable();
+}
+
+void sub_8055824(void)
+{
+ PlaySE(SE_WIN_OPEN);
+ ScriptContext1_SetupScript(TradeRoom_PromptToCancelLink);
+ ScriptContext2_Enable();
+}
+
+void sub_8055840(u8 *script)
+{
+ PlaySE(SE_SELECT);
+ ScriptContext1_SetupScript(script);
+ ScriptContext2_Enable();
+}
+
+void sub_805585C(void)
+{
+ ScriptContext1_SetupScript(TradeRoom_TerminateLink);
+ ScriptContext2_Enable();
+}
+
+bool32 sub_8055870(void)
+{
+ if (!is_c1_link_related_active())
+ return 0;
+ if (gLink.recvQueue.count >= 3)
+ gUnknown_03000588 = 1;
+ else
+ gUnknown_03000588 = 0;
+ return gUnknown_03000588;
+}
+
+bool32 sub_80558AC(void)
+{
+ u8 temp;
+
+ if (is_c1_link_related_active() != TRUE)
+ return FALSE;
+
+ if (sub_8007B24() != TRUE)
+ return FALSE;
+
+ if (gUnknown_03000584 == sub_8055408)
+ return TRUE;
+
+ if (gUnknown_03000584 != sub_80553E4)
+ return FALSE;
+
+ temp = gUnknown_03000588;
+ gUnknown_03000588 = 0;
+
+ if (temp == TRUE)
+ return TRUE;
+
+ if (gPaletteFade.active && gPaletteFade.softwareFadeFinishing)
+ return TRUE;
+
+ return FALSE;
+}
+
+bool32 sub_8055910(void)
+{
+ if (is_c1_link_related_active() != TRUE)
+ return FALSE;
+
+ if (sub_8007B24() != TRUE)
+ return FALSE;
+
+ if (gUnknown_03000584 == sub_8055438)
+ return TRUE;
+
+ return FALSE;
+}
+
+bool32 sub_8055940(void)
+{
+ if (!sub_8007B24())
+ return FALSE;
+ return TRUE;
+}
+
+void ZeroLinkPlayerMapObject(struct LinkPlayerMapObject *linkPlayerMapObj)
+{
+ memset(linkPlayerMapObj, 0, sizeof(struct LinkPlayerMapObject));
+}
+
+void strange_npc_table_clear(void)
+{
+ memset(gLinkPlayerMapObjects, 0, sizeof(gLinkPlayerMapObjects));
+}
+
+void ZeroMapObject(struct MapObject *mapObj)
+{
+ memset(mapObj, 0, sizeof(struct MapObject));
+}
+
+void SpawnLinkPlayerMapObject(u8 linkPlayerId, s16 x, s16 y, u8 a4)
+{
+ u8 mapObjId = sub_805AB54();
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId];
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+
+ ZeroLinkPlayerMapObject(linkPlayerMapObj);
+ ZeroMapObject(mapObj);
+
+ linkPlayerMapObj->active = 1;
+ linkPlayerMapObj->linkPlayerId = linkPlayerId;
+ linkPlayerMapObj->mapObjId = mapObjId;
+ linkPlayerMapObj->mode = 0;
+
+ mapObj->active = 1;
+ mapObj->mapobj_bit_1 = a4;
+ mapObj->mapobj_unk_19 = 2;
+ mapObj->spriteId = 64;
+
+ InitLinkPlayerMapObjectPos(mapObj, x, y);
+}
+
+void InitLinkPlayerMapObjectPos(struct MapObject *mapObj, s16 x, s16 y)
+{
+ mapObj->coords2.x = x;
+ mapObj->coords2.y = y;
+ mapObj->coords3.x = x;
+ mapObj->coords3.y = y;
+ sub_80603CC(x, y, &mapObj->coords1.x, &mapObj->coords1.y);
+ mapObj->coords1.x += 8;
+ FieldObjectUpdateZCoord(mapObj);
+}
+
+void unref_sub_8055A6C(u8 linkPlayerId, u8 a2)
+{
+ if (gLinkPlayerMapObjects[linkPlayerId].active)
+ {
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ mapObj->mapobj_unk_19 = a2;
+ }
+}
+
+void unref_sub_8055A9C(u8 linkPlayerId)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId];
+ u8 mapObjId = linkPlayerMapObj->mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ if (mapObj->spriteId != 64 )
+ DestroySprite(&gSprites[mapObj->spriteId]);
+ linkPlayerMapObj->active = 0;
+ mapObj->active = 0;
+}
+
+u8 sub_8055AE8(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return mapObj->spriteId;
+}
+
+void sub_8055B08(u8 linkPlayerId, u16 *x, u16 *y)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ *x = mapObj->coords2.x;
+ *y = mapObj->coords2.y;
+}
+
+u8 sub_8055B30(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return mapObj->mapobj_unk_19;
+}
+
+u8 sub_8055B50(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return mapObj->mapobj_unk_0B_0;
+}
+
+s32 unref_sub_8055B74(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return 16 - (s8)mapObj->mapobj_unk_21;
+}
+
+u8 GetLinkPlayerIdAt(s16 x, s16 y)
+{
+ u8 i;
+ for (i = 0; i < 4; i++)
+ {
+ if (gLinkPlayerMapObjects[i].active
+ && (gLinkPlayerMapObjects[i].mode == 0 || gLinkPlayerMapObjects[i].mode == 2))
+ {
+ struct MapObject *mapObj = &gMapObjects[gLinkPlayerMapObjects[i].mapObjId];
+ if (mapObj->coords2.x == x && mapObj->coords2.y == y)
+ return i;
+ }
+ }
+ return 4;
+}
+
+void sub_8055BFC(u8 linkPlayerId, u8 a2)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId];
+ u8 mapObjId = linkPlayerMapObj->mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+
+ if (linkPlayerMapObj->active)
+ {
+ if (a2 > 10)
+ mapObj->mapobj_bit_2 = 1;
+ else
+ gUnknown_082166D8[gUnknown_082166A0[linkPlayerMapObj->mode](linkPlayerMapObj, mapObj, a2)](linkPlayerMapObj, mapObj);
+ }
+}
+
+u8 sub_8055C68(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return gUnknown_082166AC[a3](linkPlayerMapObj, mapObj, a3);
+}
+
+u8 sub_8055C88(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return 1;
+}
+
+u8 sub_8055C8C(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return gUnknown_082166AC[a3](linkPlayerMapObj, mapObj, a3);
+}
+
+u8 sub_8055CAC(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return 0;
+}
+
+u8 sub_8055CB0(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ s16 x, y;
+
+ mapObj->mapobj_unk_19 = npc_something3(a3, mapObj->mapobj_unk_19);
+ FieldObjectMoveDestCoords(mapObj, mapObj->mapobj_unk_19, &x, &y);
+
+ if (LinkPlayerDetectCollision(linkPlayerMapObj->mapObjId, mapObj->mapobj_unk_19, x, y))
+ {
+ return 0;
+ }
+ else
+ {
+ mapObj->mapobj_unk_21 = 16;
+ npc_coords_shift(mapObj, x, y);
+ FieldObjectUpdateZCoord(mapObj);
+ return 1;
+ }
+}
+
+u8 sub_8055D18(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ mapObj->mapobj_unk_19 = npc_something3(a3, mapObj->mapobj_unk_19);
+ return 0;
+}
+
+void sub_8055D30(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj)
+{
+ linkPlayerMapObj->mode = 0;
+}
+
+void sub_8055D38(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj)
+{
+ mapObj->mapobj_unk_21--;
+ linkPlayerMapObj->mode = 1;
+ MoveCoords(mapObj->mapobj_unk_19, &mapObj->coords1.x, &mapObj->coords1.y);
+ if (!mapObj->mapobj_unk_21)
+ {
+ npc_coords_shift_still(mapObj);
+ linkPlayerMapObj->mode = 2;
+ }
+}
+
+u8 npc_something3(u8 a1, u8 a2)
+{
+ switch (a1 - 1)
+ {
+ case 0:
+ case 6:
+ return 2;
+ case 1:
+ case 7:
+ return 1;
+ case 2:
+ case 8:
+ return 3;
+ case 3:
+ case 9:
+ return 4;
+ }
+ return a2;
+}
+
+u8 LinkPlayerDetectCollision(u8 selfMapObjId, u8 a2, s16 x, s16 y)
+{
+ u8 i;
+ for (i = 0; i < 16; i++)
+ {
+ if (i != selfMapObjId)
+ {
+ if ((gMapObjects[i].coords2.x == x && gMapObjects[i].coords2.y == y)
+ || (gMapObjects[i].coords3.x == x && gMapObjects[i].coords3.y == y))
+ {
+ return 1;
+ }
+ }
+ }
+ return MapGridIsImpassableAt(x, y);
+}
+
+void CreateLinkPlayerSprite(u8 linkPlayerId)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId];
+ u8 mapObjId = linkPlayerMapObj->mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ struct Sprite *sprite;
+
+ if (linkPlayerMapObj->active)
+ {
+ u8 val = GetRivalAvatarGraphicsIdByStateIdAndGender(0, mapObj->mapobj_bit_1);
+ mapObj->spriteId = AddPseudoFieldObject(val, SpriteCB_LinkPlayer, 0, 0, 0);
+ sprite = &gSprites[mapObj->spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->data0 = linkPlayerId;
+ mapObj->mapobj_bit_2 = 0;
+ }
+}
+
+void SpriteCB_LinkPlayer(struct Sprite *sprite)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[sprite->data0];
+ struct MapObject *mapObj = &gMapObjects[linkPlayerMapObj->mapObjId];
+ sprite->pos1.x = mapObj->coords1.x;
+ sprite->pos1.y = mapObj->coords1.y;
+ SetObjectSubpriorityByZCoord(mapObj->elevation, sprite, 1);
+ sprite->oam.priority = ZCoordToPriority(mapObj->elevation);
+ if (!linkPlayerMapObj->mode)
+ StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(mapObj->mapobj_unk_19));
+ else
+ StartSpriteAnimIfDifferent(sprite, get_go_image_anim_num(mapObj->mapobj_unk_19));
+ sub_806487C(sprite, 0);
+ if (mapObj->mapobj_bit_2)
+ {
+ sprite->invisible = ((sprite->data7 & 4) >> 2);
+ sprite->data7++;
+ }
+}
diff --git a/src/misc/rom6.c b/src/misc/rom6.c
new file mode 100644
index 000000000..ff032b6c2
--- /dev/null
+++ b/src/misc/rom6.c
@@ -0,0 +1,202 @@
+#include "global.h"
+#include "rom6.h"
+#include "braille_puzzles.h"
+#include "field_effect.h"
+#include "field_map_obj.h"
+#include "field_player_avatar.h"
+#include "item_use.h"
+#include "pokemon_menu.h"
+#include "rom4.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+
+extern u16 gScriptLastTalked;
+extern void (*gFieldCallback)(void);
+extern u8 gLastFieldPokeMenuOpened;
+extern void (*gUnknown_03005CE4)(void);
+extern u8 UseRockSmashScript[];
+
+EWRAM_DATA struct MapPosition gUnknown_0203923C = {0};
+
+static void task08_080C9820(u8);
+static void sub_810B3DC(u8);
+static void sub_810B428(u8);
+static void sub_810B4CC(u8);
+static void sub_810B53C(void);
+static void sub_810B58C(void);
+static void sub_810B5D8(void);
+static void sub_810B634(void);
+
+bool8 npc_before_player_of_type(u8 a)
+{
+ u8 mapObjId;
+
+ GetXYCoordsOneStepInFrontOfPlayer(&gUnknown_0203923C.x, &gUnknown_0203923C.y);
+ gUnknown_0203923C.height = PlayerGetZCoord();
+ mapObjId = GetFieldObjectIdByXYZ(gUnknown_0203923C.x, gUnknown_0203923C.y, gUnknown_0203923C.height);
+ if (gMapObjects[mapObjId].graphicsId != a)
+ {
+ return FALSE;
+ }
+ else
+ {
+ gScriptLastTalked = gMapObjects[mapObjId].localId;
+ return TRUE;
+ }
+}
+
+u8 oei_task_add(void)
+{
+ GetXYCoordsOneStepInFrontOfPlayer(&gUnknown_0203923C.x, &gUnknown_0203923C.y);
+ return CreateTask(task08_080C9820, 8);
+}
+
+static void task08_080C9820(u8 taskId)
+{
+ u8 mapObjId;
+
+ ScriptContext2_Enable();
+ gPlayerAvatar.unk6 = 1;
+ mapObjId = gPlayerAvatar.mapObjectId;
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(&gMapObjects[mapObjId])
+ || FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[mapObjId]))
+ {
+ if (gMapHeader.mapType == 5)
+ {
+ FieldEffectStart(0x3B);
+ gTasks[taskId].func = sub_810B428;
+ }
+ else
+ {
+ sub_8059BF4();
+ FieldObjectSetSpecialAnim(&gMapObjects[mapObjId], 0x39);
+ gTasks[taskId].func = sub_810B3DC;
+ }
+ }
+}
+
+static void sub_810B3DC(u8 taskId)
+{
+ if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(&gMapObjects[gPlayerAvatar.mapObjectId]) == TRUE)
+ {
+ FieldEffectStart(0x3B);
+ gTasks[taskId].func = sub_810B428;
+ }
+}
+
+static void sub_810B428(u8 taskId)
+{
+ if (!FieldEffectActiveListContains(6))
+ {
+ gUnknown_0202FF84[1] = player_get_direction_lower_nybble();
+ if (gUnknown_0202FF84[1] == 1)
+ gUnknown_0202FF84[2] = 0;
+ if (gUnknown_0202FF84[1] == 2)
+ gUnknown_0202FF84[2] = 1;
+ if (gUnknown_0202FF84[1] == 3)
+ gUnknown_0202FF84[2] = 2;
+ if (gUnknown_0202FF84[1] == 4)
+ gUnknown_0202FF84[2] = 3;
+ sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByCurrentState());
+ StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], gUnknown_0202FF84[2]);
+ FieldEffectActiveListRemove(6);
+ gTasks[taskId].func = sub_810B4CC;
+ }
+}
+
+static void sub_810B4CC(u8 taskId)
+{
+ void (*func)(void) = (void (*)(void))(((u16)gTasks[taskId].data[8] << 16) | (u16)gTasks[taskId].data[9]);
+
+ func();
+ gPlayerAvatar.unk6 = 0;
+ DestroyTask(taskId);
+}
+
+bool8 SetUpFieldMove_RockSmash(void)
+{
+ if (npc_before_player_of_type(0x56) == TRUE)
+ {
+ gFieldCallback = sub_808AB90;
+ gUnknown_03005CE4 = sub_810B53C;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static void sub_810B53C(void)
+{
+ gUnknown_0202FF84[0] = gLastFieldPokeMenuOpened;
+ ScriptContext1_SetupScript(UseRockSmashScript);
+}
+
+int FldEff_RockSmash(void)
+{
+ u8 taskId = oei_task_add();
+
+ gTasks[taskId].data[8] = (u32)sub_810B58C >> 16;
+ gTasks[taskId].data[9] = (u32)sub_810B58C;
+ IncrementGameStat(0x13);
+ return 0;
+}
+
+static void sub_810B58C(void)
+{
+ PlaySE(SE_W088);
+ FieldEffectActiveListRemove(0x25);
+ EnableBothScriptContexts();
+}
+
+int SetUpFieldMove_Dig(void)
+{
+ if (sub_80CA1C8() == TRUE)
+ {
+ gFieldCallback = sub_808AB90;
+ gUnknown_03005CE4 = sub_810B5D8;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static void sub_810B5D8(void)
+{
+ sub_8053014();
+ FieldEffectStart(0x26);
+ gUnknown_0202FF84[0] = gLastFieldPokeMenuOpened;
+}
+
+int FldEff_UseDig(void)
+{
+ u8 taskId = oei_task_add();
+
+ gTasks[taskId].data[8] = (u32)sub_810B634 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_810B634;
+ if (!ShouldDoBrailleDigEffect())
+ SetPlayerAvatarTransitionFlags(1);
+ return 0;
+}
+
+static void sub_810B634(void)
+{
+ u8 taskId;
+
+ FieldEffectActiveListRemove(0x26);
+ if (ShouldDoBrailleDigEffect())
+ {
+ DoBrailleDigEffect();
+ }
+ else
+ {
+ taskId = CreateTask(task08_080A1C44, 8);
+ gTasks[taskId].data[0] = 0;
+ }
+}
diff --git a/src/misc/rom_800D42C.c b/src/misc/rom_800D42C.c
new file mode 100644
index 000000000..f51779e65
--- /dev/null
+++ b/src/misc/rom_800D42C.c
@@ -0,0 +1,118 @@
+#include "global.h"
+#include "battle.h"
+#include "link.h"
+#include "text.h"
+
+extern u16 gBattleTypeFlags;
+extern u8 gBattleOutcome;
+
+extern struct Window gUnknown_03004210;
+
+extern u8 BattleText_Win[];
+extern u8 BattleText_Loss[];
+extern u8 BattleText_Tie[];
+
+#if ENGLISH
+#define LEFT_MESSAGE_X 6
+#define RIGHT_MESSAGE_X 21
+#define TILE_OFFSET_LOSS 168
+#elif GERMAN
+#define LEFT_MESSAGE_X 5
+#define RIGHT_MESSAGE_X 20
+#define TILE_OFFSET_LOSS 172
+#endif
+#define TILE_OFFSET_WIN 160
+#define CENTER_MESSAGE_X 13
+#define MESSAGE_Y 2
+
+#define PRINT_MESSAGE(text, tileDataStartOffset, x) \
+{ \
+ InitWindow(&gUnknown_03004210, text, tileDataStartOffset, x, MESSAGE_Y); \
+ sub_8002F44(&gUnknown_03004210); \
+}
+
+#define PRINT_MESSAGE_LEFT(text, tileDataStartOffset) PRINT_MESSAGE(text, tileDataStartOffset, LEFT_MESSAGE_X)
+#define PRINT_MESSAGE_RIGHT(text, tileDataStartOffset) PRINT_MESSAGE(text, tileDataStartOffset, RIGHT_MESSAGE_X)
+
+void PrintLinkBattleWinLossTie(void)
+{
+
+ if (gBattleOutcome == 3)
+ {
+ PRINT_MESSAGE(BattleText_Tie, TILE_OFFSET_WIN, CENTER_MESSAGE_X);
+ return;
+ }
+
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ // Double battle?
+
+ if (gBattleOutcome == 1)
+ {
+
+ // lp_field_18 = player position?
+ switch (gLinkPlayers[BATTLE_STRUCT->linkPlayerIndex].lp_field_18)
+ {
+ case 0:
+ case 2:
+ PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN);
+ PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS);
+ return;
+
+ case 1:
+ case 3:
+ PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN)
+ PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS)
+ return;
+ }
+ }
+ else
+ {
+
+ switch (gLinkPlayers[BATTLE_STRUCT->linkPlayerIndex].lp_field_18)
+ {
+ case 1:
+ case 3:
+ PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN);
+ PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS);
+ return;
+
+ case 0:
+ case 2:
+ PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN);
+ PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS);
+ return;
+ }
+ }
+
+ return;
+ }
+
+
+ if (gBattleOutcome == 1)
+ {
+ if (gLinkPlayers[BATTLE_STRUCT->linkPlayerIndex].lp_field_18 != 0)
+ {
+ PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN);
+ PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS);
+ }
+ else
+ {
+ PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN);
+ PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS);
+ }
+ }
+ else
+ {
+ if (gLinkPlayers[BATTLE_STRUCT->linkPlayerIndex].lp_field_18 != 0)
+ {
+ PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN);
+ PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS);
+ }
+ else
+ {
+ PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN);
+ PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS);
+ }
+ }
+}
diff --git a/src/misc/rom_8077ABC.c b/src/misc/rom_8077ABC.c
new file mode 100644
index 000000000..249146b37
--- /dev/null
+++ b/src/misc/rom_8077ABC.c
@@ -0,0 +1,2055 @@
+#include "global.h"
+#include "rom_8077ABC.h"
+#include "battle.h"
+#include "battle_anim.h"
+#include "blend_palette.h"
+#include "data2.h"
+#include "decompress.h"
+#include "palette.h"
+#include "pokemon_icon.h"
+#include "species.h"
+#include "sprite.h"
+#include "task.h"
+#include "trig.h"
+#include "util.h"
+
+#define GET_UNOWN_LETTER(personality) ((\
+ (((personality & 0x03000000) >> 24) << 6) \
+ | (((personality & 0x00030000) >> 16) << 4) \
+ | (((personality & 0x00000300) >> 8) << 2) \
+ | (((personality & 0x00000003) >> 0) << 0) \
+) % 28)
+
+#define IS_DOUBLE_BATTLE() ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) ? TRUE : FALSE)
+
+#define NUM_BATTLE_SLOTS 4
+
+#define gBattleMonPartyPositions gBattlePartyID
+#define gCastformElevations gUnknownCastformData_0837F5A8
+#define gCastformBackSpriteYCoords gUnknown_0837F5AC
+#define gTransformPersonalities gPID_perBank
+#define gBattleMonSprites gObjectBankIDs
+
+
+struct Struct_unk_2019348 {
+ u16 field_0;
+ u16 field_2;
+ u8 field_4;
+ u32 field_8;
+ u32 field_c;
+ u32 field_10;
+};
+
+struct TransformStatus {
+ u16 unknown;
+ u16 species;
+};
+
+struct Struct_gUnknown_0837F578 {
+ u8 field_0;
+ u8 field_1;
+};
+
+struct OamMatrix {
+ s16 a;
+ s16 b;
+ s16 c;
+ s16 d;
+};
+
+struct Struct_2017810 {
+ u8 filler_0[6];
+ u8 field_6;
+ u8 filler_7[5];
+};
+
+struct Color {
+ u16 r:5;
+ u16 g:5;
+ u16 b:5;
+};
+
+struct Struct_sub_8078914 {
+ u8 *field_0;
+ u8 *field_4;
+ u8 field_8;
+};
+
+struct BGCnt {
+ u16 priority:2;
+ u16 charBase:2;
+ u16 unused:2;
+ u16 mosaic:1;
+ u16 colorMode:1;
+ u16 screenBase:5;
+ u16 overflow:1;
+ u16 size:2;
+};
+
+#define BG1CNT (*(volatile struct BGCnt*)REG_ADDR_BG1CNT)
+#define BG2CNT (*(volatile struct BGCnt*)REG_ADDR_BG2CNT)
+#define BG3CNT (*(volatile struct BGCnt*)REG_ADDR_BG3CNT)
+
+extern struct OamData gOamData_837DF9C[];
+extern const union AnimCmd *const gDummySpriteAnimTable[];
+extern const union AffineAnimCmd *const gDummySpriteAffineAnimTable[];
+
+extern struct Struct_unk_2019348 unk_2019348;
+extern struct TransformStatus gTransformStatuses[];
+extern u16 gBattleMonPartyPositions[];
+extern u16 gBattleTypeFlags;
+extern u32 gTransformPersonalities[NUM_BATTLE_SLOTS];
+extern u8 gBattleMonForms[NUM_BATTLE_SLOTS];
+extern u16 gUnknown_0202F7CA[];
+extern u8 gBattleMonSprites[NUM_BATTLE_SLOTS];
+extern u8 gBattleAnimPlayerMonIndex;
+extern u8 gBattleAnimEnemyMonIndex;
+extern s16 gBattleAnimArgs[8];
+extern u8 gBanksBySide[NUM_BATTLE_SLOTS];
+extern u8 gNoOfAllBanks; // gNumBattleMons?
+extern struct OamMatrix gOamMatrices[];
+extern struct Struct_2017810 unk_2017810[];
+extern u8 gHappinessMoveAnim;
+
+EWRAM_DATA union AffineAnimCmd *gUnknown_0202F7D4 = NULL;
+EWRAM_DATA u32 filler_0202F7D8[3] = {0};
+
+const struct Struct_gUnknown_0837F578 gUnknown_0837F578[][4] = {
+ {
+ { 72, 80 },
+ { 176, 40 },
+ { 48, 40 },
+ { 112, 80 },
+ },
+ {
+ { 32, 80 },
+ { 200, 40 },
+ { 90, 88 },
+ { 152, 32 },
+ },
+};
+
+// One entry for each of the four Castform forms.
+// Coords are probably front pic coords or back pic coords, but this data does not seem to be
+// used during battle, party summary, or pokedex screens.
+const struct MonCoords gCastformFrontSpriteCoords[] = {
+ { 0x44, 17 }, // NORMAL
+ { 0x66, 9 }, // SUN
+ { 0x46, 9 }, // RAIN
+ { 0x86, 8 }, // HAIL
+};
+
+const u8 gCastformElevations[] = {
+ 13, // NORMAL
+ 14, // SUN
+ 13, // RAIN
+ 13, // HAIL
+};
+
+// Y position of the backsprite for each of the four Castform forms.
+const u8 gCastformBackSpriteYCoords[] = {
+ 0, // NORMAL
+ 0, // SUN
+ 0, // RAIN
+ 0, // HAIL
+};
+
+const struct SpriteTemplate gSpriteTemplate_837F5B0[] = {
+ {
+ .tileTag = 55125,
+ .paletteTag = 55125,
+ .oam = gOamData_837DF9C,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+ }, {
+ .tileTag = 55126,
+ .paletteTag = 55126,
+ .oam = gOamData_837DF9C,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+ }
+};
+
+const struct SpriteSheet gUnknown_0837F5E0[] = {
+ { gMiscBlank_Gfx, 0x800, 55125, },
+ { gMiscBlank_Gfx, 0x800, 55126, },
+};
+
+
+u8 sub_8077ABC(u8 slot, u8 a2) {
+ u8 var;
+ u16 species;
+ struct TransformStatus *transform;
+
+ if (IsContest()) {
+ if (a2 == 3 && slot == 3) {
+ a2 = 1;
+ }
+ }
+ switch (a2) {
+ case 0:
+ case 2:
+ var = gUnknown_0837F578[IS_DOUBLE_BATTLE()][GetBankIdentity(slot)].field_0;
+ break;
+ case 1:
+ var = gUnknown_0837F578[IS_DOUBLE_BATTLE()][GetBankIdentity(slot)].field_1;
+ break;
+ case 3:
+ case 4:
+ default:
+ if (IsContest()) {
+ if (unk_2019348.field_4 & 1) {
+ species = unk_2019348.field_2;
+ } else {
+ species = unk_2019348.field_0;
+ }
+ } else {
+ if (GetBankSide(slot)) {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ species = GetMonData(&gEnemyParty[gBattleMonPartyPositions[slot]], MON_DATA_SPECIES);
+ } else {
+ species = transform->species;
+ }
+ } else {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ species = GetMonData(&gPlayerParty[gBattleMonPartyPositions[slot]], MON_DATA_SPECIES);
+ } else {
+ species = transform->species;
+ }
+ }
+ }
+ if (a2 == 3) {
+ var = sub_8077E44(slot, species, 1);
+ } else {
+ var = sub_8077E44(slot, species, 0);
+ }
+ break;
+ }
+ return var;
+}
+
+u8 sub_8077BFC(u8 slot, u16 species) {
+ u16 letter;
+ u32 personality;
+ struct TransformStatus *transform;
+ u8 ret;
+ u16 var;
+
+ if (!GetBankSide(slot) || IsContest()) {
+ if (species == SPECIES_UNOWN) {
+ if (IsContest()) {
+ if (unk_2019348.field_4 & 1) {
+ personality = unk_2019348.field_10;
+ } else {
+ personality = unk_2019348.field_8;
+ }
+ } else {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ personality = GetMonData(&gPlayerParty[gBattleMonPartyPositions[slot]], MON_DATA_PERSONALITY);
+ } else {
+ personality = gTransformPersonalities[slot];
+ }
+ }
+ letter = GET_UNOWN_LETTER(personality);
+ if (!letter) {
+ var = species;
+ } else {
+ var = letter + SPECIES_UNOWN_B - 1;
+ }
+ ret = gMonBackPicCoords[var].y_offset;
+ } else if (species == SPECIES_CASTFORM) {
+ ret = gCastformBackSpriteYCoords[gBattleMonForms[slot]];
+ } else if (species > NUM_SPECIES) {
+ ret = gMonBackPicCoords[0].y_offset;
+ } else {
+ ret = gMonBackPicCoords[species].y_offset;
+ }
+ } else {
+ if (species == SPECIES_UNOWN) {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ personality = GetMonData(&gEnemyParty[gBattleMonPartyPositions[slot]], MON_DATA_PERSONALITY);
+ } else {
+ personality = gTransformPersonalities[slot];
+ }
+ letter = GET_UNOWN_LETTER(personality);
+ if (!letter) {
+ var = species;
+ } else {
+ var = letter + SPECIES_UNOWN_B - 1;
+ }
+ ret = gMonFrontPicCoords[var].y_offset;
+ } else if (species == SPECIES_CASTFORM) {
+ ret = gCastformFrontSpriteCoords[gBattleMonForms[slot]].y_offset;
+ } else if (species > NUM_SPECIES) {
+ ret = gMonFrontPicCoords[0].y_offset;
+ } else {
+ ret = gMonFrontPicCoords[species].y_offset;
+ }
+ }
+ return ret;
+}
+
+u8 sub_8077DD8(u8 slot, u16 species) {
+ u8 ret = 0;
+ if (GetBankSide(slot) == 1) {
+ if (!IsContest()) {
+ if (species == SPECIES_CASTFORM) {
+ ret = gCastformElevations[gBattleMonForms[slot]];
+ } else if (species > NUM_SPECIES) {
+ ret = gEnemyMonElevation[0];
+ } else {
+ ret = gEnemyMonElevation[species];
+ }
+ }
+ }
+ return ret;
+}
+
+u8 sub_8077E44(u8 slot, u16 species, u8 a3) {
+ u16 offset;
+ u8 y;
+ if (GetBankSide(slot) == 0 || IsContest()) {
+ offset = sub_8077BFC(slot, species);
+ } else {
+ offset = sub_8077BFC(slot, species);
+ offset -= sub_8077DD8(slot, species);
+ }
+ y = offset + gUnknown_0837F578[IS_DOUBLE_BATTLE()][GetBankIdentity(slot)].field_1;
+ if (a3) {
+ if (GetBankSide(slot) == 0) {
+ y += 8;
+ }
+ if (y > 104) y = 104;
+ }
+ return y;
+}
+
+u8 sub_8077EE4(u8 slot, u8 a2) {
+ u16 species;
+ struct TransformStatus *transform;
+ if (a2 == 3 || a2 == 4) {
+ if (IsContest()) {
+ if (unk_2019348.field_4 & 1) {
+ species = unk_2019348.field_2;
+ } else {
+ species = unk_2019348.field_0;
+ }
+ } else {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ species = gUnknown_0202F7CA[slot];
+ } else {
+ species = transform->species;
+ }
+ }
+ if (a2 == 3) {
+ return sub_8077E44(slot, species, 1);
+ } else {
+ return sub_8077E44(slot, species, 0);
+ }
+ } else {
+ return sub_8077ABC(slot, a2);
+ }
+}
+
+u8 sub_8077F68(u8 slot) {
+ return sub_8077ABC(slot, 4);
+}
+
+u8 sub_8077F7C(u8 slot) {
+ u16 var;
+ if (GetBankSide(slot)) {
+ var = sub_8077ABC(slot, 1) + 16;
+ } else {
+ var = sub_8077ABC(slot, 1) + 17;
+ }
+ return var;
+}
+
+u8 sub_8077FC0(u8 slot) {
+ u16 var;
+ u8 r6;
+ struct TransformStatus *transform;
+ r6 = sub_8077ABC(slot, 1);
+ if (!IsContest()) {
+ if (GetBankSide(slot)) {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ var = GetMonData(&gEnemyParty[gBattleMonPartyPositions[slot]], MON_DATA_SPECIES);
+ } else {
+ var = transform->species;
+ }
+ } else {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ var = GetMonData(&gPlayerParty[gBattleMonPartyPositions[slot]], MON_DATA_SPECIES);
+ } else {
+ var = transform->species;
+ }
+ }
+ if (GetBankSide(slot)) {
+ r6 -= sub_8077DD8(slot, var);
+ }
+ }
+ return r6;
+}
+
+u8 obj_id_for_side_relative_to_move(u8 a1) {
+ u8 *sprites;
+ if (a1 == 0) {
+ if (sub_8078874(gBattleAnimPlayerMonIndex)) {
+ sprites = gBattleMonSprites;
+ return sprites[gBattleAnimPlayerMonIndex];
+ } else {
+ return 0xff;
+ }
+ } else if (a1 == 1) {
+ if (sub_8078874(gBattleAnimEnemyMonIndex)) {
+ sprites = gBattleMonSprites;
+ return sprites[gBattleAnimEnemyMonIndex];
+ } else {
+ return 0xff;
+ }
+ } else if (a1 == 2) {
+ if (!b_side_obj__get_some_boolean(gBattleAnimPlayerMonIndex ^ 2)) {
+ return 0xff;
+ } else {
+ return gBattleMonSprites[gBattleAnimPlayerMonIndex ^ 2];
+ }
+ } else {
+ if (b_side_obj__get_some_boolean(gBattleAnimEnemyMonIndex ^ 2)) {
+ return gBattleMonSprites[gBattleAnimEnemyMonIndex ^ 2];
+ } else {
+ return 0xff;
+ }
+ }
+}
+
+void oamt_set_x3A_32(struct Sprite *sprite, void (*callback)(struct Sprite*)) {
+ sprite->data6 = (u32)(callback) & 0xffff;
+ sprite->data7 = (u32)(callback) >> 16;
+}
+
+void sub_8078104(struct Sprite *sprite) {
+ u32 callback = (u16)sprite->data6 | (sprite->data7 << 16);
+ sprite->callback = (void (*)(struct Sprite *))callback;
+}
+
+void sub_8078114(struct Sprite *sprite) {
+ if (sprite->data3) {
+ sprite->pos2.x = Sin(sprite->data0, sprite->data1);
+ sprite->pos2.y = Cos(sprite->data0, sprite->data1);
+ sprite->data0 += sprite->data2;
+ if (sprite->data0 >= 0x100) {
+ sprite->data0 -= 0x100;
+ } else if (sprite->data0 < 0) {
+ sprite->data0 += 0x100;
+ }
+ sprite->data3--;
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_8078174(struct Sprite *sprite) {
+ if (sprite->data3) {
+ sprite->pos2.x = Sin(sprite->data0, (sprite->data5 >> 8) + sprite->data1);
+ sprite->pos2.y = Cos(sprite->data0, (sprite->data5 >> 8) + sprite->data1);
+ sprite->data0 += sprite->data2;
+ sprite->data5 += sprite->data4;
+ if (sprite->data0 >= 0x100) {
+ sprite->data0 -= 0x100;
+ } else if (sprite->data0 < 0) {
+ sprite->data0 += 0x100;
+ }
+ sprite->data3--;
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void unref_sub_80781F0(struct Sprite *sprite) {
+ if (sprite->data3) {
+ sprite->pos2.x = Sin(sprite->data0, sprite->data1);
+ sprite->pos2.y = Cos(sprite->data4, sprite->data1);
+ sprite->data0 += sprite->data2;
+ sprite->data4 += sprite->data5;
+ if (sprite->data0 >= 0x100) {
+ sprite->data0 -= 0x100;
+ } else if (sprite->data0 < 0) {
+ sprite->data0 += 0x100;
+ }
+ if (sprite->data4 >= 0x100) {
+ sprite->data4 -= 0x100;
+ } else if (sprite->data4 < 0) {
+ sprite->data4 += 0x100;
+ }
+ sprite->data3--;
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_8078278(struct Sprite *sprite) {
+ if (sprite->data3) {
+ sprite->pos2.x = Sin(sprite->data0, sprite->data1);
+ sprite->pos2.y = Cos(sprite->data0, sprite->data4);
+ sprite->data0 += sprite->data2;
+ if (sprite->data0 >= 0x100) {
+ sprite->data0 -= 0x100;
+ } else if (sprite->data0 < 0) {
+ sprite->data0 += 0x100;
+ }
+ sprite->data3--;
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_80782D8(struct Sprite *sprite) {
+ if (sprite->data0 > 0) {
+ sprite->data0--;
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_80782F8(struct Sprite *sprite) {
+ sub_8078314(sprite);
+ sprite->callback = sub_8078364;
+ sprite->callback(sprite);
+}
+
+void sub_8078314(struct Sprite *sprite) {
+ s16 old;
+ int v1;
+ if (sprite->data1 > sprite->data2) {
+ sprite->data0 = -sprite->data0;
+ }
+ v1 = sprite->data2 - sprite->data1;
+ old = sprite->data0;
+ sprite->data0 = abs(v1 / sprite->data0);
+ sprite->data2 = (sprite->data4 - sprite->data3) / sprite->data0;
+ sprite->data1 = old;
+}
+
+void sub_8078364(struct Sprite *sprite) {
+ if (sprite->data0 > 0) {
+ sprite->data0--;
+ sprite->pos2.x += sprite->data1;
+ sprite->pos2.y += sprite->data2;
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_8078394(struct Sprite *sprite) {
+ if (sprite->data0 > 0) {
+ sprite->data0--;
+ sprite->data3 += sprite->data1;
+ sprite->data4 += sprite->data2;
+ sprite->pos2.x = sprite->data3 >> 8;
+ sprite->pos2.y = sprite->data4 >> 8;
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_80783D0(struct Sprite *sprite) {
+ if (sprite->data0 > 0) {
+ sprite->data0--;
+ sprite->data3 += sprite->data1;
+ sprite->data4 += sprite->data2;
+ sprite->pos2.x = sprite->data3 >> 8;
+ sprite->pos2.y = sprite->data4 >> 8;
+ } else {
+ sub_8078104(sprite);
+ }
+ UpdateMonIconFrame(sprite);
+}
+
+void unref_sub_8078414(struct Sprite *sprite) {
+ sprite->data1 = sprite->pos1.x + sprite->pos2.x;
+ sprite->data3 = sprite->pos1.y + sprite->pos2.y;
+ sprite->data2 = sub_8077ABC(gBattleAnimEnemyMonIndex, 2);
+ sprite->data4 = sub_8077ABC(gBattleAnimEnemyMonIndex, 3);
+ sprite->callback = sub_80782F8;
+}
+
+void sub_8078458(struct Sprite *sprite) {
+ if (sprite->data0 > 0) {
+ sprite->data0--;
+ gSprites[sprite->data3].pos2.x += sprite->data1;
+ gSprites[sprite->data3].pos2.y += sprite->data2;
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_80784A8(struct Sprite *sprite) {
+ if (sprite->data0 > 0) {
+ sprite->data0--;
+ sprite->data3 += sprite->data1;
+ sprite->data4 += sprite->data2;
+ gSprites[sprite->data5].pos2.x = sprite->data3 >> 8;
+ gSprites[sprite->data5].pos2.y = sprite->data4 >> 8;
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_8078504(struct Sprite *sprite) {
+ if (sprite->data0 > 0) {
+ sprite->data0--;
+ sprite->pos2.x = sprite->data2 >> 8;
+ sprite->data2 += sprite->data1;
+ sprite->pos2.y = sprite->data4 >> 8;
+ sprite->data4 += sprite->data3;
+ if (sprite->data0 % sprite->data5 == 0) {
+ if (sprite->data5) {
+ sprite->invisible ^= 1;
+ }
+ }
+ } else {
+ sub_8078104(sprite);
+ }
+}
+
+void move_anim_8074EE0(struct Sprite *sprite) {
+ FreeSpriteOamMatrix(sprite);
+ move_anim_8072740(sprite);
+}
+
+void unref_sub_8078588(struct Sprite *sprite) {
+ sprite->data1 = sprite->pos1.x + sprite->pos2.x;
+ sprite->data3 = sprite->pos1.y + sprite->pos2.y;
+ sprite->data2 = sub_8077ABC(gBattleAnimPlayerMonIndex, 2);
+ sprite->data4 = sub_8077ABC(gBattleAnimPlayerMonIndex, 3);
+ sprite->callback = sub_80782F8;
+}
+
+void unref_sub_80785CC(struct Sprite *sprite) {
+ ResetPaletteStructByUid(sprite->data5);
+ move_anim_8074EE0(sprite);
+}
+
+void sub_80785E4(struct Sprite *sprite) {
+ if (sprite->affineAnimEnded) {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_8078600(struct Sprite *sprite) {
+ if (sprite->animEnded) {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_807861C(struct Sprite *sprite) {
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ move_anim_8072740(sprite);
+}
+
+void sub_8078634(u8 task) {
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ DestroyAnimVisualTask(task);
+}
+
+void sub_8078650(struct Sprite *sprite) {
+ sprite->pos1.x = sub_8077ABC(gBattleAnimPlayerMonIndex, 2);
+ sprite->pos1.y = sub_8077ABC(gBattleAnimPlayerMonIndex, 3);
+}
+
+void sub_807867C(struct Sprite *sprite, s16 a2) {
+ u16 v1 = sub_8077ABC(gBattleAnimPlayerMonIndex, 0);
+ u16 v2 = sub_8077ABC(gBattleAnimEnemyMonIndex, 0);
+ if (v1 > v2) {
+ sprite->pos1.x -= a2;
+ } else if (v1 < v2) {
+ sprite->pos1.x += a2;
+ } else {
+ if (GetBankSide(gBattleAnimPlayerMonIndex)) {
+ sprite->pos1.x -= a2;
+ } else {
+ sprite->pos1.x += a2;
+ }
+ }
+}
+
+void sub_80786EC(struct Sprite *sprite) {
+ sprite->data1 = sprite->pos1.x;
+ sprite->data3 = sprite->pos1.y;
+ obj_translate_based_on_private_1_2_3_4(sprite);
+ sprite->data6 = 0x8000 / sprite->data0;
+ sprite->data7 = 0;
+}
+
+bool8 sub_8078718(struct Sprite *sprite) {
+ if (sub_8078B5C(sprite)) {
+ return TRUE;
+ }
+ sprite->data7 += sprite->data6;
+ sprite->pos2.y += Sin((u8)(sprite->data7 >> 8), sprite->data5);
+ return FALSE;
+}
+
+void oamt_add_pos2_onto_pos1(struct Sprite *sprite) {
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+}
+
+void sub_8078764(struct Sprite *sprite, u8 a2) {
+ if (!a2) {
+ sprite->pos1.x = sub_8077EE4(gBattleAnimEnemyMonIndex, 0);
+ sprite->pos1.y = sub_8077EE4(gBattleAnimEnemyMonIndex, 1);
+ }
+ sub_807867C(sprite, gBattleAnimArgs[0]);
+ sprite->pos1.y += gBattleAnimArgs[1];
+}
+
+void sub_80787B0(struct Sprite *sprite, u8 a2) {
+ if (!a2) {
+ sprite->pos1.x = sub_8077EE4(gBattleAnimPlayerMonIndex, 0);
+ sprite->pos1.y = sub_8077EE4(gBattleAnimPlayerMonIndex, 1);
+ } else {
+ sprite->pos1.x = sub_8077EE4(gBattleAnimPlayerMonIndex, 2);
+ sprite->pos1.y = sub_8077EE4(gBattleAnimPlayerMonIndex, 3);
+ }
+ sub_807867C(sprite, gBattleAnimArgs[0]);
+ sprite->pos1.y += gBattleAnimArgs[1];
+}
+
+u8 GetBankSide(u8 slot) {
+ return gBanksBySide[slot] & 1;
+}
+
+u8 GetBankIdentity(u8 slot) {
+ return gBanksBySide[slot];
+}
+
+u8 GetBankByPlayerAI(u8 slot) {
+ u8 i;
+ for (i = 0; i < gNoOfAllBanks; i++) {
+ if (gBanksBySide[i] == slot) {
+ break;
+ }
+ }
+ return i;
+}
+
+bool8 sub_8078874(u8 slot) {
+ if (IsContest()) {
+ if (gBattleAnimPlayerMonIndex == slot) {
+ return TRUE;
+ }
+ if (gBattleAnimEnemyMonIndex == slot) {
+ return TRUE;
+ }
+ return FALSE;
+ } else {
+ if (gBanksBySide[slot] == 0xff) {
+ return FALSE;
+ }
+ if (GetBankSide(slot)) {
+ if (GetMonData(&gEnemyParty[gBattleMonPartyPositions[slot]], MON_DATA_HP) != 0) {
+ return TRUE;
+ }
+ } else {
+ if (GetMonData(&gPlayerParty[gBattleMonPartyPositions[slot]], MON_DATA_HP) != 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+}
+
+bool8 IsDoubleBattle() {
+ return IS_DOUBLE_BATTLE();
+}
+
+void sub_8078914(struct Struct_sub_8078914 *unk) {
+ if (IsContest()) {
+ unk->field_0 = (u8 *)0x6008000;
+ unk->field_4 = (u8 *)0x600f000;
+ unk->field_8 = 0xe;
+ } else {
+ unk->field_0 = (u8 *)0x6004000;
+ unk->field_4 = (u8 *)0x600e000;
+ unk->field_8 = 0x8;
+ }
+}
+
+void sub_8078954(struct Struct_sub_8078914 *unk) {
+ if (IsContest()) {
+ unk->field_0 = (u8 *)0x6008000;
+ unk->field_4 = (u8 *)0x600f000;
+ unk->field_8 = 0xe;
+ } else if (GetBankIdentity_permutated(gBattleAnimPlayerMonIndex) == 1) {
+ unk->field_0 = (u8 *)0x6004000;
+ unk->field_4 = (u8 *)0x600e000;
+ unk->field_8 = 0x8;
+ } else {
+ unk->field_0 = (u8 *)0x6006000;
+ unk->field_4 = (u8 *)0x600f000;
+ unk->field_8 = 0x9;
+ }
+}
+
+u8 sub_80789BC() {
+ if (IsContest()) {
+ return 1;
+ }
+ return 2;
+}
+
+void sub_80789D4(bool8 a1) {
+ if (!a1) {
+ BG3CNT.size = 0;
+ BG3CNT.overflow = 1;
+ } else if (IsContest()) {
+ BG3CNT.size = 0;
+ BG3CNT.overflow = 1;
+ } else {
+ BG3CNT.size = 1;
+ BG3CNT.overflow = 0;
+ }
+}
+
+void sub_8078A34(struct Sprite *sprite) {
+ sprite->data1 = sprite->pos1.x;
+ sprite->data3 = sprite->pos1.y;
+ sub_8078A5C(sprite);
+ sprite->callback = sub_80783D0;
+ sprite->callback(sprite);
+}
+
+void sub_8078A5C(struct Sprite *sprite) {
+ s16 x = (sprite->data2 - sprite->data1) << 8;
+ s16 y = (sprite->data4 - sprite->data3) << 8;
+ sprite->data1 = x / sprite->data0;
+ sprite->data2 = y / sprite->data0;
+ sprite->data4 = 0;
+ sprite->data3 = 0;
+}
+
+void obj_translate_based_on_private_1_2_3_4(struct Sprite *sprite) {
+ int x = sprite->data2 - sprite->data1;
+ int y = sprite->data4 - sprite->data3;
+ bool8 r8 = x < 0;
+ bool8 r9 = y < 0;
+ u16 x2 = abs(x) << 8;
+ u16 y2 = abs(y) << 8;
+ x2 = x2 / sprite->data0;
+ y2 = y2 / sprite->data0;
+ if (r8) {
+ x2 |= 1;
+ } else {
+ x2 &= ~1;
+ }
+ if (r9) {
+ y2 |= 1;
+ } else {
+ y2 &= ~1;
+ }
+ sprite->data1 = x2;
+ sprite->data2 = y2;
+ sprite->data4 = 0;
+ sprite->data3 = 0;
+}
+
+void sub_8078B34(struct Sprite *sprite) {
+ sprite->data1 = sprite->pos1.x;
+ sprite->data3 = sprite->pos1.y;
+ obj_translate_based_on_private_1_2_3_4(sprite);
+ sprite->callback = sub_8078BB8;
+ sprite->callback(sprite);
+}
+
+bool8 sub_8078B5C(struct Sprite *sprite) {
+ u16 v1, v2, x, y;
+ if (!sprite->data0) {
+ return TRUE;
+ }
+ v1 = sprite->data1;
+ v2 = sprite->data2;
+ x = sprite->data3;
+ y = sprite->data4;
+ x += v1;
+ y += v2;
+ if (v1 & 1) {
+ sprite->pos2.x = -(x >> 8);
+ } else {
+ sprite->pos2.x = x >> 8;
+ }
+ if (v2 & 1) {
+ sprite->pos2.y = -(y >> 8);
+ } else {
+ sprite->pos2.y = y >> 8;
+ }
+ sprite->data3 = x;
+ sprite->data4 = y;
+ sprite->data0--;
+ return FALSE;
+}
+
+void sub_8078BB8(struct Sprite *sprite) {
+ if (sub_8078B5C(sprite)) {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_8078BD4(struct Sprite *sprite) {
+ int v1 = abs(sprite->data2 - sprite->data1) << 8;
+ sprite->data0 = v1 / sprite->data0;
+ obj_translate_based_on_private_1_2_3_4(sprite);
+}
+
+void sub_8078C00(struct Sprite *sprite) {
+ sprite->data1 = sprite->pos1.x;
+ sprite->data3 = sprite->pos1.y;
+ sub_8078BD4(sprite);
+ sprite->callback = sub_8078BB8;
+ sprite->callback(sprite);
+}
+
+void sub_8078C28(struct Sprite *sprite) {
+ int x = sprite->data2 - sprite->data1;
+ int y = sprite->data4 - sprite->data3;
+ bool8 x_sign = x < 0;
+ bool8 y_sign = y < 0;
+ u16 x2 = abs(x) << 4;
+ u16 y2 = abs(y) << 4;
+ x2 /= sprite->data0;
+ y2 /= sprite->data0;
+ if (x_sign) {
+ x2 |= 1;
+ } else {
+ x2 &= ~1;
+ }
+ if (y_sign) {
+ y2 |= 1;
+ } else {
+ y2 &= ~1;
+ }
+ sprite->data1 = x2;
+ sprite->data2 = y2;
+ sprite->data4 = 0;
+ sprite->data3 = 0;
+}
+
+void sub_8078CC0(struct Sprite *sprite) {
+ sprite->data1 = sprite->pos1.x;
+ sprite->data3 = sprite->pos1.y;
+ sub_8078C28(sprite);
+ sprite->callback = sub_8078D44;
+ sprite->callback(sprite);
+}
+
+bool8 sub_8078CE8(struct Sprite *sprite) {
+ u16 v1, v2, x, y;
+ if (!sprite->data0) {
+ return TRUE;
+ }
+ v1 = sprite->data1;
+ v2 = sprite->data2;
+ x = sprite->data3;
+ y = sprite->data4;
+ x += v1;
+ y += v2;
+ if (v1 & 1) {
+ sprite->pos2.x = -(x >> 4);
+ } else {
+ sprite->pos2.x = x >> 4;
+ }
+ if (v2 & 1) {
+ sprite->pos2.y = -(y >> 4);
+ } else {
+ sprite->pos2.y = y >> 4;
+ }
+ sprite->data3 = x;
+ sprite->data4 = y;
+ sprite->data0--;
+ return FALSE;
+}
+
+void sub_8078D44(struct Sprite *sprite) {
+ if (sub_8078CE8(sprite)) {
+ sub_8078104(sprite);
+ }
+}
+
+void sub_8078D60(struct Sprite *sprite) {
+ int v1 = abs(sprite->data2 - sprite->data1) << 4;
+ sprite->data0 = v1 / sprite->data0;
+ sub_8078C28(sprite);
+}
+
+void sub_8078D8C(struct Sprite *sprite) {
+ sprite->data1 = sprite->pos1.x;
+ sprite->data3 = sprite->pos1.y;
+ sub_8078D60(sprite);
+ sprite->callback = sub_8078D44;
+ sprite->callback(sprite);
+}
+
+void obj_id_set_rotscale(u8 sprite, s16 xScale, s16 yScale, u16 rotation) {
+ int i;
+ struct ObjAffineSrcData src;
+ struct OamMatrix matrix;
+ src.xScale = xScale;
+ src.yScale = yScale;
+ src.rotation = rotation;
+ if (sub_8078E38()) {
+ src.xScale = -src.xScale;
+ }
+ i = gSprites[sprite].oam.matrixNum;
+ ObjAffineSet(&src, &matrix, 1, 2);
+ gOamMatrices[i].a = matrix.a;
+ gOamMatrices[i].b = matrix.b;
+ gOamMatrices[i].c = matrix.c;
+ gOamMatrices[i].d = matrix.d;
+}
+
+bool8 sub_8078E38() {
+ if (IsContest()) {
+ if (gSprites[obj_id_for_side_relative_to_move(0)].data2 == 0xc9 /* XXX SPECIES_UNOWN? */) {
+ return FALSE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_8078E70(u8 sprite, u8 a2) {
+ struct Struct_2017810 *unk;
+ u8 r7 = gSprites[sprite].data0;
+ if (IsContest() || b_side_obj__get_some_boolean(r7)) {
+ gSprites[sprite].invisible = FALSE;
+ }
+ gSprites[sprite].oam.objMode = a2;
+ gSprites[sprite].affineAnimPaused = TRUE;
+ if (!IsContest() && !gSprites[sprite].oam.affineMode) {
+ unk = &unk_2017810[r7];
+ gSprites[sprite].oam.matrixNum = unk->field_6;
+ }
+ gSprites[sprite].oam.affineMode = 3;
+ CalcCenterToCornerVec(&gSprites[sprite], gSprites[sprite].oam.shape, gSprites[sprite].oam.size, gSprites[sprite].oam.affineMode);
+}
+
+void sub_8078F40(u8 sprite) {
+ obj_id_set_rotscale(sprite, 0x100, 0x100, 0);
+ gSprites[sprite].oam.affineMode = 1;
+ gSprites[sprite].oam.objMode = 0;
+ gSprites[sprite].affineAnimPaused = FALSE;
+ CalcCenterToCornerVec(&gSprites[sprite], gSprites[sprite].oam.shape, gSprites[sprite].oam.size, gSprites[sprite].oam.affineMode);
+}
+
+void sub_8078F9C(u8 sprite) {
+ u16 matrix = gSprites[sprite].oam.matrixNum;
+ s16 c = gOamMatrices[matrix].c;
+ if (c < 0) {
+ c = -c;
+ }
+ gSprites[sprite].pos2.y = c >> 3;
+}
+
+// related to obj_id_set_rotscale
+void sub_8078FDC(struct Sprite *sprite, bool8 a2, s16 xScale, s16 yScale, u16 rotation) {
+ int i;
+ struct ObjAffineSrcData src;
+ struct OamMatrix matrix;
+ if (sprite->oam.affineMode & 1) {
+ sprite->affineAnimPaused = TRUE;
+ if (a2) {
+ CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode);
+ }
+ src.xScale = xScale;
+ src.yScale = yScale;
+ src.rotation = rotation;
+ if (sub_8078E38()) {
+ src.xScale = -src.xScale;
+ }
+ i = sprite->oam.matrixNum;
+ ObjAffineSet(&src, &matrix, 1, 2);
+ gOamMatrices[i].a = matrix.a;
+ gOamMatrices[i].b = matrix.b;
+ gOamMatrices[i].c = matrix.c;
+ gOamMatrices[i].d = matrix.d;
+ }
+}
+
+void sub_8079098(struct Sprite *sprite) {
+ sub_8078FDC(sprite, TRUE, 0x100, 0x100, 0);
+ sprite->affineAnimPaused = FALSE;
+ CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode);
+}
+
+u16 sub_80790D8(s16 a, s16 b) {
+ return ArcTan2(a, b);
+}
+
+u16 sub_80790F0(s16 a, s16 b) {
+ u16 var = sub_80790D8(a, b);
+ return -var;
+}
+
+void sub_8079108(u16 a1, bool8 a2) {
+ int i;
+ struct Color *c;
+ struct Color *c2;
+ u16 average;
+
+ a1 *= 0x10;
+
+ if (!a2) {
+ for (i = 0; i < 0x10; i++) {
+ c = (struct Color *)&gPlttBufferUnfaded[a1 + i];
+ average = c->r + c->g + c->b;
+ average /= 3;
+
+ c2 = (struct Color *)&gPlttBufferFaded[a1 + i];
+ c2->r = average;
+ c2->g = average;
+ c2->b = average;
+ }
+ } else {
+ CpuCopy32(&gPlttBufferUnfaded[a1], &gPlttBufferFaded[a1], 0x20);
+ }
+}
+
+u32 sub_80791A8(u8 a1, u8 a2, u8 a3, u8 a4, u8 a5, u8 a6, u8 a7) {
+ u32 var = 0;
+ u32 shift;
+ if (a1) {
+ if (!IsContest()) {
+ var = 0xe;
+ } else {
+ var = 1 << sub_80789BC();
+ }
+ }
+ if (a2) {
+ shift = gBattleAnimPlayerMonIndex + 16;
+ var |= 1 << shift;
+ }
+ if (a3) {
+ shift = gBattleAnimEnemyMonIndex + 16;
+ var |= 1 << shift;
+ }
+ if (a4) {
+ if (b_side_obj__get_some_boolean(gBattleAnimPlayerMonIndex ^ 2)) {
+ shift = (gBattleAnimPlayerMonIndex ^ 2) + 16;
+ var |= 1 << shift;
+ }
+ }
+ if (a5) {
+ if (b_side_obj__get_some_boolean(gBattleAnimEnemyMonIndex ^ 2)) {
+ shift = (gBattleAnimEnemyMonIndex ^ 2) + 16;
+ var |= 1 << shift;
+ }
+ }
+ if (a6) {
+ if (!IsContest()) {
+ var |= 0x100;
+ } else {
+ var |= 0x4000;
+ }
+ }
+ if (a7) {
+ if (!IsContest()) {
+ var |= 0x200;
+ }
+ }
+ return var;
+}
+
+u32 sub_80792C0(u8 a1, u8 a2, u8 a3, u8 a4) {
+ u32 var = 0;
+ u32 shift;
+ if (IsContest()) {
+ if (a1) {
+ var |= 1 << 18;
+ return var;
+ }
+ } else {
+ if (a1) {
+ if (b_side_obj__get_some_boolean(GetBankByPlayerAI(0))) {
+ var |= 1 << (GetBankByPlayerAI(0) + 16);
+ }
+ }
+ if (a2) {
+ if (b_side_obj__get_some_boolean(GetBankByPlayerAI(2))) {
+ shift = GetBankByPlayerAI(2) + 16;
+ var |= 1 << shift;
+ }
+ }
+ if (a3) {
+ if (b_side_obj__get_some_boolean(GetBankByPlayerAI(1))) {
+ shift = GetBankByPlayerAI(1) + 16;
+ var |= 1 << shift;
+ }
+ }
+ if (a4) {
+ if (b_side_obj__get_some_boolean(GetBankByPlayerAI(3))) {
+ shift = GetBankByPlayerAI(3) + 16;
+ var |= 1 << shift;
+ }
+ }
+ }
+ return var;
+}
+
+u8 sub_80793A8(u8 a1) {
+ return a1;
+}
+
+u8 unref_sub_80793B0(u8 a1) {
+ return GetBankByPlayerAI(a1);
+}
+
+void sub_80793C4(struct Sprite *sprite) {
+ bool8 var;
+ if (!sprite->data0) {
+ if (!gBattleAnimArgs[3]) {
+ var = TRUE;
+ } else {
+ var = FALSE;
+ }
+ if (!gBattleAnimArgs[2]) {
+ sub_80787B0(sprite, var);
+ } else {
+ sub_8078764(sprite, var);
+ }
+ sprite->data0++;
+
+ } else if (sprite->animEnded || sprite->affineAnimEnded) {
+ move_anim_8074EE0(sprite);
+ }
+}
+
+void sub_807941C(struct Sprite *sprite) {
+ bool8 v1;
+ u8 v2;
+ if (!(gBattleAnimArgs[5] & 0xff00)) {
+ v1 = TRUE;
+ } else {
+ v1 = FALSE;
+ }
+ if (!(gBattleAnimArgs[5] & 0xff)) {
+ v2 = 3;
+ } else {
+ v2 = 1;
+ }
+ sub_80787B0(sprite, v1);
+ if (GetBankSide(gBattleAnimPlayerMonIndex)) {
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ }
+ sprite->data0 = gBattleAnimArgs[4];
+ sprite->data2 = sub_8077ABC(gBattleAnimEnemyMonIndex, 2) + gBattleAnimArgs[2];
+ sprite->data4 = sub_8077ABC(gBattleAnimEnemyMonIndex, v2) + gBattleAnimArgs[3];
+ sprite->callback = sub_8078B34;
+ oamt_set_x3A_32(sprite, move_anim_8072740);
+}
+
+void sub_80794A8(struct Sprite *sprite) {
+ sub_80787B0(sprite, 1);
+ if (GetBankSide(gBattleAnimPlayerMonIndex)) {
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ }
+ sprite->data0 = gBattleAnimArgs[4];
+ sprite->data2 = sub_8077ABC(gBattleAnimEnemyMonIndex, 2) + gBattleAnimArgs[2];
+ sprite->data4 = sub_8077ABC(gBattleAnimEnemyMonIndex, 3) + gBattleAnimArgs[3];
+ sprite->data5 = gBattleAnimArgs[5];
+ sub_80786EC(sprite);
+ sprite->callback = sub_8079518;
+}
+
+void sub_8079518(struct Sprite *sprite) {
+ if (sub_8078718(sprite)) {
+ move_anim_8072740(sprite);
+ }
+}
+
+void sub_8079534(struct Sprite *sprite) {
+ u8 r4, slot, r7;
+ if (!gBattleAnimArgs[6]) {
+ r4 = 1;
+ r7 = 3;
+ } else {
+ r4 = 0;
+ r7 = 1;
+ }
+ if (!gBattleAnimArgs[5]) {
+ sub_80787B0(sprite, r4);
+ slot = gBattleAnimPlayerMonIndex;
+ } else {
+ sub_8078764(sprite, r4);
+ slot = gBattleAnimEnemyMonIndex;
+ }
+ if (GetBankSide(gBattleAnimPlayerMonIndex)) {
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ }
+ sub_8078764(sprite, r4);
+ sprite->data0 = gBattleAnimArgs[4];
+ sprite->data2 = sub_8077ABC(slot, 2) + gBattleAnimArgs[2];
+ sprite->data4 = sub_8077ABC(slot, r7) + gBattleAnimArgs[3];
+ sprite->callback = sub_8078B34;
+ oamt_set_x3A_32(sprite, move_anim_8072740);
+}
+
+s16 duplicate_obj_of_side_rel2move_in_transparent_mode(u8 a1) {
+ u16 i;
+ u8 sprite = obj_id_for_side_relative_to_move(a1);
+ if (sprite != 0xff) {
+ for (i = 0; i < 0x40; i++) {
+ if (gSprites[i].inUse) {
+ continue;
+ }
+ gSprites[i] = gSprites[sprite];
+ gSprites[i].oam.objMode = 1;
+ gSprites[i].invisible = FALSE;
+ return i;
+ }
+ }
+ return -1;
+}
+
+void obj_delete_but_dont_free_vram(struct Sprite *sprite) {
+ sprite->usingSheet = TRUE;
+ DestroySprite(sprite);
+}
+
+void sub_8079670(u8 task) {
+ s16 v1 = 0;
+ s16 v2 = 0;
+ if (gBattleAnimArgs[2] > gBattleAnimArgs[0]) {
+ v2 = 1;
+ }
+ if (gBattleAnimArgs[2] < gBattleAnimArgs[0]) {
+ v2 = -1;
+ }
+ if (gBattleAnimArgs[3] > gBattleAnimArgs[1]) {
+ v1 = 1;
+ }
+ if (gBattleAnimArgs[3] < gBattleAnimArgs[1]) {
+ v1 = -1;
+ }
+ gTasks[task].data[0] = 0;
+ gTasks[task].data[1] = gBattleAnimArgs[4];
+ gTasks[task].data[2] = 0;
+ gTasks[task].data[3] = gBattleAnimArgs[0];
+ gTasks[task].data[4] = gBattleAnimArgs[1];
+ gTasks[task].data[5] = v2;
+ gTasks[task].data[6] = v1;
+ gTasks[task].data[7] = gBattleAnimArgs[2];
+ gTasks[task].data[8] = gBattleAnimArgs[3];
+ REG_BLDALPHA = (gBattleAnimArgs[1] << 8) | gBattleAnimArgs[0];
+ gTasks[task].func = sub_80796F8;
+}
+
+void sub_80796F8(u8 taskId) {
+ struct Task *task = &gTasks[taskId];
+ if (++task->data[0] > task->data[1]) {
+ task->data[0] = 0;
+ if (++task->data[2] & 1) {
+ if (task->data[3] != task->data[7]) {
+ task->data[3] += task->data[5];
+ }
+ } else {
+ if (task->data[4] != task->data[8]) {
+ task->data[4] += task->data[6];
+ }
+ }
+ REG_BLDALPHA = (task->data[4] << 8) | task->data[3];
+ if (task->data[3] == task->data[7] && task->data[4] == task->data[8]) {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ }
+}
+
+void sub_8079790(u8 task) {
+ u8 sprite = obj_id_for_side_relative_to_move(gBattleAnimArgs[0]);
+ if (sprite == 0xff) {
+ DestroyAnimVisualTask(task);
+ return;
+ }
+ gTasks[task].data[0] = (gSprites[sprite].oam.paletteNum * 0x10) + 0x101;
+ sub_80797EC(&gTasks[task]);
+}
+
+void sub_80797EC(struct Task *task) {
+ task->data[1] = gBattleAnimArgs[1];
+ task->data[2] = 0;
+ task->data[3] = gBattleAnimArgs[2];
+ task->data[4] = 0;
+ task->data[5] = gBattleAnimArgs[3];
+ task->data[6] = 0;
+ task->data[7] = gBattleAnimArgs[4];
+ task->func = sub_8079814;
+}
+
+void sub_8079814(u8 taskId) {
+ struct Task *task = &gTasks[taskId];
+ if (++task->data[4] >= task->data[5]) {
+ task->data[4] = 0;
+ if (!task->data[6]) {
+ task->data[2]++;
+ BlendPalette(task->data[0], 0xf, task->data[2], task->data[1]);
+ if (task->data[2] == task->data[3]) {
+ task->data[6] = 1;
+ }
+ } else {
+ task->data[2]--;
+ BlendPalette(task->data[0], 0xf, task->data[2], task->data[1]);
+ if (!task->data[2]) {
+ if (--task->data[7]) {
+ task->data[4] = 0;
+ task->data[6] = 0;
+ } else {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ }
+ }
+ }
+}
+
+void sub_80798AC(u8 task) {
+ u8 palette = IndexOfSpritePaletteTag(gBattleAnimArgs[0]);
+ if (palette == 0xff) {
+ DestroyAnimVisualTask(task);
+ return;
+ }
+ gTasks[task].data[0] = (palette * 0x10) + 0x101;
+ sub_80797EC(&gTasks[task]);
+}
+
+void sub_80798F4(struct Task *task, u8 a2, void *a3) {
+ task->data[7] = 0;
+ task->data[8] = 0;
+ task->data[9] = 0;
+ task->data[15] = a2;
+ task->data[10] = 0x100;
+ task->data[11] = 0x100;
+ task->data[12] = 0;
+ sub_8079BF4(&task->data[13], &task->data[14], a3);
+ sub_8078E70(a2, 0);
+}
+
+bool8 sub_807992C(struct Task *task) {
+ gUnknown_0202F7D4 = sub_8079BFC(task->data[13], task->data[14]) + (task->data[7] << 3);
+ switch (gUnknown_0202F7D4->type) {
+ default:
+ if (!gUnknown_0202F7D4->frame.duration) {
+ task->data[10] = gUnknown_0202F7D4->frame.xScale;
+ task->data[11] = gUnknown_0202F7D4->frame.yScale;
+ task->data[12] = gUnknown_0202F7D4->frame.rotation;
+ task->data[7]++;
+ gUnknown_0202F7D4++;
+ }
+ task->data[10] += gUnknown_0202F7D4->frame.xScale;
+ task->data[11] += gUnknown_0202F7D4->frame.yScale;
+ task->data[12] += gUnknown_0202F7D4->frame.rotation;
+ obj_id_set_rotscale(task->data[15], task->data[10], task->data[11], task->data[12]);
+ sub_8079A64(task->data[15]);
+ if (++task->data[8] >= gUnknown_0202F7D4->frame.duration) {
+ task->data[8] = 0;
+ task->data[7]++;
+ }
+ break;
+
+ case AFFINEANIMCMDTYPE_JUMP:
+ task->data[7] = gUnknown_0202F7D4->jump.target;
+ break;
+
+ case AFFINEANIMCMDTYPE_LOOP:
+ if (gUnknown_0202F7D4->loop.count) {
+ if (task->data[9]) {
+ if (!--task->data[9]) {
+ task->data[7]++;
+ break;
+ }
+ } else {
+ task->data[9] = gUnknown_0202F7D4->loop.count;
+ }
+ if (!task->data[7]) {
+ break;
+ }
+ for (;;) {
+ task->data[7]--;
+ gUnknown_0202F7D4--;
+ if (gUnknown_0202F7D4->type == AFFINEANIMCMDTYPE_LOOP) {
+ task->data[7]++;
+ return TRUE;
+ }
+ if (!task->data[7]) {
+ return TRUE;
+ }
+ }
+ }
+ task->data[7]++;
+ break;
+
+ case 0x7fff:
+ gSprites[task->data[15]].pos2.y = 0;
+ sub_8078F40(task->data[15]);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void sub_8079A64(u8 sprite) {
+ int var = 0x40 - sub_8079B10(sprite) * 2;
+ u16 matrix = gSprites[sprite].oam.matrixNum;
+ int var2 = (var << 8) / gOamMatrices[matrix].d;
+ if (var2 > 0x80) {
+ var2 = 0x80;
+ }
+ gSprites[sprite].pos2.y = (var - var2) / 2;
+}
+
+void sub_8079AB8(u8 sprite, u8 sprite2) {
+ int var = 0x40 - sub_8079B10(sprite2) * 2;
+ u16 matrix = gSprites[sprite].oam.matrixNum;
+ int var2 = (var << 8) / gOamMatrices[matrix].d;
+ if (var2 > 0x80) {
+ var2 = 0x80;
+ }
+ gSprites[sprite].pos2.y = (var - var2) / 2;
+}
+
+u16 sub_8079B10(u8 sprite) {
+ struct TransformStatus *transform;
+ u8 slot = gSprites[sprite].data0;
+ u16 species;
+ u16 i;
+ for (i = 0; i < (sizeof(gBattleMonSprites) / sizeof(u8)); i++) {
+ if (gBattleMonSprites[i] == sprite) {
+ if (IsContest()) {
+ species = unk_2019348.field_0;
+ return gMonBackPicCoords[species].y_offset;
+ } else {
+ if (!GetBankSide(i)) {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ species = GetMonData(&gPlayerParty[gBattleMonPartyPositions[i]], MON_DATA_SPECIES);
+ } else {
+ species = transform->species;
+ }
+ return gMonBackPicCoords[species].y_offset;
+ } else {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ species = GetMonData(&gEnemyParty[gBattleMonPartyPositions[i]], MON_DATA_SPECIES);
+ } else {
+ species = transform->species;
+ }
+ return gMonFrontPicCoords[species].y_offset;
+ }
+ }
+ }
+ }
+ return 0x40;
+}
+
+void sub_8079BF4(s16 *bottom, s16 *top, void *ptr) {
+ *bottom = ((intptr_t) ptr) & 0xffff;
+ *top = (((intptr_t) ptr) >> 16) & 0xffff;
+}
+
+void *sub_8079BFC(s16 bottom, s16 top) {
+ return (void *)((u16)bottom | ((u16)top << 16));
+}
+
+
+// possible new file
+
+void sub_8079C08(struct Task *task, u8 a2, s16 a3, s16 a4, s16 a5, s16 a6, u16 a7) {
+ task->data[8] = a7;
+ task->data[15] = a2;
+ task->data[9] = a3;
+ task->data[10] = a4;
+ task->data[13] = a5;
+ task->data[14] = a6;
+ task->data[11] = (a5 - a3) / a7;
+ task->data[12] = (a6 - a4) / a7;
+}
+
+u8 sub_8079C74(struct Task *task) {
+ if (!task->data[8]) {
+ return 0;
+ }
+ if (--task->data[8]) {
+ task->data[9] += task->data[11];
+ task->data[10] += task->data[12];
+ } else {
+ task->data[9] = task->data[13];
+ task->data[10] = task->data[14];
+ }
+ obj_id_set_rotscale(task->data[15], task->data[9], task->data[10], 0);
+ if (task->data[8]) {
+ sub_8079A64(task->data[15]);
+ } else {
+ gSprites[task->data[15]].pos2.y = 0;
+ }
+ return task->data[8];
+}
+
+void sub_8079CEC(u8 task) {
+ u16 v1;
+ if (gHappinessMoveAnim <= 30) {
+ v1 = 0;
+ } else if (gHappinessMoveAnim <= 100) {
+ v1 = 1;
+ } else if (gHappinessMoveAnim <= 200) {
+ v1 = 2;
+ } else {
+ v1 = 3;
+ }
+ gBattleAnimArgs[7] = v1;
+ DestroyAnimVisualTask(task);
+}
+
+void unref_sub_8079D20(u8 priority) {
+ if (b_side_obj__get_some_boolean(gBattleAnimEnemyMonIndex)) {
+ gSprites[gBattleMonSprites[gBattleAnimEnemyMonIndex]].oam.priority = priority;
+ }
+ if (b_side_obj__get_some_boolean(gBattleAnimPlayerMonIndex)) {
+ gSprites[gBattleMonSprites[gBattleAnimPlayerMonIndex]].oam.priority = priority;
+ }
+ if (b_side_obj__get_some_boolean(gBattleAnimEnemyMonIndex ^ 2)) {
+ gSprites[gBattleMonSprites[gBattleAnimEnemyMonIndex ^ 2]].oam.priority = priority;
+ }
+ if (b_side_obj__get_some_boolean(gBattleAnimPlayerMonIndex ^ 2)) {
+ gSprites[gBattleMonSprites[gBattleAnimPlayerMonIndex ^ 2]].oam.priority = priority;
+ }
+}
+
+void sub_8079E24() {
+ int i;
+ for (i = 0; i < gNoOfAllBanks; i++) {
+ if (b_side_obj__get_some_boolean(i)) {
+ gSprites[gBattleMonSprites[i]].subpriority = sub_8079E90(i);
+ gSprites[gBattleMonSprites[i]].oam.priority = 2;
+ }
+ }
+}
+
+u8 sub_8079E90(u8 slot) {
+ u8 status;
+ u8 ret;
+ if (IsContest()) {
+ if (slot == 2) {
+ return 30;
+ } else {
+ return 40;
+ }
+ } else {
+ status = GetBankIdentity(slot);
+ if (status == 0) {
+ ret = 30;
+ } else if (status == 2) {
+ ret = 20;
+ } else if (status == 1) {
+ ret = 40;
+ } else {
+ ret = 50;
+ }
+ }
+ return ret;
+}
+
+u8 sub_8079ED4(u8 slot) {
+ u8 status = GetBankIdentity(slot);
+ if (IsContest()) {
+ return 2;
+ }
+ if (status == 0 || status == 3) {
+ return BG2CNT.priority;
+ } else {
+ return BG1CNT.priority;
+ }
+}
+
+u8 GetBankIdentity_permutated(u8 slot) {
+ u8 status;
+ if (!IsContest()) {
+ status = GetBankIdentity(slot);
+ if (status == 0 || status == 3) {
+ return 2;
+ } else {
+ return 1;
+ }
+ }
+ return 1;
+}
+
+u8 sub_8079F44(u16 species, u8 isBackpic, u8 a3, s16 a4, s16 a5, u8 a6, u32 a7, u32 a8) {
+ void *src;
+ void *dest;
+ int size;
+
+ u8 sprite;
+ u16 sheet = LoadSpriteSheet(&gUnknown_0837F5E0[a3]);
+ u16 palette = AllocSpritePalette(gSpriteTemplate_837F5B0[a3].paletteTag);
+ if (!isBackpic) {
+ LoadCompressedPalette(species_and_otid_get_pal(species, a8, a7), (palette * 0x10) + 0x100, 0x20);
+ LoadSpecialPokePic(
+ &gMonFrontPicTable[species],
+ gMonFrontPicCoords[species].coords,
+ gMonFrontPicCoords[species].y_offset,
+ 0x2000000,
+ (void *)0x2000000,
+ species,
+ a7,
+ 1
+ );
+ } else {
+ LoadCompressedPalette(
+ species_and_otid_get_pal(species, a8, a7), (palette * 0x10) + 0x100, 0x20);
+ LoadSpecialPokePic(
+ &gMonBackPicTable[species],
+ gMonBackPicCoords[species].coords,
+ gMonBackPicCoords[species].y_offset,
+ 0x2000000,
+ (void *)0x2000000,
+ species,
+ a7,
+ 0
+ );
+ }
+
+ src = (void *)0x2000000;
+ dest = (void *)(0x6010000 + (sheet * 0x20));
+ size = 0x800;
+ DmaCopy32(3, src, dest, size);
+
+ if (!isBackpic) {
+ sprite = CreateSprite(&gSpriteTemplate_837F5B0[a3], a4, a5 + gMonFrontPicCoords[species].y_offset, a6);
+ } else {
+ sprite = CreateSprite(&gSpriteTemplate_837F5B0[a3], a4, a5 + gMonBackPicCoords[species].y_offset, a6);
+ }
+ if (IsContest()) {
+ gSprites[sprite].affineAnims = &gSpriteAffineAnimTable_81E7C18;
+ StartSpriteAffineAnim(&gSprites[sprite], 0);
+ }
+ return sprite;
+}
+
+void sub_807A0F4(struct Sprite *sprite) {
+ DestroySpriteAndFreeResources(sprite);
+}
+
+int sub_807A100(u8 slot, u8 a2) {
+ u16 species;
+ u32 personality;
+ u16 letter;
+ u16 var;
+ int ret;
+ const struct MonCoords *coords;
+ struct TransformStatus *transform;
+ if (IsContest()) {
+ if (unk_2019348.field_4 & 1) {
+ species = unk_2019348.field_2;
+ personality = unk_2019348.field_10;
+ } else {
+ species = unk_2019348.field_0;
+ personality = unk_2019348.field_8;
+ }
+ if (species == SPECIES_UNOWN) {
+ letter = GET_UNOWN_LETTER(personality);
+ if (!letter) {
+ var = SPECIES_UNOWN;
+ } else {
+ var = letter + SPECIES_UNOWN_B - 1;
+ }
+ coords = &gMonBackPicCoords[var];
+ } else if (species == SPECIES_CASTFORM) {
+ coords = &gCastformFrontSpriteCoords[gBattleMonForms[slot]];
+ } else if (species <= SPECIES_EGG) {
+ coords = &gMonBackPicCoords[species];
+ } else {
+ coords = &gMonBackPicCoords[0];
+ }
+ } else {
+ if (!GetBankSide(slot)) {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ species = GetMonData(&gPlayerParty[gBattleMonPartyPositions[slot]], MON_DATA_SPECIES);
+ personality = GetMonData(&gPlayerParty[gBattleMonPartyPositions[slot]], MON_DATA_PERSONALITY);
+ } else {
+ species = transform->species;
+ personality = gTransformPersonalities[slot];
+ }
+ if (species == SPECIES_UNOWN) {
+ letter = GET_UNOWN_LETTER(personality);
+ if (!letter) {
+ var = SPECIES_UNOWN;
+ } else {
+ var = letter + SPECIES_UNOWN_B - 1;
+ }
+ coords = &gMonBackPicCoords[var];
+ } else if (species > SPECIES_EGG) {
+ coords = &gMonBackPicCoords[0];
+ } else {
+ coords = &gMonBackPicCoords[species];
+ }
+ } else {
+ transform = &gTransformStatuses[slot];
+ if (!transform->species) {
+ species = GetMonData(&gEnemyParty[gBattleMonPartyPositions[slot]], MON_DATA_SPECIES);
+ personality = GetMonData(&gEnemyParty[gBattleMonPartyPositions[slot]], MON_DATA_PERSONALITY);
+ } else {
+ species = transform->species;
+ personality = gTransformPersonalities[slot];
+ }
+ if (species == SPECIES_UNOWN) {
+ letter = GET_UNOWN_LETTER(personality);
+ if (!letter) {
+ var = SPECIES_UNOWN;
+ } else {
+ var = letter + SPECIES_UNOWN_B - 1;
+ }
+ coords = &gMonFrontPicCoords[var];
+ } else if (species == SPECIES_CASTFORM) {
+ coords = &gCastformFrontSpriteCoords[gBattleMonForms[slot]];
+ } else if (species > SPECIES_EGG) {
+ coords = &gMonFrontPicCoords[0];
+ } else {
+ coords = &gMonFrontPicCoords[species];
+ }
+ }
+ }
+
+ switch (a2) {
+ case 0:
+ return (coords->coords & 0xf) * 8;
+ case 1:
+ return (coords->coords >> 4) * 8;
+ case 4:
+ return sub_8077ABC(slot, 2) - ((coords->coords >> 4) * 4);
+ case 5:
+ return sub_8077ABC(slot, 2) + ((coords->coords >> 4) * 4);
+ case 2:
+ return sub_8077ABC(slot, 3) - ((coords->coords & 0xf) * 4);
+ case 3:
+ return sub_8077ABC(slot, 3) + ((coords->coords & 0xf) * 4);
+ case 6:
+ ret = sub_8077ABC(slot, 1) + 0x1f;
+ return ret - coords->y_offset;
+ default:
+ return 0;
+ }
+}
+
+void sub_807A3FC(u8 slot, u8 a2, s16 *a3, s16 *a4) {
+ u8 v1, v2;
+ s16 v3, v4;
+ s16 v5, v6;
+ if (!a2) {
+ v1 = 0;
+ v2 = 1;
+ } else {
+ v1 = 2;
+ v2 = 3;
+ }
+ v3 = sub_8077ABC(slot, v1);
+ v4 = sub_8077ABC(slot, v2);
+ if (IsDoubleBattle() && !IsContest()) {
+ v5 = sub_8077ABC(slot ^ 2, v1);
+ v6 = sub_8077ABC(slot ^ 2, v2);
+ } else {
+ v5 = v3;
+ v6 = v4;
+ }
+ *a3 = (v3 + v5) / 2;
+ *a4 = (v4 + v6) / 2;
+}
+
+u8 sub_807A4A0(int a1, u8 sprite, int a3) {
+ u8 new_sprite = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy);
+ gSprites[new_sprite] = gSprites[sprite];
+ gSprites[new_sprite].usingSheet = TRUE;
+ gSprites[new_sprite].oam.priority = 0;
+ gSprites[new_sprite].oam.objMode = 2;
+ gSprites[new_sprite].oam.tileNum = gSprites[sprite].oam.tileNum;
+ gSprites[new_sprite].callback = SpriteCallbackDummy;
+ return new_sprite;
+}
+
+void sub_807A544(struct Sprite *sprite) {
+ sub_8078650(sprite);
+ if (GetBankSide(gBattleAnimPlayerMonIndex)) {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ sprite->hFlip = TRUE;
+ } else {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ }
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data0 = gBattleAnimArgs[2];
+ sprite->data1 = gBattleAnimArgs[3];
+ sprite->data3 = gBattleAnimArgs[4];
+ sprite->data5 = gBattleAnimArgs[5];
+ oamt_set_x3A_32(sprite, move_anim_8074EE0);
+ sprite->callback = sub_8078504;
+}
+
+void sub_807A5C4(struct Sprite *sprite) {
+ if (GetBankSide(gBattleAnimPlayerMonIndex)) {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ gBattleAnimArgs[3] *= -1;
+ } else {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ }
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data0 = gBattleAnimArgs[2];
+ sprite->data1 = gBattleAnimArgs[3];
+ sprite->data3 = gBattleAnimArgs[4];
+ sprite->data5 = gBattleAnimArgs[5];
+ StartSpriteAnim(sprite, gBattleAnimArgs[6]);
+ oamt_set_x3A_32(sprite, move_anim_8074EE0);
+ sprite->callback = sub_8078504;
+}
+
+void sub_807A63C(struct Sprite *sprite) {
+ sub_8078650(sprite);
+ if (GetBankSide(gBattleAnimPlayerMonIndex)) {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ } else {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ }
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->callback = sub_8078600;
+ oamt_set_x3A_32(sprite, move_anim_8072740);
+}
+
+void sub_807A69C(u8 taskId) {
+ u16 src;
+ u16 dest;
+ struct Task *task = &gTasks[taskId];
+ task->data[0] = obj_id_for_side_relative_to_move(0);
+ task->data[1] = (GetBankSide(gBattleAnimPlayerMonIndex)) ? -8 : 8;
+ task->data[2] = 0;
+ task->data[3] = 0;
+ gSprites[task->data[0]].pos2.x -= task->data[0];
+ task->data[4] = AllocSpritePalette(10097);
+ task->data[5] = 0;
+
+ dest = (task->data[4] + 0x10) * 0x10;
+ src = (gSprites[task->data[0]].oam.paletteNum + 0x10) * 0x10;
+ task->data[6] = sub_8079E90(gBattleAnimPlayerMonIndex);
+ if (task->data[6] == 20 || task->data[6] == 40) {
+ task->data[6] = 2;
+ } else {
+ task->data[6] = 3;
+ }
+ CpuCopy32(&gPlttBufferUnfaded[src], &gPlttBufferFaded[dest], 0x20);
+ BlendPalette(dest, 0x10, gBattleAnimArgs[1], gBattleAnimArgs[0]);
+ task->func = sub_807A784;
+}
+
+void sub_807A784(u8 taskId) {
+ struct Task *task = &gTasks[taskId];
+ switch (task->data[2]) {
+ case 0:
+ sub_807A850(task, taskId);
+ gSprites[task->data[0]].pos2.x += task->data[1];
+ if (++task->data[3] == 5) {
+ task->data[3]--;
+ task->data[2]++;
+ }
+ break;
+ case 1:
+ sub_807A850(task, taskId);
+ gSprites[task->data[0]].pos2.x -= task->data[1];
+ if (--task->data[3] == 0) {
+ gSprites[task->data[0]].pos2.x = 0;
+ task->data[2]++;
+ }
+ break;
+ case 2:
+ if (!task->data[5]) {
+ FreeSpritePaletteByTag(10097);
+ DestroyAnimVisualTask(taskId);
+ }
+ break;
+ }
+}
+
+void sub_807A850(struct Task *task, u8 taskId) {
+ s16 sprite = duplicate_obj_of_side_rel2move_in_transparent_mode(0);
+ if (sprite >= 0) {
+ gSprites[sprite].oam.priority = task->data[6];
+ gSprites[sprite].oam.paletteNum = task->data[4];
+ gSprites[sprite].data0 = 8;
+ gSprites[sprite].data1 = taskId;
+ gSprites[sprite].data2 = sprite;
+ gSprites[sprite].pos2.x = gSprites[task->data[0]].pos2.x;
+ gSprites[sprite].callback = sub_807A8D4;
+ task->data[5]++;
+ }
+}
+
+void sub_807A8D4(struct Sprite *sprite) {
+ if (--sprite->data0 == 0) {
+ gTasks[sprite->data1].data[5]--;
+ obj_delete_but_dont_free_vram(sprite);
+ }
+}
+
+void sub_807A908(struct Sprite *sprite) {
+ sprite->pos1.x = sub_8077ABC(gBattleAnimPlayerMonIndex, 2);
+ sprite->pos1.y = sub_8077ABC(gBattleAnimPlayerMonIndex, 3);
+ if (!GetBankSide(gBattleAnimPlayerMonIndex)) {
+ sprite->data0 = 5;
+ } else {
+ sprite->data0 = -10;
+ }
+ sprite->data1 = -40;
+ sprite->callback = sub_807A960;
+}
+
+void sub_807A960(struct Sprite *sprite) {
+ sprite->data2 += sprite->data0;
+ sprite->data3 += sprite->data1;
+ sprite->pos2.x = sprite->data2 / 10;
+ sprite->pos2.y = sprite->data3 / 10;
+ if (sprite->data1 < -20) {
+ sprite->data1++;
+ }
+ if ((sprite->pos1.y + sprite->pos2.y) < -32) {
+ move_anim_8072740(sprite);
+ }
+}
+
+void sub_807A9BC(struct Sprite *sprite) {
+ int x;
+ sprite->data0 = gBattleAnimArgs[2];
+ sprite->data2 = sprite->pos1.x + gBattleAnimArgs[4];
+ sprite->data4 = sprite->pos1.y + gBattleAnimArgs[5];
+ if (!GetBankSide(gBattleAnimEnemyMonIndex)) {
+ x = (u16)gBattleAnimArgs[4] + 30;
+ sprite->pos1.x += x;
+ sprite->pos1.y = gBattleAnimArgs[5] - 20;
+ } else {
+ x = (u16)gBattleAnimArgs[4] - 30;
+ sprite->pos1.x += x;
+ sprite->pos1.y = gBattleAnimArgs[5] - 80;
+ }
+ sprite->callback = sub_8078B34;
+ oamt_set_x3A_32(sprite, move_anim_8072740);
+}
diff --git a/src/misc/script_pokemon_util_80C4BF0.c b/src/misc/script_pokemon_util_80C4BF0.c
new file mode 100644
index 000000000..cbca07011
--- /dev/null
+++ b/src/misc/script_pokemon_util_80C4BF0.c
@@ -0,0 +1,716 @@
+#include "global.h"
+#include "battle.h"
+#include "berry.h"
+#include "choose_party.h"
+#include "contest.h"
+#include "contest_link_80C2020.h"
+#include "contest_painting.h"
+#include "data2.h"
+#include "daycare.h"
+#include "debug.h"
+#include "decompress.h"
+#include "event_data.h"
+#include "items.h"
+#include "link.h"
+#include "load_save.h"
+#include "main.h"
+#include "menu.h"
+#include "pokedex.h"
+#include "pokemon.h"
+#include "rng.h"
+#include "rom4.h"
+#include "script_pokemon_80C4.h"
+#include "species.h"
+#include "task.h"
+
+#define CONTEST_ENTRY_PIC_LEFT 10
+#define CONTEST_ENTRY_PIC_TOP 3
+
+extern struct SpriteTemplate gUnknown_02024E8C;
+
+extern u8 gContestPlayerMonIndex;
+extern u8 gIsLinkContest;
+extern u8 gPlayerPartyCount;
+extern u8 gSelectedOrderFromParty[];
+
+extern u16 gSpecialVar_0x8004;
+extern u16 gSpecialVar_0x8005;
+extern u16 gSpecialVar_0x8006;
+
+extern u16 gScriptContestCategory;
+extern u16 gScriptContestRank;
+extern u16 gScriptResult;
+
+extern u32 gUnknown_03005D28;
+
+extern u8 gUnknown_02038694;
+extern u8 gUnknown_0203856C;
+extern u8 gUnknown_02038690[];
+extern u16 gUnknown_02038678[];
+
+void sub_80C4BF0(void)
+{
+ gSaveBlock1.vars[0x10] = gContestMons[0].unk16;
+ gSaveBlock1.vars[0x11] = gContestMons[1].unk16;
+ gSaveBlock1.vars[0x12] = gContestMons[2].unk16;
+}
+
+void sub_80C4C28(void)
+{
+ u16 var;
+ u8 specialVar = gSpecialVar_0x8005;
+
+ switch(specialVar)
+ {
+ case 0:
+ var = 3;
+ break;
+ case 1:
+ var = 4;
+ break;
+ case 2:
+ var = 5;
+ break;
+ default:
+ var = 100;
+ break;
+ }
+ gSpecialVar_0x8004 = var;
+}
+
+void sub_80C4C64(void)
+{
+ sub_80C46EC();
+ sub_80C4740();
+ sub_80C48F4();
+}
+
+void sub_80C4C78(void)
+{
+ u16 var;
+ u16 returnVar;
+
+ switch(gScriptContestCategory)
+ {
+ case 0:
+ var = 8;
+ break;
+ case 1:
+ var = 9;
+ break;
+ case 2:
+ var = 10;
+ break;
+ case 3:
+ var = 11;
+ break;
+ case 4:
+ default:
+ var = 12;
+ break;
+ }
+
+ returnVar = gSaveBlock1.sbStruct.unkSB2.sb1_2EFC_struct2[var].var;
+
+ if(returnVar == 0)
+ gSpecialVar_0x8004 = returnVar;
+ else
+ gSpecialVar_0x8004 = 1;
+}
+
+void sub_80C4CEC(void)
+{
+ sub_80B2A7C(0xFF);
+}
+
+void sub_80C4CF8(void)
+{
+ if(!gUnknown_02038690[gContestPlayerMonIndex]
+ && gScriptContestRank == 3
+ && (s16)gUnknown_02038678[gContestPlayerMonIndex] >= 800)
+ {
+ gSpecialVar_0x8004 = 1;
+ }
+ else
+ {
+ gSpecialVar_0x8004 = 0;
+ }
+}
+
+u8 sub_80C4D50(void)
+{
+ u8 retVar = 0;
+ int i;
+
+ for (i = 0; i < 5; i++)
+ if (gSaveBlock1.sbStruct.unkSB2.sb1_2EFC_struct2[i + 8].var)
+ retVar++;
+
+ return retVar;
+}
+
+// nope. too hard
+__attribute__((naked))
+void sub_80C4D80(void)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x8\n\
+ ldr r0, _080C4EA0 @ =gUnknown_02038670\n\
+ mov r12, r0\n\
+ ldr r1, _080C4EA4 @ =gSpecialVar_0x8006\n\
+ mov r8, r1\n\
+ ldr r2, _080C4EA8 @ =gStringVar1\n\
+ mov r9, r2\n\
+ mov r2, r12\n\
+ mov r1, sp\n\
+ movs r6, 0x3\n\
+_080C4D9E:\n\
+ ldrh r0, [r2]\n\
+ strh r0, [r1]\n\
+ adds r2, 0x2\n\
+ adds r1, 0x2\n\
+ subs r6, 0x1\n\
+ cmp r6, 0\n\
+ bge _080C4D9E\n\
+ movs r6, 0\n\
+_080C4DAE:\n\
+ movs r1, 0x3\n\
+ cmp r1, r6\n\
+ ble _080C4DD8\n\
+_080C4DB4:\n\
+ subs r4, r1, 0x1\n\
+ lsls r0, r4, 1\n\
+ mov r5, sp\n\
+ adds r3, r5, r0\n\
+ lsls r0, r1, 1\n\
+ adds r2, r5, r0\n\
+ ldrh r5, [r3]\n\
+ movs r7, 0\n\
+ ldrsh r1, [r3, r7]\n\
+ movs r7, 0\n\
+ ldrsh r0, [r2, r7]\n\
+ cmp r1, r0\n\
+ bge _080C4DD2\n\
+ strh r5, [r2]\n\
+ strh r0, [r3]\n\
+_080C4DD2:\n\
+ adds r1, r4, 0\n\
+ cmp r1, r6\n\
+ bgt _080C4DB4\n\
+_080C4DD8:\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x2\n\
+ ble _080C4DAE\n\
+ mov r2, r8\n\
+ ldrh r0, [r2]\n\
+ lsls r0, 1\n\
+ add r0, sp\n\
+ ldrh r0, [r0]\n\
+ movs r2, 0\n\
+ movs r7, 0\n\
+ movs r6, 0\n\
+ lsls r0, 16\n\
+ asrs r4, r0, 16\n\
+ adds r3, r0, 0\n\
+ mov r1, sp\n\
+_080C4DF6:\n\
+ movs r5, 0\n\
+ ldrsh r0, [r1, r5]\n\
+ cmp r0, r4\n\
+ bne _080C4E12\n\
+ lsls r0, r2, 24\n\
+ movs r2, 0x80\n\
+ lsls r2, 17\n\
+ adds r0, r2\n\
+ lsrs r2, r0, 24\n\
+ mov r5, r8\n\
+ ldrh r5, [r5]\n\
+ cmp r6, r5\n\
+ bne _080C4E12\n\
+ adds r7, r2, 0\n\
+_080C4E12:\n\
+ adds r1, 0x2\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x3\n\
+ ble _080C4DF6\n\
+ movs r6, 0\n\
+ mov r0, sp\n\
+ movs r1, 0\n\
+ ldrsh r0, [r0, r1]\n\
+ asrs r1, r3, 16\n\
+ lsls r2, 24\n\
+ mov r10, r2\n\
+ cmp r0, r1\n\
+ beq _080C4E40\n\
+ adds r2, r1, 0\n\
+ mov r1, sp\n\
+_080C4E30:\n\
+ adds r1, 0x2\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x3\n\
+ bgt _080C4E40\n\
+ movs r4, 0\n\
+ ldrsh r0, [r1, r4]\n\
+ cmp r0, r2\n\
+ bne _080C4E30\n\
+_080C4E40:\n\
+ lsls r0, r6, 24\n\
+ lsrs r4, r0, 24\n\
+ adds r2, r7, 0\n\
+ movs r6, 0\n\
+ asrs r5, r3, 16\n\
+ mov r8, r5\n\
+ mov r1, r12\n\
+ movs r5, 0\n\
+ ldrsh r0, [r1, r5]\n\
+ cmp r8, r0\n\
+ bne _080C4E60\n\
+ cmp r7, 0x1\n\
+ beq _080C4E78\n\
+_080C4E5A:\n\
+ subs r0, r2, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+_080C4E60:\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x3\n\
+ bgt _080C4E78\n\
+ lsls r0, r6, 1\n\
+ add r0, r12\n\
+ asrs r1, r3, 16\n\
+ movs r5, 0\n\
+ ldrsh r0, [r0, r5]\n\
+ cmp r1, r0\n\
+ bne _080C4E60\n\
+ cmp r2, 0x1\n\
+ bne _080C4E5A\n\
+_080C4E78:\n\
+ lsls r1, r6, 24\n\
+ lsrs r1, 24\n\
+ mov r0, r9\n\
+ bl sub_80C4698\n\
+ ldr r0, _080C4EAC @ =gIsLinkContest\n\
+ ldrb r1, [r0]\n\
+ movs r0, 0x1\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _080C4EB8\n\
+ ldr r0, _080C4EB0 @ =gStringVar2\n\
+ lsls r1, r6, 3\n\
+ subs r1, r6\n\
+ lsls r1, 2\n\
+ ldr r2, _080C4EB4 @ =gLinkPlayers + 0x8\n\
+ adds r1, r2\n\
+ bl sub_80C4674\n\
+ b _080C4EC4\n\
+ .align 2, 0\n\
+_080C4EA0: .4byte gUnknown_02038670\n\
+_080C4EA4: .4byte gSpecialVar_0x8006\n\
+_080C4EA8: .4byte gStringVar1\n\
+_080C4EAC: .4byte gIsLinkContest\n\
+_080C4EB0: .4byte gStringVar2\n\
+_080C4EB4: .4byte gLinkPlayers + 0x8\n\
+_080C4EB8:\n\
+ ldr r0, _080C4ED8 @ =gStringVar2\n\
+ lsls r1, r6, 6\n\
+ ldr r2, _080C4EDC @ =gUnknown_0203857D\n\
+ adds r1, r2\n\
+ bl sub_80C4674\n\
+_080C4EC4:\n\
+ mov r1, r10\n\
+ asrs r0, r1, 24\n\
+ cmp r0, 0x1\n\
+ beq _080C4ED0\n\
+ cmp r7, r0\n\
+ bne _080C4EE4\n\
+_080C4ED0:\n\
+ ldr r0, _080C4EE0 @ =gSpecialVar_0x8006\n\
+ strh r4, [r0]\n\
+ b _080C4EEA\n\
+ .align 2, 0\n\
+_080C4ED8: .4byte gStringVar2\n\
+_080C4EDC: .4byte gUnknown_0203857D\n\
+_080C4EE0: .4byte gSpecialVar_0x8006\n\
+_080C4EE4:\n\
+ ldr r1, _080C4EFC @ =gSpecialVar_0x8006\n\
+ adds r0, r4, 0x4\n\
+ strh r0, [r1]\n\
+_080C4EEA:\n\
+ add sp, 0x8\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .align 2, 0\n\
+_080C4EFC: .4byte gSpecialVar_0x8006\n\
+ .syntax divided");
+}
+
+void ShowContestWinnerCleanup(void)
+{
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+}
+
+void ShowContestWinner(void)
+{
+ if(gUnknown_0203856C)
+ {
+ sub_80AAF30();
+ BATTLE_STRUCT->unk15DDF = 1;
+ BATTLE_STRUCT->unk15DDE = sub_80B2C4C(254, 0);
+ sub_80B2A7C(3);
+ gUnknown_0203856C = 0;
+ }
+ SetMainCallback2(CB2_ContestPainting);
+ gMain.savedCallback = ShowContestWinnerCleanup;
+}
+
+void sub_80C4F70(void)
+{
+ VarSet(0x4010, gContestMons[0].unk16);
+ VarSet(0x4011, gContestMons[1].unk16);
+ VarSet(0x4012, gContestMons[2].unk16);
+ VarSet(0x4013, gContestMons[3].unk16);
+}
+
+bool8 GiveMonArtistRibbon(void)
+{
+ u8 ribbon = GetMonData(&gPlayerParty[gUnknown_02038694], MON_DATA_ARTIST_RIBBON);
+
+ if(ribbon == FALSE
+ && gUnknown_02038690[gContestPlayerMonIndex] == 0
+ && gScriptContestRank == 3
+ && (s16)gUnknown_02038678[gContestPlayerMonIndex] >= 800)
+ {
+ ribbon = TRUE;
+ SetMonData(&gPlayerParty[gUnknown_02038694], MON_DATA_ARTIST_RIBBON, &ribbon);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+u8 sub_80C5044(void)
+{
+ return gUnknown_0203856C;
+}
+
+void ShowContestEntryMonPic(void)
+{
+ const struct CompressedSpritePalette *palette;
+ u32 var1, var2;
+ u16 species;
+ u8 spriteId;
+ u8 taskId;
+
+ if(FindTaskIdByFunc(sub_80C5190) == 0xFF)
+ {
+ u8 left = CONTEST_ENTRY_PIC_LEFT;
+ u8 top = CONTEST_ENTRY_PIC_TOP;
+
+ MenuDrawTextWindow(left, top, 19, 13);
+ species = gContestMons[gSpecialVar_0x8006].species;
+ var1 = gContestMons[gSpecialVar_0x8006].unk38; // v2
+ var2 = gContestMons[gSpecialVar_0x8006].unk3C; // v3
+ taskId = CreateTask(sub_80C5190, 0x50);
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = species;
+ HandleLoadSpecialPokePic(
+ &gMonFrontPicTable[species],
+ gMonFrontPicCoords[species].coords,
+ gMonFrontPicCoords[species].y_offset,
+ (u32)gUnknown_081FAF4C[0],
+ gUnknown_081FAF4C[1],
+ species,
+ var1);
+ palette = sub_80409C8(species, var2, var1);
+ LoadCompressedObjectPalette(palette);
+ GetMonSpriteTemplate_803C56C(species, 1);
+ gUnknown_02024E8C.paletteTag = palette->tag;
+ spriteId = CreateSprite(&gUnknown_02024E8C, 0x78, 0x40, 0);
+ gTasks[taskId].data[2] = spriteId;
+ gTasks[taskId].data[3] = left;
+ gTasks[taskId].data[4] = top;
+ gSprites[spriteId].callback = SpriteCallbackDummy;
+ gSprites[spriteId].oam.priority = 0;
+ }
+}
+
+void sub_80C5164(void)
+{
+ u8 taskId = FindTaskIdByFunc(sub_80C5190);
+
+ if(taskId != 0xFF)
+ gTasks[taskId].data[0]++;
+}
+
+void sub_80C5190(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ struct Sprite *sprite;
+
+ switch(task->data[0])
+ {
+ case 2:
+ sprite = &gSprites[task->data[2]];
+ FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum));
+
+ if(sprite->oam.affineMode)
+ FreeOamMatrix(sprite->oam.matrixNum);
+
+ DestroySprite(sprite);
+ task->data[0]++;
+ break;
+ case 0:
+ task->data[0]++;
+ break;
+ case 3:
+ MenuZeroFillWindowRect(task->data[3], task->data[4], task->data[3] + 9, task->data[4] + 10);
+ DestroyTask(taskId);
+ break;
+ case 1:
+ default:
+ break;
+ }
+}
+
+void ScriptGetMultiplayerId(void)
+{
+ if(gIsLinkContest & 1)
+ gScriptResult = GetMultiplayerId();
+ else
+ gScriptResult = 4;
+}
+
+void ScriptRandom(void)
+{
+ u16 random;
+ u16 *scriptPtr;
+
+ if(gIsLinkContest & 1)
+ {
+ gUnknown_03005D28 = 1103515245 * gUnknown_03005D28 + 24691;
+ random = gUnknown_03005D28 >> 16;
+ scriptPtr = &gScriptResult;
+ }
+ else
+ {
+ scriptPtr = &gScriptResult;
+ random = Random();
+ }
+ *scriptPtr = random % *scriptPtr;
+}
+
+void HealPlayerParty(void)
+{
+ u8 i, j;
+ u8 ppBonuses;
+ u8 arg[4];
+
+ // restore HP.
+ for(i = 0; i < gPlayerPartyCount; i++)
+ {
+ u16 maxHP = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP);
+ arg[0] = maxHP;
+ arg[1] = maxHP >> 8;
+ SetMonData(&gPlayerParty[i], MON_DATA_HP, arg);
+ ppBonuses = GetMonData(&gPlayerParty[i], MON_DATA_PP_BONUSES);
+
+ // restore PP.
+ for(j = 0; j < 4; j++)
+ {
+ arg[0] = CalculatePPWithBonus(GetMonData(&gPlayerParty[i], MON_DATA_MOVE1 + j), ppBonuses, j);
+ SetMonData(&gPlayerParty[i], MON_DATA_PP1 + j, arg);
+ }
+
+ // since status is u32, the four 0 assignments here are probably for safety to prevent undefined data from reaching SetMonData.
+ arg[0] = 0;
+ arg[1] = 0;
+ arg[2] = 0;
+ arg[3] = 0;
+ SetMonData(&gPlayerParty[i], MON_DATA_STATUS, arg);
+ }
+}
+
+u8 ScriptGiveMon(u16 species, u8 var, u16 item, u32 var3, u32 var4, u8 var5)
+{
+ u16 nationalSpecies;
+ int sentToPc;
+ u8 array[2];
+ struct Pokemon mon;
+
+ CreateMon(&mon, species, var, 32, 0, 0, 0, 0);
+ array[0] = item;
+ array[1] = item >> 8;
+ SetMonData(&mon, MON_DATA_HELD_ITEM, array);
+ sentToPc = GiveMonToPlayer(&mon);
+ nationalSpecies = SpeciesToNationalPokedexNum(species);
+
+ // nested if check to fool compiler
+ switch(sentToPc)
+ {
+ case 0:
+ case 1:
+ GetNationalPokedexFlag(nationalSpecies, 2);
+ GetNationalPokedexFlag(nationalSpecies, 3);
+ return sentToPc;
+ default:
+ return sentToPc;
+ }
+}
+
+u8 ScriptGiveEgg(u16 value)
+{
+ struct Pokemon mon;
+ u8 data;
+
+ sub_8042044(&mon, value, 1);
+ data = 1;
+ SetMonData(&mon, MON_DATA_IS_EGG, &data);
+
+ return GiveMonToPlayer(&mon);
+}
+
+void CheckForAlivePartyMons(void)
+{
+ u8 var = sub_803DAA0();
+
+ switch(var)
+ {
+ case 1:
+ gScriptResult = var;
+ break;
+ case 0:
+ gScriptResult = var;
+ break;
+ case 2:
+ gScriptResult = var;
+ break;
+ }
+}
+
+bool8 CheckPartyMonHasHeldItem(u16 item)
+{
+ int i;
+
+ for(i = 0; i < 6; i++)
+ {
+ u16 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
+ if(species != SPECIES_NONE && species != SPECIES_EGG && GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM) == item)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 GetNameOfEnigmaBerryInPlayerParty(void)
+{
+ bool8 hasItem = CheckPartyMonHasHeldItem(ITEM_ENIGMA_BERRY);
+
+ if(hasItem == TRUE)
+ GetBerryNameByBerryType(ItemIdToBerryType(ITEM_ENIGMA_BERRY), gStringVar1);
+
+ return hasItem;
+}
+
+void ScriptWildBattle(u16 species, u8 level, u16 item)
+{
+ u8 data[2];
+
+ ZeroEnemyPartyMons();
+ CreateMon(&gEnemyParty[0], species, level, 0x20, 0, 0, 0, 0);
+
+ if(item)
+ {
+ data[0] = item;
+ data[1] = item >> 8;
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, data);
+ }
+}
+
+void ScriptSetMonMoveSlot(u8 monIndex, u16 move, u8 slot)
+{
+ if(monIndex > 6)
+ monIndex = gPlayerPartyCount - 1;
+
+ SetMonMoveSlot(&gPlayerParty[monIndex], move, slot);
+}
+
+void sub_80C5568(void)
+{
+ gMain.savedCallback = sub_80C5580;
+ sub_8121E10();
+}
+
+void sub_80C5580(void)
+{
+ u8 var = gSelectedOrderFromParty[0];
+
+ switch(var)
+ {
+ case 0:
+ gScriptResult = 0;
+ break;
+ default:
+ gScriptResult = 1;
+ break;
+ }
+
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+}
+
+void ChooseBattleTowerPlayerParty(void)
+{
+ gMain.savedCallback = SetBattleTowerPlayerParty;
+ sub_8121E34();
+}
+
+void SetBattleTowerPlayerParty(void)
+{
+ u8 var = gSelectedOrderFromParty[0];
+
+ switch(var)
+ {
+ case 0: // player quit battle tower?
+ LoadPlayerParty();
+ gScriptResult = 0;
+ break;
+ default: // load battle tower.
+ ReducePlayerPartyToThree();
+ gScriptResult = 1;
+ break;
+ }
+
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+}
+
+void ReducePlayerPartyToThree(void)
+{
+ struct Pokemon party[3];
+ int i;
+
+ CpuFill32(0, party, sizeof party);
+
+ // copy the selected pokemon according to the order.
+ for(i = 0; i < 3; i++)
+ if(gSelectedOrderFromParty[i]) // as long as the order keeps going (did the player select 1 mon? 2? 3?), do not stop
+ party[i] = gPlayerParty[gSelectedOrderFromParty[i] - 1]; // index is 0 based, not literal
+
+ // delete the last 3 pokemon
+ CpuFill32(0, gPlayerParty, sizeof gPlayerParty);
+
+ // overwrite the first 3 with the order copied to.
+ for(i = 0; i < 3; i++)
+ gPlayerParty[i] = party[i];
+
+ CalculatePlayerPartyCount();
+}
diff --git a/src/misc/script_pokemon_util_80F99CC.c b/src/misc/script_pokemon_util_80F99CC.c
new file mode 100644
index 000000000..2b48cc0d8
--- /dev/null
+++ b/src/misc/script_pokemon_util_80F99CC.c
@@ -0,0 +1,445 @@
+#include "global.h"
+#include "battle_party_menu.h"
+#include "choose_party.h"
+#include "contest.h"
+#include "data2.h"
+#include "party_menu.h"
+#include "field_fadetransition.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "pokemon.h"
+#include "pokemon_summary_screen.h"
+#include "rom4.h"
+#include "script.h"
+#include "script_pokemon_80F9.h"
+#include "sound.h"
+#include "string_util.h"
+#include "task.h"
+#include "text.h"
+
+
+
+extern u8 gPlayerPartyCount;
+extern u16 gSpecialVar_0x8004;
+extern u16 gSpecialVar_0x8005;
+extern u8 gUnknown_02038694;
+extern u16 gScriptResult;
+
+extern void (*gFieldCallback)(void);
+
+void sub_80F99CC(void)
+{
+ u8 taskId;
+
+ ScriptContext2_Enable();
+ taskId = CreateTask((void *)sub_80F9A8C, 0xA);
+ gTasks[taskId].data[0] = 2;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+}
+
+void sub_80F9A0C(void)
+{
+ u8 taskId;
+
+ ScriptContext2_Enable();
+ taskId = CreateTask((void *)sub_80F9A8C, 0xA);
+ gTasks[taskId].data[0] = 3;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+}
+
+void sub_80F9A4C(void)
+{
+ u8 taskId;
+
+ ScriptContext2_Enable();
+ taskId = CreateTask((void *)sub_80F9A8C, 0xA);
+ gTasks[taskId].data[0] = 7;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+}
+
+void sub_80F9A8C(u8 taskId)
+{
+ if(!gPaletteFade.active)
+ {
+ gPaletteFade.bufferTransferDisabled = 1;
+ OpenPartyMenu((u8) gTasks[taskId].data[0], 0);
+ DestroyTask(taskId);
+ }
+}
+
+bool8 sub_80F9ACC(void)
+{
+ switch(EWRAM_1B000.unk264)
+ {
+ case 0:
+ if(EWRAM_1B000.unk266 < gPlayerPartyCount)
+ {
+ TryCreatePartyMenuMonIcon(EWRAM_1B000.unk260, EWRAM_1B000.unk266, &gPlayerParty[EWRAM_1B000.unk266]);
+ EWRAM_1B000.unk266++;
+ }
+ else
+ {
+ EWRAM_1B000.unk266 = 0;
+ EWRAM_1B000.unk264++;
+ }
+ break;
+ case 1:
+ LoadHeldItemIconGraphics();
+ EWRAM_1B000.unk264++;
+ break;
+ case 2:
+ CreateHeldItemIcons_806DC34(EWRAM_1B000.unk260);
+ EWRAM_1B000.unk264++;
+ break;
+ case 3:
+ if(sub_806BD58(EWRAM_1B000.unk260, EWRAM_1B000.unk266) != 1)
+ {
+ EWRAM_1B000.unk266++;
+ break;
+ }
+ else
+ {
+ EWRAM_1B000.unk266 = 0;
+ EWRAM_1B000.unk264++;
+ break;
+ }
+ case 4:
+ PartyMenuPrintMonsLevelOrStatus();
+ EWRAM_1B000.unk264++;
+ break;
+ case 5:
+ PrintPartyMenuMonNicknames();
+ EWRAM_1B000.unk264++;
+ break;
+ case 6:
+ sub_80F9C00();
+ EWRAM_1B000.unk264++;
+ break;
+ case 7: // the only case that can return true.
+ if(sub_806B58C(EWRAM_1B000.unk266) != 1)
+ {
+ EWRAM_1B000.unk266++;
+ break;
+ }
+ else
+ {
+ EWRAM_1B000.unk266 = 0;
+ EWRAM_1B000.unk264 = 0;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void sub_80F9C00(void)
+{
+ u8 i;
+
+ for(i = 0; i < gPlayerPartyCount; i++)
+ {
+ switch(sub_80AE47C(&gPlayerParty[i]))
+ {
+ case 0:
+ case 3:
+ case 4:
+ sub_806BC3C(i, 0x7E);
+ break;
+ case 1:
+ case 2:
+ sub_806BC3C(i, 0x70);
+ break;
+ }
+ }
+}
+
+void sub_80F9C6C(u8 var)
+{
+ if(!gPaletteFade.active)
+ {
+ switch(sub_806BD80(var))
+ {
+ case 1:
+ PlaySE(5);
+ gUnknown_02038694 = sub_806CA38(var);
+ gSpecialVar_0x8004 = gUnknown_02038694;
+ sub_8123138(var);
+ break;
+ case 2:
+ PlaySE(5);
+ gUnknown_02038694 = 0xFF;
+ gSpecialVar_0x8004 = 0xFF;
+ sub_8123138(var);
+ break;
+ }
+ }
+}
+
+bool8 sub_80F9CE8(void) // this is the same function as sub_80F9ACC except case 6 calls a different function. why
+{
+ switch(EWRAM_1B000.unk264)
+ {
+ case 0:
+ if(EWRAM_1B000.unk266 < gPlayerPartyCount)
+ {
+ TryCreatePartyMenuMonIcon(EWRAM_1B000.unk260, EWRAM_1B000.unk266, &gPlayerParty[EWRAM_1B000.unk266]);
+ EWRAM_1B000.unk266++;
+ }
+ else
+ {
+ EWRAM_1B000.unk266 = 0;
+ EWRAM_1B000.unk264++;
+ }
+ break;
+ case 1:
+ LoadHeldItemIconGraphics();
+ EWRAM_1B000.unk264++;
+ break;
+ case 2:
+ CreateHeldItemIcons_806DC34(EWRAM_1B000.unk260);
+ EWRAM_1B000.unk264++;
+ break;
+ case 3:
+ if(sub_806BD58(EWRAM_1B000.unk260, EWRAM_1B000.unk266) != 1)
+ {
+ EWRAM_1B000.unk266++;
+ break;
+ }
+ else
+ {
+ EWRAM_1B000.unk266 = 0;
+ EWRAM_1B000.unk264++;
+ break;
+ }
+ case 4:
+ PartyMenuPrintMonsLevelOrStatus();
+ EWRAM_1B000.unk264++;
+ break;
+ case 5:
+ PrintPartyMenuMonNicknames();
+ EWRAM_1B000.unk264++;
+ break;
+ case 6:
+ sub_80F9E1C();
+ EWRAM_1B000.unk264++;
+ break;
+ case 7: // the only case that can return true.
+ if(sub_806B58C(EWRAM_1B000.unk266) != 1)
+ {
+ EWRAM_1B000.unk266++;
+ break;
+ }
+ else
+ {
+ EWRAM_1B000.unk266 = 0;
+ EWRAM_1B000.unk264 = 0;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void sub_80F9E1C(void)
+{
+ u8 i;
+
+ for(i = 0; i < gPlayerPartyCount; i++)
+ {
+ if(!sub_8040574(&gPlayerParty[i]))
+ sub_806BC3C(i, 0x9A);
+ else
+ sub_806BC3C(i, 0x8C);
+ }
+}
+
+void sub_80F9E64(u8 var)
+{
+ if(!gPaletteFade.active)
+ {
+ switch(sub_806BD80(var))
+ {
+ case 1:
+ PlaySE(5);
+ gSpecialVar_0x8004 = sub_806CA38(var);
+ gSpecialVar_0x8005 = sub_8040574(&gPlayerParty[gSpecialVar_0x8004]);
+ sub_8123138(var);
+ break;
+ case 2:
+ PlaySE(5);
+ gSpecialVar_0x8004 = 0xFF;
+ sub_8123138(var);
+ }
+ }
+}
+
+void sub_80F9EEC(void)
+{
+ sub_809D9F0(&gPlayerParty[0], gSpecialVar_0x8004, gPlayerPartyCount - 1, c2_exit_to_overworld_2_switch, 0);
+ unk_2018000.unk8 = 3;
+ gFieldCallback = sub_8080990;
+}
+
+void sub_80F9F3C(void) // count pokemon moves
+{
+ u8 i;
+
+ gScriptResult = 0;
+
+ for(i = 0; i < 4; i++) // checks MOVE1-MOVE4
+ if(GetMonData(&gPlayerParty[gSpecialVar_0x8004], i + 13))
+ gScriptResult++;
+}
+
+void sub_80F9F84(void)
+{
+ struct Pokemon *party = &gPlayerParty[gSpecialVar_0x8004];
+ u16 data = GetMonData(party, gSpecialVar_0x8005 + 13);
+
+ GetMonNickname(party, gStringVar1);
+ StringCopy(gStringVar2, gMoveNames[data]);
+}
+
+// no. hard
+__attribute__((naked))
+void sub_80F9FDC(struct Pokemon *party, u8 var, u8 var2)
+{
+ 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, 0x20\n\
+ mov r8, r0\n\
+ adds r5, r1, 0\n\
+ adds r4, r2, 0\n\
+ lsls r5, 24\n\
+ lsrs r5, 24\n\
+ lsls r4, 24\n\
+ lsrs r4, 24\n\
+ adds r0, r5, 0\n\
+ adds r0, 0xD\n\
+ str r0, [sp, 0x8]\n\
+ mov r0, r8\n\
+ ldr r1, [sp, 0x8]\n\
+ bl GetMonData\n\
+ mov r1, sp\n\
+ adds r1, 0x2\n\
+ str r1, [sp, 0x14]\n\
+ strh r0, [r1]\n\
+ adds r3, r4, 0\n\
+ adds r3, 0xD\n\
+ str r3, [sp, 0xC]\n\
+ mov r0, r8\n\
+ adds r1, r3, 0\n\
+ bl GetMonData\n\
+ mov r1, sp\n\
+ strh r0, [r1]\n\
+ adds r7, r5, 0\n\
+ adds r7, 0x11\n\
+ str r7, [sp, 0x10]\n\
+ mov r0, r8\n\
+ adds r1, r7, 0\n\
+ bl GetMonData\n\
+ mov r1, sp\n\
+ adds r1, 0x5\n\
+ str r1, [sp, 0x18]\n\
+ strb r0, [r1]\n\
+ adds r3, r4, 0\n\
+ adds r3, 0x11\n\
+ str r3, [sp, 0x1C]\n\
+ mov r0, r8\n\
+ adds r1, r3, 0\n\
+ bl GetMonData\n\
+ add r7, sp, 0x4\n\
+ mov r10, r7\n\
+ strb r0, [r7]\n\
+ mov r0, r8\n\
+ movs r1, 0x15\n\
+ bl GetMonData\n\
+ mov r6, sp\n\
+ adds r6, 0x6\n\
+ strb r0, [r6]\n\
+ ldr r1, _080FA0D8 @ =gUnknown_08208238\n\
+ adds r0, r5, r1\n\
+ ldrb r0, [r0]\n\
+ mov r9, r0\n\
+ ldrb r0, [r6]\n\
+ adds r2, r0, 0\n\
+ mov r3, r9\n\
+ ands r2, r3\n\
+ lsls r5, 1\n\
+ asrs r2, r5\n\
+ lsls r2, 24\n\
+ lsrs r2, 24\n\
+ adds r1, r4, r1\n\
+ ldrb r3, [r1]\n\
+ adds r1, r0, 0\n\
+ ands r1, r3\n\
+ lsls r4, 1\n\
+ asrs r1, r4\n\
+ lsls r1, 24\n\
+ lsrs r1, 24\n\
+ mov r7, r9\n\
+ bics r0, r7\n\
+ strb r0, [r6]\n\
+ ldrb r0, [r6]\n\
+ bics r0, r3\n\
+ strb r0, [r6]\n\
+ lsls r2, r4\n\
+ lsls r1, r5\n\
+ adds r2, r1\n\
+ ldrb r0, [r6]\n\
+ orrs r0, r2\n\
+ strb r0, [r6]\n\
+ mov r0, r8\n\
+ ldr r1, [sp, 0x8]\n\
+ mov r2, sp\n\
+ bl SetMonData\n\
+ mov r0, r8\n\
+ ldr r1, [sp, 0xC]\n\
+ ldr r2, [sp, 0x14]\n\
+ bl SetMonData\n\
+ mov r0, r8\n\
+ ldr r1, [sp, 0x10]\n\
+ mov r2, r10\n\
+ bl SetMonData\n\
+ mov r0, r8\n\
+ ldr r1, [sp, 0x1C]\n\
+ ldr r2, [sp, 0x18]\n\
+ bl SetMonData\n\
+ mov r0, r8\n\
+ movs r1, 0x15\n\
+ adds r2, r6, 0\n\
+ bl SetMonData\n\
+ add sp, 0x20\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\
+_080FA0D8: .4byte gUnknown_08208238\n\
+ .syntax divided");
+}
+
+void sub_80FA0DC(void)
+{
+ u16 i;
+
+ SetMonMoveSlot(&gPlayerParty[gSpecialVar_0x8004], 0, gSpecialVar_0x8005);
+ RemoveMonPPBonus(&gPlayerParty[gSpecialVar_0x8004], gSpecialVar_0x8005);
+
+ for(i = gSpecialVar_0x8005; i < 3; i++)
+ sub_80F9FDC(&gPlayerParty[gSpecialVar_0x8004], i, i + 1);
+}
+
+void sub_80FA148(void)
+{
+ struct Pokemon *party = &gPlayerParty[gSpecialVar_0x8004];
+ gScriptResult = 0;
+
+ if(GetMonData(party, MON_DATA_IS_EGG))
+ gScriptResult = 1;
+}
diff --git a/src/misc/unknown_task.c b/src/misc/unknown_task.c
new file mode 100644
index 000000000..81b89ef92
--- /dev/null
+++ b/src/misc/unknown_task.c
@@ -0,0 +1,255 @@
+#include "global.h"
+#include "data2.h"
+#include "task.h"
+#include "trig.h"
+
+struct UnknownStruct1
+{
+ void *src[2];
+ void *dest;
+ u32 unkC;
+ void (*unk10)(void);
+ u8 srcBank;
+ u8 unk15;
+ u8 unk16;
+ u8 unk17;
+ u8 taskId;
+ u8 filler19[0x7];
+};
+
+struct UnknownStruct2
+{
+ void *dest;
+ u32 control;
+ u8 unk8;
+ u8 unk9;
+};
+
+static void sub_80896F4(void);
+static void sub_8089714(void);
+
+extern u16 gUnknown_030041B0;
+extern u16 gUnknown_030041B4;
+extern u16 gUnknown_030041B8;
+extern u16 gUnknown_03004280;
+extern u16 gUnknown_03004288;
+extern u16 gUnknown_030042A0;
+extern u16 gUnknown_030042A4;
+extern u16 gUnknown_030042C0;
+
+extern u8 gUnknown_0202FFA4;
+
+extern struct UnknownStruct1 gUnknown_03004DC0;
+
+extern u16 gUnknown_03004DE0[][0x3C0];
+
+void remove_some_task(void)
+{
+ gUnknown_03004DC0.unk15 = 0;
+ DmaStop(0);
+ if (gUnknown_03004DC0.taskId != 0xFF)
+ {
+ DestroyTask(gUnknown_03004DC0.taskId);
+ gUnknown_03004DC0.taskId = 0xFF;
+ }
+}
+
+void dp12_8087EA4(void)
+{
+ CpuFill16(0, gUnknown_03004DE0, 0x780 * 2);
+ gUnknown_03004DC0.src[0] = 0;
+ gUnknown_03004DC0.src[1] = 0;
+ gUnknown_03004DC0.dest = 0;
+ gUnknown_03004DC0.unkC = 0;
+ gUnknown_03004DC0.srcBank = 0;
+ gUnknown_03004DC0.unk15 = 0;
+ gUnknown_03004DC0.unk16 = 0;
+ gUnknown_03004DC0.unk17 = 0;
+ gUnknown_03004DC0.taskId = 0xFF;
+}
+
+void sub_80895F8(struct UnknownStruct2 unk)
+{
+ if (unk.control == (((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1))
+ {
+ gUnknown_03004DC0.src[0] = &gUnknown_03004DE0[0][1];
+ gUnknown_03004DC0.src[1] = &gUnknown_03004DE0[1][1];
+ gUnknown_03004DC0.unk10 = sub_80896F4;
+ }
+ else
+ {
+ gUnknown_03004DC0.src[0] = &gUnknown_03004DE0[0][2];
+ gUnknown_03004DC0.src[1] = &gUnknown_03004DE0[1][2];
+ gUnknown_03004DC0.unk10 = sub_8089714;
+ }
+
+ gUnknown_03004DC0.unkC = unk.control;
+ gUnknown_03004DC0.dest = unk.dest;
+ gUnknown_03004DC0.unk15 = unk.unk8;
+ gUnknown_03004DC0.unk16 = unk.unk9;
+ gUnknown_03004DC0.unk17 = unk.unk9;
+}
+
+void sub_8089668(void)
+{
+ if (gUnknown_03004DC0.unk15)
+ {
+ if (gUnknown_03004DC0.unk15 == 3)
+ {
+ gUnknown_03004DC0.unk15 = 0;
+ DmaStop(0);
+ gUnknown_0202FFA4 = 1;
+ }
+ else
+ {
+ DmaStop(0);
+ DmaSet(0, gUnknown_03004DC0.src[gUnknown_03004DC0.srcBank], gUnknown_03004DC0.dest, gUnknown_03004DC0.unkC);
+ gUnknown_03004DC0.unk10();
+ gUnknown_03004DC0.srcBank ^= 1;
+ }
+ }
+}
+
+static void sub_80896F4(void)
+{
+ u16 *dest = (u16 *)gUnknown_03004DC0.dest;
+ u16 *src = (u16 *)&gUnknown_03004DE0[gUnknown_03004DC0.srcBank];
+ *dest = *src;
+}
+
+static void sub_8089714(void)
+{
+ u32 *dest = (u32 *)gUnknown_03004DC0.dest;
+ u32 *src = (u32 *)&gUnknown_03004DE0[gUnknown_03004DC0.srcBank];
+ *dest = *src;
+}
+
+static void task00_for_dp12(u8 taskId)
+{
+ int value = 0;
+
+ if (gUnknown_0202FFA4)
+ {
+ DestroyTask(taskId);
+ gUnknown_03004DC0.taskId = 0xFF;
+ }
+ else
+ {
+ if (gTasks[taskId].data[7])
+ {
+ switch (gTasks[taskId].data[6])
+ {
+ case 0x0:
+ value = gUnknown_030042A4;
+ break;
+ case 0x2:
+ value = gUnknown_030042A0;
+ break;
+ case 0x4:
+ value = gUnknown_030042C0;
+ break;
+ case 0x6:
+ value = gUnknown_030041B4;
+ break;
+ case 0x8:
+ value = gUnknown_03004288;
+ break;
+ case 0xA:
+ value = gUnknown_03004280;
+ break;
+ case 0xC:
+ value = gUnknown_030041B0;
+ break;
+ case 0xE:
+ value = gUnknown_030041B8;
+ break;
+ }
+ }
+ if (gTasks[taskId].data[4])
+ {
+ int i;
+ int offset;
+ gTasks[taskId].data[4]--;
+ offset = gTasks[taskId].data[3] + 320;
+ for (i = gTasks[taskId].data[0]; i < gTasks[taskId].data[1]; i++)
+ {
+ gUnknown_03004DE0[gUnknown_03004DC0.srcBank][i] = gUnknown_03004DE0[0][offset] + value;
+ offset++;
+ }
+ }
+ else
+ {
+ int i;
+ int offset;
+ gTasks[taskId].data[4] = gTasks[taskId].data[5];
+ offset = gTasks[taskId].data[3] + 320;
+ for (i = gTasks[taskId].data[0]; i < gTasks[taskId].data[1]; i++)
+ {
+ gUnknown_03004DE0[gUnknown_03004DC0.srcBank][i] = gUnknown_03004DE0[0][offset] + value;
+ offset++;
+ }
+ gTasks[taskId].data[3]++;
+ if (gTasks[taskId].data[3] == gTasks[taskId].data[2])
+ {
+ gTasks[taskId].data[3] = 0;
+ }
+ }
+ }
+}
+
+static void sub_80898FC(u16 *a1, u8 a2, u8 a3, u8 a4)
+{
+ u16 i = 0;
+ u8 offset = 0;
+
+ while (i < 0x100)
+ {
+ a1[i] = (gSineTable[offset] * a3) / 256;
+ offset += a2;
+ i++;
+ }
+}
+
+u8 sub_8089944(u8 a1, u8 a2, u8 a3, u8 a4, u8 a5, u8 a6, u8 a7)
+{
+ int i;
+ int offset;
+ struct UnknownStruct2 unk;
+ u8 taskId;
+
+ dp12_8087EA4();
+
+ unk.dest = (void *)(REG_ADDR_BG0HOFS + a6);
+ unk.control = ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1;
+ unk.unk8 = 1;
+ unk.unk9 = 0;
+
+ sub_80895F8(unk);
+
+ taskId = CreateTask(task00_for_dp12, 0);
+
+ gTasks[taskId].data[0] = a1;
+ gTasks[taskId].data[1] = a2;
+ gTasks[taskId].data[2] = 256 / a3;
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].data[4] = a5;
+ gTasks[taskId].data[5] = a5;
+ gTasks[taskId].data[6] = a6;
+ gTasks[taskId].data[7] = a7;
+
+ gUnknown_03004DC0.taskId = taskId;
+ gUnknown_0202FFA4 = 0;
+
+ sub_80898FC(&gUnknown_03004DE0[0][320], a3, a4, a2 - a1);
+
+ offset = 320;
+
+ for (i = a1; i < a2; i++)
+ {
+ gUnknown_03004DE0[0][i] = gUnknown_03004DE0[0][offset];
+ gUnknown_03004DE0[1][i] = gUnknown_03004DE0[0][offset];
+ offset++;
+ }
+
+ return taskId;
+}
diff --git a/src/misc/unused_8124F94.c b/src/misc/unused_8124F94.c
new file mode 100644
index 000000000..93b569058
--- /dev/null
+++ b/src/misc/unused_8124F94.c
@@ -0,0 +1,126 @@
+#include "global.h"
+#include "decompress.h"
+#include "palette.h"
+
+struct UnknownStruct2
+{
+ void *src;
+ u8 unk4;
+ u8 unk5;
+ u8 unk6;
+ u16 unk8;
+};
+
+struct UnknownStruct3
+{
+ u16 *paletteSrc;
+ u8 unk4;
+ u8 paletteCount;
+};
+
+struct UnknownStruct1
+{
+ u8 paletteNum;
+ u8 unk1;
+ u16 unk2;
+ u8 *dest;
+ struct UnknownStruct3 unk8[16];
+ struct UnknownStruct2 unk88[32];
+};
+
+void unref_sub_8124F94(struct UnknownStruct1 *a)
+{
+ a->unk1 = 0;
+ a->paletteNum = 0;
+ a->unk2 = 0;
+ a->dest = (void *)VRAM;
+ DmaFill16(3, 0, a->unk8, sizeof(a->unk8));
+ DmaFill16(3, 0, a->unk88, sizeof(a->unk88));
+}
+
+u8 unref_sub_8124FD8(struct UnknownStruct1 *a, const struct UnknownStruct2 *b)
+{
+ while (1)
+ {
+ s32 r6;
+ s32 temp;
+
+ // Couldn't get it to match any other way
+ if (a->unk1 < 32 && b->src == NULL)
+ return 0;
+ if (a->unk1 >= 32)
+ break;
+
+ a->unk88[a->unk1].src = b->src;
+ a->unk88[a->unk1].unk6 = b->unk6;
+ a->unk88[a->unk1].unk4 = b->unk4;
+ a->unk88[a->unk1].unk5 = b->unk5;
+ r6 = b->unk4 * b->unk5;
+ if (a->unk2 + r6 > 0x400)
+ return 2;
+ if (b->unk8 == 0)
+ {
+ DmaCopy16(3, b->src, a->dest + a->unk2 * 64, r6 * 32);
+ }
+ else
+ {
+ sub_800D238(b->src, a->dest + a->unk2 * 64);
+ }
+ a->unk88[a->unk1].unk8 = a->unk2;
+ temp = r6 + a->unk2;
+ a->unk2 = temp;
+ a->unk1++;
+ b++;
+ }
+ return 1;
+}
+
+u8 unref_sub_81250A4(struct UnknownStruct1 *a, struct UnknownStruct3 *b)
+{
+ while (1)
+ {
+ // Couldn't get it to match any other way
+ if (a->paletteNum < 16 && b->paletteSrc == NULL)
+ return 0;
+ if (a->paletteNum >= 16)
+ break;
+
+ a->unk8[a->paletteNum].paletteSrc = b->paletteSrc;
+ a->unk8[a->paletteNum].unk4 = b->unk4;
+ if (b->paletteCount == 0)
+ {
+ LoadPalette(b->paletteSrc, a->paletteNum * 16, 32);
+ }
+ else
+ {
+ u16 palette[16];
+
+ sub_800D238(b->paletteSrc, palette);
+ LoadPalette(palette, a->paletteNum * 16, 32);
+ }
+ a->unk8[a->paletteNum].paletteCount = a->paletteNum;
+ a->paletteNum = a->paletteNum + 1;
+ b++;
+ }
+ return 1;
+}
+
+u8 unref_sub_8125118(struct UnknownStruct1 *a, struct UnknownStruct3 *b)
+{
+ u16 palettes[16][16] = {0};
+ u8 r7 = b->paletteCount;
+ u8 i;
+
+ sub_800D238(b->paletteSrc, palettes);
+ for (i = a->paletteNum; i < r7; i++)
+ {
+ if (a->paletteNum + i >= 16)
+ return 1;
+ a->unk8[i].paletteSrc = b->paletteSrc;
+ a->unk8[i].unk4 = b->unk4 + i;
+ a->unk8[i].paletteCount = a->paletteNum;
+ LoadPalette(palettes[i], a->paletteNum * 16, sizeof(palettes[i]));
+ a->paletteNum++;
+ }
+ return 0;
+}