summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/battle_anim_sound_tasks.c2
-rw-r--r--src/battle_interface.c2
-rw-r--r--src/battle_main.c6
-rw-r--r--src/battle_script_commands.c4
-rw-r--r--src/battle_setup.c6
-rw-r--r--src/battle_tv.c2
-rw-r--r--src/berry_blender.c11
-rw-r--r--src/bg.c6
-rw-r--r--src/bike.c1
-rw-r--r--src/daycare.c37
-rw-r--r--src/decompress.c4
-rw-r--r--src/decoration.c13
-rw-r--r--src/dewford_trend.c2
-rw-r--r--src/egg_hatch.c17
-rw-r--r--src/field_effect.c3884
-rw-r--r--src/field_map_obj.c2
-rw-r--r--src/field_tasks.c776
-rw-r--r--src/fldeff_teleport.c2
-rw-r--r--src/fossil_specials.c2
-rw-r--r--src/hof_pc.c1
-rw-r--r--src/item.c2
-rwxr-xr-xsrc/item_menu.c7
-rwxr-xr-xsrc/item_use.c3
-rw-r--r--src/lilycove_lady.c14
-rw-r--r--src/link.c2
-rw-r--r--src/link_rfu.c10
-rw-r--r--src/list_menu.c832
-rw-r--r--src/main_menu.c2
-rw-r--r--src/map_name_popup.c2
-rw-r--r--src/match_call.c4
-rw-r--r--src/mauville_old_man.c33
-rw-r--r--src/menu.c2
-rw-r--r--src/menu_helpers.c455
-rw-r--r--src/mon_markings.c3
-rw-r--r--src/new_game.c7
-rw-r--r--src/overworld.c18
-rw-r--r--src/player_pc.c8
-rw-r--r--src/pokeblock.c3
-rw-r--r--src/pokemon_animation.c2
-rw-r--r--src/pokemon_summary_screen.c14
-rw-r--r--src/record_mixing.c2286
-rw-r--r--src/recorded_battle.c2
-rw-r--r--src/rom_8034C54.c454
-rw-r--r--src/rotating_gate.c8
-rw-r--r--src/secret_base.c9
-rw-r--r--src/text.c8
-rw-r--r--src/time_events.c2
-rw-r--r--src/title_screen.c3
-rw-r--r--src/tv.c22
-rw-r--r--src/util.c2
-rw-r--r--src/walda_phrase.c3
51 files changed, 8809 insertions, 193 deletions
diff --git a/src/battle_anim_sound_tasks.c b/src/battle_anim_sound_tasks.c
index e956fd44f..2316b9759 100644
--- a/src/battle_anim_sound_tasks.c
+++ b/src/battle_anim_sound_tasks.c
@@ -386,7 +386,7 @@ void sub_8159308(u8 taskId)
DestroyAnimVisualTask(taskId);
}
#else
-ASM_DIRECT
+NAKED
void sub_8159308(u8 taskId)
{
asm_unified(" push {r4,r5,lr}\n\
diff --git a/src/battle_interface.c b/src/battle_interface.c
index 0a8bf3ed7..9ef45020d 100644
--- a/src/battle_interface.c
+++ b/src/battle_interface.c
@@ -648,7 +648,7 @@ static void sub_8072308(s16 arg0, u16 *arg1, u8 arg2)
}
#else
-ASM_DIRECT
+NAKED
static void sub_8072308(s16 arg0, u16 *arg1, u8 arg2)
{
asm(".syntax unified\n\
diff --git a/src/battle_main.c b/src/battle_main.c
index 70eebed85..8649209c0 100644
--- a/src/battle_main.c
+++ b/src/battle_main.c
@@ -1830,7 +1830,7 @@ static void FreeRestoreBattleData(void)
gScanlineEffect.state = 3;
gMain.inBattle = 0;
ZeroEnemyPartyMons();
- m4aSongNumStop(0x5A);
+ m4aSongNumStop(SE_HINSI);
FreeMonSpritesGfx();
FreeBattleSpritesData();
FreeBattleResources();
@@ -3591,7 +3591,7 @@ static void BattleIntroOpponent1SendsOutMonAnimation(void)
gBattleMainFunc = BattleIntroRecordMonsToDex;
}
#else
-ASM_DIRECT
+NAKED
static void BattleIntroOpponent1SendsOutMonAnimation(void)
{
asm(".syntax unified\n\
@@ -5224,7 +5224,7 @@ static void ReturnFromBattleToOverworld(void)
SetRoamerInactive();
}
- m4aSongNumStop(0x5A);
+ m4aSongNumStop(SE_HINSI);
SetMainCallback2(gMain.savedCallback);
}
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index d1a18e38f..811aba128 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -3357,7 +3357,7 @@ static void atk23_getexp(void)
if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong)
{
BattleStopLowHpSound();
- PlayBGM(0x161);
+ PlayBGM(MUS_KACHI2);
gBattleStruct->wildVictorySong++;
}
@@ -3608,7 +3608,7 @@ static void atk24(void)
}
}
#else
-ASM_DIRECT
+NAKED
static void atk24(void)
{
asm("\n\
diff --git a/src/battle_setup.c b/src/battle_setup.c
index 97e8f7041..48a2ef257 100644
--- a/src/battle_setup.c
+++ b/src/battle_setup.c
@@ -51,8 +51,6 @@ struct TrainerBattleParameter
u8 ptrType;
};
-extern void (*gFieldCallback)(void);
-
extern bool8 InBattlePyramid(void);
extern bool8 InBattlePike(void);
extern bool32 InTrainerHill(void);
@@ -396,7 +394,7 @@ static void DoStandardWildBattle(void)
gBattleTypeFlags = 0;
if (InBattlePyramid())
{
- VarSet(VAR_0x400E, 0);
+ VarSet(VAR_TEMP_E, 0);
gBattleTypeFlags |= BATTLE_TYPE_PYRAMID;
}
CreateBattleStartTask(GetWildBattleTransition(), 0);
@@ -1260,7 +1258,7 @@ void BattleSetup_StartTrainerBattle(void)
if (InBattlePyramid())
{
- VarSet(VAR_0x400E, 0);
+ VarSet(VAR_TEMP_E, 0);
gBattleTypeFlags |= BATTLE_TYPE_PYRAMID;
if (gNoOfApproachingTrainers == 2)
diff --git a/src/battle_tv.c b/src/battle_tv.c
index 777b4846f..e5d97be30 100644
--- a/src/battle_tv.c
+++ b/src/battle_tv.c
@@ -812,7 +812,7 @@ void TryPutLinkBattleTvShowOnAir(void)
}
#else
-ASM_DIRECT
+NAKED
void TryPutLinkBattleTvShowOnAir(void)
{
asm_unified(
diff --git a/src/berry_blender.c b/src/berry_blender.c
index c3b0cc80d..2edb14748 100644
--- a/src/berry_blender.c
+++ b/src/berry_blender.c
@@ -151,15 +151,14 @@ extern const u8 gText_Space[];
extern const u8 gText_BlenderMaxSpeedRecord[];
extern const u8 gText_234Players[];
-extern void sub_81978B0(u16);
extern void sub_800A418(void);
extern u8 sub_800A9D8(void);
-extern bool8 sub_800A4D8(u8);
extern void sub_809882C(u8, u16, u8);
extern void copy_textbox_border_tile_patterns_to_vram(u8, u16, u8);
extern void sub_81AABF0(void (*callback)(void));
extern void sub_800B4C0(void);
extern void ClearLinkCallback(void);
+extern void sub_8009F8C(void);
extern void sub_8153430(void);
extern bool8 sub_8153474(void);
extern void sub_80EECEC(void);
@@ -818,7 +817,7 @@ static bool8 LoadBerryBlenderGfx(void)
switch (sBerryBlenderData->loadGfxState)
{
case 0:
- sBerryBlenderData->tilesBuffer = AllocZeroed(sub_8034974(sBlenderCenterGfx) + 100);
+ sBerryBlenderData->tilesBuffer = AllocZeroed(GetDecompressedDataSize(sBlenderCenterGfx) + 100);
LZDecompressWram(sBlenderCenterGfx, sBerryBlenderData->tilesBuffer);
sBerryBlenderData->loadGfxState++;
break;
@@ -829,7 +828,7 @@ static bool8 LoadBerryBlenderGfx(void)
sBerryBlenderData->loadGfxState++;
break;
case 2:
- LoadBgTiles(2, sBerryBlenderData->tilesBuffer, sub_8034974(sBlenderCenterGfx), 0);
+ LoadBgTiles(2, sBerryBlenderData->tilesBuffer, GetDecompressedDataSize(sBlenderCenterGfx), 0);
sBerryBlenderData->loadGfxState++;
break;
case 3:
@@ -837,7 +836,7 @@ static bool8 LoadBerryBlenderGfx(void)
sBerryBlenderData->loadGfxState++;
break;
case 4:
- LoadBgTiles(1, sBerryBlenderData->tilesBuffer, sub_8034974(gUnknown_08D91DB8), 0);
+ LoadBgTiles(1, sBerryBlenderData->tilesBuffer, GetDecompressedDataSize(gUnknown_08D91DB8), 0);
sBerryBlenderData->loadGfxState++;
break;
case 5:
@@ -845,7 +844,7 @@ static bool8 LoadBerryBlenderGfx(void)
sBerryBlenderData->loadGfxState++;
break;
case 6:
- CopyToBgTilemapBuffer(1, sBerryBlenderData->tilesBuffer, sub_8034974(gUnknown_08D927EC), 0);
+ CopyToBgTilemapBuffer(1, sBerryBlenderData->tilesBuffer, GetDecompressedDataSize(gUnknown_08D927EC), 0);
CopyBgTilemapBufferToVram(1);
sBerryBlenderData->loadGfxState++;
break;
diff --git a/src/bg.c b/src/bg.c
index 975c72a94..2f4cdc856 100644
--- a/src/bg.c
+++ b/src/bg.c
@@ -463,7 +463,7 @@ bool8 IsDma3ManagerBusyWithBgCopy(void)
return FALSE;
}
#else
-ASM_DIRECT
+NAKED
bool8 IsDma3ManagerBusyWithBgCopy(void)
{
asm("push {r4-r7,lr}\n\
@@ -1048,7 +1048,7 @@ void CopyRectToBgTilemapBufferRect(u8 bg, const void* src, u8 srcX, u8 srcY, u8
}
}
}*/
-ASM_DIRECT
+NAKED
void CopyRectToBgTilemapBufferRect(u8 bg, const void* src, u8 srcX, u8 srcY, u8 srcWidth, u8 srcHeight, u8 destX, u8 destY, u8 rectWidth, u8 rectHeight, u8 palette1, u16 tileOffset, u16 palette2)
{
asm("push {r4-r7,lr}\n\
@@ -1495,7 +1495,7 @@ void CopyTileMapEntry(u16 *src, u16 *dest, s32 palette1, u32 tileOffset, u32 pal
*dest = test;
}
#else
-ASM_DIRECT
+NAKED
void CopyTileMapEntry(u16 *src, u16 *dest, s32 palette1, u32 tileOffset, u32 palette2)
{
asm("push {r4-r6,lr}\n\
diff --git a/src/bike.c b/src/bike.c
index 782eceb8e..e827707cd 100644
--- a/src/bike.c
+++ b/src/bike.c
@@ -13,7 +13,6 @@
extern bool8 gBikeCyclingChallenge;
extern u8 gBikeCollisions;
-extern u8 sub_8093514(u8 direction);
extern u8 sub_808B980(u8 direction);
extern u8 sub_808B9BC(u8 direction);
extern u8 sub_808B9A4(u8 direction);
diff --git a/src/daycare.c b/src/daycare.c
index d567ff79a..5a6aa2b40 100644
--- a/src/daycare.c
+++ b/src/daycare.c
@@ -1,5 +1,6 @@
#include "global.h"
#include "pokemon.h"
+#include "battle.h"
#include "daycare.h"
#include "string_util.h"
#include "constants/species.h"
@@ -22,8 +23,6 @@
#define EGG_MOVES_ARRAY_COUNT 10
#define EGG_LVL_UP_MOVES_ARRAY_COUNT 50
-extern u16 gMoveToLearn;
-
// text
extern const u8 gText_MaleSymbol4[];
extern const u8 gText_FemaleSymbol4[];
@@ -48,7 +47,7 @@ extern void sub_81B9328(void);
extern void CB2_ReturnToField(void);
// this file's functions
-static void ClearDaycareMonMisc(struct DaycareMiscMon *misc);
+static void ClearDaycareMonMail(struct DayCareMail *mail);
static void SetInitialEggData(struct Pokemon *mon, u16 species, struct DayCare *daycare);
static u8 GetDaycareCompatibilityScore(struct DayCare *daycare);
static void DaycarePrintMonInfo(u8 windowId, s32 daycareSlotId, u8 y);
@@ -180,13 +179,13 @@ static void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycar
{
u8 mailId;
- StringCopy(daycareMon->misc.OT_name, gSaveBlock2Ptr->playerName);
- GetMonNick(mon, daycareMon->misc.monName);
- StripExtCtrlCodes(daycareMon->misc.monName);
- daycareMon->misc.gameLanguage = LANGUAGE_ENGLISH;
- daycareMon->misc.monLanguage = GetMonData(mon, MON_DATA_LANGUAGE);
+ StringCopy(daycareMon->mail.OT_name, gSaveBlock2Ptr->playerName);
+ GetMonNick(mon, daycareMon->mail.monName);
+ StripExtCtrlCodes(daycareMon->mail.monName);
+ daycareMon->mail.gameLanguage = LANGUAGE_ENGLISH;
+ daycareMon->mail.monLanguage = GetMonData(mon, MON_DATA_LANGUAGE);
mailId = GetMonData(mon, MON_DATA_MAIL);
- daycareMon->misc.mail = gSaveBlock1Ptr->mail[mailId];
+ daycareMon->mail.message = gSaveBlock1Ptr->mail[mailId];
TakeMailFromMon(mon);
}
@@ -220,10 +219,10 @@ static void ShiftDaycareSlots(struct DayCare *daycare)
daycare->mons[0].mon = daycare->mons[1].mon;
ZeroBoxMonData(&daycare->mons[1].mon);
- daycare->mons[0].misc = daycare->mons[1].misc;
+ daycare->mons[0].mail = daycare->mons[1].mail;
daycare->mons[0].steps = daycare->mons[1].steps;
daycare->mons[1].steps = 0;
- ClearDaycareMonMisc(&daycare->mons[1].misc);
+ ClearDaycareMonMail(&daycare->mons[1].mail);
}
}
@@ -278,10 +277,10 @@ static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon)
}
gPlayerParty[PARTY_SIZE - 1] = pokemon;
- if (daycareMon->misc.mail.itemId)
+ if (daycareMon->mail.message.itemId)
{
- GiveMailToMon2(&gPlayerParty[PARTY_SIZE - 1], &daycareMon->misc.mail);
- ClearDaycareMonMisc(&daycareMon->misc);
+ GiveMailToMon2(&gPlayerParty[PARTY_SIZE - 1], &daycareMon->mail.message);
+ ClearDaycareMonMail(&daycareMon->mail);
}
ZeroBoxMonData(&daycareMon->mon);
@@ -365,23 +364,23 @@ u8 GetNumLevelsGainedFromDaycare(void)
return 0;
}
-static void ClearDaycareMonMisc(struct DaycareMiscMon *misc)
+static void ClearDaycareMonMail(struct DayCareMail *mail)
{
s32 i;
for (i = 0; i < OT_NAME_LENGTH + 1; i++)
- misc->OT_name[i] = 0;
+ mail->OT_name[i] = 0;
for (i = 0; i < POKEMON_NAME_LENGTH + 1; i++)
- misc->monName[i] = 0;
+ mail->monName[i] = 0;
- ClearMailStruct(&misc->mail);
+ ClearMailStruct(&mail->message);
}
static void ClearDaycareMon(struct DaycareMon *daycareMon)
{
ZeroBoxMonData(&daycareMon->mon);
daycareMon->steps = 0;
- ClearDaycareMonMisc(&daycareMon->misc);
+ ClearDaycareMonMail(&daycareMon->mail);
}
static void ClearAllDaycareData(struct DayCare *daycare)
diff --git a/src/decompress.c b/src/decompress.c
index fb288bf4a..83a9db0b6 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -117,7 +117,7 @@ void Unused_LZDecompressWramIndirect(const void **src, void *dest)
}
// This one (unused) function is really challenging, won't even try to decompile it.
-ASM_DIRECT
+NAKED
void sub_803471C()
{
asm(".syntax unified\n\
@@ -459,7 +459,7 @@ _08034964:\n\
.syntax divided");
}
-u32 sub_8034974(const u8 *ptr)
+u32 GetDecompressedDataSize(const u8 *ptr)
{
return (ptr[3] << 16) | (ptr[2] << 8) | (ptr[1]);
}
diff --git a/src/decoration.c b/src/decoration.c
index f376c2115..08287a3cc 100644
--- a/src/decoration.c
+++ b/src/decoration.c
@@ -21,7 +21,6 @@
#include "list_menu.h"
#include "menu_helpers.h"
#include "menu.h"
-#include "menu_indicators.h"
#include "sound.h"
#include "event_scripts.h"
#include "event_data.h"
@@ -38,8 +37,6 @@
#include "decoration.h"
#include "graphics.h"
-extern void (*gFieldCallback)(void);
-
// Static type declarations
#define OVERWORLD_PLACE_DECOR_SELECTOR_PAL_TAG 0xbe5
@@ -1294,7 +1291,7 @@ void sub_8128060(u8 taskId)
gTasks[taskId].data[2] = 2;
break;
case 2:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
gTasks[taskId].data[12] = 0;
sub_8128FD8(taskId);
@@ -1710,7 +1707,7 @@ void sub_8128C64(u8 taskId)
data[2] ++;
break;
case 3:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
gTasks[taskId].func = sub_812764C;
}
@@ -2220,7 +2217,7 @@ void sub_81298EC(u8 taskId)
gTasks[taskId].data[2] = 3;
break;
case 3:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
StringExpandPlaceholders(gStringVar4, gText_DecorationReturnedToPC);
DisplayItemMessageOnField(taskId, gStringVar4, sub_8129D64);
@@ -2290,7 +2287,7 @@ void sub_8129ABC(u8 taskId)
data[2] = 2;
break;
case 2:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
data[12] = 1;
sub_8129B34(taskId);
@@ -2616,7 +2613,7 @@ void sub_812A2C4(u8 taskId)
data[2] ++;
break;
case 3:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
gTasks[taskId].func = sub_8126B80;
}
diff --git a/src/dewford_trend.c b/src/dewford_trend.c
index 3ceec6563..44b42c123 100644
--- a/src/dewford_trend.c
+++ b/src/dewford_trend.c
@@ -158,7 +158,7 @@ static void sub_8122804(struct EasyChatPair *s, u16 b, u8 c)
}
}
-void sub_812287C(void *a, u32 b, u8 unused)
+void ReceiveEasyChatPairsData(void *a, u32 b, u8 unused)
{
u16 i, j, r3, players;
struct EasyChatPair *buffer1, *buffer2, *src, *dst, *foo_of_buffer2;
diff --git a/src/egg_hatch.c b/src/egg_hatch.c
index e64a98ab1..1ed38c67e 100644
--- a/src/egg_hatch.c
+++ b/src/egg_hatch.c
@@ -25,6 +25,7 @@
#include "window.h"
#include "constants/abilities.h"
#include "daycare.h"
+#include "overworld.h"
#include "battle.h" // to get rid of later
struct EggHatchData
@@ -44,8 +45,6 @@ struct EggHatchData
u8 textColor[3];
};
-extern void (*gFieldCallback)(void);
-
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
extern const u8 gBattleTextboxTiles[];
extern const u8 gBattleTextboxTilemap[];
@@ -391,13 +390,13 @@ static bool8 sub_807158C(struct DayCare *daycare, u8 daycareId)
struct DaycareMon *daycareMon = &daycare->mons[daycareId];
GetBoxMonNick(&daycareMon->mon, nick);
- if (daycareMon->misc.mail.itemId != 0
- && (StringCompareWithoutExtCtrlCodes(nick, daycareMon->misc.monName) != 0
- || StringCompareWithoutExtCtrlCodes(gSaveBlock2Ptr->playerName, daycareMon->misc.OT_name) != 0))
+ if (daycareMon->mail.message.itemId != 0
+ && (StringCompareWithoutExtCtrlCodes(nick, daycareMon->mail.monName) != 0
+ || StringCompareWithoutExtCtrlCodes(gSaveBlock2Ptr->playerName, daycareMon->mail.OT_name) != 0))
{
StringCopy(gStringVar1, nick);
- TVShowConvertInternationalString(gStringVar2, daycareMon->misc.OT_name, daycareMon->misc.gameLanguage);
- TVShowConvertInternationalString(gStringVar3, daycareMon->misc.monName, daycareMon->misc.monLanguage);
+ TVShowConvertInternationalString(gStringVar2, daycareMon->mail.OT_name, daycareMon->mail.gameLanguage);
+ TVShowConvertInternationalString(gStringVar3, daycareMon->mail.monName, daycareMon->mail.monLanguage);
return TRUE;
}
return FALSE;
@@ -575,10 +574,10 @@ static void Task_EggHatchPlayBGM(u8 taskID)
play_some_sound();
}
if (gTasks[taskID].data[0] == 1)
- PlayBGM(376);
+ PlayBGM(MUS_ME_SHINKA);
if (gTasks[taskID].data[0] > 60)
{
- PlayBGM(377);
+ PlayBGM(MUS_SHINKA);
DestroyTask(taskID);
// UB: task is destroyed, yet the value is incremented
}
diff --git a/src/field_effect.c b/src/field_effect.c
index 628dc776a..692090779 100644
--- a/src/field_effect.c
+++ b/src/field_effect.c
@@ -1,15 +1,3897 @@
// Includes
#include "global.h"
+#include "field_effect.h"
+#include "battle_dome_cards.h"
+#include "decompress.h"
+#include "field_camera.h"
+#include "field_effect_helpers.h"
+#include "field_map_obj.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "field_screen.h"
+#include "field_weather.h"
+#include "fieldmap.h"
+#include "fldeff_groundshake.h"
+#include "gpu_regs.h"
+#include "main.h"
+#include "menu.h"
+#include "metatile_behavior.h"
+#include "overworld.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "pokemon.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+#include "trig.h"
+#include "util.h"
+#include "constants/rgb.h"
+#include "constants/songs.h"
+
+#define subsprite_table(ptr) {.subsprites = ptr, .subspriteCount = (sizeof ptr) / (sizeof(struct Subsprite))}
+
+EWRAM_DATA s32 gFieldEffectArguments[8] = {0};
// Static type declarations
// Static RAM declarations
-IWRAM_DATA u8 gUnknown_03000F58[32];
+static IWRAM_DATA u8 sActiveList[32];
// Static ROM declarations
+extern u8 *gFieldEffectScriptPointers[];
+
// .rodata
+const u32 gNewGameBirchPic[] = INCBIN_U32("graphics/birch_speech/birch.4bpp");
+const u32 gUnusedBirchBeauty[] = INCBIN_U32("graphics/unused/intro_birch_beauty.4bpp");
+const u16 gNewGameBirchPalette[16] = INCBIN_U16("graphics/birch_speech/birch.gbapal");
+const u32 gSpriteImage_855A970[] = INCBIN_U32("graphics/misc/pokeball_glow.4bpp");
+const u16 gFieldEffectObjectPalette4[16] = INCBIN_U16("graphics/map_objects/palettes/field_effect_object_palette_04.gbapal");
+const u32 gSpriteImage_855A9B0[] = INCBIN_U32("graphics/misc/pokecenter_monitor/0.4bpp");
+const u32 gSpriteImage_855AA70[] = INCBIN_U32("graphics/misc/pokecenter_monitor/1.4bpp");
+const u32 gSpriteImage_855AB30[] = INCBIN_U32("graphics/misc/big_hof_monitor.4bpp");
+const u8 gSpriteImage_855AD30[] = INCBIN_U8("graphics/misc/small_hof_monitor.4bpp");
+const u16 gFieldEffectObjectPalette5[16] = INCBIN_U16("graphics/map_objects/palettes/field_effect_object_palette_05.gbapal");
+
+// Graphics for the lights streaking past your Pokemon when it uses a field move.
+const u32 gFieldMoveStreaksTiles[] = INCBIN_U32("graphics/misc/field_move_streaks.4bpp");
+const u16 gFieldMoveStreaksPalette[16] = INCBIN_U16("graphics/misc/field_move_streaks.gbapal");
+const u16 gFieldMoveStreaksTilemap[] = INCBIN_U16("graphics/misc/field_move_streaks_map.bin");
+
+// The following light streaks effect is used when the map is dark (e.g. a cave).
+const u32 gDarknessFieldMoveStreaksTiles[] = INCBIN_U32("graphics/misc/darkness_field_move_streaks.4bpp");
+const u16 gDarknessFieldMoveStreaksPalette[16] = INCBIN_U16("graphics/misc/darkness_field_move_streaks.gbapal");
+const u16 gDarknessFieldMoveStreaksTilemap[] = INCBIN_U16("graphics/misc/darkness_field_move_streaks_map.bin");
+
+const u16 gUnknown_0855B610[16] = INCBIN_U16("graphics/misc/spotlight.gbapal");
+const u8 gUnknown_0855B630[] = INCBIN_U8("graphics/misc/spotlight.4bpp");
+const u8 gUnknown_0855C170[] = INCBIN_U8("graphics/unknown/unknown_55C170.4bpp");
+const u8 gUnknown_0855C190[] = INCBIN_U8("graphics/unknown/unknown_55C190.4bpp");
+const u8 gUnknown_0855C1B0[] = INCBIN_U8("graphics/unknown/unknown_55C1B0.4bpp");
+const u8 gUnknown_0855C1D0[] = INCBIN_U8("graphics/unknown/unknown_55C1D0.4bpp");
+
+bool8 (*const gFieldEffectScriptFuncs[])(u8 **, u32 *) = {
+ FieldEffectCmd_loadtiles,
+ FieldEffectCmd_loadfadedpal,
+ FieldEffectCmd_loadpal,
+ FieldEffectCmd_callnative,
+ FieldEffectCmd_end,
+ FieldEffectCmd_loadgfx_callnative,
+ FieldEffectCmd_loadtiles_callnative,
+ FieldEffectCmd_loadfadedpal_callnative,
+};
+
+const struct OamData gNewGameBirchOamAttributes = {.size = 3};
+const struct OamData gOamData_855C218 = {.size = 0};
+const struct OamData gOamData_855C220 = {.size = 1};
+
+const struct SpriteFrameImage gNewGameBirchPicTable[] = {
+ obj_frame_tiles(gNewGameBirchPic)
+};
+const struct SpritePalette gNewGameBirchObjectPaletteInfo = {.data = gNewGameBirchPalette, .tag = 0x1006};
+
+const union AnimCmd gNewGameBirchImageAnim[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 1),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gNewGameBirchImageAnimTable[] = {
+ gNewGameBirchImageAnim
+};
+
+const struct SpriteTemplate gNewGameBirchObjectTemplate = {
+ .tileTag = 0xffff,
+ .paletteTag = 4102,
+ .oam = &gNewGameBirchOamAttributes,
+ .anims = gNewGameBirchImageAnimTable,
+ .images = gNewGameBirchPicTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+};
+
+const struct SpritePalette gFieldEffectObjectPaletteInfo4 = {.data = gFieldEffectObjectPalette4, .tag = 0x1007};
+const struct SpritePalette gFieldEffectObjectPaletteInfo5 = {.data = gFieldEffectObjectPalette5, .tag = 0x1010};
+const struct OamData gOamData_855C26C = {
+ .shape = 1,
+ .size = 2
+};
+
+const struct SpriteFrameImage gSpriteImageTable_855C274[] = {
+ obj_frame_tiles(gSpriteImage_855A970)
+};
+
+const struct SpriteFrameImage gSpriteImageTable_855C27C[] = {
+ obj_frame_tiles(gSpriteImage_855A9B0),
+ obj_frame_tiles(gSpriteImage_855AA70)
+};
+
+const struct SpriteFrameImage gSpriteImageTable_855C28C[] = {
+ obj_frame_tiles(gSpriteImage_855AB30)
+};
+
+const struct SpriteFrameImage gSpriteImageTable_855C294[] = {
+ {.data = gSpriteImage_855AD30, .size = 0x200} // the macro breaks down here
+};
+
+const struct Subsprite gSubspriteTable_855C29C[] = {
+ {.x = -12, .y = -8, .priority = 2, .tileOffset = 0, .shape = 1, .size = 0},
+ {.x = 4, .y = -8, .priority = 2, .tileOffset = 2, .shape = 0, .size = 0},
+ {.x = -12, .y = 0, .priority = 2, .tileOffset = 3, .shape = 1, .size = 0},
+ {.x = 4, .y = 0, .priority = 2, .tileOffset = 5, .shape = 0, .size = 0}
+};
+
+const struct SubspriteTable gUnknown_0855C2AC = subsprite_table(gSubspriteTable_855C29C);
+
+const struct Subsprite gSubspriteTable_855C2B4[] = {
+ {.x = -32, .y = -8, .priority = 2, .tileOffset = 0, .shape = 1, .size = 1},
+ {.x = 0, .y = -8, .priority = 2, .tileOffset = 4, .shape = 1, .size = 1},
+ {.x = -32, .y = 0, .priority = 2, .tileOffset = 8, .shape = 1, .size = 1},
+ {.x = 0, .y = 0, .priority = 2, .tileOffset = 12, .shape = 1, .size = 1}
+};
+
+const struct SubspriteTable gUnknown_0855C2C4 = subsprite_table(gSubspriteTable_855C2B4);
+
+const union AnimCmd gSpriteAnim_855C2CC[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 1),
+ ANIMCMD_JUMP(0)
+};
+
+const union AnimCmd gSpriteAnim_855C2D4[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gSpriteAnimTable_855C2F8[] = {
+ gSpriteAnim_855C2CC,
+ gSpriteAnim_855C2D4
+};
+
+const union AnimCmd *const gSpriteAnimTable_855C300[] = {
+ gSpriteAnim_855C2CC
+};
+
+const struct SpriteTemplate gSpriteTemplate_855C304 = {
+ .tileTag = 0xffff,
+ .paletteTag = 4103,
+ .oam = &gOamData_855C218,
+ .anims = gSpriteAnimTable_855C2F8,
+ .images = gSpriteImageTable_855C274,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_PokeballGlow
+};
+
+const struct SpriteTemplate gSpriteTemplate_855C31C = {
+ .tileTag = 0xffff,
+ .paletteTag = 4100,
+ .oam = &gOamData_855C220,
+ .anims = gSpriteAnimTable_855C2F8,
+ .images = gSpriteImageTable_855C27C,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_PokecenterMonitor
+};
+
+const struct SpriteTemplate gSpriteTemplate_855C334 = {
+ .tileTag = 0xffff,
+ .paletteTag = 4112,
+ .oam = &gOamData_855C220,
+ .anims = gSpriteAnimTable_855C300,
+ .images = gSpriteImageTable_855C28C,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HallOfFameMonitor
+};
+
+const struct SpriteTemplate gSpriteTemplate_855C34C = {
+ .tileTag = 0xffff,
+ .paletteTag = 4112,
+ .oam = &gOamData_855C26C,
+ .anims = gSpriteAnimTable_855C300,
+ .images = gSpriteImageTable_855C294,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HallOfFameMonitor
+};
+
+void (*const gUnknown_0855C364[])(struct Task *) = {
+ PokecenterHealEffect_0,
+ PokecenterHealEffect_1,
+ PokecenterHealEffect_2,
+ PokecenterHealEffect_3
+};
+
+void (*const gUnknown_0855C374[])(struct Task *) = {
+ HallOfFameRecordEffect_0,
+ HallOfFameRecordEffect_1,
+ HallOfFameRecordEffect_2,
+ HallOfFameRecordEffect_3
+};
+
+void (*const gUnknown_0855C384[])(struct Sprite *) = {
+ PokeballGlowEffect_0,
+ PokeballGlowEffect_1,
+ PokeballGlowEffect_2,
+ PokeballGlowEffect_3,
+ PokeballGlowEffect_4,
+ PokeballGlowEffect_5,
+ PokeballGlowEffect_6,
+ PokeballGlowEffect_7
+};
+
+const struct Coords16 gUnknown_0855C3A4[] = {
+ {.x = 0, .y = 0},
+ {.x = 6, .y = 0},
+ {.x = 0, .y = 4},
+ {.x = 6, .y = 4},
+ {.x = 0, .y = 8},
+ {.x = 6, .y = 8}
+};
+
+const u8 gUnknown_0855C3BC[] = {16, 12, 8, 0};
+const u8 gUnknown_0855C3C0[] = {16, 12, 8, 0};
+const u8 gUnknown_0855C3C4[] = { 0, 0, 0, 0};
+
+bool8 (*const gUnknown_0855C3C8[])(struct Task *) = {
+ sub_80B6BCC,
+ sub_80B6C74,
+ sub_80B6C90,
+ sub_80B6D04,
+ sub_80B6DBC,
+ sub_80B6DD8,
+ sub_80B6E18,
+};
+
+bool8 (*const gUnknown_0855C3E4[])(struct Task *) = {
+ sub_80B6EC0,
+ sub_80B6EE0,
+ sub_80B6F50,
+ sub_80B6F74,
+ sub_80B6F84,
+ sub_80B6FA8,
+};
+
+bool8 (*const gUnknown_0855C3FC[])(struct Task *) = {
+ sub_80B7114,
+ sub_80B7190,
+ sub_80B71D0,
+ sub_80B7230,
+ sub_80B7270,
+ sub_80B72D0,
+ sub_80B72F4,
+};
+
+bool8 (*const gUnknown_0855C418[])(struct Task *, struct MapObject *) = {
+ sub_80B73D0,
+ waterfall_1_do_anim_probably,
+ waterfall_2_wait_anim_finish_probably,
+ sub_80B7450,
+ sub_80B7478,
+};
+
+bool8 (*const gUnknown_0855C42C[])(struct Task *) = {
+ dive_1_lock,
+ dive_2_unknown,
+ dive_3_unknown,
+};
+
+bool8 (*const gUnknown_0855C438[])(struct Task *, struct MapObject *, struct Sprite *) = {
+ sub_80B764C,
+ sub_80B7684,
+ sub_80B76B8,
+ sub_80B7704,
+ sub_80B77F8,
+ sub_80B7814,
+};
+
+bool8 (*const gUnknown_0855C450[])(struct Task *, struct MapObject *, struct Sprite *) = {
+ sub_80B78EC,
+ sub_80B791C,
+ sub_80B7968,
+ sub_80B79BC,
+};
+
+bool8 (*const gUnknown_0855C460[])(struct Task *, struct MapObject *, struct Sprite *) = {
+ sub_80B7AE8,
+ sub_80B7B18,
+ sub_80B7B94,
+ sub_80B7BCC,
+ sub_80B7BF4,
+};
+
+void (*const gUnknown_0855C474[])(struct Task *) = {
+ sub_80B7D14,
+ sub_80B7D34,
+};
// .text
+
+u32 FieldEffectStart(u8 id)
+{
+ u8 *script;
+ u32 val;
+
+ FieldEffectActiveListAdd(id);
+
+ script = gFieldEffectScriptPointers[id];
+
+ while (gFieldEffectScriptFuncs[*script](&script, &val))
+ ;
+
+ return val;
+}
+
+bool8 FieldEffectCmd_loadtiles(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadTiles(script);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_loadfadedpal(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadFadedPalette(script);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_loadpal(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadPalette(script);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_callnative(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_CallNative(script, val);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_end(u8 **script, u32 *val)
+{
+ return FALSE;
+}
+
+bool8 FieldEffectCmd_loadgfx_callnative(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadTiles(script);
+ FieldEffectScript_LoadFadedPalette(script);
+ FieldEffectScript_CallNative(script, val);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_loadtiles_callnative(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadTiles(script);
+ FieldEffectScript_CallNative(script, val);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_loadfadedpal_callnative(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadFadedPalette(script);
+ FieldEffectScript_CallNative(script, val);
+ return TRUE;
+}
+
+u32 FieldEffectScript_ReadWord(u8 **script)
+{
+ return (*script)[0]
+ + ((*script)[1] << 8)
+ + ((*script)[2] << 16)
+ + ((*script)[3] << 24);
+}
+
+void FieldEffectScript_LoadTiles(u8 **script)
+{
+ struct SpriteSheet *sheet = (struct SpriteSheet *)FieldEffectScript_ReadWord(script);
+ if (GetSpriteTileStartByTag(sheet->tag) == 0xFFFF)
+ LoadSpriteSheet(sheet);
+ (*script) += 4;
+}
+
+void FieldEffectScript_LoadFadedPalette(u8 **script)
+{
+ struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script);
+ LoadSpritePalette(palette);
+ UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(palette->tag));
+ (*script) += 4;
+}
+
+void FieldEffectScript_LoadPalette(u8 **script)
+{
+ struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script);
+ LoadSpritePalette(palette);
+ (*script) += 4;
+}
+
+void FieldEffectScript_CallNative(u8 **script, u32 *val)
+{
+ u32 (*func)(void) = (u32 (*)(void))FieldEffectScript_ReadWord(script);
+ *val = func();
+ (*script) += 4;
+}
+
+void FieldEffectFreeGraphicsResources(struct Sprite *sprite)
+{
+ u16 sheetTileStart = sprite->sheetTileStart;
+ u32 paletteNum = sprite->oam.paletteNum;
+ DestroySprite(sprite);
+ FieldEffectFreeTilesIfUnused(sheetTileStart);
+ FieldEffectFreePaletteIfUnused(paletteNum);
+}
+
+void FieldEffectStop(struct Sprite *sprite, u8 id)
+{
+ FieldEffectFreeGraphicsResources(sprite);
+ FieldEffectActiveListRemove(id);
+}
+
+void FieldEffectFreeTilesIfUnused(u16 tileStart)
+{
+ u8 i;
+ u16 tag = GetSpriteTileTagByTileStart(tileStart);
+
+ if (tag != 0xFFFF)
+ {
+ for (i = 0; i < MAX_SPRITES; i++)
+ if (gSprites[i].inUse && gSprites[i].usingSheet && tileStart == gSprites[i].sheetTileStart)
+ return;
+ FreeSpriteTilesByTag(tag);
+ }
+}
+
+void FieldEffectFreePaletteIfUnused(u8 paletteNum)
+{
+ u8 i;
+ u16 tag = GetSpritePaletteTagByPaletteNum(paletteNum);
+
+ if (tag != 0xFFFF)
+ {
+ for (i = 0; i < MAX_SPRITES; i++)
+ if (gSprites[i].inUse && gSprites[i].oam.paletteNum == paletteNum)
+ return;
+ FreeSpritePaletteByTag(tag);
+ }
+}
+
+void FieldEffectActiveListClear(void)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
+ sActiveList[i] = 0xFF;
+}
+
+void FieldEffectActiveListAdd(u8 id)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
+ {
+ if (sActiveList[i] == 0xFF)
+ {
+ sActiveList[i] = id;
+ return;
+ }
+ }
+}
+
+void FieldEffectActiveListRemove(u8 id)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
+ {
+ if (sActiveList[i] == id)
+ {
+ sActiveList[i] = 0xFF;
+ return;
+ }
+ }
+}
+
+bool8 FieldEffectActiveListContains(u8 id)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
+ if (sActiveList[i] == id)
+ return TRUE;
+ return FALSE;
+}
+
+u8 CreateTrainerSprite(u8 trainerSpriteID, s16 x, s16 y, u8 subpriority, u8 *buffer)
+{
+ struct SpriteTemplate spriteTemplate;
+ LoadCompressedObjectPaletteOverrideBuffer(&gTrainerFrontPicPaletteTable[trainerSpriteID], buffer);
+ LoadCompressedObjectPicOverrideBuffer(&gTrainerFrontPicTable[trainerSpriteID], buffer);
+ spriteTemplate.tileTag = gTrainerFrontPicTable[trainerSpriteID].tag;
+ spriteTemplate.paletteTag = gTrainerFrontPicPaletteTable[trainerSpriteID].tag;
+ spriteTemplate.oam = &gNewGameBirchOamAttributes;
+ spriteTemplate.anims = gDummySpriteAnimTable;
+ spriteTemplate.images = NULL;
+ spriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
+ spriteTemplate.callback = SpriteCallbackDummy;
+ return CreateSprite(&spriteTemplate, x, y, subpriority);
+}
+
+void LoadTrainerGfx_TrainerCard(u8 gender, u16 palOffset, u8 *dest)
+{
+ LZDecompressVram(gTrainerFrontPicTable[gender].data, dest);
+ LoadCompressedPalette(gTrainerFrontPicPaletteTable[gender].data, palOffset, 0x20);
+}
+
+u8 AddNewGameBirchObject(s16 x, s16 y, u8 subpriority)
+{
+ LoadSpritePalette(&gNewGameBirchObjectPaletteInfo);
+ return CreateSprite(&gNewGameBirchObjectTemplate, x, y, subpriority);
+}
+
+#ifdef NONMATCHING
+u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y)
+{
+ u16 spriteId = sub_818D7D8(species, 0, 0x8000, 1, x, y, 0, gMonPaletteTable[species].tag);
+ PreservePaletteInWeather(IndexOfSpritePaletteTag(gMonPaletteTable[species].tag) + 0x10);
+ if (spriteId == 0xFFFF)
+ return 0x40;
+
+ return spriteId;
+}
+#else
+NAKED
+u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y)
+{
+ asm_unified("push {r4,r5,lr}\n\
+ sub sp, 0x10\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ movs r3, 0x80\n\
+ lsls r3, 8\n\
+ lsls r1, 16\n\
+ asrs r1, 16\n\
+ str r1, [sp]\n\
+ lsls r2, 16\n\
+ asrs r2, 16\n\
+ str r2, [sp, 0x4]\n\
+ movs r1, 0\n\
+ str r1, [sp, 0x8]\n\
+ ldr r1, =gMonPaletteTable\n\
+ lsls r4, r0, 3\n\
+ adds r4, r1\n\
+ ldrh r1, [r4, 0x4]\n\
+ str r1, [sp, 0xC]\n\
+ movs r1, 0\n\
+ adds r2, r3, 0\n\
+ movs r3, 0x1\n\
+ bl sub_818D7D8\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ ldrh r0, [r4, 0x4]\n\
+ bl IndexOfSpritePaletteTag\n\
+ adds r0, 0x10\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ bl PreservePaletteInWeather\n\
+ ldr r0, =0x0000ffff\n\
+ cmp r5, r0\n\
+ beq _080B5FDC\n\
+ lsls r0, r5, 24\n\
+ lsrs r0, 24\n\
+ b _080B5FDE\n\
+ .pool\n\
+_080B5FDC:\n\
+ movs r0, 0x40\n\
+_080B5FDE:\n\
+ add sp, 0x10\n\
+ pop {r4,r5}\n\
+ pop {r1}\n\
+ bx r1");
+}
+#endif //NONMATCHING
+
+u8 CreateMonSprite_FieldMove(u16 species, u32 d, u32 g, s16 x, s16 y, u8 subpriority)
+{
+ const struct CompressedSpritePalette *spritePalette = GetMonSpritePalStructFromOtIdPersonality(species, d, g);
+ u16 spriteId = sub_818D7D8(species, d, g, 1, x, y, 0, spritePalette->tag);
+ PreservePaletteInWeather(IndexOfSpritePaletteTag(spritePalette->tag) + 0x10);
+ if (spriteId == 0xFFFF)
+ return 0x40;
+
+ return spriteId;
+}
+
+void FreeResourcesAndDestroySprite(struct Sprite *sprite, u8 spriteId)
+{
+ ResetPreservedPalettesInWeather();
+ if (sprite->oam.affineMode != 0)
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ }
+ sub_818D820(spriteId);
+}
+
+#ifdef NONMATCHING
+void MultiplyInvertedPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
+{
+ int curRed;
+ int curGreen;
+ int curBlue;
+
+ curRed = gPlttBufferUnfaded[i] & 0x1f;
+ curGreen = (gPlttBufferUnfaded[i] & (0x1f << 5)) >> 5;
+ curBlue = (gPlttBufferUnfaded[i] & (0x1f << 10)) >> 10;
+ curRed += (((0x1f - curRed) * r) >> 4);
+ curGreen += (((0x1f - curGreen) * g) >> 4);
+ curBlue += (((0x1f - curBlue) * b) >> 4);
+ gPlttBufferFaded[i] = RGB(curRed, curGreen, curBlue);
+}
+
+void MultiplyPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
+{
+ int curRed;
+ int curGreen;
+ int curBlue;
+
+ curRed = gPlttBufferUnfaded[i] & 0x1f;
+ curGreen = (gPlttBufferUnfaded[i] & (0x1f << 5)) >> 5;
+ curBlue = (gPlttBufferUnfaded[i] & (0x1f << 10)) >> 10;
+ curRed -= ((curRed * r) >> 4);
+ curGreen -= ((curGreen * g) >> 4);
+ curBlue -= ((curBlue * b) >> 4);
+ gPlttBufferFaded[i] = RGB(curRed, curGreen, curBlue);
+}
+#else
+NAKED
+void MultiplyInvertedPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
+{
+ asm(".syntax unified\n"
+ "\tpush {r4-r7,lr}\n"
+ "\tmov r7, r9\n"
+ "\tmov r6, r8\n"
+ "\tpush {r6,r7}\n"
+ "\tlsls r0, 16\n"
+ "\tlsls r1, 24\n"
+ "\tlsrs r1, 24\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r2, 24\n"
+ "\tlsls r3, 24\n"
+ "\tlsrs r3, 24\n"
+ "\tldr r4, _08085D00 @ =gPlttBufferUnfaded\n"
+ "\tlsrs r0, 15\n"
+ "\tadds r4, r0, r4\n"
+ "\tldrh r4, [r4]\n"
+ "\tmovs r5, 0x1F\n"
+ "\tmov r9, r5\n"
+ "\tmov r8, r4\n"
+ "\tmov r6, r8\n"
+ "\tands r6, r5\n"
+ "\tmov r8, r6\n"
+ "\tmovs r6, 0xF8\n"
+ "\tlsls r6, 2\n"
+ "\tands r6, r4\n"
+ "\tlsrs r6, 5\n"
+ "\tmovs r5, 0xF8\n"
+ "\tlsls r5, 7\n"
+ "\tands r4, r5\n"
+ "\tlsrs r4, 10\n"
+ "\tmov r7, r9\n"
+ "\tmov r5, r8\n"
+ "\tsubs r7, r5\n"
+ "\tmov r12, r7\n"
+ "\tmov r7, r12\n"
+ "\tmuls r7, r1\n"
+ "\tadds r1, r7, 0\n"
+ "\tasrs r1, 4\n"
+ "\tadd r8, r1\n"
+ "\tmov r5, r9\n"
+ "\tsubs r1, r5, r6\n"
+ "\tmuls r1, r2\n"
+ "\tasrs r1, 4\n"
+ "\tadds r6, r1\n"
+ "\tsubs r5, r4\n"
+ "\tmov r9, r5\n"
+ "\tmov r1, r9\n"
+ "\tmuls r1, r3\n"
+ "\tasrs r1, 4\n"
+ "\tadds r4, r1\n"
+ "\tmov r7, r8\n"
+ "\tlsls r7, 16\n"
+ "\tlsls r6, 21\n"
+ "\torrs r6, r7\n"
+ "\tlsls r4, 26\n"
+ "\torrs r4, r6\n"
+ "\tlsrs r4, 16\n"
+ "\tldr r1, _08085D04 @ =gPlttBufferFaded\n"
+ "\tadds r0, r1\n"
+ "\tstrh r4, [r0]\n"
+ "\tpop {r3,r4}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.align 2, 0\n"
+ "_08085D00: .4byte gPlttBufferUnfaded\n"
+ "_08085D04: .4byte gPlttBufferFaded\n"
+ ".syntax divided");
+}
+
+NAKED
+void MultiplyPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
+{
+ asm(".syntax unified\n"
+ "\tpush {r4-r6,lr}\n"
+ "\tmov r6, r8\n"
+ "\tpush {r6}\n"
+ "\tlsls r0, 16\n"
+ "\tlsls r1, 24\n"
+ "\tlsrs r1, 24\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r2, 24\n"
+ "\tlsls r3, 24\n"
+ "\tlsrs r3, 24\n"
+ "\tldr r4, _08085D78 @ =gPlttBufferUnfaded\n"
+ "\tlsrs r0, 15\n"
+ "\tadds r4, r0, r4\n"
+ "\tldrh r4, [r4]\n"
+ "\tmovs r5, 0x1F\n"
+ "\tmov r8, r5\n"
+ "\tmov r6, r8\n"
+ "\tands r6, r4\n"
+ "\tmov r8, r6\n"
+ "\tmovs r5, 0xF8\n"
+ "\tlsls r5, 2\n"
+ "\tands r5, r4\n"
+ "\tlsrs r5, 5\n"
+ "\tmovs r6, 0xF8\n"
+ "\tlsls r6, 7\n"
+ "\tands r4, r6\n"
+ "\tlsrs r4, 10\n"
+ "\tmov r6, r8\n"
+ "\tmuls r6, r1\n"
+ "\tadds r1, r6, 0\n"
+ "\tasrs r1, 4\n"
+ "\tmov r6, r8\n"
+ "\tsubs r6, r1\n"
+ "\tadds r1, r5, 0\n"
+ "\tmuls r1, r2\n"
+ "\tasrs r1, 4\n"
+ "\tsubs r5, r1\n"
+ "\tadds r1, r4, 0\n"
+ "\tmuls r1, r3\n"
+ "\tasrs r1, 4\n"
+ "\tsubs r4, r1\n"
+ "\tlsls r6, 16\n"
+ "\tlsls r5, 21\n"
+ "\torrs r5, r6\n"
+ "\tlsls r4, 26\n"
+ "\torrs r4, r5\n"
+ "\tlsrs r4, 16\n"
+ "\tldr r1, _08085D7C @ =gPlttBufferFaded\n"
+ "\tadds r0, r1\n"
+ "\tstrh r4, [r0]\n"
+ "\tpop {r3}\n"
+ "\tmov r8, r3\n"
+ "\tpop {r4-r6}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.align 2, 0\n"
+ "_08085D78: .4byte gPlttBufferUnfaded\n"
+ "_08085D7C: .4byte gPlttBufferFaded\n"
+ ".syntax divided");
+}
+#endif
+
+void Task_PokecenterHeal(u8 taskId);
+u8 CreatePokeballGlowSprite(s16, s16, s16, u16);
+u8 PokecenterHealEffectHelper(s16, s16);
+
+bool8 FldEff_PokecenterHeal(void)
+{
+ u8 nPokemon;
+ struct Task *task;
+
+ nPokemon = CalculatePlayerPartyCount();
+ task = &gTasks[CreateTask(Task_PokecenterHeal, 0xff)];
+ task->data[1] = nPokemon;
+ task->data[2] = 0x5d;
+ task->data[3] = 0x24;
+ task->data[4] = 0x7c;
+ task->data[5] = 0x18;
+ return FALSE;
+}
+
+void Task_PokecenterHeal(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ gUnknown_0855C364[task->data[0]](task);
+}
+
+void PokecenterHealEffect_0(struct Task *task)
+{
+ task->data[0]++;
+ task->data[6] = CreatePokeballGlowSprite(task->data[1], task->data[2], task->data[3], 1);
+ task->data[7] = PokecenterHealEffectHelper(task->data[4], task->data[5]);
+}
+
+void PokecenterHealEffect_1(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 1)
+ {
+ gSprites[task->data[7]].data[0]++;
+ task->data[0]++;
+ }
+}
+
+void PokecenterHealEffect_2(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 4)
+ {
+ task->data[0]++;
+ }
+}
+
+void PokecenterHealEffect_3(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 6)
+ {
+ DestroySprite(&gSprites[task->data[6]]);
+ FieldEffectActiveListRemove(FLDEFF_POKECENTER_HEAL);
+ DestroyTask(FindTaskIdByFunc(Task_PokecenterHeal));
+ }
+}
+
+void Task_HallOfFameRecord(u8 taskId);
+void HallOfFameRecordEffectHelper(s16, s16, s16, u8);
+
+bool8 FldEff_HallOfFameRecord(void)
+{
+ u8 nPokemon;
+ struct Task *task;
+
+ nPokemon = CalculatePlayerPartyCount();
+ task = &gTasks[CreateTask(Task_HallOfFameRecord, 0xff)];
+ task->data[1] = nPokemon;
+ task->data[2] = 0x75;
+ task->data[3] = 0x34;
+ return FALSE;
+}
+
+void Task_HallOfFameRecord(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ gUnknown_0855C374[task->data[0]](task);
+}
+
+void HallOfFameRecordEffect_0(struct Task *task)
+{
+ u8 taskId;
+ task->data[0]++;
+ task->data[6] = CreatePokeballGlowSprite(task->data[1], task->data[2], task->data[3], 0);
+ taskId = FindTaskIdByFunc(Task_HallOfFameRecord);
+ HallOfFameRecordEffectHelper(taskId, 0x78, 0x18, 0);
+ HallOfFameRecordEffectHelper(taskId, 0x28, 0x08, 1);
+ HallOfFameRecordEffectHelper(taskId, 0x48, 0x08, 1);
+ HallOfFameRecordEffectHelper(taskId, 0xa8, 0x08, 1);
+ HallOfFameRecordEffectHelper(taskId, 0xc8, 0x08, 1);
+}
+
+void HallOfFameRecordEffect_1(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 1)
+ {
+ task->data[15]++; // was this ever initialized? is this ever used?
+ task->data[0]++;
+ }
+}
+
+void HallOfFameRecordEffect_2(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 4)
+ {
+ task->data[0]++;
+ }
+}
+
+void HallOfFameRecordEffect_3(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 6)
+ {
+ DestroySprite(&gSprites[task->data[6]]);
+ FieldEffectActiveListRemove(FLDEFF_HALL_OF_FAME_RECORD);
+ DestroyTask(FindTaskIdByFunc(Task_HallOfFameRecord));
+ }
+}
+
+void SpriteCB_PokeballGlowEffect(struct Sprite *);
+
+u8 CreatePokeballGlowSprite(s16 data6, s16 x, s16 y, u16 data5)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+ spriteId = CreateInvisibleSprite(SpriteCB_PokeballGlowEffect);
+ sprite = &gSprites[spriteId];
+ sprite->pos2.x = x;
+ sprite->pos2.y = y;
+ sprite->data[5] = data5;
+ sprite->data[6] = data6;
+ sprite->data[7] = spriteId;
+ return spriteId;
+}
+
+void SpriteCB_PokeballGlowEffect(struct Sprite *sprite)
+{
+ gUnknown_0855C384[sprite->data[0]](sprite);
+}
+
+void PokeballGlowEffect_0(struct Sprite *sprite)
+{
+ u8 endSpriteId;
+ if (sprite->data[1] == 0 || (--sprite->data[1]) == 0)
+ {
+ sprite->data[1] = 25;
+ endSpriteId = CreateSpriteAtEnd(&gSpriteTemplate_855C304, gUnknown_0855C3A4[sprite->data[2]].x + sprite->pos2.x, gUnknown_0855C3A4[sprite->data[2]].y + sprite->pos2.y, 0);
+ gSprites[endSpriteId].oam.priority = 2;
+ gSprites[endSpriteId].data[0] = sprite->data[7];
+ sprite->data[2]++;
+ sprite->data[6]--;
+ PlaySE(SE_BOWA);
+ }
+ if (sprite->data[6] == 0)
+ {
+ sprite->data[1] = 32;
+ sprite->data[0]++;
+ }
+}
+
+void PokeballGlowEffect_1(struct Sprite *sprite)
+{
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->data[0]++;
+ sprite->data[1] = 8;
+ sprite->data[2] = 0;
+ sprite->data[3] = 0;
+ if (sprite->data[5])
+ {
+ PlayFanfare(MUS_ME_ASA);
+ }
+ }
+}
+
+void PokeballGlowEffect_2(struct Sprite *sprite)
+{
+ u8 phase;
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->data[1] = 8;
+ sprite->data[2]++;
+ sprite->data[2] &= 3;
+ if (sprite->data[2] == 0)
+ {
+ sprite->data[3]++;
+ }
+ }
+ phase = (sprite->data[2] + 3) & 3;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x108, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ phase = (sprite->data[2] + 2) & 3;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x106, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ phase = (sprite->data[2] + 1) & 3;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x102, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ phase = sprite->data[2];
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x105, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x103, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ if (sprite->data[3] > 2)
+ {
+ sprite->data[0]++;
+ sprite->data[1] = 8;
+ sprite->data[2] = 0;
+ }
+}
+
+void PokeballGlowEffect_3(struct Sprite *sprite)
+{
+ u8 phase;
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->data[1] = 8;
+ sprite->data[2]++;
+ sprite->data[2] &= 3;
+ if (sprite->data[2] == 3)
+ {
+ sprite->data[0]++;
+ sprite->data[1] = 30;
+ }
+ }
+ phase = sprite->data[2];
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x108, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x106, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x102, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x105, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x103, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+}
+
+void PokeballGlowEffect_4(struct Sprite *sprite)
+{
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->data[0]++;
+ }
+}
+
+void PokeballGlowEffect_5(struct Sprite *sprite)
+{
+ sprite->data[0]++;
+}
+
+void PokeballGlowEffect_6(struct Sprite *sprite)
+{
+ if (sprite->data[5] == 0 || IsFanfareTaskInactive())
+ {
+ sprite->data[0]++;
+ }
+}
+
+void PokeballGlowEffect_7(struct Sprite *sprite)
+{
+}
+
+void SpriteCB_PokeballGlow(struct Sprite *sprite)
+{
+ if (gSprites[sprite->data[0]].data[0] > 4)
+ {
+ FieldEffectFreeGraphicsResources(sprite);
+ }
+}
+
+u8 PokecenterHealEffectHelper(s16 x, s16 y)
+{
+ u8 spriteIdAtEnd;
+ struct Sprite *sprite;
+ spriteIdAtEnd = CreateSpriteAtEnd(&gSpriteTemplate_855C31C, x, y, 0);
+ sprite = &gSprites[spriteIdAtEnd];
+ sprite->oam.priority = 2;
+ sprite->invisible = 1;
+ SetSubspriteTables(sprite, &gUnknown_0855C2AC);
+ return spriteIdAtEnd;
+}
+
+void SpriteCB_PokecenterMonitor(struct Sprite *sprite)
+{
+ if (sprite->data[0] != 0)
+ {
+ sprite->data[0] = 0;
+ sprite->invisible = 0;
+ StartSpriteAnim(sprite, 1);
+ }
+ if (sprite->animEnded)
+ {
+ FieldEffectFreeGraphicsResources(sprite);
+ }
+}
+
+void HallOfFameRecordEffectHelper(s16 a0, s16 a1, s16 a2, u8 a3)
+{
+ u8 spriteIdAtEnd;
+ if (!a3)
+ {
+ spriteIdAtEnd = CreateSpriteAtEnd(&gSpriteTemplate_855C334, a1, a2, 0);
+ SetSubspriteTables(&gSprites[spriteIdAtEnd], &gUnknown_0855C2C4);
+ } else
+ {
+ spriteIdAtEnd = CreateSpriteAtEnd(&gSpriteTemplate_855C34C, a1, a2, 0);
+ }
+ gSprites[spriteIdAtEnd].invisible = 1;
+ gSprites[spriteIdAtEnd].data[0] = a0;
+}
+
+void SpriteCB_HallOfFameMonitor(struct Sprite *sprite)
+{
+ if (gTasks[sprite->data[0]].data[15])
+ {
+ if (sprite->data[1] == 0 || (--sprite->data[1]) == 0)
+ {
+ sprite->data[1] = 16;
+ sprite->invisible ^= 1;
+ }
+ sprite->data[2]++;
+ }
+ if (sprite->data[2] > 127)
+ {
+ FieldEffectFreeGraphicsResources(sprite);
+ }
+}
+
+void mapldr_080842E8(void);
+void mapldr_08084390(void);
+void task00_8084310(u8);
+void c3_080843F8(u8);
+
+void sub_80B69DC(void)
+{
+ SetMainCallback2(CB2_ReturnToField);
+ gFieldCallback = mapldr_080842E8;
+}
+
+void mapldr_080842E8(void)
+{
+ pal_fill_black();
+ CreateTask(task00_8084310, 0);
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+}
+
+void task00_8084310(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ if (!task->data[0])
+ {
+ if (!IsWeatherNotFadingIn())
+ {
+ return;
+ }
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
+ if ((int)gFieldEffectArguments[0] > 5)
+ {
+ gFieldEffectArguments[0] = 0;
+ }
+ FieldEffectStart(FLDEFF_USE_FLY);
+ task->data[0]++;
+ }
+ if (!FieldEffectActiveListContains(FLDEFF_USE_FLY))
+ {
+ Overworld_ResetStateAfterFly();
+ warp_in();
+ SetMainCallback2(CB2_LoadMap);
+ gFieldCallback = mapldr_08084390;
+ DestroyTask(taskId);
+ }
+}
+
+void mapldr_08084390(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_black();
+ CreateTask(c3_080843F8, 0);
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ if (gPlayerAvatar.flags & 0x08)
+ {
+ FieldObjectTurn(&gMapObjects[gPlayerAvatar.mapObjectId], DIR_WEST);
+ }
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+}
+
+void c3_080843F8(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ if (task->data[0] == 0)
+ {
+ if (gPaletteFade.active)
+ {
+ return;
+ }
+ FieldEffectStart(FLDEFF_FLY_IN);
+ task->data[0]++;
+ }
+ if (!FieldEffectActiveListContains(FLDEFF_FLY_IN))
+ {
+ ScriptContext2_Disable();
+ UnfreezeMapObjects();
+ DestroyTask(taskId);
+ }
+}
+
+extern void pal_fill_for_maplights(void);
+void sub_80B6B94(u8);
+extern void CameraObjectReset2(void);
+extern void CameraObjectReset1(void);
+
+void sub_80B6B68(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ CreateTask(sub_80B6B94, 0);
+ gFieldCallback = NULL;
+}
+
+void sub_80B6B94(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ while (gUnknown_0855C3C8[task->data[0]](task)); // return code signifies whether to continue blocking here
+}
+
+bool8 sub_80B6BCC(struct Task *task) // gUnknown_0855C3C8[0]
+{
+ struct MapObject *playerObject;
+ struct Sprite *playerSprite;
+ playerObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ playerSprite = &gSprites[gPlayerAvatar.spriteId];
+ CameraObjectReset2();
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ gPlayerAvatar.preventStep = TRUE;
+ FieldObjectSetSpecialAnim(playerObject, GetFaceDirectionAnimId(player_get_direction_lower_nybble()));
+ task->data[4] = playerSprite->subspriteMode;
+ playerObject->mapobj_bit_26 = 1;
+ playerSprite->oam.priority = 1;
+ playerSprite->subspriteMode = 2;
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B6C74(struct Task *task) // gUnknown_0855C3C8[1]
+{
+ if (IsWeatherNotFadingIn())
+ {
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6C90(struct Task *task) // gUnknown_0855C3C8[2]
+{
+ struct Sprite *sprite;
+ s16 centerToCornerVecY;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ centerToCornerVecY = -(sprite->centerToCornerVecY << 1);
+ sprite->pos2.y = -(sprite->pos1.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY + centerToCornerVecY);
+ task->data[1] = 1;
+ task->data[2] = 0;
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 0;
+ PlaySE(SE_RU_HYUU);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B6D04(struct Task *task)
+{
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.y += task->data[1];
+ if (task->data[1] < 8)
+ {
+ task->data[2] += task->data[1];
+ if (task->data[2] & 0xf)
+ {
+ task->data[1] <<= 1;
+ }
+ }
+ if (task->data[3] == 0 && sprite->pos2.y >= -16)
+ {
+ task->data[3]++;
+ mapObject->mapobj_bit_26 = 0;
+ sprite->subspriteMode = task->data[4];
+ mapObject->mapobj_bit_2 = 1;
+ }
+ if (sprite->pos2.y >= 0)
+ {
+ PlaySE(SE_W070);
+ mapObject->mapobj_bit_3 = 1;
+ mapObject->mapobj_bit_5 = 1;
+ sprite->pos2.y = 0;
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6DBC(struct Task *task)
+{
+ task->data[0]++;
+ task->data[1] = 4;
+ task->data[2] = 0;
+ SetCameraPanningCallback(NULL);
+ return TRUE;
+}
+
+bool8 sub_80B6DD8(struct Task *task)
+{
+ SetCameraPanning(0, task->data[1]);
+ task->data[1] = -task->data[1];
+ task->data[2]++;
+ if ((task->data[2] & 3) == 0)
+ {
+ task->data[1] >>= 1;
+ }
+ if (task->data[1] == 0)
+ {
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6E18(struct Task *task)
+{
+ gPlayerAvatar.preventStep = FALSE;
+ ScriptContext2_Disable();
+ CameraObjectReset1();
+ UnfreezeMapObjects();
+ InstallCameraPanAheadCallback();
+ DestroyTask(FindTaskIdByFunc(sub_80B6B94));
+ return FALSE;
+}
+
+void sub_80B6E88(u8);
+extern void sub_80E1558(u8);
+extern void sub_80AF0B4(void);
+
+void sub_80B6FB8(struct Task *);
+void sub_80B7004(struct Task *);
+void sub_80B7050(void);
+void sub_80B7060(void);
+bool8 sub_80859A0(void);
+void sub_80B70B4(void);
+void sub_80E1570(void);
+void sub_80B70DC(u8);
+
+void sub_80B6E4C(u8 a0, u8 priority)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_80B6E88, priority);
+ gTasks[taskId].data[1] = 0;
+ if (a0 == 0x6a)
+ {
+ gTasks[taskId].data[1] = 1;
+ }
+}
+
+void sub_80B6E88(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ while (gUnknown_0855C3E4[task->data[0]](task));
+}
+
+bool8 sub_80B6EC0(struct Task *task)
+{
+ FreezeMapObjects();
+ CameraObjectReset2();
+ sub_80E1558(task->data[1]);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B6EE0(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(player_get_direction_lower_nybble()));
+ task->data[0]++;
+ task->data[2] = 0;
+ task->data[3] = 0;
+ if ((u8)task->data[1] == 0)
+ {
+ task->data[0] = 4;
+ }
+ PlaySE(SE_ESUKA);
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6F50(struct Task *task)
+{
+ sub_80B6FB8(task);
+ if (task->data[2] > 3)
+ {
+ sub_80B7050();
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6F74(struct Task *task)
+{
+ sub_80B6FB8(task);
+ sub_80B7060();
+ return FALSE;
+}
+
+bool8 sub_80B6F84(struct Task *task)
+{
+ sub_80B7004(task);
+ if (task->data[2] > 3)
+ {
+ sub_80B7050();
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6FA8(struct Task *task)
+{
+ sub_80B7004(task);
+ sub_80B7060();
+ return FALSE;
+}
+
+void sub_80B6FB8(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x84, task->data[2]);
+ sprite->pos2.y = Sin(0x94, task->data[2]);
+ task->data[3]++;
+ if (task->data[3] & 1)
+ {
+ task->data[2]++;
+ }
+}
+
+void sub_80B7004(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x7c, task->data[2]);
+ sprite->pos2.y = Sin(0x76, task->data[2]);
+ task->data[3]++;
+ if (task->data[3] & 1)
+ {
+ task->data[2]++;
+ }
+}
+
+void sub_80B7050(void)
+{
+ music_something();
+ sub_80AF0B4();
+}
+
+void sub_80B7060(void)
+{
+ if (!gPaletteFade.active && sub_80859A0() == TRUE)
+ {
+ sub_80E1570();
+ warp_in();
+ gFieldCallback = sub_80B70B4;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80B6E88));
+ }
+}
+
+void sub_80B70B4(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ CreateTask(sub_80B70DC, 0);
+ gFieldCallback = NULL;
+}
+
+void sub_80B70DC(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ while (gUnknown_0855C3FC[task->data[0]](task));
+}
+
+bool8 sub_80B7114(struct Task *task)
+{
+ struct MapObject *mapObject;
+ s16 x;
+ s16 y;
+ u8 behavior;
+ CameraObjectReset2();
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(DIR_EAST));
+ PlayerGetDestCoords(&x, &y);
+ behavior = MapGridGetMetatileBehaviorAt(x, y);
+ task->data[0]++;
+ task->data[1] = 16;
+ if (behavior == 0x6b)
+ {
+ behavior = 1;
+ task->data[0] = 3;
+ } else
+ {
+ behavior = 0;
+ }
+ sub_80E1558(behavior);
+ return TRUE;
+}
+
+bool8 sub_80B7190(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x84, task->data[1]);
+ sprite->pos2.y = Sin(0x94, task->data[1]);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B71D0(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x84, task->data[1]);
+ sprite->pos2.y = Sin(0x94, task->data[1]);
+ task->data[2]++;
+ if (task->data[2] & 1)
+ {
+ task->data[1]--;
+ }
+ if (task->data[1] == 0)
+ {
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ task->data[0] = 5;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B7230(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x7c, task->data[1]);
+ sprite->pos2.y = Sin(0x76, task->data[1]);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B7270(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x7c, task->data[1]);
+ sprite->pos2.y = Sin(0x76, task->data[1]);
+ task->data[2]++;
+ if (task->data[2] & 1)
+ {
+ task->data[1]--;
+ }
+ if (task->data[1] == 0)
+ {
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+extern bool8 sub_80E1584(void);
+
+bool8 sub_80B72D0(struct Task *task)
+{
+ if (sub_80E1584())
+ {
+ return FALSE;
+ }
+ sub_80E1570();
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B72F4(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ CameraObjectReset1();
+ ScriptContext2_Disable();
+ FieldObjectSetSpecialAnim(mapObject, GetGoSpeed0AnimId(DIR_EAST));
+ DestroyTask(FindTaskIdByFunc(sub_80B70DC));
+ }
+ return FALSE;
+}
+
+void sub_80B7384(u8);
+
+bool8 FldEff_UseWaterfall(void)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_80B7384, 0xff);
+ gTasks[taskId].data[1] = gFieldEffectArguments[0];
+ sub_80B7384(taskId);
+ return FALSE;
+}
+
+void sub_80B7384(u8 taskId)
+{
+ while (gUnknown_0855C418[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId]));
+}
+
+bool8 sub_80B73D0(struct Task *task, struct MapObject *mapObject)
+{
+ ScriptContext2_Enable();
+ gPlayerAvatar.preventStep = TRUE;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 waterfall_1_do_anim_probably(struct Task *task, struct MapObject *mapObject)
+{
+ ScriptContext2_Enable();
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject))
+ {
+ FieldObjectClearAnimIfSpecialAnimFinished(mapObject);
+ gFieldEffectArguments[0] = task->data[1];
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 waterfall_2_wait_anim_finish_probably(struct Task *task, struct MapObject *mapObject)
+{
+ if (FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ return FALSE;
+ }
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B7450(struct Task *task, struct MapObject *mapObject)
+{
+ FieldObjectSetSpecialAnim(mapObject, GetSimpleGoAnimId(DIR_NORTH));
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B7478(struct Task *task, struct MapObject *mapObject)
+{
+ if (!FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ return FALSE;
+ }
+ if (MetatileBehavior_IsWaterfall(mapObject->mapobj_unk_1E))
+ {
+ task->data[0] = 3;
+ return TRUE;
+ }
+ ScriptContext2_Disable();
+ gPlayerAvatar.preventStep = FALSE;
+ DestroyTask(FindTaskIdByFunc(sub_80B7384));
+ FieldEffectActiveListRemove(FLDEFF_USE_WATERFALL);
+ return FALSE;
+}
+
+void Task_Dive(u8);
+extern int dive_warp(struct MapPosition *, u16);
+
+bool8 FldEff_UseDive(void)
+{
+ u8 taskId;
+ taskId = CreateTask(Task_Dive, 0xff);
+ gTasks[taskId].data[15] = gFieldEffectArguments[0];
+ gTasks[taskId].data[14] = gFieldEffectArguments[1];
+ Task_Dive(taskId);
+ return FALSE;
+}
+
+void Task_Dive(u8 taskId)
+{
+ while (gUnknown_0855C42C[gTasks[taskId].data[0]](&gTasks[taskId]));
+}
+
+bool8 dive_1_lock(struct Task *task)
+{
+ gPlayerAvatar.preventStep = TRUE;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 dive_2_unknown(struct Task *task)
+{
+ ScriptContext2_Enable();
+ gFieldEffectArguments[0] = task->data[15];
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 dive_3_unknown(struct Task *task)
+{
+ struct MapPosition mapPosition;
+ PlayerGetDestCoords(&mapPosition.x, &mapPosition.y);
+ if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ dive_warp(&mapPosition, gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E);
+ DestroyTask(FindTaskIdByFunc(Task_Dive));
+ FieldEffectActiveListRemove(FLDEFF_USE_DIVE);
+ }
+ return FALSE;
+}
+
+void sub_80B75F0(u8);
+void mapldr_080851BC(void);
+
+void sub_80B75D8(u8 priority)
+{
+ CreateTask(sub_80B75F0, priority);
+}
+
+void sub_80B75F0(u8 taskId)
+{
+ while (gUnknown_0855C438[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gSprites[gPlayerAvatar.spriteId]));
+}
+
+bool8 sub_80B764C(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FreezeMapObjects();
+ CameraObjectReset2();
+ SetCameraPanningCallback(NULL);
+ gPlayerAvatar.preventStep = TRUE;
+ mapObject->mapobj_bit_26 = 1;
+ task->data[1] = 1;
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B7684(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ SetCameraPanning(0, task->data[1]);
+ task->data[1] = -task->data[1];
+ task->data[2]++;
+ if (task->data[2] > 7)
+ {
+ task->data[2] = 0;
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B76B8(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite->pos2.y = 0;
+ task->data[3] = 1;
+ gFieldEffectArguments[0] = mapObject->coords2.x;
+ gFieldEffectArguments[1] = mapObject->coords2.y;
+ gFieldEffectArguments[2] = sprite->subpriority - 1;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_LAVARIDGE_GYM_WARP);
+ PlaySE(SE_W153);
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B7704(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ s16 centerToCornerVecY;
+ SetCameraPanning(0, task->data[1]);
+ if (task->data[1] = -task->data[1], ++task->data[2] <= 17)
+ {
+ if (!(task->data[2] & 1) && (task->data[1] <= 3))
+ {
+ task->data[1] <<= 1;
+ }
+ } else if (!(task->data[2] & 4) && (task->data[1] > 0))
+ {
+ task->data[1] >>= 1;
+ }
+ if (task->data[2] > 6)
+ {
+ centerToCornerVecY = -(sprite->centerToCornerVecY << 1);
+ if (sprite->pos2.y > -(sprite->pos1.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY + centerToCornerVecY))
+ {
+ sprite->pos2.y -= task->data[3];
+ if (task->data[3] <= 7)
+ {
+ task->data[3]++;
+ }
+ } else
+ {
+ task->data[4] = 1;
+ }
+ }
+ if (task->data[5] == 0 && sprite->pos2.y < -0x10)
+ {
+ task->data[5]++;
+ mapObject->mapobj_bit_26 = 1;
+ sprite->oam.priority = 1;
+ sprite->subspriteMode = 2;
+ }
+ if (task->data[1] == 0 && task->data[4] != 0)
+ {
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B77F8(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ music_something();
+ sub_80AF0B4();
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B7814(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (!gPaletteFade.active && sub_80859A0() == TRUE)
+ {
+ warp_in();
+ gFieldCallback = mapldr_080851BC;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80B75F0));
+ }
+ return FALSE;
+}
+
+void sub_80B7890(u8);
+
+void mapldr_080851BC(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ gFieldCallback = NULL;
+ CreateTask(sub_80B7890, 0);
+}
+
+void sub_80B7890(u8 taskId)
+{
+ while (gUnknown_0855C450[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gSprites[gPlayerAvatar.spriteId]));
+}
+
+bool8 sub_80B78EC(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ CameraObjectReset2();
+ FreezeMapObjects();
+ gPlayerAvatar.preventStep = TRUE;
+ mapObject->mapobj_bit_13 = 1;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B791C(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (IsWeatherNotFadingIn())
+ {
+ gFieldEffectArguments[0] = mapObject->coords2.x;
+ gFieldEffectArguments[1] = mapObject->coords2.y;
+ gFieldEffectArguments[2] = sprite->subpriority - 1;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ task->data[1] = FieldEffectStart(FLDEFF_POP_OUT_OF_ASH);
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B7968(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite = &gSprites[task->data[1]];
+ if (sprite->animCmdIndex > 1)
+ {
+ task->data[0]++;
+ mapObject->mapobj_bit_13 = 0;
+ CameraObjectReset1();
+ PlaySE(SE_W091);
+ FieldObjectSetSpecialAnim(mapObject, sub_8093514(DIR_EAST));
+ }
+ return FALSE;
+}
+
+bool8 sub_80B79BC(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ gPlayerAvatar.preventStep = FALSE;
+ ScriptContext2_Disable();
+ UnfreezeMapObjects();
+ DestroyTask(FindTaskIdByFunc(sub_80B7890));
+ }
+ return FALSE;
+}
+
+extern const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[36];
+
+u8 FldEff_LavaridgeGymWarp(void)
+{
+ u8 spriteId;
+ sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[33], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ gSprites[spriteId].oam.priority = gFieldEffectArguments[3];
+ gSprites[spriteId].coordOffsetEnabled = 1;
+ return spriteId;
+}
+
+void sub_80B7A58(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ FieldEffectStop(sprite, FLDEFF_LAVARIDGE_GYM_WARP);
+ }
+}
+
+void sub_80B7A8C(u8);
+
+void sub_80B7A74(u8 priority)
+{
+ CreateTask(sub_80B7A8C, priority);
+}
+
+void sub_80B7A8C(u8 taskId)
+{
+ while(gUnknown_0855C460[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gSprites[gPlayerAvatar.spriteId]));
+}
+
+bool8 sub_80B7AE8(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FreezeMapObjects();
+ CameraObjectReset2();
+ gPlayerAvatar.preventStep = TRUE;
+ mapObject->mapobj_bit_26 = 1;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B7B18(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ if (task->data[1] > 3)
+ {
+ gFieldEffectArguments[0] = mapObject->coords2.x;
+ gFieldEffectArguments[1] = mapObject->coords2.y;
+ gFieldEffectArguments[2] = sprite->subpriority - 1;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ task->data[1] = FieldEffectStart(FLDEFF_POP_OUT_OF_ASH);
+ task->data[0]++;
+ } else
+ {
+ task->data[1]++;
+ FieldObjectSetSpecialAnim(mapObject, GetStepInPlaceDelay4AnimId(mapObject->mapobj_unk_18));
+ PlaySE(SE_FU_ZUZUZU);
+ }
+ }
+ return FALSE;
+}
+
+bool8 sub_80B7B94(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (gSprites[task->data[1]].animCmdIndex == 2)
+ {
+ mapObject->mapobj_bit_13 = 1;
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B7BCC(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (!FieldEffectActiveListContains(FLDEFF_POP_OUT_OF_ASH))
+ {
+ music_something();
+ sub_80AF0B4();
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+void sub_80B7CE4(u8);
+void mapldr_080859D4(void);
+
+bool8 sub_80B7BF4(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (!gPaletteFade.active && sub_80859A0() == TRUE)
+ {
+ warp_in();
+ gFieldCallback = sub_80B6B68;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80B7A8C));
+ }
+ return FALSE;
+}
+
+u8 FldEff_PopOutOfAsh(void)
+{
+ u8 spriteId;
+ sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[32], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ gSprites[spriteId].oam.priority = gFieldEffectArguments[3];
+ gSprites[spriteId].coordOffsetEnabled = 1;
+ return spriteId;
+}
+
+void sub_80B7CAC(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ FieldEffectStop(sprite, FLDEFF_POP_OUT_OF_ASH);
+ }
+}
+
+void sub_80B7CC8(void)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ CreateTask(sub_80B7CE4, 0x50);
+}
+
+void sub_80B7CE4(u8 taskId)
+{
+ gUnknown_0855C474[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B7D14(struct Task *task)
+{
+ task->data[0]++;
+ task->data[14] = 64;
+ task->data[15] = player_get_direction_lower_nybble();
+}
+
+void sub_80B7D34(struct Task *task)
+{
+ struct MapObject *mapObject;
+ u8 spinDirections[5] = {1, 3, 4, 2, 1};
+ if (task->data[14] != 0 && (--task->data[14]) == 0)
+ {
+ music_something();
+ sub_80AF0B4();
+ }
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ if (task->data[14] == 0 && !gPaletteFade.active && sub_80859A0() == TRUE)
+ {
+ FieldObjectSetDirection(mapObject, task->data[15]);
+ sub_8084E14();
+ warp_in();
+ gFieldCallback = mapldr_080859D4;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80B7CE4));
+ } else if (task->data[1] == 0 || (--task->data[1]) == 0)
+ {
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(spinDirections[mapObject->mapobj_unk_18]));
+ if (task->data[2] < 12)
+ {
+ task->data[2]++;
+ }
+ task->data[1] = 8 >> (task->data[2] >> 2);
+ }
+ }
+}
+
+void (*const gUnknown_0855C484[])(struct Task *) = {
+ sub_80B7EC4,
+ sub_80B7EE8
+};
+
+void sub_80B7E94(u8);
+
+void mapldr_080859D4(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ CreateTask(sub_80B7E94, 0);
+}
+
+void sub_80B7E94(u8 taskId)
+{
+ gUnknown_0855C484[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B7EC4(struct Task *task)
+{
+ if (IsWeatherNotFadingIn())
+ {
+ task->data[0]++;
+ task->data[15] = player_get_direction_lower_nybble();
+ }
+}
+
+void sub_80B7EE8(struct Task *task)
+{
+ u8 spinDirections[5] = {1, 3, 4, 2, 1};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (task->data[1] == 0 || (--task->data[1]) == 0)
+ {
+ if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) && !FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ return;
+ }
+ if (task->data[2] >= 32 && task->data[15] == player_get_direction_lower_nybble())
+ {
+ mapObject->mapobj_bit_13 = 0;
+ ScriptContext2_Disable();
+ UnfreezeMapObjects();
+ DestroyTask(FindTaskIdByFunc(sub_80B7E94));
+ return;
+ }
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(spinDirections[mapObject->mapobj_unk_18]));
+ if (task->data[2] < 32)
+ {
+ task->data[2]++;
+ }
+ task->data[1] = task->data[2] >> 2;
+ }
+ mapObject->mapobj_bit_13 ^= 1;
+}
+
+static void ExecuteTeleportFieldEffectTask(u8);
+static void TeleportFieldEffectTask1(struct Task*);
+static void TeleportFieldEffectTask2(struct Task*);
+static void TeleportFieldEffectTask3(struct Task*);
+static void TeleportFieldEffectTask4(struct Task*);
+static void mapldr_08085D88(void);
+
+void CreateTeleportFieldEffectTask(void)
+{
+ CreateTask(ExecuteTeleportFieldEffectTask, 0);
+}
+
+static void (*const sTeleportFieldEffectTasks[])(struct Task *) = {
+ TeleportFieldEffectTask1,
+ TeleportFieldEffectTask2,
+ TeleportFieldEffectTask3,
+ TeleportFieldEffectTask4
+};
+
+static void ExecuteTeleportFieldEffectTask(u8 taskId)
+{
+ sTeleportFieldEffectTasks[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+static void TeleportFieldEffectTask1(struct Task *task)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ CameraObjectReset2();
+ task->data[15] = player_get_direction_lower_nybble();
+ task->data[0]++;
+}
+
+static void TeleportFieldEffectTask2(struct Task *task)
+{
+ u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (task->data[1] == 0 || (--task->data[1]) == 0)
+ {
+ FieldObjectTurn(mapObject, spinDirections[mapObject->mapobj_unk_18]);
+ task->data[1] = 8;
+ task->data[2]++;
+ }
+ if (task->data[2] > 7 && task->data[15] == mapObject->mapobj_unk_18)
+ {
+ task->data[0]++;
+ task->data[1] = 4;
+ task->data[2] = 8;
+ task->data[3] = 1;
+ PlaySE(SE_TK_WARPIN);
+ }
+}
+
+static void TeleportFieldEffectTask3(struct Task *task)
+{
+ u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ struct Sprite *sprite = &gSprites[gPlayerAvatar.spriteId];
+ if ((--task->data[1]) <= 0)
+ {
+ task->data[1] = 4;
+ FieldObjectTurn(mapObject, spinDirections[mapObject->mapobj_unk_18]);
+ }
+ sprite->pos1.y -= task->data[3];
+ task->data[4] += task->data[3];
+ if ((--task->data[2]) <= 0 && (task->data[2] = 4, task->data[3] < 8))
+ {
+ task->data[3] <<= 1;
+ }
+ if (task->data[4] > 8 && (sprite->oam.priority = 1, sprite->subspriteMode != 0))
+ {
+ sprite->subspriteMode = 2;
+ }
+ if (task->data[4] >= 0xa8)
+ {
+ task->data[0]++;
+ music_something();
+ sub_80AF0B4();
+ }
+}
+
+static void TeleportFieldEffectTask4(struct Task *task)
+{
+ if (!gPaletteFade.active)
+ {
+ if (task->data[5] == FALSE)
+ {
+ sub_81BE72C();
+ task->data[5] = TRUE;
+ }
+
+ if (sub_80859A0() == TRUE)
+ {
+ Overworld_SetWarpDestToLastHealLoc();
+ warp_in();
+ SetMainCallback2(CB2_LoadMap);
+ gFieldCallback = mapldr_08085D88;
+ DestroyTask(FindTaskIdByFunc(ExecuteTeleportFieldEffectTask));
+ }
+ }
+}
+
+void sub_80B8250(u8);
+
+static void mapldr_08085D88(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ CameraObjectReset2();
+ CreateTask(sub_80B8250, 0);
+}
+
+void (*const gUnknown_0855C49C[])(struct Task *) = {
+ sub_80B8280,
+ sub_80B830C,
+ sub_80B8410
+};
+
+void sub_80B8250(u8 taskId)
+{
+ gUnknown_0855C49C[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B8280(struct Task *task)
+{
+ struct Sprite *sprite;
+ s16 centerToCornerVecY;
+ if (IsWeatherNotFadingIn())
+ {
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ centerToCornerVecY = -(sprite->centerToCornerVecY << 1);
+ sprite->pos2.y = -(sprite->pos1.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY + centerToCornerVecY);
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 0;
+ task->data[0]++;
+ task->data[1] = 8;
+ task->data[2] = 1;
+ task->data[14] = sprite->subspriteMode;
+ task->data[15] = player_get_direction_lower_nybble();
+ PlaySE(SE_TK_WARPIN);
+ }
+}
+
+void sub_80B830C(struct Task *task)
+{
+ u8 spinDirections[5] = {1, 3, 4, 2, 1};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ struct Sprite *sprite = &gSprites[gPlayerAvatar.spriteId];
+ if ((sprite->pos2.y += task->data[1]) >= -8)
+ {
+ if (task->data[13] == 0)
+ {
+ task->data[13]++;
+ mapObject->mapobj_bit_2 = 1;
+ sprite->subspriteMode = task->data[14];
+ }
+ } else
+ {
+ sprite->oam.priority = 1;
+ if (sprite->subspriteMode != 0)
+ {
+ sprite->subspriteMode = 2;
+ }
+ }
+ if (sprite->pos2.y >= -0x30 && task->data[1] > 1 && !(sprite->pos2.y & 1))
+ {
+ task->data[1]--;
+ }
+ if ((--task->data[2]) == 0)
+ {
+ task->data[2] = 4;
+ FieldObjectTurn(mapObject, spinDirections[mapObject->mapobj_unk_18]);
+ }
+ if (sprite->pos2.y >= 0)
+ {
+ sprite->pos2.y = 0;
+ task->data[0]++;
+ task->data[1] = 1;
+ task->data[2] = 0;
+ }
+}
+
+void sub_80B8410(struct Task *task)
+{
+ u8 spinDirections[5] = {1, 3, 4, 2, 1};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if ((--task->data[1]) == 0)
+ {
+ FieldObjectTurn(mapObject, spinDirections[mapObject->mapobj_unk_18]);
+ task->data[1] = 8;
+ if ((++task->data[2]) > 4 && task->data[14] == mapObject->mapobj_unk_18)
+ {
+ ScriptContext2_Disable();
+ CameraObjectReset1();
+ UnfreezeMapObjects();
+ DestroyTask(FindTaskIdByFunc(sub_80B8250));
+ }
+ }
+}
+
+void sub_80B8554(u8);
+void sub_80B88B4(u8);
+u8 sub_80B8C60(u32, u32, u32);
+void sub_80B880C(void);
+void sub_80B8874(u16);
+void sub_80B8CC0(struct Sprite *);
+
+bool8 FldEff_FieldMoveShowMon(void)
+{
+ u8 taskId;
+ if (is_map_type_1_2_3_5_or_6(Overworld_GetMapTypeOfSaveblockLocation()) == TRUE)
+ {
+ taskId = CreateTask(sub_80B8554, 0xff);
+ } else
+ {
+ taskId = CreateTask(sub_80B88B4, 0xff);
+ }
+ gTasks[taskId].data[15] = sub_80B8C60(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ return FALSE;
+}
+
+bool8 FldEff_FieldMoveShowMonInit(void)
+{
+ struct Pokemon *pokemon;
+ u32 flag = gFieldEffectArguments[0] & 0x80000000;
+ pokemon = &gPlayerParty[(u8)gFieldEffectArguments[0]];
+ gFieldEffectArguments[0] = GetMonData(pokemon, MON_DATA_SPECIES);
+ gFieldEffectArguments[1] = GetMonData(pokemon, MON_DATA_OT_ID);
+ gFieldEffectArguments[2] = GetMonData(pokemon, MON_DATA_PERSONALITY);
+ gFieldEffectArguments[0] |= flag;
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON);
+ FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ return FALSE;
+}
+
+void (*const gUnknown_0855C4A8[])(struct Task *) = {
+ sub_80B8584,
+ sub_80B85F8,
+ sub_80B8660,
+ sub_80B86EC,
+ sub_80B871C,
+ sub_80B8770,
+ overworld_bg_setup_2,
+};
+
+void sub_80B8554(u8 taskId)
+{
+ gUnknown_0855C4A8[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B8584(struct Task *task)
+{
+ task->data[11] = REG_WININ;
+ task->data[12] = REG_WINOUT;
+ StoreWordInTwoHalfwords(&task->data[13], (u32)gMain.vblankCallback);
+ task->data[1] = 0xf0f1;
+ task->data[2] = 0x5051;
+ task->data[3] = 0x3f;
+ task->data[4] = 0x3e;
+ SetGpuReg(REG_OFFSET_WIN0H, task->data[1]);
+ SetGpuReg(REG_OFFSET_WIN0V, task->data[2]);
+ SetGpuReg(REG_OFFSET_WININ, task->data[3]);
+ SetGpuReg(REG_OFFSET_WINOUT, task->data[4]);
+ SetVBlankCallback(sub_80B880C);
+ task->data[0]++;
+}
+
+void sub_80B85F8(struct Task *task)
+{
+ u16 offset;
+ u16 delta;
+ offset = ((REG_BG0CNT >> 2) << 14);
+ delta = ((REG_BG0CNT >> 8) << 11);
+ CpuCopy16(gFieldMoveStreaksTiles, (void *)(VRAM + offset), 0x200);
+ CpuFill32(0, (void *)(VRAM + delta), 0x800);
+ LoadPalette(gFieldMoveStreaksPalette, 0xf0, 0x20);
+ sub_80B8874(delta);
+ task->data[0]++;
+}
+
+void sub_80B8660(struct Task *task)
+{
+ s16 v0;
+ s16 v2;
+ s16 v3;
+ task->data[5] -= 16;
+ v0 = ((u16)task->data[1] >> 8);
+ v2 = ((u16)task->data[2] >> 8);
+ v3 = ((u16)task->data[2] & 0xff);
+ v0 -= 16;
+ v2 -= 2;
+ v3 += 2;
+ if (v0 < 0)
+ {
+ v0 = 0;
+ }
+ if (v2 < 0x28)
+ {
+ v2 = 0x28;
+ }
+ if (v3 > 0x78)
+ {
+ v3 = 0x78;
+ }
+ task->data[1] = (v0 << 8) | (task->data[1] & 0xff);
+ task->data[2] = (v2 << 8) | v3;
+ if (v0 == 0 && v2 == 0x28 && v3 == 0x78)
+ {
+ gSprites[task->data[15]].callback = sub_80B8CC0;
+ task->data[0]++;
+ }
+}
+
+void sub_80B86EC(struct Task *task)
+{
+ task->data[5] -= 16;
+ if (gSprites[task->data[15]].data[7])
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B871C(struct Task *task)
+{
+ s16 v2;
+ s16 v3;
+ task->data[5] -= 16;
+ v2 = (task->data[2] >> 8);
+ v3 = (task->data[2] & 0xff);
+ v2 += 6;
+ v3 -= 6;
+ if (v2 > 0x50)
+ {
+ v2 = 0x50;
+ }
+ if (v3 < 0x51)
+ {
+ v3 = 0x51;
+ }
+ task->data[2] = (v2 << 8) | v3;
+ if (v2 == 0x50 && v3 == 0x51)
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B8770(struct Task *task)
+{
+ u16 bg0cnt;
+ bg0cnt = (REG_BG0CNT >> 8) << 11;
+ CpuFill32(0, (void *)VRAM + bg0cnt, 0x800);
+ task->data[1] = 0xf1;
+ task->data[2] = 0xa1;
+ task->data[3] = task->data[11];
+ task->data[4] = task->data[12];
+ task->data[0]++;
+}
+
+void overworld_bg_setup_2(struct Task *task)
+{
+ IntrCallback callback;
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&callback);
+ SetVBlankCallback(callback);
+ sub_8197200();
+ FreeResourcesAndDestroySprite(&gSprites[task->data[15]], task->data[15]);
+ FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON);
+ DestroyTask(FindTaskIdByFunc(sub_80B8554));
+}
+
+void sub_80B880C(void)
+{
+ struct Task *task;
+ IntrCallback callback;
+ task = &gTasks[FindTaskIdByFunc(sub_80B8554)];
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&callback);
+ callback();
+ SetGpuReg(REG_OFFSET_WIN0H, task->data[1]);
+ SetGpuReg(REG_OFFSET_WIN0V, task->data[2]);
+ SetGpuReg(REG_OFFSET_WININ, task->data[3]);
+ SetGpuReg(REG_OFFSET_WINOUT, task->data[4]);
+ SetGpuReg(REG_OFFSET_BG0HOFS, task->data[5]);
+ SetGpuReg(REG_OFFSET_BG0VOFS, task->data[6]);
+}
+
+void sub_80B8874(u16 offs)
+{
+ u16 i;
+ u16 *dest;
+ dest = (u16 *)(VRAM + 0x140 + offs);
+ for (i = 0; i < 0x140; i++, dest++)
+ {
+ *dest = gFieldMoveStreaksTilemap[i] | 0xf000;
+ }
+}
+
+void sub_80B8AE0(void);
+bool8 sub_80B8B38(struct Task *);
+void sub_80B8B28(struct Task *);
+bool8 sub_80B8BF0(struct Task *);
+
+void (*const gUnknown_0855C4C4[])(struct Task *) = {
+ sub_80B88E4,
+ sub_80B8920,
+ sub_80B898C,
+ sub_80B89DC,
+ sub_80B8A0C,
+ sub_80B8A44,
+ sub_80B8A64,
+};
+
+void sub_80B88B4(u8 taskId)
+{
+ gUnknown_0855C4C4[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B88E4(struct Task *task)
+{
+ SetGpuReg(REG_OFFSET_BG0HOFS, task->data[1]);
+ SetGpuReg(REG_OFFSET_BG0VOFS, task->data[2]);
+ StoreWordInTwoHalfwords((u16 *)&task->data[13], (u32)gMain.vblankCallback);
+ SetVBlankCallback(sub_80B8AE0);
+ task->data[0]++;
+}
+
+void sub_80B8920(struct Task *task)
+{
+ u16 offset;
+ u16 delta;
+ offset = ((REG_BG0CNT >> 2) << 14);
+ delta = ((REG_BG0CNT >> 8) << 11);
+ task->data[12] = delta;
+ CpuCopy16(gDarknessFieldMoveStreaksTiles, (void *)(VRAM + offset), 0x80);
+ CpuFill32(0, (void *)(VRAM + delta), 0x800);
+ LoadPalette(gDarknessFieldMoveStreaksPalette, 0xf0, 0x20);
+ task->data[0]++;
+}
+
+void sub_80B898C(struct Task *task)
+{
+ if (sub_80B8B38(task))
+ {
+ SetGpuReg(REG_OFFSET_WIN1H, 0x00f0);
+ SetGpuReg(REG_OFFSET_WIN1V, 0x2878);
+ gSprites[task->data[15]].callback = sub_80B8CC0;
+ task->data[0]++;
+ }
+ sub_80B8B28(task);
+}
+
+void sub_80B89DC(struct Task *task)
+{
+ sub_80B8B28(task);
+ if (gSprites[task->data[15]].data[7])
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B8A0C(struct Task *task)
+{
+ sub_80B8B28(task);
+ task->data[3] = task->data[1] & 7;
+ task->data[4] = 0;
+ SetGpuReg(REG_OFFSET_WIN1H, 0xffff);
+ SetGpuReg(REG_OFFSET_WIN1V, 0xffff);
+ task->data[0]++;
+}
+
+void sub_80B8A44(struct Task *task)
+{
+ sub_80B8B28(task);
+ if (sub_80B8BF0(task))
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B8A64(struct Task *task)
+{
+ IntrCallback intrCallback;
+ u16 bg0cnt;
+ bg0cnt = (REG_BG0CNT >> 8) << 11;
+ CpuFill32(0, (void *)VRAM + bg0cnt, 0x800);
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&intrCallback);
+ SetVBlankCallback(intrCallback);
+ sub_8197200();
+ FreeResourcesAndDestroySprite(&gSprites[task->data[15]], task->data[15]);
+ FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON);
+ DestroyTask(FindTaskIdByFunc(sub_80B88B4));
+}
+
+void sub_80B8AE0(void)
+{
+ IntrCallback intrCallback;
+ struct Task *task;
+ task = &gTasks[FindTaskIdByFunc(sub_80B88B4)];
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&intrCallback);
+ intrCallback();
+ SetGpuReg(REG_OFFSET_BG0HOFS, task->data[1]);
+ SetGpuReg(REG_OFFSET_BG0VOFS, task->data[2]);
+}
+
+void sub_80B8B28(struct Task *task)
+{
+ task->data[1] -= 16;
+ task->data[3] += 16;
+}
+
+#ifdef NONMATCHING
+bool8 sub_80B8B38(struct Task *task)
+{
+ u16 i;
+ u16 srcOffs;
+ u16 dstOffs;
+ u16 *dest;
+ if (task->data[4] >= 32)
+ {
+ return TRUE;
+ }
+ dstOffs = (task->data[3] >> 3) & 0x1f;
+ if (dstOffs >= task->data[4])
+ {
+ dstOffs = (32 - dstOffs) & 0x1f;
+ srcOffs = (32 - task->data[4]) & 0x1f;
+ dest = (u16 *)(VRAM + 0x140 + (u16)task->data[12]);
+ for (i=0; i<10; i++)
+ {
+ dest[dstOffs + i * 32] = gDarknessFieldMoveStreaksTilemap[srcOffs + i * 32] | 0xf000;
+ dest[((dstOffs + 1) & 0x1f) + i * 32] = gDarknessFieldMoveStreaksTilemap[((srcOffs + 1) & 0x1f) + i * 32] | 0xf000;
+ }
+ task->data[4] += 2;
+ }
+ return FALSE;
+}
+#else
+NAKED
+bool8 sub_80B8B38(struct Task *task)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r10\n"
+ "\tmov r6, r9\n"
+ "\tmov r5, r8\n"
+ "\tpush {r5-r7}\n"
+ "\tsub sp, 0x4\n"
+ "\tadds r5, r0, 0\n"
+ "\tldrh r2, [r5, 0x10]\n"
+ "\tmovs r1, 0x10\n"
+ "\tldrsh r0, [r5, r1]\n"
+ "\tcmp r0, 0x1F\n"
+ "\tble _08088724\n"
+ "\tmovs r0, 0x1\n"
+ "\tb _080887A8\n"
+ "_08088724:\n"
+ "\tldrh r0, [r5, 0xE]\n"
+ "\tlsls r0, 16\n"
+ "\tasrs r3, r0, 19\n"
+ "\tmovs r1, 0x1F\n"
+ "\tands r3, r1\n"
+ "\tmovs r4, 0x10\n"
+ "\tldrsh r0, [r5, r4]\n"
+ "\tcmp r3, r0\n"
+ "\tblt _080887A6\n"
+ "\tmovs r0, 0x20\n"
+ "\tsubs r3, r0, r3\n"
+ "\tands r3, r1\n"
+ "\tsubs r0, r2\n"
+ "\tmov r12, r0\n"
+ "\tmov r7, r12\n"
+ "\tands r7, r1\n"
+ "\tmov r12, r7\n"
+ "\tldrh r0, [r5, 0x20]\n"
+ "\tldr r1, _080887B8 @ =0x06000140\n"
+ "\tadds r1, r0\n"
+ "\tmov r8, r1\n"
+ "\tmovs r4, 0\n"
+ "\tldr r7, _080887BC @ =gDarknessFieldMoveStreaksTilemap\n"
+ "\tmov r10, r7\n"
+ "\tmovs r0, 0xF0\n"
+ "\tlsls r0, 8\n"
+ "\tmov r9, r0\n"
+ "\tadds r1, r3, 0x1\n"
+ "\tmovs r0, 0x1F\n"
+ "\tands r1, r0\n"
+ "\tstr r1, [sp]\n"
+ "\tmov r6, r12\n"
+ "\tadds r6, 0x1\n"
+ "\tands r6, r0\n"
+ "_08088768:\n"
+ "\tlsls r1, r4, 5\n"
+ "\tadds r2, r1, r3\n"
+ "\tlsls r2, 1\n"
+ "\tadd r2, r8\n"
+ "\tmov r7, r12\n"
+ "\tadds r0, r7, r1\n"
+ "\tlsls r0, 1\n"
+ "\tadd r0, r10\n"
+ "\tldrh r0, [r0]\n"
+ "\tmov r7, r9\n"
+ "\torrs r0, r7\n"
+ "\tstrh r0, [r2]\n"
+ "\tldr r0, [sp]\n"
+ "\tadds r2, r1, r0\n"
+ "\tlsls r2, 1\n"
+ "\tadd r2, r8\n"
+ "\tadds r1, r6, r1\n"
+ "\tlsls r1, 1\n"
+ "\tadd r1, r10\n"
+ "\tldrh r0, [r1]\n"
+ "\tmov r1, r9\n"
+ "\torrs r0, r1\n"
+ "\tstrh r0, [r2]\n"
+ "\tadds r0, r4, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r4, r0, 16\n"
+ "\tcmp r4, 0x9\n"
+ "\tbls _08088768\n"
+ "\tldrh r0, [r5, 0x10]\n"
+ "\tadds r0, 0x2\n"
+ "\tstrh r0, [r5, 0x10]\n"
+ "_080887A6:\n"
+ "\tmovs r0, 0\n"
+ "_080887A8:\n"
+ "\tadd sp, 0x4\n"
+ "\tpop {r3-r5}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tmov r10, r5\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r1}\n"
+ "\tbx r1\n"
+ "\t.align 2, 0\n"
+ "_080887B8: .4byte 0x06000140\n"
+ "_080887BC: .4byte gDarknessFieldMoveStreaksTilemap");
+}
+#endif
+
+bool8 sub_80B8BF0(struct Task *task)
+{
+ u16 i;
+ u16 dstOffs;
+ u16 *dest;
+ if (task->data[4] >= 32)
+ {
+ return TRUE;
+ }
+ dstOffs = task->data[3] >> 3;
+ if (dstOffs >= task->data[4])
+ {
+ dstOffs = (task->data[1] >> 3) & 0x1f;
+ dest = (u16 *)(VRAM + 0x140 + (u16)task->data[12]);
+ for (i=0; i<10; i++)
+ {
+ dest[dstOffs + i * 32] = 0xf000;
+ dest[((dstOffs + 1) & 0x1f) + i * 32] = 0xf000;
+ }
+ task->data[4] += 2;
+ }
+ return FALSE;
+}
+
+u8 sub_80B8C60(u32 a0, u32 a1, u32 a2)
+{
+ u16 v0;
+ u8 monSprite;
+ struct Sprite *sprite;
+ v0 = (a0 & 0x80000000) >> 16;
+ a0 &= 0x7fffffff;
+ monSprite = CreateMonSprite_FieldMove(a0, a1, a2, 0x140, 0x50, 0);
+ sprite = &gSprites[monSprite];
+ sprite->callback = SpriteCallbackDummy;
+ sprite->oam.priority = 0;
+ sprite->data[0] = a0;
+ sprite->data[6] = v0;
+ return monSprite;
+}
+
+void sub_80B8D04(struct Sprite *);
+
+void sub_80B8CC0(struct Sprite *sprite)
+{
+ if ((sprite->pos1.x -= 20) <= 0x78)
+ {
+ sprite->pos1.x = 0x78;
+ sprite->data[1] = 30;
+ sprite->callback = sub_80B8D04;
+ if (sprite->data[6])
+ {
+ PlayCry2(sprite->data[0], 0, 0x7d, 0xa);
+ } else
+ {
+ PlayCry1(sprite->data[0], 0);
+ }
+ }
+}
+
+void sub_80B8D20(struct Sprite *);
+
+void sub_80B8D04(struct Sprite *sprite)
+{
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->callback = sub_80B8D20;
+ }
+}
+
+void sub_80B8D20(struct Sprite *sprite)
+{
+ if (sprite->pos1.x < -0x40)
+ {
+ sprite->data[7] = 1;
+ } else
+ {
+ sprite->pos1.x -= 20;
+ }
+}
+
+void sub_80B8D84(u8);
+
+u8 FldEff_UseSurf(void)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_80B8D84, 0xff);
+ gTasks[taskId].data[15] = gFieldEffectArguments[0];
+ Overworld_ClearSavedMusic();
+ Overworld_ChangeMusicTo(MUS_NAMINORI);
+ return FALSE;
+}
+
+void (*const gUnknown_0855C4E0[])(struct Task *) = {
+ sub_80B8DB4,
+ sub_80B8E14,
+ sub_80B8E60,
+ sub_80B8EA8,
+ sub_80B8F24,
+};
+
+void sub_80B8D84(u8 taskId)
+{
+ gUnknown_0855C4E0[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B8DB4(struct Task *task)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gPlayerAvatar.preventStep = TRUE;
+ SetPlayerAvatarStateMask(8);
+ PlayerGetDestCoords(&task->data[1], &task->data[2]);
+ MoveCoords(gMapObjects[gPlayerAvatar.mapObjectId].placeholder18, &task->data[1], &task->data[2]);
+ task->data[0]++;
+}
+
+void sub_80B8E14(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ sub_808C114();
+ FieldObjectSetSpecialAnim(mapObject, 0x39);
+ task->data[0]++;
+ }
+}
+
+void sub_80B8E60(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(mapObject))
+ {
+ gFieldEffectArguments[0] = task->data[15] | 0x80000000;
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ task->data[0]++;
+ }
+}
+
+void sub_80B8EA8(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ FieldObjectSetGraphicsId(mapObject, GetPlayerAvatarGraphicsIdByStateId(3));
+ FieldObjectClearAnimIfSpecialAnimFinished(mapObject);
+ FieldObjectSetSpecialAnim(mapObject, sub_8093540(mapObject->placeholder18));
+ gFieldEffectArguments[0] = task->data[1];
+ gFieldEffectArguments[1] = task->data[2];
+ gFieldEffectArguments[2] = gPlayerAvatar.mapObjectId;
+ mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_SURF_BLOB);
+ task->data[0]++;
+ }
+}
+
+void sub_80B8F24(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ gPlayerAvatar.preventStep = FALSE;
+ gPlayerAvatar.flags &= 0xdf;
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(mapObject->placeholder18));
+ sub_81555AC(mapObject->mapobj_unk_1A, 1);
+ UnfreezeMapObjects();
+ ScriptContext2_Disable();
+ FieldEffectActiveListRemove(FLDEFF_USE_SURF);
+ DestroyTask(FindTaskIdByFunc(sub_80B8D84));
+ }
+}
+
+#ifdef NONMATCHING
+u8 sub_80B8F98(void)
+{
+ u8 spriteId, i, j, k, l;
+ struct Sprite *sprite;
+ spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[36], 0x78, -0x18, 1);
+ sprite = &gSprites[spriteId];
+ sprite->oam.priority = 1;
+ sprite->oam.paletteNum = 4;
+ sprite->data[0] = 0;
+ sprite->data[1] = 0;
+ sprite->data[2] = 0;
+ sprite->data[3] = -1;
+ sprite->data[4] = sprite->pos1.y;
+ sprite->data[5] = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(14, 14));
+ SetGpuReg(REG_OFFSET_WININ, 0x3F3F);
+ LoadPalette(gUnknown_0855B610, 0xC0, sizeof(gUnknown_0855B610));
+ SetGpuReg(REG_OFFSET_BG0VOFS, 120);
+ for (i = 3; i < 15; i++)
+ {
+ for (j = 12; j < 18; j++)
+ {
+ ((u16*)(VRAM + 0xF800))[i * 32 + j] = 0xBFF4 + i * 6 + j + 1;
+ }
+ }
+ for (k = 0; k < 90; k++)
+ {
+ for (l = 0; l < 8; l++)
+ {
+ *(u16*)(VRAM + 0x8000 + (k + 1) * 32 + l * 4) = (gUnknown_0855B630[k * 32 + l * 4 + 1] << 8) + gUnknown_0855B630[k * 32 + l * 4];
+ *(u16*)(VRAM + 0x8000 + (k + 1) * 32 + l * 4 + 2) = (gUnknown_0855B630[k * 32 + l * 4 + 3] << 8) + gUnknown_0855B630[k * 32 + l * 4 + 2];
+ }
+ }
+ return spriteId;
+}
+#else
+NAKED
+u8 sub_80B8F98(void)
+{
+ asm_unified("push {r4-r7,lr}\n\
+ mov r7, r8\n\
+ push {r7}\n\
+ ldr r0, =gFieldEffectObjectTemplatePointers\n\
+ adds r0, 0x90\n\
+ ldr r0, [r0]\n\
+ movs r2, 0x18\n\
+ negs r2, r2\n\
+ movs r1, 0x78\n\
+ movs r3, 0x1\n\
+ bl CreateSprite\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r8, r0\n\
+ lsls r1, r0, 4\n\
+ add r1, r8\n\
+ lsls r1, 2\n\
+ ldr r0, =gSprites\n\
+ adds r1, r0\n\
+ ldrb r2, [r1, 0x5]\n\
+ movs r0, 0xD\n\
+ negs r0, r0\n\
+ ands r0, r2\n\
+ movs r2, 0x4\n\
+ orrs r0, r2\n\
+ movs r2, 0xF\n\
+ ands r0, r2\n\
+ movs r2, 0x40\n\
+ orrs r0, r2\n\
+ strb r0, [r1, 0x5]\n\
+ movs r2, 0\n\
+ strh r2, [r1, 0x2E]\n\
+ strh r2, [r1, 0x30]\n\
+ strh r2, [r1, 0x32]\n\
+ ldr r0, =0x0000ffff\n\
+ strh r0, [r1, 0x34]\n\
+ ldrh r0, [r1, 0x22]\n\
+ strh r0, [r1, 0x36]\n\
+ strh r2, [r1, 0x38]\n\
+ ldr r1, =0x00003e41\n\
+ movs r0, 0x50\n\
+ bl SetGpuReg\n\
+ ldr r1, =0x00000e0e\n\
+ movs r0, 0x52\n\
+ bl SetGpuReg\n\
+ ldr r1, =0x00003f3f\n\
+ movs r0, 0x48\n\
+ bl SetGpuReg\n\
+ ldr r0, =gUnknown_0855B610\n\
+ movs r1, 0xC0\n\
+ movs r2, 0x20\n\
+ bl LoadPalette\n\
+ movs r0, 0x12\n\
+ movs r1, 0x78\n\
+ bl SetGpuReg\n\
+ movs r4, 0x3\n\
+ ldr r7, =0x0600f800\n\
+ ldr r0, =0x0000bff4\n\
+ adds r6, r0, 0\n\
+_080B901A:\n\
+ movs r2, 0xC\n\
+ lsls r0, r4, 1\n\
+ lsls r5, r4, 5\n\
+ adds r0, r4\n\
+ lsls r3, r0, 1\n\
+_080B9024:\n\
+ adds r0, r5, r2\n\
+ lsls r0, 1\n\
+ adds r0, r7\n\
+ adds r1, r2, r6\n\
+ adds r1, r3, r1\n\
+ adds r1, 0x1\n\
+ strh r1, [r0]\n\
+ adds r0, r2, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+ cmp r2, 0x11\n\
+ bls _080B9024\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ cmp r4, 0xE\n\
+ bls _080B901A\n\
+ movs r0, 0\n\
+ ldr r5, =gUnknown_0855B630\n\
+_080B904A:\n\
+ movs r4, 0\n\
+ adds r7, r0, 0x1\n\
+ lsls r6, r0, 5\n\
+_080B9050:\n\
+ lsls r1, r4, 2\n\
+ adds r1, r6, r1\n\
+ ldr r0, =0x06008020\n\
+ adds r3, r1, r0\n\
+ adds r0, r1, 0x1\n\
+ adds r0, r5\n\
+ ldrb r2, [r0]\n\
+ lsls r2, 8\n\
+ adds r0, r1, r5\n\
+ ldrb r0, [r0]\n\
+ adds r0, r2\n\
+ strh r0, [r3]\n\
+ ldr r0, =0x06008022\n\
+ adds r3, r1, r0\n\
+ adds r0, r1, 0x3\n\
+ adds r0, r5\n\
+ ldrb r2, [r0]\n\
+ lsls r2, 8\n\
+ adds r1, 0x2\n\
+ adds r1, r5\n\
+ ldrb r0, [r1]\n\
+ adds r0, r2\n\
+ strh r0, [r3]\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ cmp r4, 0x7\n\
+ bls _080B9050\n\
+ lsls r0, r7, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0x59\n\
+ bls _080B904A\n\
+ mov r0, r8\n\
+ pop {r3}\n\
+ mov r8, r3\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .pool");
+}
+#endif // NONMATCHING
+
+void sub_80B9128(struct Sprite *);
+
+u8 FldEff_NPCFlyOut(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+ spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[26], 0x78, 0, 1);
+ sprite = &gSprites[spriteId];
+ sprite->oam.paletteNum = 0;
+ sprite->oam.priority = 1;
+ sprite->callback = sub_80B9128;
+ sprite->data[1] = gFieldEffectArguments[0];
+ PlaySE(SE_W019);
+ return spriteId;
+}
+
+void sub_80B9128(struct Sprite *sprite)
+{
+ struct Sprite *npcSprite;
+ sprite->pos2.x = Cos(sprite->data[2], 0x8c);
+ sprite->pos2.y = Sin(sprite->data[2], 0x48);
+ sprite->data[2] = (sprite->data[2] + 4) & 0xff;
+ if (sprite->data[0])
+ {
+ npcSprite = &gSprites[sprite->data[1]];
+ npcSprite->coordOffsetEnabled = 0;
+ npcSprite->pos1.x = sprite->pos1.x + sprite->pos2.x;
+ npcSprite->pos1.y = sprite->pos1.y + sprite->pos2.y - 8;
+ npcSprite->pos2.x = 0;
+ npcSprite->pos2.y = 0;
+ }
+ if (sprite->data[2] >= 0x80)
+ {
+ FieldEffectStop(sprite, FLDEFF_NPCFLY_OUT);
+ }
+}
+
+void sub_80B91D4(u8);
+extern void sub_81555D8(u8, u8);
+u8 sub_80B94C4(void);
+bool8 sub_80B9508(u8);
+void sub_80B9524(u8);
+void sub_80B9560(u8, u8);
+void sub_80B957C(struct Sprite *);
+void sub_80B963C(struct Sprite *);
+
+u8 FldEff_UseFly(void)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_80B91D4, 0xfe);
+ gTasks[taskId].data[1] = gFieldEffectArguments[0];
+ return 0;
+}
+
+void (*const gUnknown_0855C4F4[])(struct Task *) = {
+ sub_80B9204,
+ sub_80B925C,
+ sub_80B92A0,
+ sub_80B92F8,
+ sub_80B933C,
+ sub_80B9390,
+ sub_80B9418,
+ sub_80B9474,
+ sub_80B9494,
+};
+
+void sub_80B91D4(u8 taskId)
+{
+ gUnknown_0855C4F4[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B9204(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ task->data[15] = gPlayerAvatar.flags;
+ gPlayerAvatar.preventStep = TRUE;
+ SetPlayerAvatarStateMask(1);
+ sub_808C114();
+ FieldObjectSetSpecialAnim(mapObject, 0x39);
+ task->data[0]++;
+ }
+}
+
+void sub_80B925C(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ task->data[0]++;
+ gFieldEffectArguments[0] = task->data[1];
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ }
+}
+
+void sub_80B92A0(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (task->data[15] & 0x08)
+ {
+ sub_81555AC(mapObject->mapobj_unk_1A, 2);
+ sub_81555D8(mapObject->mapobj_unk_1A, 0);
+ }
+ task->data[1] = sub_80B94C4();
+ task->data[0]++;
+ }
+}
+
+void sub_80B92F8(struct Task *task)
+{
+ if (sub_80B9508(task->data[1]))
+ {
+ task->data[0]++;
+ task->data[2] = 16;
+ SetPlayerAvatarTransitionFlags(PLAYER_AVATAR_FLAG_ON_FOOT);
+ FieldObjectSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], 0x02);
+ }
+}
+
+void sub_80B933C(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if ((task->data[2] == 0 || (--task->data[2]) == 0) && FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ task->data[0]++;
+ PlaySE(SE_W019);
+ sub_80B9524(task->data[1]);
+ }
+}
+
+void sub_80B9390(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if ((++task->data[2]) >= 8)
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ FieldObjectSetGraphicsId(mapObject, GetPlayerAvatarGraphicsIdByStateId(0x03));
+ StartSpriteAnim(&gSprites[mapObject->spriteId], 0x16);
+ mapObject->mapobj_bit_12 = 1;
+ FieldObjectSetSpecialAnim(mapObject, 0x48);
+ if (task->data[15] & 0x08)
+ {
+ DestroySprite(&gSprites[mapObject->mapobj_unk_1A]);
+ }
+ task->data[0]++;
+ task->data[2] = 0;
+ }
+}
+
+void sub_80B9418(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if ((++task->data[2]) >= 10)
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ FieldObjectClearAnimIfSpecialAnimActive(mapObject);
+ mapObject->mapobj_bit_12 = 0;
+ mapObject->mapobj_bit_22 = 0;
+ sub_80B9560(task->data[1], mapObject->spriteId);
+ CameraObjectReset2();
+ task->data[0]++;
+ }
+}
+
+void sub_80B9474(struct Task *task)
+{
+ if (sub_80B9508(task->data[1]))
+ {
+ sub_80AF0B4();
+ task->data[0]++;
+ }
+}
+
+void sub_80B9494(struct Task *task)
+{
+ if (!gPaletteFade.active)
+ {
+ FieldEffectActiveListRemove(FLDEFF_USE_FLY);
+ DestroyTask(FindTaskIdByFunc(sub_80B91D4));
+ }
+}
+
+u8 sub_80B94C4(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+ spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[26], 0xff, 0xb4, 0x1);
+ sprite = &gSprites[spriteId];
+ sprite->oam.paletteNum = 0;
+ sprite->oam.priority = 1;
+ sprite->callback = sub_80B957C;
+ return spriteId;
+}
+
+u8 sub_80B9508(u8 spriteId)
+{
+ return gSprites[spriteId].data[7];
+}
+
+void sub_80B9524(u8 spriteId)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[spriteId];
+ sprite->callback = sub_80B963C;
+ sprite->pos1.x = 0x78;
+ sprite->pos1.y = 0x00;
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ memset(&sprite->data[0], 0, 8 * sizeof(u16) /* zero all data cells */);
+ sprite->data[6] = 0x40;
+}
+
+void sub_80B9560(u8 a0, u8 a1)
+{
+ gSprites[a0].data[6] = a1;
+}
+
+const union AffineAnimCmd SpriteAffineAnim_855C518[] = {
+ AFFINEANIMCMD_FRAME(8, 8, -30, 0),
+ AFFINEANIMCMD_FRAME(28, 28, 0, 30),
+ AFFINEANIMCMD_END
+};
+
+const union AffineAnimCmd SpriteAffineAnim_855C530[] = {
+ AFFINEANIMCMD_FRAME(256, 256, 64, 0),
+ AFFINEANIMCMD_FRAME(-10, -10, 0, 22),
+ AFFINEANIMCMD_END
+};
+
+const union AffineAnimCmd *const gSpriteAffineAnimTable_0855C548[] = {
+ SpriteAffineAnim_855C518,
+ SpriteAffineAnim_855C530
+};
+
+void sub_80B957C(struct Sprite *sprite)
+{
+ if (sprite->data[7] == 0)
+ {
+ if (sprite->data[0] == 0)
+ {
+ sprite->oam.affineMode = 3;
+ sprite->affineAnims = gSpriteAffineAnimTable_0855C548;
+ InitSpriteAffineAnim(sprite);
+ StartSpriteAffineAnim(sprite, 0);
+ sprite->pos1.x = 0x76;
+ sprite->pos1.y = -0x30;
+ sprite->data[0]++;
+ sprite->data[1] = 0x40;
+ sprite->data[2] = 0x100;
+ }
+ sprite->data[1] += (sprite->data[2] >> 8);
+ sprite->pos2.x = Cos(sprite->data[1], 0x78);
+ sprite->pos2.y = Sin(sprite->data[1], 0x78);
+ if (sprite->data[2] < 0x800)
+ {
+ sprite->data[2] += 0x60;
+ }
+ if (sprite->data[1] > 0x81)
+ {
+ sprite->data[7]++;
+ sprite->oam.affineMode = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, 0);
+ }
+ }
+}
+
+void sub_80B963C(struct Sprite *sprite)
+{
+ struct Sprite *sprite1;
+ sprite->pos2.x = Cos(sprite->data[2], 0x8c);
+ sprite->pos2.y = Sin(sprite->data[2], 0x48);
+ sprite->data[2] = (sprite->data[2] + 4) & 0xff;
+ if (sprite->data[6] != 0x40)
+ {
+ sprite1 = &gSprites[sprite->data[6]];
+ sprite1->coordOffsetEnabled = 0;
+ sprite1->pos1.x = sprite->pos1.x + sprite->pos2.x;
+ sprite1->pos1.y = sprite->pos1.y + sprite->pos2.y - 8;
+ sprite1->pos2.x = 0;
+ sprite1->pos2.y = 0;
+ }
+ if (sprite->data[2] >= 0x80)
+ {
+ sprite->data[7] = 1;
+ }
+}
+
+void sub_80B96B0(struct Sprite *sprite)
+{
+ if (sprite->data[7] == 0)
+ {
+ if (sprite->data[0] == 0)
+ {
+ sprite->oam.affineMode = 3;
+ sprite->affineAnims = gSpriteAffineAnimTable_0855C548;
+ InitSpriteAffineAnim(sprite);
+ StartSpriteAffineAnim(sprite, 1);
+ sprite->pos1.x = 0x5e;
+ sprite->pos1.y = -0x20;
+ sprite->data[0]++;
+ sprite->data[1] = 0xf0;
+ sprite->data[2] = 0x800;
+ sprite->data[4] = 0x80;
+ }
+ sprite->data[1] += sprite->data[2] >> 8;
+ sprite->data[3] += sprite->data[2] >> 8;
+ sprite->data[1] &= 0xff;
+ sprite->pos2.x = Cos(sprite->data[1], 0x20);
+ sprite->pos2.y = Sin(sprite->data[1], 0x78);
+ if (sprite->data[2] > 0x100)
+ {
+ sprite->data[2] -= sprite->data[4];
+ }
+ if (sprite->data[4] < 0x100)
+ {
+ sprite->data[4] += 24;
+ }
+ if (sprite->data[2] < 0x100)
+ {
+ sprite->data[2] = 0x100;
+ }
+ if (sprite->data[3] >= 60)
+ {
+ sprite->data[7]++;
+ sprite->oam.affineMode = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->invisible = 1;
+ }
+ }
+}
+
+void sub_80B9794(u8 spriteId)
+{
+ sub_80B9524(spriteId);
+ gSprites[spriteId].callback = sub_80B96B0;
+}
+
+void sub_80B97D4(u8);
+
+u8 FldEff_FlyIn(void)
+{
+ CreateTask(sub_80B97D4, 0xfe);
+ return 0;
+}
+
+void (*const gUnknown_0855C550[])(struct Task *) = {
+ sub_80B9804,
+ sub_80B98B8,
+ sub_80B9924,
+ sub_80B9978,
+ sub_80B99F0,
+ sub_80B9A28,
+ sub_80B9A60,
+};
+
+void sub_80B97D4(u8 taskId)
+{
+ gUnknown_0855C550[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B9804(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ task->data[0]++;
+ task->data[2] = 17;
+ task->data[15] = gPlayerAvatar.flags;
+ gPlayerAvatar.preventStep = TRUE;
+ SetPlayerAvatarStateMask(0x01);
+ if (task->data[15] & 0x08)
+ {
+ sub_81555AC(mapObject->mapobj_unk_1A, 0);
+ }
+ FieldObjectSetGraphicsId(mapObject, GetPlayerAvatarGraphicsIdByStateId(0x3));
+ CameraObjectReset2();
+ FieldObjectTurn(mapObject, DIR_WEST);
+ StartSpriteAnim(&gSprites[mapObject->spriteId], 0x16);
+ mapObject->mapobj_bit_13 = 0;
+ task->data[1] = sub_80B94C4();
+ sub_80B9524(task->data[1]);
+ sub_80B9560(task->data[1], mapObject->spriteId);
+ }
+}
+
+void sub_80B98B8(struct Task *task)
+{
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+ if (task->data[2] == 0 || (--task->data[2]) == 0)
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sprite = &gSprites[mapObject->spriteId];
+ sub_80B9560(task->data[1], 0x40);
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ task->data[0]++;
+ task->data[2] = 0;
+ }
+}
+
+void sub_80B9924(struct Task *task)
+{
+ s16 unknown_0855C56C[18] = {
+ -2,
+ -4,
+ -5,
+ -6,
+ -7,
+ -8,
+ -8,
+ -8,
+ -7,
+ -7,
+ -6,
+ -5,
+ -3,
+ -2,
+ 0,
+ 2,
+ 4,
+ 8
+ };
+ struct Sprite *sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.y = unknown_0855C56C[task->data[2]];
+ if ((++task->data[2]) >= 18)
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B9978(struct Task *task)
+{
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+ if (sub_80B9508(task->data[1]))
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sprite = &gSprites[mapObject->spriteId];
+ mapObject->mapobj_bit_12 = 0;
+ sub_808EB08(mapObject, mapObject->coords2.x, mapObject->coords2.y);
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ sprite->coordOffsetEnabled = 1;
+ sub_808C114();
+ FieldObjectSetSpecialAnim(mapObject, 0x39);
+ task->data[0]++;
+ }
+}
+
+void sub_80B99F0(struct Task *task)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[gPlayerAvatar.mapObjectId]))
+ {
+ task->data[0]++;
+ sub_80B9794(task->data[1]);
+ }
+}
+
+void sub_80B9A28(struct Task *task)
+{
+ if (sub_80B9508(task->data[1]))
+ {
+ DestroySprite(&gSprites[task->data[1]]);
+ task->data[0]++;
+ task->data[1] = 0x10;
+ }
+}
+
+void sub_80B9A60(struct Task *task)
+{
+ u8 state;
+ struct MapObject *mapObject;
+ if ((--task->data[1]) == 0)
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ state = 0;
+ if (task->data[15] & 0x08)
+ {
+ state = 3;
+ sub_81555AC(mapObject->mapobj_unk_1A, 1);
+ }
+ FieldObjectSetGraphicsId(mapObject, GetPlayerAvatarGraphicsIdByStateId(state));
+ FieldObjectTurn(mapObject, DIR_SOUTH);
+ gPlayerAvatar.flags = task->data[15];
+ gPlayerAvatar.preventStep = FALSE;
+ FieldEffectActiveListRemove(FLDEFF_FLY_IN);
+ DestroyTask(FindTaskIdByFunc(sub_80B97D4));
+ }
+}
+
+void sub_80B9BE8(u8 taskId);
+
+bool8 sub_80B9ADC(void)
+{
+ u8 taskId;
+ u8 mapObjectIdBuffer;
+ if (!TryGetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &mapObjectIdBuffer))
+ {
+ taskId = CreateTask(sub_80B9BE8, 0x50);
+ gTasks[taskId].data[2] = mapObjectIdBuffer;
+ gTasks[taskId].data[6] = gFieldEffectArguments[0];
+ gTasks[taskId].data[7] = gFieldEffectArguments[1];
+ gTasks[taskId].data[8] = gFieldEffectArguments[2];
+ }
+ else
+ {
+ FieldEffectActiveListRemove(0x41);
+ }
+ return FALSE;
+}
+
+void sub_80B9B3C(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ if (data[7] != 0)
+ {
+ if (++data[6] > 20)
+ {
+ data[6] = 0;
+ if (data[5] != 0)
+ data[5]--;
+ }
+ }
+ else
+ {
+ data[5] = 4;
+ }
+
+ if (++data[0] > 1)
+ {
+ data[0] = 0;
+ if (++data[1] & 1)
+ {
+ SetCameraPanning(0, -data[5]);
+ }
+ else
+ {
+ SetCameraPanning(0, data[5]);
+ }
+ }
+ UpdateCameraPanning();
+ if (data[5] == 0)
+ DestroyTask(taskId);
+}
+
+void sub_80B9BD0(u8 taskId)
+{
+ gTasks[taskId].data[7] = 1;
+}
+
+void (*const gUnknown_0855C590[])(s16*, u8) = {
+ sub_80B9C28,
+ sub_80B9C54,
+ sub_80B9CDC,
+};
+
+void sub_80B9BE8(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ InstallCameraPanAheadCallback();
+ SetCameraPanningCallback(0);
+ gUnknown_0855C590[data[1]](data, taskId);
+}
+
+void sub_80B9C28(s16* data, u8 taskId)
+{
+ u8 newTaskId = CreateTask(sub_80B9B3C, 0x5A);
+ PlaySE(SE_T_KAMI2);
+ data[5] = newTaskId;
+ data[1]++;
+}
+
+void sub_80B9D24(struct Sprite*);
+
+void sub_80B9C54(s16* data, u8 taskId)
+{
+ if (++data[3] > 0x78)
+ {
+ struct Sprite *sprite = &gSprites[gMapObjects[data[2]].spriteId];
+ gMapObjects[data[2]].mapobj_bit_13 = TRUE;
+ BlendPalettes(0x0000FFFF, 0x10, RGB_WHITE);
+ BeginNormalPaletteFade(0x0000FFFF, 0, 0x10, 0, RGB_WHITE);
+ sub_80B9D24(sprite);
+ PlaySE(SE_T_KAMI);
+ sub_80B9BD0(data[5]);
+ data[3] = 0;
+ data[1]++;
+ }
+}
+
+void sub_80B9CDC(s16* a0, u8 taskId)
+{
+ if (!gPaletteFade.active && !FuncIsActiveTask(sub_80B9B3C))
+ {
+ InstallCameraPanAheadCallback();
+ RemoveFieldObjectByLocalIdAndMap(a0[6], a0[7], a0[8]);
+ FieldEffectActiveListRemove(0x41);
+ DestroyTask(taskId);
+ }
+}
+
+void sub_80B9DB8(struct Sprite* sprite);
+
+const struct SpriteFrameImage gSpriteImageTable_855C59C[] = {
+ obj_frame_tiles(gUnknown_0855C170),
+ obj_frame_tiles(gUnknown_0855C190),
+ obj_frame_tiles(gUnknown_0855C1B0),
+ obj_frame_tiles(gUnknown_0855C1D0),
+};
+
+const union AnimCmd gSpriteAnim_855C5BC[] = {
+ ANIMCMD_FRAME(.imageValue = 0),
+ ANIMCMD_END
+};
+
+const union AnimCmd gSpriteAnim_855C5C4[] = {
+ ANIMCMD_FRAME(.imageValue = 1),
+ ANIMCMD_END
+};
+
+const union AnimCmd gSpriteAnim_855C5CC[] = {
+ ANIMCMD_FRAME(.imageValue = 2),
+ ANIMCMD_END
+};
+
+const union AnimCmd gSpriteAnim_855C5D4[] = {
+ ANIMCMD_FRAME(.imageValue = 3),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gSpriteAnimTable_855C5DC[] = {
+ gSpriteAnim_855C5BC,
+ gSpriteAnim_855C5C4,
+ gSpriteAnim_855C5CC,
+ gSpriteAnim_855C5D4,
+};
+
+const struct SpriteTemplate gUnknown_0855C5EC = {
+ .tileTag = 0xffff,
+ .paletteTag = 4378,
+ .oam = &gOamData_855C218,
+ .anims = gSpriteAnimTable_855C5DC,
+ .images = gSpriteImageTable_855C59C,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B9DB8
+};
+
+void sub_80B9D24(struct Sprite* sprite)
+{
+ int i;
+ int xPos = (s16)gUnknown_03005DEC + sprite->pos1.x + sprite->pos2.x;
+ int yPos = (s16)gUnknown_03005DE8 + sprite->pos1.y + sprite->pos2.y - 4;
+
+ for (i = 0; i < 4; i++)
+ {
+ u8 spriteId = CreateSprite(&gUnknown_0855C5EC, xPos, yPos, 0);
+ if (spriteId != 0x40)
+ {
+ StartSpriteAnim(&gSprites[spriteId], i);
+ gSprites[spriteId].data[0] = i;
+ gSprites[spriteId].oam.paletteNum = sprite->oam.paletteNum;
+ }
+ }
+}
+
+void sub_80B9DB8(struct Sprite* sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->pos1.x -= 16;
+ sprite->pos1.y -= 12;
+ break;
+ case 1:
+ sprite->pos1.x += 16;
+ sprite->pos1.y -= 12;
+ break;
+ case 2:
+ sprite->pos1.x -= 16;
+ sprite->pos1.y += 12;
+ break;
+ case 3:
+ sprite->pos1.x += 16;
+ sprite->pos1.y += 12;
+ break;
+ }
+ if ((u16)(sprite->pos1.x + 4) > 0xF8 || sprite->pos1.y < -4 || sprite->pos1.y > 0xA4)
+ DestroySprite(sprite);
+}
+
+void sub_80B9EDC(u8 taskId);
+
+bool8 sub_80B9E28(struct Sprite* sprite)
+{
+ u8 mapObjectIdBuffer;
+ if (!TryGetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &mapObjectIdBuffer))
+ {
+ struct MapObject *object;
+ int xPos, yPos;
+ u8 taskId;
+ object = &gMapObjects[mapObjectIdBuffer];
+ xPos = object->coords2.x - 7;
+ yPos = object->coords2.y - 7;
+ xPos = (gFieldEffectArguments[3] - xPos) * 16;
+ yPos = (gFieldEffectArguments[4] - yPos) * 16;
+ npc_coords_shift(object, gFieldEffectArguments[3] + 7, gFieldEffectArguments[4] + 7);
+ taskId = CreateTask(sub_80B9EDC, 0x50);
+ gTasks[taskId].data[1] = object->spriteId;
+ gTasks[taskId].data[2] = gSprites[object->spriteId].pos1.x + xPos;
+ gTasks[taskId].data[3] = gSprites[object->spriteId].pos1.y + yPos;
+ gTasks[taskId].data[8] = gFieldEffectArguments[5];
+ gTasks[taskId].data[9] = mapObjectIdBuffer;
+ }
+ return FALSE;
+}
+
+void sub_80B9EDC(u8 taskId)
+{
+ // BUG: Possible divide by zero
+ s16 *data = gTasks[taskId].data;
+ struct Sprite *sprite = &gSprites[data[1]];
+ switch (data[0])
+ {
+ case 0:
+ data[4] = sprite->pos1.x << 4;
+ data[5] = sprite->pos1.y << 4;
+ data[6] = (data[2] * 16 - data[4]) / data[8];
+ data[7] = (data[3] * 16 - data[5]) / data[8];
+ data[0]++;
+ case 1:
+ if (data[8] != 0)
+ {
+ data[8]--;
+ data[4] += data[6];
+ data[5] += data[7];
+ sprite->pos1.x = data[4] >> 4;
+ sprite->pos1.y = data[5] >> 4;
+ }
+ else
+ {
+ struct MapObject *object = &gMapObjects[data[9]];
+ sprite->pos1.x = data[2];
+ sprite->pos1.y = data[3];
+ npc_coords_shift_still(object);
+ object->mapobj_bit_3 = TRUE;
+ FieldEffectActiveListRemove(0x42);
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
diff --git a/src/field_map_obj.c b/src/field_map_obj.c
index 81cbe5210..af018eb16 100644
--- a/src/field_map_obj.c
+++ b/src/field_map_obj.c
@@ -353,7 +353,7 @@ static u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u
return slot;
}
#else
-static __attribute__((naked)) u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId)
+static NAKED u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r9\n"
diff --git a/src/field_tasks.c b/src/field_tasks.c
new file mode 100644
index 000000000..d9c3078da
--- /dev/null
+++ b/src/field_tasks.c
@@ -0,0 +1,776 @@
+#include "global.h"
+#include "task.h"
+#include "main.h"
+#include "constants/vars.h"
+#include "bike.h"
+#include "item.h"
+#include "constants/items.h"
+#include "event_data.h"
+#include "overworld.h"
+#include "clock.h"
+#include "script.h"
+#include "field_special_scene.h"
+#include "field_effect_helpers.h"
+#include "secret_base.h"
+#include "metatile_behavior.h"
+#include "fieldmap.h"
+#include "field_player_avatar.h"
+#include "field_camera.h"
+#include "constants/songs.h"
+#include "sound.h"
+#include "field_tasks.h"
+
+struct MetatileOffset
+{
+ s8 x;
+ s8 y;
+ u16 tileId;
+};
+
+// this file's functions
+static void DummyPerStepCallback(u8 taskId);
+static void PerStepCallback_8069F64(u8 taskId);
+static void PerStepCallback_8069AA0(u8 taskId);
+static void PerStepCallback_8069864(u8 taskId);
+static void PerStepCallback_8069DD4(u8 taskId);
+static void PerStepCallback_806A07C(u8 taskId);
+static void Task_MuddySlope(u8 taskId);
+
+// const rom data
+static void (*const gUnknown_08510348[])(u8) =
+{
+ DummyPerStepCallback,
+ PerStepCallback_8069F64,
+ PerStepCallback_8069AA0,
+ PerStepCallback_8069864,
+ PerStepCallback_8069DD4,
+ EndTruckSequence,
+ sub_80EA3E4,
+ PerStepCallback_806A07C
+};
+
+// they are in pairs but declared as 1D array
+static const struct MetatileOffset gUnknown_08510368[] =
+{
+ { 0, 0,0x259}, { 0, 1,0x261},
+ { 0, -1,0x259}, { 0, 0,0x261},
+ { 0, 0,0x252}, { 1, 0,0x253},
+ { -1, 0,0x252}, { 0, 0,0x253}
+};
+
+static const struct MetatileOffset gUnknown_08510388[] =
+{
+ { 0, 0,0x25A}, { 0, 1,0x262},
+ { 0, -1,0x25A}, { 0, 0,0x262},
+ { 0, 0,0x254}, { 1, 0,0x255},
+ { -1, 0,0x254}, { 0, 0,0x255}
+};
+
+static const struct MetatileOffset gUnknown_085103A8[] =
+{
+ { 0, 0,0x258}, { 0, 1,0x260},
+ { 0, -1,0x258}, { 0, 0,0x260},
+ { 0, 0,0x250}, { 1, 0,0x251},
+ { -1, 0,0x250}, { 0, 0,0x251}
+};
+
+static const u16 gUnknown_085103C8[] =
+{
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ VAR_TEMP_1,
+ VAR_TEMP_2,
+ VAR_TEMP_3,
+ VAR_TEMP_4,
+ 0,
+ 0,
+ VAR_TEMP_5,
+ VAR_TEMP_6,
+ VAR_TEMP_7,
+ 0,
+ 0,
+ VAR_TEMP_8,
+ VAR_TEMP_9,
+ VAR_TEMP_A,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+static const u16 gUnknown_085103FC[] = {0xe8, 0xeb, 0xea, 0xe9};
+
+// code
+static void Task_RunPerStepCallback(u8 taskId)
+{
+ int idx = gTasks[taskId].data[0];
+ gUnknown_08510348[idx](taskId);
+}
+
+#define tState data[0]
+#define tAmbientCryState data[1]
+#define tAmbientCryDelay data[2]
+
+static void RunTimeBasedEvents(s16 *data)
+{
+ switch (tState)
+ {
+ case 0:
+ if (gMain.vblankCounter1 & 0x1000)
+ {
+ DoTimeBasedEvents();
+ tState++;
+ }
+ break;
+ case 1:
+ if (!(gMain.vblankCounter1 & 0x1000))
+ {
+ tState--;
+ }
+ break;
+ }
+}
+
+static void Task_RunTimeBasedEvents(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (!ScriptContext2_IsEnabled())
+ {
+ RunTimeBasedEvents(data);
+ UpdateAmbientCry(&tAmbientCryState, &tAmbientCryDelay);
+ }
+}
+
+#undef tState
+#undef tAmbientCryState
+#undef tAmbientCryDelay
+
+void SetUpFieldTasks(void)
+{
+ if (!FuncIsActiveTask(Task_RunPerStepCallback))
+ {
+ u8 taskId = CreateTask(Task_RunPerStepCallback, 0x50);
+ gTasks[taskId].data[0] = 0;
+ }
+ if (!FuncIsActiveTask(Task_MuddySlope))
+ {
+ CreateTask(Task_MuddySlope, 0x50);
+ }
+ if (!FuncIsActiveTask(Task_RunTimeBasedEvents))
+ {
+ CreateTask(Task_RunTimeBasedEvents, 0x50);
+ }
+}
+
+void ActivatePerStepCallback(u8 callbackId)
+{
+ u8 taskId = FindTaskIdByFunc(Task_RunPerStepCallback);
+ if (taskId != 0xff)
+ {
+ s32 i;
+ s16 *data = gTasks[taskId].data;
+
+ for (i = 0; i < 16; i++)
+ data[i] = 0;
+
+ if (callbackId >= ARRAY_COUNT(gUnknown_08510348))
+ {
+ data[0] = 0;
+ }
+ else
+ {
+ data[0] = callbackId;
+ }
+ }
+}
+
+void ResetFieldTasksArgs(void)
+{
+ u8 taskId;
+ s16 *data;
+
+ taskId = FindTaskIdByFunc(Task_RunPerStepCallback);
+ if (taskId != 0xff)
+ {
+ data = gTasks[taskId].data;
+ }
+ taskId = FindTaskIdByFunc(Task_RunTimeBasedEvents);
+ if (taskId != 0xff)
+ {
+ data = gTasks[taskId].data;
+ data[1] = 0;
+ data[2] = 0;
+ }
+}
+
+static void DummyPerStepCallback(u8 taskId)
+{
+
+}
+
+static const struct MetatileOffset *sub_809DA30(const struct MetatileOffset *offsets, u16 metatileBehavior)
+{
+ if (MetatileBehavior_IsPacifilogVerticalLog1(metatileBehavior))
+ return &offsets[0 * 2];
+ else if (MetatileBehavior_IsPacifilogVerticalLog2(metatileBehavior))
+ return &offsets[1 * 2];
+ else if (MetatileBehavior_IsPacifilogHorizontalLog1(metatileBehavior))
+ return &offsets[2 * 2];
+ else if (MetatileBehavior_IsPacifilogHorizontalLog2(metatileBehavior))
+ return &offsets[3 * 2];
+ else
+ return NULL;
+}
+
+static void sub_809DA88(const struct MetatileOffset *offsets, s16 x, s16 y, bool32 flag)
+{
+ offsets = sub_809DA30(offsets, MapGridGetMetatileBehaviorAt(x, y));
+
+ if (offsets != NULL)
+ {
+ MapGridSetMetatileIdAt(x + offsets[0].x, y + offsets[0].y, offsets[0].tileId);
+ if (flag)
+ CurrentMapDrawMetatileAt(x + offsets[0].x, y + offsets[0].y);
+
+ MapGridSetMetatileIdAt(x + offsets[1].x, y + offsets[1].y, offsets[1].tileId);
+ if (flag)
+ CurrentMapDrawMetatileAt(x + offsets[1].x, y + offsets[1].y);
+ }
+}
+
+static void sub_809DB10(s16 x, s16 y, bool32 flag)
+{
+ sub_809DA88(gUnknown_08510368, x, y, flag);
+}
+
+static void sub_809DB34(s16 x, s16 y, bool32 flag)
+{
+ sub_809DA88(gUnknown_08510388, x, y, flag);
+}
+
+static void sub_809DB58(s16 x, s16 y, bool32 flag)
+{
+ sub_809DA88(gUnknown_085103A8, x, y, flag);
+}
+
+static bool32 sub_809DB7C(s16 x1, s16 y1, s16 x2, s16 y2)
+{
+ u16 metatileBehavior = MapGridGetMetatileBehaviorAt(x2, y2);
+
+ if (MetatileBehavior_IsPacifilogVerticalLog1(metatileBehavior))
+ {
+ if (y1 > y2)
+ return FALSE;
+ }
+ else if (MetatileBehavior_IsPacifilogVerticalLog2(metatileBehavior))
+ {
+ if (y1 < y2)
+ return FALSE;
+ }
+ else if (MetatileBehavior_IsPacifilogHorizontalLog1(metatileBehavior))
+ {
+ if (x1 > x2)
+ return FALSE;
+ }
+ else if (MetatileBehavior_IsPacifilogHorizontalLog2(metatileBehavior))
+ {
+ if (x1 < x2)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static bool32 sub_809DC18(s16 x1, s16 y1, s16 x2, s16 y2)
+{
+ u16 metatileBehavior = MapGridGetMetatileBehaviorAt(x1, y1);
+
+ if (MetatileBehavior_IsPacifilogVerticalLog1(metatileBehavior))
+ {
+ if (y1 < y2)
+ return FALSE;
+ }
+ else if (MetatileBehavior_IsPacifilogVerticalLog2(metatileBehavior))
+ {
+ if (y1 > y2)
+ return FALSE;
+ }
+ else if (MetatileBehavior_IsPacifilogHorizontalLog1(metatileBehavior))
+ {
+ if (x1 < x2)
+ return FALSE;
+ }
+ else if (MetatileBehavior_IsPacifilogHorizontalLog2(metatileBehavior))
+ {
+ if (x1 > x2)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void PerStepCallback_8069864(u8 taskId)
+{
+ s16 *data;
+ s16 x, y;
+ data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ switch (data[1])
+ {
+ case 0:
+ data[2] = x;
+ data[3] = y;
+ sub_809DB34(x, y, TRUE);
+ data[1] = 1;
+ break;
+ case 1:
+ if (x != data[2] || y != data[3])
+ {
+ if (sub_809DB7C(x, y, data[2], data[3]))
+ {
+ sub_809DB10(data[2], data[3], TRUE);
+ sub_809DB58(data[2], data[3], FALSE);
+ data[4] = data[2];
+ data[5] = data[3];
+ data[1] = 2;
+ data[6] = 8;
+ }
+ else
+ {
+ data[4] = -1;
+ data[5] = -1;
+ }
+ if (sub_809DC18(x, y, data[2], data[3]))
+ {
+ sub_809DB10(x, y, TRUE);
+ data[1] = 2;
+ data[6] = 8;
+ }
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsPacifidlogLog(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ PlaySE(SE_MIZU);
+ }
+ }
+ break;
+ case 2:
+ if ((--data[6]) == 0)
+ {
+ sub_809DB34(x, y, TRUE);
+ if (data[4] != -1 && data[5] != -1)
+ {
+ sub_809DB58(data[4], data[5], TRUE);
+ }
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+static void sub_809DE28(s16 x, s16 y)
+{
+ u8 z = PlayerGetZCoord();
+ if (!(z & 0x01))
+ {
+ switch (MapGridGetMetatileIdAt(x, y))
+ {
+ case 0x24e:
+ MapGridSetMetatileIdAt(x, y, 0x24f);
+ break;
+ case 0x256:
+ MapGridSetMetatileIdAt(x, y, 0x257);
+ break;
+ }
+ }
+}
+
+static void sub_809DE8C(s16 x, s16 y)
+{
+ u8 z = PlayerGetZCoord();
+ if (!(z & 0x01))
+ {
+ switch (MapGridGetMetatileIdAt(x, y))
+ {
+ case 0x24f:
+ MapGridSetMetatileIdAt(x, y, 0x24e);
+ break;
+ case 0x257:
+ MapGridSetMetatileIdAt(x, y, 0x256);
+ break;
+ }
+ }
+}
+
+static void PerStepCallback_8069AA0(u8 taskId)
+{
+ bool8 isFortreeBridgeCur;
+ bool8 isFortreeBridgePrev;
+ u8 z, flag;
+ s16 x, y, x2, y2;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ switch (data[1])
+ {
+ default:
+ break;
+ case 0:
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsFortreeBridge(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ sub_809DE28(x, y);
+ CurrentMapDrawMetatileAt(x, y);
+ }
+ data[1] = 1;
+ break;
+ case 1:
+ x2 = data[2];
+ y2 = data[3];
+ if (x == x2 && y == y2)
+ {
+ break;
+ }
+ isFortreeBridgeCur = MetatileBehavior_IsFortreeBridge(MapGridGetMetatileBehaviorAt(x, y));
+ isFortreeBridgePrev = MetatileBehavior_IsFortreeBridge(MapGridGetMetatileBehaviorAt(x2, y2));
+ z = PlayerGetZCoord();
+ flag = 0;
+ if ((u8)(z & 1) == 0)
+ {
+ flag = 1;
+ }
+ if (flag && (isFortreeBridgeCur == 1 || isFortreeBridgePrev == 1))
+ {
+ PlaySE(SE_HASHI);
+ }
+ if (isFortreeBridgePrev)
+ {
+ sub_809DE8C(x2, y2);
+ CurrentMapDrawMetatileAt(x2, y2);
+ sub_809DE28(x, y);
+ CurrentMapDrawMetatileAt(x, y);
+ }
+ data[4] = x2;
+ data[5] = y2;
+ data[2] = x;
+ data[3] = y;
+ if (!isFortreeBridgePrev)
+ {
+ break;
+ }
+ data[6] = 16;
+ data[1] = 2;
+ // fallthrough
+ case 2:
+ data[6]--;
+ x2 = data[4];
+ y2 = data[5];
+ switch (data[6] % 7)
+ {
+ case 0:
+ CurrentMapDrawMetatileAt(x2, y2);
+ case 1:
+ case 2:
+ case 3:
+ break;
+ case 4:
+ sub_809DE28(x2, y2);
+ CurrentMapDrawMetatileAt(x2, y2);
+ sub_809DE8C(x2, y2);
+ case 5:
+ case 6:
+ case 7:
+ break;
+ }
+ if (data[6] == 0)
+ {
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+static bool32 sub_809E108(s16 x, s16 y)
+{
+ if ((u16)(x - 3) < 11 && (u16)(y - 6) < 14 && gUnknown_085103C8[y])
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void sub_809E14C(s16 x, s16 y)
+{
+ if (sub_809E108(x, y))
+ *GetVarPointer(gUnknown_085103C8[y]) |= (1 << (x - 3));
+}
+
+static bool32 sub_809E184(s16 x, s16 y)
+{
+ u32 var;
+ if (!sub_809E108(x, y))
+ return FALSE;
+
+ var = VarGet(gUnknown_085103C8[y]) << 16;
+ if (((1 << 16) << (x - 3)) & var) // TODO: fix that if
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void SetSootopolisGymCrackedIceMetatiles(void)
+{
+ s32 x, y;
+ s32 width = gMapHeader.mapData->width;
+ s32 height = gMapHeader.mapData->height;
+ for (x = 0; x < width; x++)
+ {
+ for (y = 0; y < height; y++)
+ {
+ if (sub_809E184(x, y) == TRUE)
+ {
+ MapGridSetMetatileIdAt(x + 7, y + 7, 0x20e);
+ }
+ }
+ }
+}
+
+static void PerStepCallback_8069DD4(u8 taskId)
+{
+ s16 x, y;
+ u16 tileBehavior;
+ u16 *var;
+ s16 *data = gTasks[taskId].data;
+ switch (data[1])
+ {
+ case 0:
+ PlayerGetDestCoords(&x, &y);
+ data[2] = x;
+ data[3] = y;
+ data[1] = 1;
+ break;
+ case 1:
+ PlayerGetDestCoords(&x, &y);
+ if (x != data[2] || y != data[3])
+ {
+ data[2] = x;
+ data[3] = y;
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ var = GetVarPointer(VAR_ICE_STEP_COUNT);
+ if (MetatileBehavior_IsThinIce(tileBehavior) == TRUE)
+ {
+ (*var)++;
+ data[6] = 4;
+ data[1] = 2;
+ data[4] = x;
+ data[5] = y;
+ }
+ else if (MetatileBehavior_IsCrackedIce(tileBehavior) == TRUE)
+ {
+ *var = 0;
+ data[6] = 4;
+ data[1] = 3;
+ data[4] = x;
+ data[5] = y;
+ }
+ }
+ break;
+ case 2:
+ if (data[6] != 0)
+ {
+ data[6]--;
+ }
+ else
+ {
+ x = data[4];
+ y = data[5];
+ PlaySE(SE_RU_BARI);
+ MapGridSetMetatileIdAt(x, y, 0x20e);
+ CurrentMapDrawMetatileAt(x, y);
+ sub_809E14C(x - 7, y - 7);
+ data[1] = 1;
+ }
+ break;
+ case 3:
+ if (data[6] != 0)
+ {
+ data[6]--;
+ }
+ else
+ {
+ x = data[4];
+ y = data[5];
+ PlaySE(SE_RU_GASYAN);
+ MapGridSetMetatileIdAt(x, y, 0x206);
+ CurrentMapDrawMetatileAt(x, y);
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+static void PerStepCallback_8069F64(u8 taskId)
+{
+ s16 x, y;
+ u16 *var;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ if (x != data[1] || y != data[2])
+ {
+ data[1] = x;
+ data[2] = y;
+ if (MetatileBehavior_IsAsh(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ if (MapGridGetMetatileIdAt(x, y) == 0x20a)
+ {
+ ash(x, y, 0x212, 4);
+ }
+ else
+ {
+ ash(x, y, 0x206, 4);
+ }
+ if (CheckBagHasItem(ITEM_SOOT_SACK, 1))
+ {
+ var = GetVarPointer(VAR_ASH_GATHER_COUNT);
+ if (*var < 9999)
+ {
+ (*var)++;
+ }
+ }
+ }
+ }
+}
+
+static void sub_809E490(s16 x, s16 y)
+{
+ MapGridSetMetatileIdAt(x, y, MapGridGetMetatileIdAt(x, y) == 0x22f ? 0x206 : 0x237);
+ CurrentMapDrawMetatileAt(x, y);
+}
+
+static void PerStepCallback_806A07C(u8 taskId)
+{
+ s16 x, y;
+ u16 behavior;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ behavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (data[4] != 0 && (--data[4]) == 0)
+ {
+ sub_809E490(data[5], data[6]);
+ }
+ if (data[7] != 0 && (--data[7]) == 0)
+ {
+ sub_809E490(data[8], data[9]);
+ }
+ if (MetatileBehavior_IsCrackedFloorHole(behavior))
+ {
+ VarSet(VAR_ICE_STEP_COUNT, 0); // this var does double duty
+ }
+ if ((x != data[2] || y != data[3]))
+ {
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsCrackedFloor(behavior))
+ {
+ if (GetPlayerSpeed() != 4)
+ {
+ VarSet(VAR_ICE_STEP_COUNT, 0); // this var does double duty
+ }
+ if (data[4] == 0)
+ {
+ data[4] = 3;
+ data[5] = x;
+ data[6] = y;
+ }
+ else if (data[7] == 0)
+ {
+ data[7] = 3;
+ data[8] = x;
+ data[9] = y;
+ }
+ }
+ }
+}
+
+static void sub_809E5DC(s16 *data, s16 x, s16 y)
+{
+ u16 tile;
+ if ((--data[0]) == 0)
+ {
+ tile = 0xe8;
+ }
+ else
+ {
+ tile = gUnknown_085103FC[data[0] / 8];
+ }
+ MapGridSetMetatileIdAt(x, y, tile);
+ CurrentMapDrawMetatileAt(x, y);
+ MapGridSetMetatileIdAt(x, y, 0xe8);
+}
+
+static void Task_MuddySlope(u8 taskId)
+{
+ s16 x, y, x2, y2;
+ int i;
+ u16 mapIndices;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ mapIndices = (gSaveBlock1Ptr->location.mapGroup << 8) | gSaveBlock1Ptr->location.mapNum;
+ switch (data[1])
+ {
+ case 0:
+ data[0] = mapIndices;
+ data[2] = x;
+ data[3] = y;
+ data[1] = 1;
+ data[4] = 0;
+ data[7] = 0;
+ data[10] = 0;
+ data[13] = 0;
+ break;
+ case 1:
+ if (data[2] != x || data[3] != y)
+ {
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsMuddySlope(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ for (i=4; i<14; i+=3)
+ {
+ if (data[i] == 0)
+ {
+ data[i] = 32;
+ data[i + 1] = x;
+ data[i + 2] = y;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ if (gCamera.active && mapIndices != data[0])
+ {
+ data[0] = mapIndices;
+ x2 = gCamera.x;
+ y2 = gCamera.y;
+ }
+ else
+ {
+ x2 = 0;
+ y2 = 0;
+ }
+ for (i = 4; i < 14; i += 3)
+ {
+ if (data[i])
+ {
+ data[i + 1] -= x2;
+ data[i + 2] -= y2;
+ sub_809E5DC(&data[i], data[i + 1], data[i + 2]);
+ }
+ }
+}
diff --git a/src/fldeff_teleport.c b/src/fldeff_teleport.c
index e675ef0a5..1b88b42d7 100644
--- a/src/fldeff_teleport.c
+++ b/src/fldeff_teleport.c
@@ -37,7 +37,7 @@ bool8 FldEff_UseTeleport(void)
void sub_817C94C(void)
{
FieldEffectActiveListRemove(FLDEFF_USE_TELEPORT);
- sub_80B7FC8();
+ CreateTeleportFieldEffectTask();
}
diff --git a/src/fossil_specials.c b/src/fossil_specials.c
index 95fafc17b..060915fa6 100644
--- a/src/fossil_specials.c
+++ b/src/fossil_specials.c
@@ -335,7 +335,7 @@ static void sub_81BED50(u8 taskId)
}
#else
-ASM_DIRECT
+NAKED
static void sub_81BED50(u8 taskId)
{
asm("\n\
diff --git a/src/hof_pc.c b/src/hof_pc.c
index e5b6f96f8..44b929337 100644
--- a/src/hof_pc.c
+++ b/src/hof_pc.c
@@ -7,7 +7,6 @@
#include "script_menu.h"
#include "task.h"
-extern void (*gFieldCallback)(void);
extern void (*gUnknown_0300485C)(void);
extern void Overworld_PlaySpecialMapMusic(void);
diff --git a/src/item.c b/src/item.c
index 975fef3ae..319d167fc 100644
--- a/src/item.c
+++ b/src/item.c
@@ -234,7 +234,7 @@ bool8 CheckBagHasSpace(u16 itemId, u16 count)
}
}
#else
-ASM_DIRECT
+NAKED
bool8 CheckBagHasSpace(u16 itemId, u16 count)
{
asm_unified("push {r4-r7,lr}\n\
diff --git a/src/item_menu.c b/src/item_menu.c
index d7edea301..c4b4b15b1 100755
--- a/src/item_menu.c
+++ b/src/item_menu.c
@@ -26,7 +26,6 @@
#include "malloc.h"
#include "map_name_popup.h"
#include "menu.h"
-#include "menu_indicators.h"
#include "money.h"
#include "overworld.h"
#include "palette.h"
@@ -265,14 +264,12 @@ struct TempWallyStruct {
};
EWRAM_DATA struct UnkBagStruct *gUnknown_0203CE54 = 0;
-EWRAM_DATA struct BagStruct gUnknown_0203CE58 = {0, 0, 0, {0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}};
+EWRAM_DATA struct BagStruct gUnknown_0203CE58 = {0};
EWRAM_DATA struct ListBuffer1 *gUnknown_0203CE74 = 0;
EWRAM_DATA struct ListBuffer2 *gUnknown_0203CE78 = 0;
EWRAM_DATA u16 gSpecialVar_ItemId = 0;
EWRAM_DATA struct TempWallyStruct *gUnknown_0203CE80 = 0;
-void (*gFieldCallback)(void);
-
extern u8 *gPocketNamesStringsTable[];
extern u8 gUnknown_08D9A88C[];
extern struct ListMenuTemplate gUnknown_08613F9C;
@@ -752,7 +749,7 @@ void sub_81AB824(void)
void bag_menu_add_list_scroll_arrow_indicators_maybe(void)
{
if (gUnknown_0203CE54->unk81B != 1 && gUnknown_0203CE54->unk81F == 0xFF)
- gUnknown_0203CE54->unk81F = AddScrollIndicatorArrowPair(&gUnknown_08614094, gUnknown_0203CE58.unk6);
+ gUnknown_0203CE54->unk81F = AddScrollIndicatorArrowPair(&gUnknown_08614094, &gUnknown_0203CE58.unk6);
}
void sub_81AB89C(void)
diff --git a/src/item_use.c b/src/item_use.c
index 80b33220e..d036da6d3 100755
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -91,7 +91,6 @@ extern u8* sub_806CF78(u16);
extern void sub_81B89F0(void);
extern u8 GetItemEffectType(u16);
extern struct MapConnection *sub_8088A8C(s16, s16);
-extern void (*gFieldCallback)(void);
void MapPostLoadHook_UseItem(void);
void sub_80AF6D4(void);
@@ -167,7 +166,7 @@ void MapPostLoadHook_UseItem(void)
void Task_CallItemUseOnFieldCallback(u8 taskId)
{
- if (sub_80ABDFC() == 1)
+ if (IsWeatherNotFadingIn() == 1)
gUnknown_0203A0F4(taskId);
}
diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c
index ea244b6a0..1012a8e08 100644
--- a/src/lilycove_lady.c
+++ b/src/lilycove_lady.c
@@ -237,11 +237,11 @@ void sub_818D9C0(void)
{
LilycoveLady *lilycoveLady;
- VarSet(VAR_0x4010, sUnknown_0860B07E[GetLilycoveLadyId()]);
+ VarSet(VAR_OBJ_GFX_ID_0, sUnknown_0860B07E[GetLilycoveLadyId()]);
if (GetLilycoveLadyId() == LILYCOVE_LADY_CONTEST)
{
lilycoveLady = &gSaveBlock1Ptr->lilycoveLady;
- VarSet(VAR_0x4011, sUnknown_0860B074[lilycoveLady->contest.category]);
+ VarSet(VAR_OBJ_GFX_ID_1, sUnknown_0860B074[lilycoveLady->contest.category]);
gSpecialVar_Result = TRUE;
}
else
@@ -801,26 +801,26 @@ void sub_818E564(void)
EnableBothScriptContexts();
}
-void sub_818E570(const struct LilycoveLadyQuiz *quiz)
+void sub_818E570(const LilycoveLady *lilycoveLady)
{
u8 i;
gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz;
- if (quiz->unk_02c < 16 && gUnknown_0203CD68->id == LILYCOVE_LADY_QUIZ)
+ if (lilycoveLady->quiz.unk_02c < 16 && gUnknown_0203CD68->id == LILYCOVE_LADY_QUIZ)
{
for (i = 0; i < 4; i ++)
{
- if (quiz->unk_02c != gUnknown_0203CD68->unk_02b)
+ if (lilycoveLady->quiz.unk_02c != gUnknown_0203CD68->unk_02b)
{
break;
}
gUnknown_0203CD68->unk_02b = Random() % 16;
}
- if (quiz->unk_02c == gUnknown_0203CD68->unk_02b)
+ if (lilycoveLady->quiz.unk_02c == gUnknown_0203CD68->unk_02b)
{
gUnknown_0203CD68->unk_02b = (gUnknown_0203CD68->unk_02b + 1) % 16;
}
- gUnknown_0203CD68->unk_02c = quiz->unk_02c;
+ gUnknown_0203CD68->unk_02c = lilycoveLady->quiz.unk_02c;
}
}
diff --git a/src/link.c b/src/link.c
index 292ffecf2..acdb6cae0 100644
--- a/src/link.c
+++ b/src/link.c
@@ -798,7 +798,7 @@ bool32 sub_800A040(void)
return TRUE;
}
-bool32 sub_800A064(void)
+bool32 Link_AnyPartnersPlayingRubyOrSapphire(void)
{
if (sub_8009FF8(VERSION_RUBY, VERSION_SAPPHIRE) >= 0)
{
diff --git a/src/link_rfu.c b/src/link_rfu.c
index a1917ed24..37aa20950 100644
--- a/src/link_rfu.c
+++ b/src/link_rfu.c
@@ -2051,7 +2051,7 @@ u8 sub_800DD1C(u8 maxFlags)
return 0;
}
#else
-ASM_DIRECT u8 sub_800DD1C(u8 maxFlags)
+NAKED u8 sub_800DD1C(u8 maxFlags)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tlsls r0, 24\n"
@@ -2897,7 +2897,7 @@ void sub_800EFB0(void)
CpuFill16(0, gRecvCmds, sizeof gRecvCmds);
}
#else
-ASM_DIRECT void sub_800EFB0(void)
+NAKED void sub_800EFB0(void)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tsub sp, 0x4\n"
@@ -3233,7 +3233,7 @@ void sub_800F638(u8 unused, u32 flags)
}
}
#else
-ASM_DIRECT void sub_800F638(u8 unused, u32 flags)
+NAKED void sub_800F638(u8 unused, u32 flags)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r10\n"
@@ -3601,7 +3601,7 @@ void sub_800FD14(u16 command)
}
}
#else
-ASM_DIRECT void sub_800FD14(u16 command)
+NAKED void sub_800FD14(u16 command)
{
asm_unified("\tpush {r4,r5,lr}\n"
"\tlsls r0, 16\n"
@@ -4699,7 +4699,7 @@ void sub_801120C(u8 a0)
}
}
#else
-ASM_DIRECT void sub_801120C(u8 a0)
+NAKED void sub_801120C(u8 a0)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r10\n"
diff --git a/src/list_menu.c b/src/list_menu.c
index c78d32bb3..de7de8269 100644
--- a/src/list_menu.c
+++ b/src/list_menu.c
@@ -5,11 +5,16 @@
#include "text_window.h"
#include "main.h"
#include "task.h"
-#include "menu_indicators.h"
+#include "trig.h"
+#include "decompress.h"
+#include "palette.h"
+#include "malloc.h"
#include "strings.h"
#include "sound.h"
#include "constants/songs.h"
+// This file needs better labels and function names.
+
struct UnknownMysteryGiftLinkMenuStruct
{
s32 field_0;
@@ -29,7 +34,71 @@ struct UnknownListMenuPals
u8 field_3_7:1;
};
-extern struct UnknownMysteryGiftLinkMenuStruct gUnknown_0203CE84;
+struct UnkIndicatorsStruct
+{
+ u8 field_0;
+ u16 *field_4;
+ u16 field_8;
+ u16 field_A;
+ u16 field_C;
+ u16 field_E;
+ u8 field_10;
+ u8 field_11;
+ u8 field_12;
+ u8 field_13;
+ u8 field_14_0:4;
+ u8 field_14_1:4;
+ u8 field_15_0:4;
+ u8 field_15_1:4;
+ u8 field_16_0:3;
+ u8 field_16_1:3;
+ u8 field_16_2:2;
+ u8 field_17_0:6;
+ u8 field_17_1:2;
+};
+
+struct UnkIndicatorsStruct2
+{
+ u8 field_0;
+ u16 *field_4;
+ u16 field_8;
+ u16 field_A;
+ u8 field_C;
+ u8 field_D;
+ u16 tileTag;
+ u16 palTag;
+ u16 field_12;
+ u16 field_14;
+ u16 field_16;
+ u16 field_18;
+ u16 field_1A;
+ u16 field_1C;
+ s16 field_1E;
+};
+
+struct UnkIndicatorsStruct3
+{
+ struct SubspriteTable subspriteTable;
+ struct Subsprite *subspritesPtr; // not a const pointer
+ u8 spriteId;
+ u16 tileTag;
+ u16 palTag;
+};
+
+struct UnkIndicatorsStruct4
+{
+ u8 field_0;
+ u16 tileTag;
+ u16 palTag;
+};
+
+struct UnkSmallIndicatorsStruct
+{
+ u8 field_0_0:4;
+ u8 field_0_1:4;
+ u8 field_1;
+ u16 field_2;
+};
// this file's functions
static u8 ListMenuInitInternal(struct ListMenuTemplate *listMenuTemplate, u16 scrollOffset, u16 selectedRow);
@@ -38,11 +107,220 @@ static void ListMenuPrintEntries(struct ListMenu *list, u16 startIndex, u16 yOff
static void ListMenuDrawCursor(struct ListMenu *list);
static void ListMenuCallSelectionChangedCallback(struct ListMenu *list, u8 a2);
static u8 ListMenuAddCursorObject(struct ListMenu *list, u32 cursorKind);
+static void Task_ScrollIndicatorArrowPair(u8 taskId);
+static u8 ListMenuAddRedOutlineCursorObject(struct CursorStruct *cursor);
+static u8 ListMenuAddRedArrowCursorObject(struct CursorStruct *cursor);
+static void ListMenuUpdateRedOutlineCursorObject(u8 taskId, u16 x, u16 y);
+static void ListMenuUpdateRedArrowCursorObject(u8 taskId, u16 x, u16 y);
+static void ListMenuRemoveRedOutlineCursorObject(u8 taskId);
+static void ListMenuRemoveRedArrowCursorObject(u8 taskId);
+static u8 ListMenuAddCursorObjectInternal(struct CursorStruct *cursor, u32 cursorKind);
+static void ListMenuUpdateCursorObject(u8 taskId, u16 x, u16 y, u32 cursorKind);
+static void ListMenuRemoveCursorObject(u8 taskId, u32 cursorKind);
+static void sub_81AF264(struct Sprite *sprite);
+static void ObjectCB_RedArrowCursor(struct Sprite *sprite);
+
+// EWRAM vars
+ EWRAM_DATA struct UnknownMysteryGiftLinkMenuStruct gUnknown_0203CE84 = {0};
+ EWRAM_DATA struct ArrowStruct gUnknown_0203CE8C = {0};
// IWRAM common
struct UnknownListMenuPals gUnknown_03006300;
struct ListMenuTemplate gMultiuseListMenuTemplate;
+// const rom data
+static const struct UnkSmallIndicatorsStruct gUnknown_086141FC[] =
+{
+ {0, 0, 2, 8},
+ {1, 0, 2, -8},
+ {2, 1, 2, 8},
+ {3, 1, 2, -8},
+};
+
+static const struct OamData sOamData_861420C =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_8614214[] =
+{
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_861421C[] =
+{
+ ANIMCMD_FRAME(0, 30, 1, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8614224[] =
+{
+ ANIMCMD_FRAME(4, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_861422C[] =
+{
+ ANIMCMD_FRAME(4, 30, 0, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_8614234[] =
+{
+ sSpriteAnim_8614214,
+ sSpriteAnim_861421C,
+ sSpriteAnim_8614224,
+ sSpriteAnim_861422C
+};
+
+static const struct SpriteTemplate gUnknown_08614244 =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &sOamData_861420C,
+ .anims = sSpriteAnimTable_8614234,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_81AF264,
+};
+
+static const struct Subsprite sSubsprite_861425C =
+{
+ .x = 0,
+ .y = 0,
+ .shape = 0,
+ .size = 0,
+ .tileOffset = 0,
+ .priority = 0,
+};
+
+static const struct Subsprite sSubsprite_8614260 =
+{
+ .x = 0,
+ .y = 0,
+ .shape = 0,
+ .size = 0,
+ .tileOffset = 1,
+ .priority = 0,
+};
+
+static const struct Subsprite sSubsprite_8614264 =
+{
+ .x = 0,
+ .y = 0,
+ .shape = 0,
+ .size = 0,
+ .tileOffset = 2,
+ .priority = 0,
+};
+
+static const struct Subsprite sSubsprite_8614268 =
+{
+ .x = 0,
+ .y = 0,
+ .shape = 0,
+ .size = 0,
+ .tileOffset = 3,
+ .priority = 0,
+};
+
+static const struct Subsprite sSubsprite_861426C =
+{
+ .x = 0,
+ .y = 0,
+ .shape = 0,
+ .size = 0,
+ .tileOffset = 4,
+ .priority = 0,
+};
+
+static const struct Subsprite sSubsprite_8614270 =
+{
+ .x = 0,
+ .y = 0,
+ .shape = 0,
+ .size = 0,
+ .tileOffset = 5,
+ .priority = 0,
+};
+
+static const struct Subsprite sSubsprite_8614274 =
+{
+ .x = 0,
+ .y = 0,
+ .shape = 0,
+ .size = 0,
+ .tileOffset = 6,
+ .priority = 0,
+};
+
+static const struct Subsprite sSubsprite_8614278 =
+{
+ .x = 0,
+ .y = 0,
+ .shape = 0,
+ .size = 0,
+ .tileOffset = 7,
+ .priority = 0,
+};
+
+static const struct OamData sOamData_861427C =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_8614284[] =
+{
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_861428C[] =
+{
+ sSpriteAnim_8614284
+};
+
+static const struct SpriteTemplate gUnknown_08614290 =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &sOamData_861427C,
+ .anims = sSpriteAnimTable_861428C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = ObjectCB_RedArrowCursor,
+};
+
+static const u16 gUnknown_086142A8[] = INCBIN_U16("graphics/interface/red_arrow.gbapal");
+static const u8 gUnknown_086142C8[] = INCBIN_U8("graphics/interface/red_arrow_other.4bpp.lz");
+static const u8 gUnknown_08614338[] = INCBIN_U8("graphics/interface/selector_outline.4bpp.lz");
+static const u8 gUnknown_08614378[] = INCBIN_U8("graphics/interface/red_arrow.4bpp.lz");
+
// code
static void ListMenuDummyTask(u8 taskId)
{
@@ -415,9 +693,9 @@ static u8 ListMenuAddCursorObject(struct ListMenu *list, u32 cursorKind)
cursor.unk1 = 0xA0;
cursor.unk2 = GetWindowAttribute(list->template.windowId, WINDOW_WIDTH) * 8 + 2;
cursor.unk4 = GetFontAttribute(list->template.fontId, 1) + 2;
- cursor.unk6 = 0x4000;
- cursor.unk8 = 0xFFFF;
- cursor.unkA = 0xF;
+ cursor.tileTag = 0x4000;
+ cursor.palTag = 0xFFFF;
+ cursor.palNum = 0xF;
return ListMenuAddCursorObjectInternal(&cursor, cursorKind);
}
@@ -631,3 +909,547 @@ void sub_81AF078(s32 arg0, u8 arg1, struct ListMenu *list)
if (!arg1)
PlaySE(SE_SELECT);
}
+
+// unused
+s32 sub_81AF08C(u8 taskId, u8 field)
+{
+ struct UnkIndicatorsStruct *data = (void*) gTasks[taskId].data;
+
+ switch (field)
+ {
+ case 0:
+ case 1:
+ return (s32)(data->field_4);
+ case 2:
+ return data->field_C;
+ case 3:
+ return data->field_E;
+ case 4:
+ return data->field_10;
+ case 5:
+ return data->field_11;
+ case 6:
+ return data->field_12;
+ case 7:
+ return data->field_13;
+ case 8:
+ return data->field_14_0;
+ case 9:
+ return data->field_14_1;
+ case 10:
+ return data->field_15_0;
+ case 11:
+ return data->field_15_1;
+ case 12:
+ return data->field_16_0;
+ case 13:
+ return data->field_16_1;
+ case 14:
+ return data->field_16_2;
+ case 15:
+ return data->field_17_0;
+ case 16:
+ return data->field_17_1;
+ default:
+ return -1;
+ }
+}
+
+// unused
+void sub_81AF15C(u8 taskId, u8 field, s32 value)
+{
+ struct UnkIndicatorsStruct *data = (void*) &gTasks[taskId].data;
+
+ switch (field)
+ {
+ case 0:
+ case 1:
+ data->field_4 = (void*)(value);
+ break;
+ case 2:
+ data->field_C = value;
+ break;
+ case 3:
+ data->field_E = value;
+ break;
+ case 4:
+ data->field_10 = value;
+ break;
+ case 5:
+ data->field_11 = value;
+ break;
+ case 6:
+ data->field_12 = value;
+ break;
+ case 7:
+ data->field_13 = value;
+ break;
+ case 8:
+ data->field_14_0 = value;
+ break;
+ case 9:
+ data->field_14_1 = value;
+ break;
+ case 10:
+ data->field_15_0 = value;
+ break;
+ case 11:
+ data->field_15_1 = value;
+ break;
+ case 12:
+ data->field_16_0 = value;
+ break;
+ case 13:
+ data->field_16_1 = value;
+ break;
+ case 14:
+ data->field_16_2 = value;
+ break;
+ case 15:
+ data->field_17_0 = value;
+ break;
+ case 16:
+ data->field_17_1 = value;
+ break;
+ }
+}
+
+static void sub_81AF264(struct Sprite *sprite)
+{
+ s32 multiplier;
+
+ switch (sprite->data[0])
+ {
+ case 0:
+ StartSpriteAnim(sprite, sprite->data[1]);
+ sprite->data[0]++;
+ break;
+ case 1:
+ switch (sprite->data[2])
+ {
+ case 0:
+ multiplier = sprite->data[3];
+ sprite->pos2.x = (gSineTable[(u8)(sprite->data[5])] * multiplier) / 256;
+ break;
+ case 1:
+ multiplier = sprite->data[3];
+ sprite->pos2.y = (gSineTable[(u8)(sprite->data[5])] * multiplier) / 256;
+ break;
+ }
+ sprite->data[5] += sprite->data[4];
+ break;
+ }
+}
+
+static u8 AddScrollIndicatorArrowObject(u8 arg0, u8 x, u8 y, u16 tileTag, u16 palTag)
+{
+ u8 spriteId;
+ struct SpriteTemplate spriteTemplate;
+
+ spriteTemplate = gUnknown_08614244;
+ spriteTemplate.tileTag = tileTag;
+ spriteTemplate.paletteTag = palTag;
+
+ spriteId = CreateSprite(&spriteTemplate, x, y, 0);
+ gSprites[spriteId].invisible = 1;
+ gSprites[spriteId].data[0] = 0;
+ gSprites[spriteId].data[1] = gUnknown_086141FC[arg0].field_0_0;
+ gSprites[spriteId].data[2] = gUnknown_086141FC[arg0].field_0_1;
+ gSprites[spriteId].data[3] = gUnknown_086141FC[arg0].field_1;
+ gSprites[spriteId].data[4] = gUnknown_086141FC[arg0].field_2;
+ gSprites[spriteId].data[5] = 0;
+
+ return spriteId;
+}
+
+u8 AddScrollIndicatorArrowPair(const struct ArrowStruct *arrowInfo, u16 *arg1)
+{
+ struct CompressedSpriteSheet spriteSheet;
+ struct SpritePalette spritePal;
+ struct UnkIndicatorsStruct2 *data;
+ u8 taskId;
+
+ spriteSheet.data = gUnknown_086142C8;
+ spriteSheet.size = 0x100;
+ spriteSheet.tag = arrowInfo->tileTag;
+ LoadCompressedObjectPic(&spriteSheet);
+
+ if (arrowInfo->palTag == 0xFFFF)
+ {
+ LoadPalette(gUnknown_086142A8, (16 * arrowInfo->palNum) + 0x100, 0x20);
+ }
+ else
+ {
+ spritePal.data = gUnknown_086142A8;
+ spritePal.tag = arrowInfo->palTag;
+ LoadSpritePalette(&spritePal);
+ }
+
+ taskId = CreateTask(Task_ScrollIndicatorArrowPair, 0);
+ data = (void*) gTasks[taskId].data;
+
+ data->field_0 = 0;
+ data->field_4 = arg1;
+ data->field_8 = arrowInfo->unk6;
+ data->field_A = arrowInfo->unk8;
+ data->tileTag = arrowInfo->tileTag;
+ data->palTag = arrowInfo->palTag;
+ data->field_C = AddScrollIndicatorArrowObject(arrowInfo->unk0, arrowInfo->unk1, arrowInfo->unk2, arrowInfo->tileTag, arrowInfo->palTag);
+ data->field_D = AddScrollIndicatorArrowObject(arrowInfo->unk3, arrowInfo->unk4, arrowInfo->unk5, arrowInfo->tileTag, arrowInfo->palTag);
+
+ if (arrowInfo->palTag == 0xFFFF)
+ {
+ gSprites[data->field_C].oam.paletteNum = arrowInfo->palNum;
+ gSprites[data->field_D].oam.paletteNum = arrowInfo->palNum;
+ }
+
+ return taskId;
+}
+
+u8 AddScrollIndicatorArrowPairParametrized(u32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 tileTag, s32 palTag, void *arg7)
+{
+ if (arg0 == 2 || arg0 == 3)
+ {
+ gUnknown_0203CE8C.unk0 = 2;
+ gUnknown_0203CE8C.unk1 = arg1;
+ gUnknown_0203CE8C.unk2 = arg2;
+ gUnknown_0203CE8C.unk3 = 3;
+ gUnknown_0203CE8C.unk4 = arg1;
+ gUnknown_0203CE8C.unk5 = arg3;
+ }
+ else
+ {
+ gUnknown_0203CE8C.unk0 = 0;
+ gUnknown_0203CE8C.unk1 = arg2;
+ gUnknown_0203CE8C.unk2 = arg1;
+ gUnknown_0203CE8C.unk3 = 1;
+ gUnknown_0203CE8C.unk4 = arg3;
+ gUnknown_0203CE8C.unk5 = arg1;
+ }
+
+ gUnknown_0203CE8C.unk6 = 0;
+ gUnknown_0203CE8C.unk8 = arg4;
+ gUnknown_0203CE8C.tileTag = tileTag;
+ gUnknown_0203CE8C.palTag = palTag;
+ gUnknown_0203CE8C.palNum = 0;
+
+ return AddScrollIndicatorArrowPair(&gUnknown_0203CE8C, arg7);
+}
+
+static void Task_ScrollIndicatorArrowPair(u8 taskId)
+{
+ struct UnkIndicatorsStruct2 *data = (void*) gTasks[taskId].data;
+ u16 var = (*data->field_4);
+
+ if (var == data->field_8 && var != 0xFFFF)
+ gSprites[data->field_C].invisible = 1;
+ else
+ gSprites[data->field_C].invisible = 0;
+
+ if (var == data->field_A)
+ gSprites[data->field_D].invisible = 1;
+ else
+ gSprites[data->field_D].invisible = 0;
+}
+
+void Task_ScrollIndicatorArrowPairOnMainMenu(u8 taskId)
+{
+ struct UnkIndicatorsStruct2 *data = (void*) gTasks[taskId].data;
+
+ if (data->field_1E != 0)
+ {
+ gSprites[data->field_C].invisible = 0;
+ gSprites[data->field_D].invisible = 1;
+ }
+ else
+ {
+ gSprites[data->field_C].invisible = 1;
+ gSprites[data->field_D].invisible = 0;
+ }
+}
+
+void RemoveScrollIndicatorArrowPair(u8 taskId)
+{
+ struct UnkIndicatorsStruct2 *data = (void*) gTasks[taskId].data;
+
+ if (data->tileTag != 0xFFFF)
+ FreeSpriteTilesByTag(data->tileTag);
+ if (data->palTag != 0xFFFF)
+ FreeSpritePaletteByTag(data->palTag);
+
+ DestroySprite(&gSprites[data->field_C]);
+ DestroySprite(&gSprites[data->field_D]);
+
+ DestroyTask(taskId);
+}
+
+static u8 ListMenuAddCursorObjectInternal(struct CursorStruct *cursor, u32 cursorKind)
+{
+ switch (cursorKind)
+ {
+ case 0:
+ default:
+ return ListMenuAddRedOutlineCursorObject(cursor);
+ case 1:
+ return ListMenuAddRedArrowCursorObject(cursor);
+ }
+}
+
+static void ListMenuUpdateCursorObject(u8 taskId, u16 x, u16 y, u32 cursorKind)
+{
+ switch (cursorKind)
+ {
+ case 0:
+ ListMenuUpdateRedOutlineCursorObject(taskId, x, y);
+ break;
+ case 1:
+ ListMenuUpdateRedArrowCursorObject(taskId, x, y);
+ break;
+ }
+}
+
+static void ListMenuRemoveCursorObject(u8 taskId, u32 cursorKind)
+{
+ switch (cursorKind)
+ {
+ case 0:
+ ListMenuRemoveRedOutlineCursorObject(taskId);
+ break;
+ case 1:
+ ListMenuRemoveRedArrowCursorObject(taskId);
+ break;
+ }
+}
+
+static void Task_RedOutlineCursor(u8 taskId)
+{
+
+}
+
+u8 ListMenuGetRedOutlineCursorSpriteCount(u16 arg0, u16 arg1)
+{
+ s32 i;
+ s32 count = 4;
+
+ if (arg0 > 16)
+ {
+ for (i = 8; i < (arg0 - 8); i += 8)
+ count += 2;
+ }
+ if (arg1 > 16)
+ {
+ for (i = 8; i < (arg1 - 8); i += 8)
+ count += 2;
+ }
+
+ return count;
+}
+
+void ListMenuSetUpRedOutlineCursorSpriteOamTable(u16 arg0, u16 arg1, struct Subsprite *subsprites)
+{
+ s32 i, j, id = 0;
+
+ subsprites[id] = sSubsprite_861425C;
+ subsprites[id].x = 136;
+ subsprites[id].y = 136;
+ id++;
+
+ subsprites[id] = sSubsprite_8614260;
+ subsprites[id].x = arg0 + 128;
+ subsprites[id].y = 136;
+ id++;
+
+ subsprites[id] = sSubsprite_8614274;
+ subsprites[id].x = 136;
+ subsprites[id].y = arg1 + 128;
+ id++;
+
+ subsprites[id] = sSubsprite_8614278;
+ subsprites[id].x = arg0 + 128;
+ subsprites[id].y = arg1 + 128;
+ id++;
+
+ if (arg0 > 16)
+ {
+ for (i = 8; i < arg0 - 8; i += 8)
+ {
+ subsprites[id] = sSubsprite_8614264;
+ subsprites[id].x = i - 120;
+ subsprites[id].y = 136;
+ id++;
+
+ subsprites[id] = sSubsprite_8614270;
+ subsprites[id].x = i - 120;
+ subsprites[id].y = arg1 + 128;
+ id++;
+ }
+ }
+
+ if (arg1 > 16)
+ {
+ for (j = 8; j < arg1 - 8; j += 8)
+ {
+ subsprites[id] = sSubsprite_8614268;
+ subsprites[id].x = 136;
+ subsprites[id].y = j - 120;
+ id++;
+
+ subsprites[id] = sSubsprite_861426C;
+ subsprites[id].x = arg0 + 128;
+ subsprites[id].y = j - 120;
+ id++;
+ }
+ }
+}
+
+static u8 ListMenuAddRedOutlineCursorObject(struct CursorStruct *cursor)
+{
+ struct CompressedSpriteSheet spriteSheet;
+ struct SpritePalette spritePal;
+ struct UnkIndicatorsStruct3 *data;
+ struct SpriteTemplate spriteTemplate;
+ u8 taskId;
+
+ spriteSheet.data = gUnknown_08614338;
+ spriteSheet.size = 0x100;
+ spriteSheet.tag = cursor->tileTag;
+ LoadCompressedObjectPic(&spriteSheet);
+
+ if (cursor->palTag == 0xFFFF)
+ {
+ LoadPalette(gUnknown_086142A8, (16 * cursor->palNum) + 0x100, 0x20);
+ }
+ else
+ {
+ spritePal.data = gUnknown_086142A8;
+ spritePal.tag = cursor->palTag;
+ LoadSpritePalette(&spritePal);
+ }
+
+ taskId = CreateTask(Task_RedOutlineCursor, 0);
+ data = (void*) gTasks[taskId].data;
+
+ data->tileTag = cursor->tileTag;
+ data->palTag = cursor->palTag;
+ data->subspriteTable.subspriteCount = ListMenuGetRedOutlineCursorSpriteCount(cursor->unk2, cursor->unk4);
+ data->subspriteTable.subsprites = data->subspritesPtr = Alloc(data->subspriteTable.subspriteCount * 4);
+ ListMenuSetUpRedOutlineCursorSpriteOamTable(cursor->unk2, cursor->unk4, data->subspritesPtr);
+
+ spriteTemplate = gDummySpriteTemplate;
+ spriteTemplate.tileTag = cursor->tileTag;
+ spriteTemplate.paletteTag = cursor->palTag;
+
+ data->spriteId = CreateSprite(&spriteTemplate, cursor->unk0 + 120, cursor->unk1 + 120, 0);
+ SetSubspriteTables(&gSprites[data->spriteId], &data->subspriteTable);
+ gSprites[data->spriteId].oam.priority = 0;
+ gSprites[data->spriteId].subpriority = 0;
+ gSprites[data->spriteId].subspriteTableNum = 0;
+
+ if (cursor->palTag == 0xFFFF)
+ {
+ gSprites[data->spriteId].oam.paletteNum = cursor->palNum;
+ }
+
+ return taskId;
+}
+
+static void ListMenuUpdateRedOutlineCursorObject(u8 taskId, u16 x, u16 y)
+{
+ struct UnkIndicatorsStruct3 *data = (void*) gTasks[taskId].data;
+
+ gSprites[data->spriteId].pos1.x = x + 120;
+ gSprites[data->spriteId].pos1.y = y + 120;
+}
+
+static void ListMenuRemoveRedOutlineCursorObject(u8 taskId)
+{
+ struct UnkIndicatorsStruct3 *data = (void*) gTasks[taskId].data;
+
+ Free(data->subspritesPtr);
+
+ if (data->tileTag != 0xFFFF)
+ FreeSpriteTilesByTag(data->tileTag);
+ if (data->palTag != 0xFFFF)
+ FreeSpritePaletteByTag(data->palTag);
+
+ DestroySprite(&gSprites[data->spriteId]);
+ DestroyTask(taskId);
+}
+
+static void ObjectCB_RedArrowCursor(struct Sprite *sprite)
+{
+ sprite->pos2.x = gSineTable[(u8)(sprite->data[0])] / 64;
+ sprite->data[0] += 8;
+}
+
+static void Task_RedArrowCursor(u8 taskId)
+{
+
+}
+
+static u8 ListMenuAddRedArrowCursorObject(struct CursorStruct *cursor)
+{
+ struct CompressedSpriteSheet spriteSheet;
+ struct SpritePalette spritePal;
+ struct UnkIndicatorsStruct4 *data;
+ struct SpriteTemplate spriteTemplate;
+ u8 taskId;
+
+ spriteSheet.data = gUnknown_08614378;
+ spriteSheet.size = 0x80;
+ spriteSheet.tag = cursor->tileTag;
+ LoadCompressedObjectPic(&spriteSheet);
+
+ if (cursor->palTag == 0xFFFF)
+ {
+ LoadPalette(gUnknown_086142A8, (16 * cursor->palNum) + 0x100, 0x20);
+ }
+ else
+ {
+ spritePal.data = gUnknown_086142A8;
+ spritePal.tag = cursor->palTag;
+ LoadSpritePalette(&spritePal);
+ }
+
+ taskId = CreateTask(Task_RedArrowCursor, 0);
+ data = (void*) gTasks[taskId].data;
+
+ data->tileTag = cursor->tileTag;
+ data->palTag = cursor->palTag;
+
+ spriteTemplate = gUnknown_08614290;
+ spriteTemplate.tileTag = cursor->tileTag;
+ spriteTemplate.paletteTag = cursor->palTag;
+
+ data->field_0 = CreateSprite(&spriteTemplate, cursor->unk0, cursor->unk1, 0);
+ gSprites[data->field_0].pos2.x = 8;
+ gSprites[data->field_0].pos2.y = 8;
+
+ if (cursor->palTag == 0xFFFF)
+ {
+ gSprites[data->field_0].oam.paletteNum = cursor->palNum;
+ }
+
+ return taskId;
+}
+
+static void ListMenuUpdateRedArrowCursorObject(u8 taskId, u16 x, u16 y)
+{
+ struct UnkIndicatorsStruct4 *data = (void*) gTasks[taskId].data;
+
+ gSprites[data->field_0].pos1.x = x;
+ gSprites[data->field_0].pos1.y = y;
+}
+
+static void ListMenuRemoveRedArrowCursorObject(u8 taskId)
+{
+ struct UnkIndicatorsStruct4 *data = (void*) gTasks[taskId].data;
+
+ if (data->tileTag != 0xFFFF)
+ FreeSpriteTilesByTag(data->tileTag);
+ if (data->palTag != 0xFFFF)
+ FreeSpritePaletteByTag(data->palTag);
+
+ DestroySprite(&gSprites[data->field_0]);
+ DestroyTask(taskId);
+}
diff --git a/src/main_menu.c b/src/main_menu.c
index 3d6c1df76..3490424af 100644
--- a/src/main_menu.c
+++ b/src/main_menu.c
@@ -16,7 +16,7 @@
#include "link.h"
#include "main.h"
#include "menu.h"
-#include "menu_indicators.h"
+#include "list_menu.h"
#include "mystery_event_menu.h"
#include "naming_screen.h"
#include "option_menu.h"
diff --git a/src/map_name_popup.c b/src/map_name_popup.c
index 59b1622eb..1782e9af8 100644
--- a/src/map_name_popup.c
+++ b/src/map_name_popup.c
@@ -276,7 +276,7 @@ static void sub_80D4A78(u8 bg, u8 x, u8 y, u8 deltaX, u8 deltaY, u8 unused)
}
}
#else
-ASM_DIRECT
+NAKED
static void sub_80D4A78(u8 bg, u8 x, u8 y, u8 deltaX, u8 deltaY, u8 unused)
{
asm("\n\
diff --git a/src/match_call.c b/src/match_call.c
index 9c1e02947..aa6945161 100644
--- a/src/match_call.c
+++ b/src/match_call.c
@@ -980,7 +980,7 @@ static void sub_81D199C(const match_call_text_data_t *sub0, u16 idx, u8 *dest)
}
}
#else
-static ASM_DIRECT void sub_81D199C(const match_call_text_data_t *sub0, u16 idx, u8 *dest)
+static NAKED void sub_81D199C(const match_call_text_data_t *sub0, u16 idx, u8 *dest)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r10\n"
@@ -1163,7 +1163,7 @@ const u8 *sub_81D1B40(u32 idx, u32 offset)
return NULL;
}
#else
-ASM_DIRECT const u8 *sub_81D1B40(u32 idx, u32 offset)
+NAKED const u8 *sub_81D1B40(u32 idx, u32 offset)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r9\n"
diff --git a/src/mauville_old_man.c b/src/mauville_old_man.c
index ea466b2ec..2ce8a271d 100644
--- a/src/mauville_old_man.c
+++ b/src/mauville_old_man.c
@@ -387,7 +387,7 @@ static void ResetStorytellerFlag(void)
Storyteller_ResetFlag();
}
-void ResetMauvilleOldManFlag(void) // ResetMauvilleOldManFlag
+void ResetMauvilleOldManFlag(void)
{
switch (GetCurrentMauvilleOldMan())
{
@@ -673,7 +673,7 @@ static void Task_BardSong(u8 taskId)
void ScrSpecial_SetMauvilleOldManMapObjGfx(void)
{
- VarSet(VAR_0x4010, MAP_OBJ_GFX_BARD);
+ VarSet(VAR_OBJ_GFX_ID_0, MAP_OBJ_GFX_BARD);
}
// Language fixers?
@@ -793,11 +793,11 @@ void sub_8120C0C(union OldMan * oldMan, u32 r8, u32 r7, u32 r3)
}
}
-void sub_8120CD0(union OldMan * oldMan, u32 unused, u32 a2)
+void SanitizeReceivedEmeraldOldMan(union OldMan * oldMan, u32 version, u32 language)
{
u8 sp00[8];
s32 i;
- if (oldMan->common.id == MAUVILLE_MAN_STORYTELLER && a2 == LANGUAGE_JAPANESE)
+ if (oldMan->common.id == MAUVILLE_MAN_STORYTELLER && language == LANGUAGE_JAPANESE)
{
struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
@@ -816,9 +816,10 @@ void sub_8120CD0(union OldMan * oldMan, u32 unused, u32 a2)
}
}
-void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
+void SanitizeReceivedRubyOldMan(union OldMan * oldMan, u32 version, u32 language)
{
- u32 r2 = (r1 == LANGUAGE_JAPANESE || r1 == LANGUAGE_ENGLISH) ? 1 : 0;
+ bool32 isRuby = (version == VERSION_SAPPHIRE || version == VERSION_RUBY);
+
switch (oldMan->common.id)
{
case MAUVILLE_MAN_TRADER:
@@ -826,7 +827,7 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
struct MauvilleOldManTrader * trader = &oldMan->trader;
s32 i;
- if (r2)
+ if (isRuby)
{
for (i = 0; i < 4; i++)
{
@@ -837,7 +838,7 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
trader->language[i] = LANGUAGE_JAPANESE;
}
else
- trader->language[i] = r6;
+ trader->language[i] = language;
}
}
else
@@ -858,12 +859,12 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
s32 i;
- if (r2)
+ if (isRuby)
{
for (i = 0; i < 4; i++)
{
if (storyteller->gameStatIDs[i] != 0)
- storyteller->language[i] = r6;
+ storyteller->language[i] = language;
}
}
}
@@ -872,9 +873,9 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
{
struct MauvilleManBard * bard = &oldMan->bard;
- if (r2)
+ if (isRuby)
{
- bard->language = r6;
+ bard->language = language;
}
}
break;
@@ -882,9 +883,9 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
{
struct MauvilleManHipster * hipster = &oldMan->hipster;
- if (r2)
+ if (isRuby)
{
- hipster->language = r6;
+ hipster->language = language;
}
}
break;
@@ -892,9 +893,9 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
{
struct MauvilleManGiddy * giddy = &oldMan->giddy;
- if (r2)
+ if (isRuby)
{
- giddy->language = r6;
+ giddy->language = language;
}
}
break;
diff --git a/src/menu.c b/src/menu.c
index 0aaf2d186..dedfcc3be 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -2080,7 +2080,7 @@ void sub_819A080(struct UnkStruct_819A080 *a0, struct UnkStruct_819A080 *a1, u16
}
}
#else
-__attribute__((naked))
+NAKED
void sub_819A080(struct UnkStruct_819A080 *a0, struct UnkStruct_819A080 *a1, u16 a2, u16 a3, u16 a4, u16 a5, u16 a6, u16 a7)
{
asm("push {r4-r7,lr}\n\
diff --git a/src/menu_helpers.c b/src/menu_helpers.c
new file mode 100644
index 000000000..178fbb5fa
--- /dev/null
+++ b/src/menu_helpers.c
@@ -0,0 +1,455 @@
+#include "global.h"
+#include "task.h"
+#include "window.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "gpu_regs.h"
+#include "bg.h"
+#include "main.h"
+#include "text.h"
+#include "link.h"
+#include "string_util.h"
+#include "sound.h"
+#include "mail.h"
+#include "overworld.h"
+#include "decompress.h"
+#include "constants/songs.h"
+#include "constants/items.h"
+#include "constants/maps.h"
+
+extern bool32 sub_800B504(void);
+
+extern const u8 gBagSwapLineGfx[];
+extern const u8 gBagSwapLinePal[];
+
+// this file's functions
+static void Task_ContinueTaskAfterMessagePrints(u8 taskId);
+static void Task_CallYesOrNoCallback(u8 taskId);
+
+// EWRAM vars
+EWRAM_DATA static struct YesNoFuncTable gUnknown_0203A138 = {0};
+EWRAM_DATA static u8 gUnknown_0203A140 = 0;
+
+// IWRAM bss vars
+IWRAM_DATA static TaskFunc gUnknown_0300117C;
+
+// const rom data
+static const struct OamData sOamData_859F4E8 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_859F4F0[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_859F4F8[] =
+{
+ ANIMCMD_FRAME(4, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_859F500[] =
+{
+ ANIMCMD_FRAME(0, 0, 1, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_859F508[] =
+{
+ sSpriteAnim_859F4F0,
+ sSpriteAnim_859F4F8,
+ sSpriteAnim_859F500
+};
+
+static const struct CompressedSpriteSheet gUnknown_0859F514 =
+{
+ gBagSwapLineGfx, 0x100, 109
+};
+
+static const struct CompressedSpritePalette gUnknown_0859F51C =
+{
+ gBagSwapLinePal, 109
+};
+
+static const struct SpriteTemplate gUnknown_0859F524 =
+{
+ .tileTag = 109,
+ .paletteTag = 109,
+ .oam = &sOamData_859F4E8,
+ .anims = sSpriteAnimTable_859F508,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+// code
+void ResetVramOamAndBgCntRegs(void)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG3CNT, 0);
+ SetGpuReg(REG_OFFSET_BG2CNT, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, 0);
+ CpuFill16(0, (void*) VRAM, VRAM_SIZE);
+ CpuFill32(0, (void*) OAM, OAM_SIZE);
+ CpuFill16(0, (void*) PLTT, PLTT_SIZE);
+}
+
+void ResetAllBgsCoordinates(void)
+{
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ ChangeBgX(1, 0, 0);
+ ChangeBgY(1, 0, 0);
+ ChangeBgX(2, 0, 0);
+ ChangeBgY(2, 0, 0);
+ ChangeBgX(3, 0, 0);
+ ChangeBgY(3, 0, 0);
+}
+
+void SetVBlankHBlankCallbacksToNull(void)
+{
+ SetVBlankCallback(NULL);
+ SetHBlankCallback(NULL);
+}
+
+void DisplayMessageAndContinueTask(u8 taskId, u8 windowId, u16 arg2, u8 arg3, u8 fontId, u8 textSpeed, const u8 *string, void *taskFunc)
+{
+ gUnknown_0203A140 = windowId;
+ sub_8197B1C(windowId, TRUE, arg2, arg3);
+
+ if (string != gStringVar4)
+ StringExpandPlaceholders(gStringVar4, string);
+
+ gTextFlags.flag_0 = 1;
+ AddTextPrinterParameterized(windowId, fontId, gStringVar4, textSpeed, NULL, 2, 1, 3);
+ gUnknown_0300117C = taskFunc;
+ gTasks[taskId].func = Task_ContinueTaskAfterMessagePrints;
+}
+
+bool16 RunTextPrintersRetIsActive(u8 textPrinterId)
+{
+ RunTextPrinters();
+ return IsTextPrinterActive(textPrinterId);
+}
+
+static void Task_ContinueTaskAfterMessagePrints(u8 taskId)
+{
+ if (!RunTextPrintersRetIsActive(gUnknown_0203A140))
+ gUnknown_0300117C(taskId);
+}
+
+void sub_8121F68(u8 taskId, const struct YesNoFuncTable *data)
+{
+ gUnknown_0203A138 = *data;
+ gTasks[taskId].func = Task_CallYesOrNoCallback;
+}
+
+void CreateYesNoMenuWithCallbacks(u8 taskId, const struct WindowTemplate *template, u8 arg2, u8 arg3, u8 arg4, u16 tileStart, u8 palette, const struct YesNoFuncTable *yesNo)
+{
+ CreateYesNoMenu(template, tileStart, palette, 0);
+ gUnknown_0203A138 = *yesNo;
+ gTasks[taskId].func = Task_CallYesOrNoCallback;
+}
+
+static void Task_CallYesOrNoCallback(u8 taskId)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0:
+ PlaySE(SE_SELECT);
+ gUnknown_0203A138.yesFunc(taskId);
+ break;
+ case 1:
+ case MENU_B_PRESSED:
+ PlaySE(SE_SELECT);
+ gUnknown_0203A138.noFunc(taskId);
+ break;
+ }
+}
+
+bool8 AdjustQuantityAccordingToDPadInput(s16 *arg0, u16 arg1)
+{
+ s16 valBefore = (*arg0);
+
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_UP)
+ {
+ (*arg0)++;
+ if ((*arg0) > arg1)
+ (*arg0) = 1;
+
+ if ((*arg0) == valBefore)
+ {
+ return FALSE;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_DOWN)
+ {
+ (*arg0)--;
+ if ((*arg0) <= 0)
+ (*arg0) = arg1;
+
+ if ((*arg0) == valBefore)
+ {
+ return FALSE;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_RIGHT)
+ {
+ (*arg0) += 10;
+ if ((*arg0) > arg1)
+ (*arg0) = arg1;
+
+ if ((*arg0) == valBefore)
+ {
+ return FALSE;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_LEFT)
+ {
+ (*arg0) -= 10;
+ if ((*arg0) <= 0)
+ (*arg0) = 1;
+
+ if ((*arg0) == valBefore)
+ {
+ return FALSE;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+u8 GetLRKeysState(void)
+{
+ if (gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR)
+ {
+ if (gMain.newKeys & L_BUTTON)
+ return 1;
+ if (gMain.newKeys & R_BUTTON)
+ return 2;
+ }
+
+ return 0;
+}
+
+u8 sub_812210C(void)
+{
+ if (gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR)
+ {
+ if (gMain.newAndRepeatedKeys & L_BUTTON)
+ return 1;
+ if (gMain.newAndRepeatedKeys & R_BUTTON)
+ return 2;
+ }
+
+ return 0;
+}
+
+bool8 sub_8122148(u16 itemId)
+{
+ if (itemId != ITEM_ENIGMA_BERRY)
+ return TRUE;
+ else if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(TRADE_CENTER) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(TRADE_CENTER))
+ return FALSE;
+ else if (InUnionRoom() != TRUE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 itemid_80BF6D8_mail_related(u16 itemId)
+{
+ if (is_c1_link_related_active() != TRUE && InUnionRoom() != TRUE)
+ return TRUE;
+ else if (ItemIsMail(itemId) != TRUE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_81221AC(void)
+{
+ if (is_c1_link_related_active() == TRUE || gReceivedRemoteLinkPlayers == 1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 sub_81221D0(void)
+{
+ if (!sub_81221AC())
+ return FALSE;
+ else
+ return sub_8087598();
+}
+
+bool8 sub_81221EC(void)
+{
+ if (sub_81221D0() == TRUE)
+ return TRUE;
+ else if (sub_800B504() != TRUE)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void sub_812220C(struct ItemSlot *slots, u8 count, u8 *arg2, u8 *usedSlotsCount, u8 maxUsedSlotsCount)
+{
+ u16 i;
+ struct ItemSlot *slots_ = slots;
+
+ (*usedSlotsCount) = 0;
+ for (i = 0; i < count; i++)
+ {
+ if (slots_[i].itemId != ITEM_NONE)
+ (*usedSlotsCount)++;
+ }
+
+ (*usedSlotsCount)++;
+ if ((*usedSlotsCount) > maxUsedSlotsCount)
+ *arg2 = maxUsedSlotsCount;
+ else
+ *arg2 = (*usedSlotsCount);
+}
+
+void sub_812225C(u16 *arg0, u16 *arg1, u8 arg2, u8 arg3)
+{
+ if ((*arg0) != 0 && (*arg0) + arg2 > arg3)
+ (*arg0) = arg3 - arg2;
+
+ if ((*arg0) + (*arg1) >= arg3)
+ {
+ if (arg3 == 0)
+ (*arg1) = 0;
+ else
+ (*arg1) = arg3 - 1;
+ }
+}
+
+void sub_8122298(u16 *arg0, u16 *arg1, u8 arg2, u8 arg3, u8 arg4)
+{
+ u8 i;
+
+ if (arg4 % 2 != 0)
+ {
+ if ((*arg1) >= arg4 / 2)
+ {
+ for (i = 0; i < (*arg1) - (arg4 / 2); i++)
+ {
+ if ((*arg0) + arg2 == arg3)
+ break;
+ (*arg1)--;
+ (*arg0)++;
+ }
+ }
+ }
+ else
+ {
+ if ((*arg1) >= (arg4 / 2) + 1)
+ {
+ for (i = 0; i <= (*arg1) - (arg4 / 2); i++)
+ {
+ if ((*arg0) + arg2 == arg3)
+ break;
+ (*arg1)--;
+ (*arg0)++;
+ }
+ }
+ }
+}
+
+void LoadListMenuArrowsGfx(void)
+{
+ LoadCompressedObjectPic(&gUnknown_0859F514);
+ LoadCompressedObjectPalette(&gUnknown_0859F51C);
+}
+
+void sub_8122344(u8 *spriteIds, u8 count)
+{
+ u8 i;
+
+ for (i = 0; i < count; i++)
+ {
+ spriteIds[i] = CreateSprite(&gUnknown_0859F524, i * 16, 0, 0);
+ if (i != 0)
+ StartSpriteAnim(&gSprites[spriteIds[i]], 1);
+
+ gSprites[spriteIds[i]].invisible = 1;
+ }
+}
+
+void sub_81223B0(u8 *spriteIds, u8 count)
+{
+ u8 i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (i == count - 1)
+ DestroySpriteAndFreeResources(&gSprites[spriteIds[i]]);
+ else
+ DestroySprite(&gSprites[spriteIds[i]]);
+ }
+}
+
+void sub_81223FC(u8 *spriteIds, u8 count, bool8 invisible)
+{
+ u8 i;
+
+ for (i = 0; i < count; i++)
+ {
+ gSprites[spriteIds[i]].invisible = invisible;
+ }
+}
+
+void sub_8122448(u8 *spriteIds, u8 count, s16 x, u16 y)
+{
+ u8 i;
+ bool8 unknownBit = count & 0x80;
+ count &= ~(0x80);
+
+ for (i = 0; i < count; i++)
+ {
+ if (i == count - 1 && unknownBit)
+ gSprites[spriteIds[i]].pos2.x = x - 8;
+ else
+ gSprites[spriteIds[i]].pos2.x = x;
+
+ gSprites[spriteIds[i]].pos1.y = 1 + y;
+ }
+}
diff --git a/src/mon_markings.c b/src/mon_markings.c
index 147872ab6..7f320002d 100644
--- a/src/mon_markings.c
+++ b/src/mon_markings.c
@@ -2,7 +2,8 @@
#include "dma3.h"
#include "graphics.h"
#include "main.h"
-#include "menu_indicators.h"
+#include "window.h"
+#include "list_menu.h"
#include "mon_markings.h"
#include "constants/songs.h"
#include "sound.h"
diff --git a/src/new_game.c b/src/new_game.c
index 37336016e..c387bce65 100644
--- a/src/new_game.c
+++ b/src/new_game.c
@@ -119,11 +119,10 @@ void ClearAllContestWinnerPics(void)
void sub_8084400(void)
{
// probably clearing one struct for battle frontier
- CpuFill32(0, gSaveBlock2Ptr->field_64C, 2272);
+ CpuFill32(0, &gSaveBlock2Ptr->battleTower, 2272);
- // those look like strings
- gSaveBlock2Ptr->field_EE1 = 0xFF;
- gSaveBlock2Ptr->field_EE9 = 0xFF;
+ gSaveBlock2Ptr->field_EE1[0][0] = EOS;
+ gSaveBlock2Ptr->field_EE1[1][0] = EOS;
}
void WarpToTruck(void)
diff --git a/src/overworld.c b/src/overworld.c
index f42f0db7f..3d9a1bdc2 100644
--- a/src/overworld.c
+++ b/src/overworld.c
@@ -38,6 +38,7 @@
#include "roamer.h"
// #include "rotating_gate.h"
#include "safari_zone.h"
+#include "save.h"
#include "script.h"
// #include "script_pokemon_80C4.h"
#include "secret_base.h"
@@ -87,12 +88,11 @@ extern const struct MapHeader *const *const gMapGroups[];
extern const s32 gMaxFlashLevel;
extern const u16 gUnknown_82EC7C4[];
-extern u16 gSaveFileStatus;
-extern u16 gUnknown_03005DA8;
-extern bool8 (*gUnknown_03005DB0)(void);
-extern u8 gUnknown_03005DB4;
-extern u8 gFieldLinkPlayerCount;
-extern MainCallback gFieldCallback;
+u16 gUnknown_03005DA8;
+MainCallback gFieldCallback;
+bool8 (*gUnknown_03005DB0)(void);
+u8 gUnknown_03005DB4;
+u8 gFieldLinkPlayerCount;
// functions
extern void HealPlayerParty(void);
@@ -713,7 +713,7 @@ void sub_8084D5C(s16 a1, s16 a2)
{
u8 currMapType = Overworld_GetMapTypeOfSaveblockLocation();
u8 destMapType = GetMapTypeByGroupAndId(sWarpDestination.mapGroup, sWarpDestination.mapNum);
- if (is_light_level_1_2_3_5_or_6(currMapType) && is_light_level_1_2_3_5_or_6(destMapType) != TRUE)
+ if (is_map_type_1_2_3_5_or_6(currMapType) && is_map_type_1_2_3_5_or_6(destMapType) != TRUE)
sub_8084DD4(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1, a1 - 7, a2 - 6);
}
@@ -872,7 +872,7 @@ static void mli0_load_map(u32 a1)
LoadMapObjTemplatesFromHeader();
}
- v2 = is_light_level_1_2_3_5_or_6(gMapHeader.mapType);
+ v2 = is_map_type_1_2_3_5_or_6(gMapHeader.mapType);
indoors = Overworld_MapTypeIsIndoors(gMapHeader.mapType);
sub_80EB218();
@@ -1365,7 +1365,7 @@ u8 get_map_light_from_warp0(void)
return GetMapTypeByWarpData(&gUnknown_020322DC);
}
-bool8 is_light_level_1_2_3_5_or_6(u8 mapType)
+bool8 is_map_type_1_2_3_5_or_6(u8 mapType)
{
if (mapType == MAP_TYPE_ROUTE
|| mapType == MAP_TYPE_TOWN
diff --git a/src/player_pc.c b/src/player_pc.c
index 6f39fa449..c10c63dda 100644
--- a/src/player_pc.c
+++ b/src/player_pc.c
@@ -18,7 +18,6 @@
#include "malloc.h"
#include "menu.h"
#include "menu_helpers.h"
-#include "menu_indicators.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
@@ -43,9 +42,6 @@ struct Struct203BCC4
u8 spriteIds[7];
};
-// extern offset
-void (*gFieldCallback)(void);
-
// static functions
static void InitPlayerPCMenu(u8 taskId);
static void PlayerPCProcessMenuInput(u8 taskId);
@@ -436,7 +432,7 @@ void Mailbox_DoRedrawMailboxMenuAfterReturn(void)
static void ItemStorage_HandleReturnToProcessInput(u8 taskId)
{
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
gTasks[taskId].func = ItemStorageMenuProcessInput;
}
@@ -673,7 +669,7 @@ static void pal_fill_for_maplights_or_black(void)
static void Mailbox_HandleReturnToProcessInput(u8 taskId)
{
- if(sub_80ABDFC() == TRUE)
+ if(IsWeatherNotFadingIn() == TRUE)
gTasks[taskId].func = Mailbox_ProcessInput;
}
diff --git a/src/pokeblock.c b/src/pokeblock.c
index 60087b5bf..216c9e2c5 100644
--- a/src/pokeblock.c
+++ b/src/pokeblock.c
@@ -24,11 +24,11 @@
#include "constants/songs.h"
#include "sound.h"
#include "berry.h"
-#include "menu_indicators.h"
#include "event_data.h"
#include "battle_message.h"
#include "safari_zone.h"
#include "lilycove_lady.h"
+#include "overworld.h"
#define POKEBLOCK_MAX_FEEL 99
#define FIELD_E75_COUNT 7
@@ -70,7 +70,6 @@ enum
};
extern u16 gSpecialVar_ItemId;
-extern void (*gFieldCallback)(void);
extern const u16 gUnknown_0860F074[];
diff --git a/src/pokemon_animation.c b/src/pokemon_animation.c
index 02755fe40..c50aa4a75 100644
--- a/src/pokemon_animation.c
+++ b/src/pokemon_animation.c
@@ -1184,7 +1184,7 @@ static void sub_817F9F4(struct Sprite *sprite)
}
#else
-__attribute__((naked))
+NAKED
static void sub_817F9F4(struct Sprite *sprite)
{
asm(".syntax unified\n\
diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c
index f77b7c38c..74dc11973 100644
--- a/src/pokemon_summary_screen.c
+++ b/src/pokemon_summary_screen.c
@@ -1417,7 +1417,7 @@ void sub_81C14BC(struct Pokemon *mon, u8 swappingFromId, u8 swappingToId)
*ppBonusesPtr = localPpBonuses;
}
#else
-ASM_DIRECT
+NAKED
void sub_81C14BC(struct Pokemon *mon, u8 swappingFromId, u8 swappingToId)
{
asm(".syntax unified\n\
@@ -1628,7 +1628,7 @@ void sub_81C15EC(struct BoxPokemon *mon, u8 swappingFromId, u8 swappingToId)
*ppBonusesPtr = localPpBonuses;
}
#else
-ASM_DIRECT
+NAKED
void sub_81C15EC(struct BoxPokemon *mon, u8 swappingFromId, u8 swappingToId)
{
asm(".syntax unified\n\
@@ -1825,7 +1825,7 @@ void sub_81C174C(u8 taskId)
}
else
{
- PlaySE(0x20);
+ PlaySE(SE_HAZURE);
sub_81C18F4(taskId);
}
}
@@ -2039,7 +2039,7 @@ void sub_81C1CB0(struct UnkStruct_61CC04 *a, u16 *b, u8 c, u8 d)
Free(alloced);
}
#else
-ASM_DIRECT
+NAKED
void sub_81C1CB0(struct UnkStruct_61CC04 *a, u16 *b, u8 c, u8 d)
{
asm(".syntax unified\n\
@@ -2341,7 +2341,7 @@ void sub_81C2194(u16 *a, u16 b, u8 c)
}
}
#else
-ASM_DIRECT
+NAKED
void sub_81C2194(u16 *a, u16 b, u8 c)
{
asm(".syntax unified\n\
@@ -3026,7 +3026,7 @@ void sub_81C335C()
sub_81C25A4(r4, gText_FiveMarks, r5, 1, 0, 1);
}
#else
-ASM_DIRECT
+NAKED
void sub_81C335C()
{
asm(".syntax unified\n\
@@ -3369,7 +3369,7 @@ void sub_81C3B08(u8 a)
sub_81C25A4(sp, text, offset, (a<<4), 0, r5);
}
#else
-ASM_DIRECT
+NAKED
void sub_81C3B08(u8 a)
{
asm(".syntax unified\n\
diff --git a/src/record_mixing.c b/src/record_mixing.c
index 151835e5e..35e518d8a 100644
--- a/src/record_mixing.c
+++ b/src/record_mixing.c
@@ -1,28 +1,2282 @@
-
-// Includes
#include "global.h"
+#include "malloc.h"
+#include "random.h"
+#include "constants/items.h"
+#include "text.h"
+#include "item.h"
+#include "task.h"
+#include "constants/species.h"
+#include "save.h"
+#include "load_save.h"
+#include "pokemon.h"
+#include "cable_club.h"
+#include "link.h"
+#include "link_rfu.h"
+#include "tv.h"
+#include "battle_tower.h"
+#include "window.h"
+#include "mystery_event_script.h"
+#include "secret_base.h"
+#include "mauville_old_man.h"
+#include "sound.h"
+#include "constants/songs.h"
+#include "menu.h"
+#include "overworld.h"
+#include "field_screen.h"
+#include "fldeff_80F9BCC.h"
+#include "script.h"
+#include "event_data.h"
+#include "lilycove_lady.h"
+#include "strings.h"
+#include "string_util.h"
+#include "record_mixing.h"
+#include "new_game.h"
+#include "daycare.h"
+#include "international_string_util.h"
+
+extern void ReceiveSecretBasesData(struct SecretBaseRecord *, size_t, u8);
+extern void ReceiveEasyChatPairsData(struct EasyChatPair *, size_t, u8);
// Static type declarations
+struct UnknownRecMixingStruct
+{
+ u32 field_0;
+ u16 field_4;
+ u8 field_6[9];
+};
+
+struct UnknownRecMixingStruct2
+{
+ u32 field_0;
+ u16 field_4;
+ u16 field_6;
+ u16 field_8;
+ u8 field_A[16];
+};
+
+struct UnknownRecMixingStruct3
+{
+ u8 field_0[0x810];
+};
+
+struct PlayerRecordsRS
+{
+ struct SecretBaseRecord secretBases[SECRET_BASES_COUNT];
+ TVShow tvShows[TV_SHOWS_COUNT];
+ PokeNews pokeNews[POKE_NEWS_COUNT];
+ OldMan oldMan;
+ struct EasyChatPair easyChatPairs[5];
+ struct RecordMixingDayCareMail dayCareMail;
+ struct RSBattleTowerRecord battleTowerRecord;
+ u16 filler11C8[0x32];
+};
+
+struct PlayerRecordsEmerald
+{
+ /* 0x0000 */ struct SecretBaseRecord secretBases[SECRET_BASES_COUNT];
+ /* 0x0c80 */ TVShow tvShows[TV_SHOWS_COUNT];
+ /* 0x1004 */ PokeNews pokeNews[POKE_NEWS_COUNT];
+ /* 0x1044 */ OldMan oldMan;
+ /* 0x1084 */ struct EasyChatPair easyChatPairs[5];
+ /* 0x10ac */ struct RecordMixingDayCareMail dayCareMail;
+ /* 0x1124 */ struct EmeraldBattleTowerRecord battleTowerRecord;
+ /* 0x1210 */ u16 unk_1210;
+ /* 0x1214 */ LilycoveLady lilycoveLady;
+ /* 0x1254 */ struct UnkRecordMixingStruct unk_1254[2];
+ /* 0x12dc */ struct UnkRecordMixingStruct2 unk_12dc;
+ /* 0x1434 */ u8 field_1434[0x10];
+}; // 0x1444
+
+union PlayerRecords
+{
+ struct PlayerRecordsRS ruby;
+ struct PlayerRecordsEmerald emerald;
+};
+
// Static RAM declarations
-IWRAM_DATA bool8 gUnknown_03001130;
-IWRAM_DATA struct SecretBaseRecord *gUnknown_03001134;
-IWRAM_DATA TVShow *gUnknown_03001138;
-IWRAM_DATA struct UnknownSaveStruct2ABC *gUnknown_0300113C;
-IWRAM_DATA OldMan *gUnknown_03001140;
-IWRAM_DATA struct EasyChatPair *gUnknown_03001144;
-IWRAM_DATA struct DaycareData *gUnknown_03001148;
-IWRAM_DATA void *gUnknown_0300114C; // gSaveBlock2Ptr->field_64C
-IWRAM_DATA LilycoveLady *gUnknown_03001150;
-IWRAM_DATA void *gUnknown_03001154; // gSaveBlock2Ptr->field_0DC;
-IWRAM_DATA void *gUnknown_03001158; // gSaveBlock2Ptr->field_64C
-IWRAM_DATA u32 gUnknown_0300115C;
-IWRAM_DATA u8 gUnknown_03001160[8];
-IWRAM_DATA u32 gUnknown_03001168[3];
+static IWRAM_DATA bool8 gUnknown_03001130;
+static IWRAM_DATA struct SecretBaseRecord *sSecretBasesSave;
+static IWRAM_DATA TVShow *sTvShowsSave;
+static IWRAM_DATA PokeNews *sPokeNewsSave;
+static IWRAM_DATA OldMan *sOldManSave;
+static IWRAM_DATA struct EasyChatPair *sEasyChatPairsSave;
+static IWRAM_DATA struct RecordMixingDayCareMail *gUnknown_03001148;
+static IWRAM_DATA void *sBattleTowerSave;
+static IWRAM_DATA LilycoveLady *sLilycoveLadySave;
+static IWRAM_DATA void *gUnknown_03001154; // gSaveBlock2Ptr->field_0DC;
+static IWRAM_DATA void *sBattleTowerSave_Duplicate;
+static IWRAM_DATA u32 sRecordStructSize;
+static IWRAM_DATA u8 gUnknown_03001160;
+static IWRAM_DATA u32 filler_03001164;
+static IWRAM_DATA u32 gUnknown_03001168[3];
+
+static EWRAM_DATA struct RecordMixingDayCareMail gUnknown_02039F9C = {0};
+static EWRAM_DATA union PlayerRecords *sReceivedRecords = NULL;
+static EWRAM_DATA union PlayerRecords *sSentRecord = NULL;
// Static ROM declarations
+static void Task_RecordMixing_Main(u8 taskId);
+static void sub_80E7324(u8 taskId);
+static void Task_SendPacket(u8 taskId);
+static void Task_CopyReceiveBuffer(u8 taskId);
+static void Task_SendPacket_SwitchToReceive(u8 taskId);
+static void *LoadPtrFromTaskData(const u16 *asShort);
+static void StorePtrInTaskData(void *records, u16 *a1);
+static u8 GetMultiplayerId_(void);
+static void *GetPlayerRecvBuffer(u8);
+static void ReceiveOldManData(OldMan *, size_t, u8);
+static void ReceiveBattleTowerData(void *battleTowerRecord, size_t, u8);
+static void ReceiveLilycoveLadyData(LilycoveLady *, size_t, u8);
+static void sub_80E7B2C(const u8 *);
+static void ReceiveDaycareMailData(struct RecordMixingDayCareMail *, size_t, u8, TVShow *);
+static void sub_80E7F68(u16 *item, u8 which);
+static void sub_80E7FF8(u8 taskId);
+static void sub_80E8110(struct UnkRecordMixingStruct *arg0, struct UnkRecordMixingStruct *arg1);
+static void sub_80E8468(struct UnkRecordMixingStruct *arg0, size_t arg1, u32 arg2);
+static void sub_80E89AC(struct UnkRecordMixingStruct2 *arg0, size_t arg1, u32 arg2);
+static void sub_80E89F8(struct RecordMixingDayCareMail *dst);
+static void SanitizeDayCareMailForRuby(struct RecordMixingDayCareMail *src);
+static void SanitizeEmeraldBattleTowerRecord(struct EmeraldBattleTowerRecord *arg0);
+static void SanitizeRubyBattleTowerRecord(struct RSBattleTowerRecord *src);
+
// .rodata
+static const u8 gUnknown_0858CF8C[] = {1, 0};
+
+static const u8 gUnknown_0858CF8E[][3] =
+{
+ {1, 2, 0},
+ {2, 0, 1},
+};
+
+static const u8 gUnknown_0858CF94[][4] =
+{
+ {1, 0, 3, 2},
+ {3, 0, 1, 2},
+ {2, 0, 3, 1},
+ {1, 3, 0, 2},
+ {2, 3, 0, 1},
+ {3, 2, 0, 1},
+ {1, 2, 3, 0},
+ {2, 3, 1, 0},
+ {3, 2, 1, 0},
+};
+
+static const u8 gUnknown_0858CFB8[3][2] =
+{
+ {0, 1},
+ {1, 2},
+ {2, 0},
+};
+
+static const u8 gUnknown_0858CFBE[3][4] =
+{
+ {0, 1, 2, 3},
+ {0, 2, 1, 3},
+ {0, 3, 2, 1},
+};
+
// .text
+
+#define BUFFER_CHUNK_SIZE 200
+
+void sub_80E6BE8(void)
+{
+ sub_80B37D4(Task_RecordMixing_Main);
+}
+
+// these variables were const in R/S, but had to become changeable because of saveblocks changing RAM position
+static void SetSrcLookupPointers(void)
+{
+ sSecretBasesSave = gSaveBlock1Ptr->secretBases;
+ sTvShowsSave = gSaveBlock1Ptr->tvShows;
+ sPokeNewsSave = gSaveBlock1Ptr->pokeNews;
+ sOldManSave = &gSaveBlock1Ptr->oldMan;
+ sEasyChatPairsSave = gSaveBlock1Ptr->easyChatPairs;
+ gUnknown_03001148 = &gUnknown_02039F9C;
+ sBattleTowerSave = &gSaveBlock2Ptr->battleTower;
+ sLilycoveLadySave = &gSaveBlock1Ptr->lilycoveLady;
+ gUnknown_03001154 = gSaveBlock2Ptr->field_DC;
+ sBattleTowerSave_Duplicate = &gSaveBlock2Ptr->battleTower;
+}
+
+static void PrepareUnknownExchangePacket(struct PlayerRecordsRS *dest)
+{
+ memcpy(dest->secretBases, sSecretBasesSave, sizeof(dest->secretBases));
+ memcpy(dest->tvShows, sTvShowsSave, sizeof(dest->tvShows));
+ sub_80F14F8(dest->tvShows);
+ memcpy(dest->pokeNews, sPokeNewsSave, sizeof(dest->pokeNews));
+ memcpy(&dest->oldMan, sOldManSave, sizeof(dest->oldMan));
+ memcpy(dest->easyChatPairs, sEasyChatPairsSave, sizeof(dest->easyChatPairs));
+ sub_80E89F8(&dest->dayCareMail);
+ sub_81659DC(sBattleTowerSave, &dest->battleTowerRecord);
+
+ if (GetMultiplayerId() == 0)
+ dest->battleTowerRecord.unk_11c8 = GetRecordMixingGift();
+}
+
+static void PrepareExchangePacketForRubySapphire(struct PlayerRecordsRS *dest)
+{
+ memcpy(dest->secretBases, sSecretBasesSave, sizeof(dest->secretBases));
+ sub_80EB18C(dest->secretBases);
+ memcpy(dest->tvShows, sTvShowsSave, sizeof(dest->tvShows));
+ sub_80F1208(dest->tvShows);
+ memcpy(dest->pokeNews, sPokeNewsSave, sizeof(dest->pokeNews));
+ memcpy(&dest->oldMan, sOldManSave, sizeof(dest->oldMan));
+ sub_8120B70(&dest->oldMan);
+ memcpy(dest->easyChatPairs, sEasyChatPairsSave, sizeof(dest->easyChatPairs));
+ sub_80E89F8(&dest->dayCareMail);
+ SanitizeDayCareMailForRuby(&dest->dayCareMail);
+ sub_81659DC(sBattleTowerSave, &dest->battleTowerRecord);
+ SanitizeRubyBattleTowerRecord(&dest->battleTowerRecord);
+
+ if (GetMultiplayerId() == 0)
+ dest->battleTowerRecord.unk_11c8 = GetRecordMixingGift();
+}
+
+static void PrepareExchangePacket(void)
+{
+ sub_80E9914();
+ sub_80F0BB8();
+ SetSrcLookupPointers();
+
+ if (Link_AnyPartnersPlayingRubyOrSapphire())
+ {
+ if (sub_800A03C() == 0)
+ PrepareUnknownExchangePacket(&sSentRecord->ruby);
+ else
+ PrepareExchangePacketForRubySapphire(&sSentRecord->ruby);
+ }
+ else
+ {
+ memcpy(sSentRecord->emerald.secretBases, sSecretBasesSave, sizeof(sSentRecord->emerald.secretBases));
+ memcpy(sSentRecord->emerald.tvShows, sTvShowsSave, sizeof(sSentRecord->emerald.tvShows));
+ memcpy(sSentRecord->emerald.pokeNews, sPokeNewsSave, sizeof(sSentRecord->emerald.pokeNews));
+ memcpy(&sSentRecord->emerald.oldMan, sOldManSave, sizeof(sSentRecord->emerald.oldMan));
+ memcpy(&sSentRecord->emerald.lilycoveLady, sLilycoveLadySave, sizeof(sSentRecord->emerald.lilycoveLady));
+ memcpy(sSentRecord->emerald.easyChatPairs, sEasyChatPairsSave, sizeof(sSentRecord->emerald.easyChatPairs));
+ sub_80E89F8(&sSentRecord->emerald.dayCareMail);
+ memcpy(&sSentRecord->emerald.battleTowerRecord, sBattleTowerSave, sizeof(sSentRecord->emerald.battleTowerRecord));
+ SanitizeEmeraldBattleTowerRecord(&sSentRecord->emerald.battleTowerRecord);
+
+ if (GetMultiplayerId() == 0)
+ sSentRecord->emerald.unk_1210 = GetRecordMixingGift();
+
+ sub_80E8110(sSentRecord->emerald.unk_1254, gUnknown_03001154);
+ sub_80E8260(&sSentRecord->emerald.unk_12dc);
+ }
+}
+
+static void ReceiveExchangePacket(u32 which)
+{
+ if (Link_AnyPartnersPlayingRubyOrSapphire())
+ {
+ // Ruby/Sapphire
+ sub_80E7B2C((void *)sReceivedRecords->ruby.tvShows);
+ ReceiveSecretBasesData(sReceivedRecords->ruby.secretBases, sizeof(struct PlayerRecordsRS), which);
+ ReceiveDaycareMailData(&sReceivedRecords->ruby.dayCareMail, sizeof(struct PlayerRecordsRS), which, sReceivedRecords->ruby.tvShows);
+ ReceiveBattleTowerData(&sReceivedRecords->ruby.battleTowerRecord, sizeof(struct PlayerRecordsRS), which);
+ ReceiveTvShowsData(sReceivedRecords->ruby.tvShows, sizeof(struct PlayerRecordsRS), which);
+ ReceivePokeNewsData(sReceivedRecords->ruby.pokeNews, sizeof(struct PlayerRecordsRS), which);
+ ReceiveOldManData(&sReceivedRecords->ruby.oldMan, sizeof(struct PlayerRecordsRS), which);
+ ReceiveEasyChatPairsData(sReceivedRecords->ruby.easyChatPairs, sizeof(struct PlayerRecordsRS), which);
+ sub_80E7F68(&sReceivedRecords->ruby.battleTowerRecord.unk_11c8, which);
+ }
+ else
+ {
+ // Emerald
+ sub_80E7B2C((void *)sReceivedRecords->emerald.tvShows);
+ ReceiveSecretBasesData(sReceivedRecords->emerald.secretBases, sizeof(struct PlayerRecordsEmerald), which);
+ ReceiveTvShowsData(sReceivedRecords->emerald.tvShows, sizeof(struct PlayerRecordsEmerald), which);
+ ReceivePokeNewsData(sReceivedRecords->emerald.pokeNews, sizeof(struct PlayerRecordsEmerald), which);
+ ReceiveOldManData(&sReceivedRecords->emerald.oldMan, sizeof(struct PlayerRecordsEmerald), which);
+ ReceiveEasyChatPairsData(sReceivedRecords->emerald.easyChatPairs, sizeof(struct PlayerRecordsEmerald), which);
+ ReceiveDaycareMailData(&sReceivedRecords->emerald.dayCareMail, sizeof(struct PlayerRecordsEmerald), which, sReceivedRecords->emerald.tvShows);
+ ReceiveBattleTowerData(&sReceivedRecords->emerald.battleTowerRecord, sizeof(struct PlayerRecordsEmerald), which);
+ sub_80E7F68(&sReceivedRecords->emerald.unk_1210, which);
+ ReceiveLilycoveLadyData(&sReceivedRecords->emerald.lilycoveLady, sizeof(struct PlayerRecordsEmerald), which);
+ sub_80E8468(sReceivedRecords->emerald.unk_1254, sizeof(struct PlayerRecordsEmerald), (u8) which);
+ sub_80E89AC(&sReceivedRecords->emerald.unk_12dc, sizeof(struct PlayerRecordsEmerald), (u8) which);
+ }
+}
+
+static void PrintTextOnRecordMixing(const u8 *src)
+{
+ NewMenuHelpers_DrawDialogueFrame(0, 0);
+ PrintTextOnWindow(0, 1, src, 0, 1, 0, NULL);
+ CopyWindowToVram(0, 3);
+}
+
+#define tCounter data[0]
+
+static void Task_RecordMixing_SoundEffect(u8 taskId)
+{
+ if (++gTasks[taskId].tCounter == 50)
+ {
+ PlaySE(SE_W213);
+ gTasks[taskId].tCounter = 0;
+ }
+}
+
+#undef tCounter
+
+#define tState data[0]
+#define tSndEffTaskId data[15]
+
+static void Task_RecordMixing_Main(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ switch (tState)
+ {
+ case 0: // init
+ sSentRecord = malloc(sizeof(union PlayerRecords));
+ sReceivedRecords = malloc(sizeof(union PlayerRecords) * 4);
+ sub_8009628(gSpecialVar_0x8005);
+ VarSet(VAR_TEMP_0, 1);
+ gUnknown_03001130 = FALSE;
+ PrepareExchangePacket();
+ CreateRecordMixingSprite();
+ tState = 1;
+ data[10] = CreateTask(sub_80E7324, 80);
+ tSndEffTaskId = CreateTask(Task_RecordMixing_SoundEffect, 81);
+ break;
+ case 1: // wait for sub_80E7324
+ if (!gTasks[data[10]].isActive)
+ {
+ tState = 2;
+ FlagSet(FLAG_SYS_MIX_RECORD);
+ DestroyRecordMixingSprite();
+ DestroyTask(tSndEffTaskId);
+ }
+ break;
+ case 2:
+ data[10] = CreateTask(sub_80E7FF8, 10);
+ tState = 3;
+ PlaySE(SE_W226);
+ break;
+ case 3: // wait for sub_80E7FF8
+ if (!gTasks[data[10]].isActive)
+ {
+ tState = 4;
+ if (gWirelessCommType == 0)
+ data[10] = sub_80B3050();
+
+ PrintTextOnRecordMixing(gText_RecordMixingComplete);
+ data[8] = 0;
+ }
+ break;
+ case 4: // wait 60 frames
+ if (++data[8] > 60)
+ tState = 5;
+ break;
+ case 5:
+ if (!gTasks[data[10]].isActive)
+ {
+ free(sReceivedRecords);
+ free(sSentRecord);
+ sub_808729C();
+ if (gWirelessCommType != 0)
+ {
+ CreateTask(sub_80AF2B4, 10);
+ }
+ sub_8197434(0, 1);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+ break;
+ }
+}
+
+#undef tState
+#undef tSndEffTaskId
+
+static void sub_80E7324(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ PrintTextOnRecordMixing(gText_MixingRecords);
+ task->data[8] = 0x708;
+ task->data[0] = 400;
+ ClearLinkCallback_2();
+ break;
+ case 100: // wait 20 frames
+ if (++task->data[12] > 20)
+ {
+ task->data[12] = 0;
+ task->data[0] = 101;
+ }
+ break;
+ case 101:
+ {
+ u8 players = GetLinkPlayerCount_2();
+ if (IsLinkMaster() == TRUE)
+ {
+ if (players == sub_800AA48())
+ {
+ PlaySE(SE_PIN);
+ task->data[0] = 201;
+ task->data[12] = 0;
+ }
+ }
+ else
+ {
+ PlaySE(SE_BOO);
+ task->data[0] = 301;
+ }
+ }
+ break;
+ case 201:
+ if (sub_800AA48() == GetLinkPlayerCount_2() && ++task->data[12] > (GetLinkPlayerCount_2() * 30))
+ {
+ sub_800A620();
+ task->data[0] = 1;
+ }
+ break;
+ case 301:
+ if (sub_800AA48() == GetLinkPlayerCount_2())
+ task->data[0] = 1;
+ break;
+ case 400: // wait 20 frames
+ if (++task->data[12] > 20)
+ {
+ task->data[0] = 1;
+ task->data[12] = 0;
+ }
+ break;
+ case 1: // wait for handshake
+ if (gReceivedRemoteLinkPlayers != 0)
+ {
+ ConvertIntToDecimalStringN(gStringVar1, GetMultiplayerId_(), STR_CONV_MODE_LEADING_ZEROS, 2);
+ task->data[0] = 5;
+ }
+ break;
+ case 2:
+ {
+ u8 subTaskId;
+
+ task->data[6] = GetLinkPlayerCount_2();
+ task->data[0] = 0;
+ task->data[5] = GetMultiplayerId_();
+ task->func = Task_SendPacket;
+ if (Link_AnyPartnersPlayingRubyOrSapphire())
+ {
+ StorePtrInTaskData(sSentRecord, (u16 *)&task->data[2]);
+ subTaskId = CreateTask(Task_CopyReceiveBuffer, 80);
+ task->data[10] = subTaskId;
+ gTasks[subTaskId].data[0] = taskId;
+ StorePtrInTaskData(sReceivedRecords, (u16 *)&gTasks[subTaskId].data[5]);
+ sRecordStructSize = sizeof(struct PlayerRecordsRS);
+ }
+ else
+ {
+ StorePtrInTaskData(sSentRecord, (u16 *)&task->data[2]);
+ subTaskId = CreateTask(Task_CopyReceiveBuffer, 80);
+ task->data[10] = subTaskId;
+ gTasks[subTaskId].data[0] = taskId;
+ StorePtrInTaskData(sReceivedRecords, (u16 *)&gTasks[subTaskId].data[5]);
+ sRecordStructSize = sizeof(struct PlayerRecordsEmerald);
+ }
+ }
+ break;
+ case 5: // wait 60 frames
+ if (++task->data[10] > 60)
+ {
+ task->data[10] = 0;
+ task->data[0] = 2;
+ }
+ break;
+ }
+}
+
+static void Task_SendPacket(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ // does this send the data 24 times?
+
+ switch (task->data[0])
+ {
+ case 0: // Copy record data to send buffer
+ {
+ void *recordData = LoadPtrFromTaskData(&task->data[2]) + task->data[4] * BUFFER_CHUNK_SIZE;
+
+ memcpy(gBlockSendBuffer, recordData, BUFFER_CHUNK_SIZE);
+ task->data[0]++;
+ }
+ break;
+ case 1:
+ if (GetMultiplayerId() == 0)
+ sub_800A4D8(1);
+ task->data[0]++;
+ break;
+ case 2:
+ break;
+ case 3:
+ task->data[4]++;
+ if (task->data[4] == sRecordStructSize / 200 + 1)
+ task->data[0]++;
+ else
+ task->data[0] = 0;
+ break;
+ case 4:
+ if (!gTasks[task->data[10]].isActive)
+ task->func = Task_SendPacket_SwitchToReceive;
+ break;
+ }
+}
+
+static void Task_CopyReceiveBuffer(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ u8 status = GetBlockReceivedStatus();
+ u8 handledPlayers = 0;
+
+ if (status == sub_800A9D8())
+ {
+ u8 i;
+
+ for (i = 0; i < GetLinkPlayerCount(); i++)
+ {
+ void *dest;
+ void *src;
+
+ if ((status >> i) & 1)
+ {
+ dest = LoadPtrFromTaskData((u16 *)&task->data[5]) + task->data[i + 1] * BUFFER_CHUNK_SIZE + sRecordStructSize * i;
+ src = GetPlayerRecvBuffer(i);
+ if ((task->data[i + 1] + 1) * BUFFER_CHUNK_SIZE > sRecordStructSize)
+ memcpy(dest, src, sRecordStructSize - task->data[i + 1] * BUFFER_CHUNK_SIZE);
+ else
+ memcpy(dest, src, BUFFER_CHUNK_SIZE);
+ ResetBlockReceivedFlag(i);
+ task->data[i + 1]++;
+ if (task->data[i + 1] == sRecordStructSize / BUFFER_CHUNK_SIZE + 1)
+ handledPlayers++;
+ }
+ }
+ gTasks[task->data[0]].data[0]++;
+ }
+
+ if (handledPlayers == GetLinkPlayerCount())
+ DestroyTask(taskId);
+}
+
+static void sub_80E776C(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (!gTasks[task->data[10]].isActive)
+ DestroyTask(taskId);
+}
+
+static void Task_ReceivePacket(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->func = sub_80E776C;
+ if (gUnknown_03001130 == TRUE)
+ ReceiveExchangePacket(task->data[5]);
+}
+
+static void Task_SendPacket_SwitchToReceive(u8 taskId)
+{
+ gTasks[taskId].func = Task_ReceivePacket;
+ gUnknown_03001130 = TRUE;
+}
+
+static void *LoadPtrFromTaskData(const u16 *asShort)
+{
+ return (void *)(asShort[0] | (asShort[1] << 16));
+}
+
+static void StorePtrInTaskData(void *records, u16 *asShort)
+{
+ asShort[0] = (u32)records;
+ asShort[1] = ((u32)records >> 16);
+}
+
+static u8 GetMultiplayerId_(void)
+{
+ return GetMultiplayerId();
+}
+
+static void *GetPlayerRecvBuffer(u8 id)
+{
+ return gBlockRecvBuffer[id];
+}
+
+static void ShufflePlayerIndices(u32 *data)
+{
+ u32 i;
+ u32 linkTrainerId;
+ u32 players = GetLinkPlayerCount();
+
+ switch (players)
+ {
+ case 2:
+ for (i = 0; i < 2; i++)
+ data[i] = gUnknown_0858CF8C[i];
+ break;
+ case 3:
+ linkTrainerId = GetLinkPlayerTrainerId(0) % 2;
+ for (i = 0; i < 3; i++)
+ data[i] = gUnknown_0858CF8E[linkTrainerId][i];
+ break;
+ case 4:
+ linkTrainerId = GetLinkPlayerTrainerId(0) % 9;
+ for (i = 0; i < 4; i++)
+ data[i] = gUnknown_0858CF94[linkTrainerId][i];
+ break;
+ }
+}
+
+static void ReceiveOldManData(OldMan *oldMan, size_t recordSize, u8 which)
+{
+ u8 version;
+ u16 language;
+ OldMan *dest;
+ u32 mixIndices[4];
+
+ ShufflePlayerIndices(mixIndices);
+ dest = (void *)oldMan + recordSize * mixIndices[which];
+ version = gLinkPlayers[mixIndices[which]].version;
+ language = gLinkPlayers[mixIndices[which]].language;
+
+ if (Link_AnyPartnersPlayingRubyOrSapphire())
+ SanitizeReceivedRubyOldMan(dest, version, language);
+ else
+ SanitizeReceivedEmeraldOldMan(dest, version, language);
+
+ memcpy(sOldManSave, (void *)oldMan + recordSize * mixIndices[which], sizeof(OldMan));
+ ResetMauvilleOldManFlag();
+}
+
+static void ReceiveBattleTowerData(void *battleTowerRecord, size_t recordSize, u8 which)
+{
+ struct EmeraldBattleTowerRecord *dest;
+ struct UnknownPokemonStruct *btPokemon;
+ u32 mixIndices[4];
+ s32 i;
+
+ ShufflePlayerIndices(mixIndices);
+ if (Link_AnyPartnersPlayingRubyOrSapphire())
+ {
+ if (sub_816587C((void *)battleTowerRecord + recordSize * mixIndices[which], (void *)battleTowerRecord + recordSize * which) == TRUE)
+ {
+ dest = (void *)battleTowerRecord + recordSize * which;
+ dest->language = gLinkPlayers[mixIndices[which]].language;
+ CalcEmeraldBattleTowerChecksum(dest);
+ }
+ }
+ else
+ {
+ memcpy((void *)battleTowerRecord + recordSize * which, (void *)battleTowerRecord + recordSize * mixIndices[which], sizeof(union BattleTowerRecord));
+ dest = (void *)battleTowerRecord + recordSize * which;
+ for (i = 0; i < 4; i ++)
+ {
+ btPokemon = &dest->party[i];
+ if (btPokemon->species != SPECIES_NONE && IsStringJapanese(btPokemon->nickname))
+ ConvertInternationalString(btPokemon->nickname, LANGUAGE_JAPANESE);
+ }
+ CalcEmeraldBattleTowerChecksum(dest);
+ }
+ sub_81628A0((void *)battleTowerRecord + recordSize * which);
+}
+
+static void ReceiveLilycoveLadyData(LilycoveLady *lilycoveLady, size_t recordSize, u8 which)
+{
+ LilycoveLady *dest;
+ u32 mixIndices[4];
+
+ ShufflePlayerIndices(mixIndices);
+ memcpy((void *)lilycoveLady + recordSize * which, sLilycoveLadySave, sizeof(LilycoveLady));
+
+ if (GetLilycoveLadyId() == 0)
+ {
+ dest = malloc(sizeof(LilycoveLady));
+ if (dest == NULL)
+ return;
+
+ memcpy(dest, sLilycoveLadySave, sizeof(LilycoveLady));
+ }
+ else
+ {
+ dest = NULL;
+ }
+
+ memcpy(sLilycoveLadySave, (void *)lilycoveLady + recordSize * mixIndices[which], sizeof(LilycoveLady));
+ sub_818DA78();
+ if (dest != NULL)
+ {
+ sub_818E570(dest);
+ free(dest);
+ }
+}
+
+static u8 sub_80E7A9C(struct DayCareMail *rmMail)
+{
+ return rmMail->message.itemId;
+}
+
+static void sub_80E7AA4(struct RecordMixingDayCareMail *src, size_t recordSize, u8 (*idxs)[2], u8 which0, u8 which1)
+{
+ struct DayCareMail buffer;
+ struct RecordMixingDayCareMail *mail1;
+ struct RecordMixingDayCareMail *mail2;
+
+ mail1 = (void *)src + recordSize * idxs[which0][0];
+ memcpy(&buffer, &mail1->mail[idxs[which0][1]], sizeof(struct DayCareMail));
+ mail2 = (void *)src + recordSize * idxs[which1][0];
+ memcpy(&mail1->mail[idxs[which0][1]], &mail2->mail[idxs[which1][1]], sizeof(struct DayCareMail));
+ memcpy(&mail2->mail[idxs[which1][1]], &buffer, sizeof(struct DayCareMail));
+}
+
+static void sub_80E7B2C(const u8 *src)
+{
+ u8 sum;
+ s32 i;
+
+ sum = 0;
+ for (i = 0; i < 256; i ++)
+ sum += src[i];
+
+ gUnknown_03001160 = sum;
+}
+
+static u8 sub_80E7B54(void)
+{
+ return gUnknown_03001160;
+}
+
+#ifdef NONMATCHING
+static void ReceiveDaycareMailData(struct RecordMixingDayCareMail *src, size_t recordSize, u8 which, TVShow *shows)
+{
+ // r9 = which
+ u16 i;
+ u16 j;
+ u8 linkPlayerCount;
+ u16 language;
+ u16 otNameLanguage;
+ u16 nicknameLanguage;
+ u32 version;
+ u8 dcMail1;
+ u8 dcMail2;
+ u8 r1_80e7b54;
+ struct DayCareMail *recordMixingMail;
+ struct RecordMixingDayCareMail *_src;
+ u8 sp04[4];
+ u8 sp08[4];
+ struct RecordMixingDayCareMail *sp0c[4]; // -> sp+48
+ u8 sp1c[4][2]; // [][0] -> sp+4c, [][1] -> sp+50
+ u8 sp24[4][2];
+ // sp+2c = src
+ // sp+30 = recordSize
+ u8 sp34;
+ u16 oldSeed;
+ bool32 anyRS; // sp+3c
+
+ oldSeed = Random2();
+ SeedRng2(gLinkPlayers[0].trainerId);
+ linkPlayerCount = GetLinkPlayerCount();
+ for (i = 0; i < 4; i ++)
+ {
+ sp04[i] = 0xFF;
+ sp08[i] = 0;
+ sp1c[i][0] = 0;
+ sp1c[i][1] = 0;
+ }
+ anyRS = Link_AnyPartnersPlayingRubyOrSapphire();
+ for (i = 0; i < GetLinkPlayerCount(); i ++) // r8 = i
+ {
+ // sp+54 = linkPlayerCount << 16
+ // sp+44 = which * recordSize
+ _src = (void *)src + i * recordSize; // r7
+ language = gLinkPlayers[i].language; // r9
+ version = (u8)gLinkPlayers[i].version; // sp+40
+ for (j = 0; j < _src->unk_70; j ++)
+ {
+ // r10 = ~0x10
+ recordMixingMail = &_src->unk_00[j];
+ if (recordMixingMail->mail.itemId != ITEM_NONE)
+ {
+ if (anyRS)
+ {
+ if (StringLength(recordMixingMail->OT_name) <= 5)
+ {
+ otNameLanguage = LANGUAGE_JAPANESE;
+ }
+ else
+ {
+ StripExtCtrlCodes(recordMixingMail->OT_name);
+ otNameLanguage = language;
+ }
+ if (recordMixingMail->monName[0] == EXT_CTRL_CODE_BEGIN && recordMixingMail->monName[1] == EXT_CTRL_CODE_JPN)
+ {
+ StripExtCtrlCodes(recordMixingMail->monName);
+ nicknameLanguage = LANGUAGE_JAPANESE;
+ }
+ else
+ {
+ nicknameLanguage = language;
+ }
+ if (version == VERSION_RUBY || version == VERSION_SAPPHIRE)
+ {
+ recordMixingMail->language_maybe = otNameLanguage;
+ recordMixingMail->unknown = nicknameLanguage;
+ }
+ }
+ else if (language == LANGUAGE_JAPANESE)
+ {
+ if (IsStringJapanese(recordMixingMail->OT_name))
+ {
+ recordMixingMail->language_maybe = LANGUAGE_JAPANESE;
+ }
+ else
+ {
+ recordMixingMail->language_maybe = GAME_LANGUAGE;
+ }
+ if (IsStringJapanese(recordMixingMail->monName))
+ {
+ recordMixingMail->unknown = LANGUAGE_JAPANESE;
+ }
+ else
+ {
+ recordMixingMail->unknown = GAME_LANGUAGE;
+ }
+ }
+ }
+ }
+ }
+ sp34 = 0;
+ for (i = 0; i < linkPlayerCount; i ++)
+ {
+ _src = (void *)src + i * recordSize; // r7
+ if (_src->unk_70 != 0)
+ {
+ for (j = 0; j < _src->unk_70; j ++)
+ {
+ if (_src->unk_74[j] == 0)
+ {
+ sp1c[i][j] = 1;
+ }
+ }
+ }
+ }
+ i = 0;
+ for (j = 0; j < linkPlayerCount; j ++)
+ {
+ _src = (void *)src + j * recordSize;
+ if (sp1c[j][0] == TRUE || sp1c[j][1] == TRUE)
+ {
+ sp34 ++;
+ }
+ if (sp1c[j][0] == TRUE && sp1c[j][1] == FALSE)
+ {
+ sp24[i][0] = j;
+ sp24[i][1] = 0;
+ i ++;
+ }
+ else if (sp1c[j][0] == FALSE && sp1c[j][1] == TRUE)
+ {
+ sp24[i][0] = j;
+ sp24[i][1] = 0;
+ i ++;
+ }
+ else if (sp1c[j][0] == TRUE && sp1c[j][1] == TRUE)
+ {
+ sp24[i][0] = j;
+ dcMail1 = sub_80E7A9C(&_src->unk_00[0]);
+ dcMail2 = sub_80E7A9C(&_src->unk_00[1]);
+ if (!dcMail1 && dcMail2)
+ {
+ sp24[i][1] = 1;
+ }
+ else if ((dcMail1 && dcMail2) || (!dcMail1 && !dcMail2))
+ {
+ sp24[i][1] = Random2() % 2;
+ }
+ else
+ {
+ sp24[i][1] = 0;
+ }
+ i ++;
+ }
+ }
+ for (i = 0; i < 4; i ++)
+ {
+ _src = &src[which * recordSize];
+ sp0c[i] = _src;
+ }
+ r1_80e7b54 = sub_80E7B54() % 3;
+ switch (sp34)
+ {
+ case 2:
+ sub_80E7AA4(src, recordSize, sp24, 0, 1);
+ break;
+ case 3:
+ sub_80E7AA4(src, recordSize, sp24, gUnknown_0858CFB8[r1_80e7b54][0], gUnknown_0858CFB8[r1_80e7b54][1]);
+ break;
+ case 4:
+ sub_80E7AA4(src, recordSize, sp24, gUnknown_0858CFBE[r1_80e7b54][0], gUnknown_0858CFBE[r1_80e7b54][1]);
+ sub_80E7AA4(src, recordSize, sp24, gUnknown_0858CFBE[r1_80e7b54][2], gUnknown_0858CFBE[r1_80e7b54][3]);
+ break;
+ }
+ _src = (void *)src + which * recordSize;
+ memcpy(&gSaveBlock1Ptr->daycare.mons[0].misc.mail, &_src->unk_00[0], sizeof(struct DayCareMail));
+ memcpy(&gSaveBlock1Ptr->daycare.mons[1].misc.mail, &_src->unk_00[1], sizeof(struct DayCareMail));
+ SeedRng(oldSeed);
+}
+#else
+NAKED
+static void ReceiveDaycareMailData(struct RecordMixingDayCareMail *src, size_t recordSize, u8 which, TVShow *shows)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r10\n"
+ "\tmov r6, r9\n"
+ "\tmov r5, r8\n"
+ "\tpush {r5-r7}\n"
+ "\tsub sp, 0x58\n"
+ "\tstr r0, [sp, 0x2C]\n"
+ "\tstr r1, [sp, 0x30]\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r2, 24\n"
+ "\tmov r9, r2\n"
+ "\tbl Random2\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tstr r0, [sp, 0x38]\n"
+ "\tldr r0, =gLinkPlayers\n"
+ "\tldrh r0, [r0, 0x4]\n"
+ "\tbl SeedRng2\n"
+ "\tbl GetLinkPlayerCount\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tmovs r0, 0\n"
+ "\tmov r8, r0\n"
+ "\tmov r1, sp\n"
+ "\tadds r1, 0x1C\n"
+ "\tstr r1, [sp, 0x4C]\n"
+ "\tmov r2, sp\n"
+ "\tadds r2, 0x1D\n"
+ "\tstr r2, [sp, 0x50]\n"
+ "\tmov r3, sp\n"
+ "\tadds r3, 0xC\n"
+ "\tstr r3, [sp, 0x48]\n"
+ "\tmovs r7, 0xFF\n"
+ "\tadd r3, sp, 0x8\n"
+ "\tmovs r2, 0\n"
+ "\tadds r6, r1, 0\n"
+ "\tldr r5, [sp, 0x50]\n"
+ "_080E7BB0:\n"
+ "\tmov r1, sp\n"
+ "\tadd r1, r8\n"
+ "\tadds r1, 0x4\n"
+ "\tldrb r0, [r1]\n"
+ "\torrs r0, r7\n"
+ "\tstrb r0, [r1]\n"
+ "\tmov r1, r8\n"
+ "\tadds r0, r3, r1\n"
+ "\tstrb r2, [r0]\n"
+ "\tlsls r1, 1\n"
+ "\tadds r0, r6, r1\n"
+ "\tstrb r2, [r0]\n"
+ "\tadds r1, r5, r1\n"
+ "\tstrb r2, [r1]\n"
+ "\tmov r0, r8\n"
+ "\tadds r0, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmov r8, r0\n"
+ "\tcmp r0, 0x3\n"
+ "\tbls _080E7BB0\n"
+ "\tbl Link_AnyPartnersPlayingRubyOrSapphire\n"
+ "\tstr r0, [sp, 0x3C]\n"
+ "\tmovs r2, 0\n"
+ "\tmov r8, r2\n"
+ "\tlsls r4, 16\n"
+ "\tstr r4, [sp, 0x54]\n"
+ "\tldr r0, [sp, 0x30]\n"
+ "\tmov r3, r9\n"
+ "\tmuls r3, r0\n"
+ "\tstr r3, [sp, 0x44]\n"
+ "\tb _080E7D04\n"
+ "\t.pool\n"
+ "_080E7BF8:\n"
+ "\tldr r1, [sp, 0x30]\n"
+ "\tmov r0, r8\n"
+ "\tmuls r0, r1\n"
+ "\tldr r2, [sp, 0x2C]\n"
+ "\tadds r7, r2, r0\n"
+ "\tldr r1, =gLinkPlayers\n"
+ "\tmov r3, r8\n"
+ "\tlsls r0, r3, 3\n"
+ "\tsubs r0, r3\n"
+ "\tlsls r0, 2\n"
+ "\tadds r0, r1\n"
+ "\tldrh r1, [r0, 0x1A]\n"
+ "\tmov r9, r1\n"
+ "\tldrb r0, [r0]\n"
+ "\tstr r0, [sp, 0x40]\n"
+ "\tmovs r6, 0\n"
+ "\tldr r0, [r7, 0x70]\n"
+ "\tcmp r6, r0\n"
+ "\tbcs _080E7CFA\n"
+ "\tmovs r2, 0x10\n"
+ "\tnegs r2, r2\n"
+ "\tmov r10, r2\n"
+ "_080E7C24:\n"
+ "\tlsls r0, r6, 3\n"
+ "\tsubs r0, r6\n"
+ "\tlsls r0, 3\n"
+ "\tadds r5, r7, r0\n"
+ "\tldrh r0, [r5, 0x20]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080E7CEE\n"
+ "\tldr r3, [sp, 0x3C]\n"
+ "\tcmp r3, 0\n"
+ "\tbeq _080E7C9A\n"
+ "\tadds r4, r5, 0\n"
+ "\tadds r4, 0x24\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl StringLength\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tcmp r0, 0x5\n"
+ "\tbhi _080E7C54\n"
+ "\tmovs r4, 0x1\n"
+ "\tb _080E7C5C\n"
+ "\t.pool\n"
+ "_080E7C54:\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl StripExtCtrlCodes\n"
+ "\tmov r4, r9\n"
+ "_080E7C5C:\n"
+ "\tldrh r1, [r5, 0x2C]\n"
+ "\tldr r0, =0x000015fc\n"
+ "\tcmp r1, r0\n"
+ "\tbne _080E7C74\n"
+ "\tadds r0, r5, 0\n"
+ "\tadds r0, 0x2C\n"
+ "\tbl StripExtCtrlCodes\n"
+ "\tmovs r1, 0x1\n"
+ "\tb _080E7C76\n"
+ "\t.pool\n"
+ "_080E7C74:\n"
+ "\tmov r1, r9\n"
+ "_080E7C76:\n"
+ "\tldr r0, [sp, 0x40]\n"
+ "\tsubs r0, 0x1\n"
+ "\tcmp r0, 0x1\n"
+ "\tbhi _080E7CEE\n"
+ "\tadds r2, r5, 0\n"
+ "\tadds r2, 0x37\n"
+ "\tmovs r0, 0xF\n"
+ "\tands r4, r0\n"
+ "\tldrb r0, [r2]\n"
+ "\tmov r3, r10\n"
+ "\tands r0, r3\n"
+ "\torrs r0, r4\n"
+ "\tlsls r1, 4\n"
+ "\tmovs r3, 0xF\n"
+ "\tands r0, r3\n"
+ "\torrs r0, r1\n"
+ "\tstrb r0, [r2]\n"
+ "\tb _080E7CEE\n"
+ "_080E7C9A:\n"
+ "\tmov r0, r9\n"
+ "\tcmp r0, 0x1\n"
+ "\tbne _080E7CEE\n"
+ "\tadds r0, r5, 0\n"
+ "\tadds r0, 0x24\n"
+ "\tbl IsStringJapanese\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080E7CBA\n"
+ "\tadds r0, r5, 0\n"
+ "\tadds r0, 0x37\n"
+ "\tldrb r1, [r0]\n"
+ "\tmov r2, r10\n"
+ "\tands r1, r2\n"
+ "\tmovs r2, 0x1\n"
+ "\tb _080E7CC6\n"
+ "_080E7CBA:\n"
+ "\tadds r0, r5, 0\n"
+ "\tadds r0, 0x37\n"
+ "\tldrb r1, [r0]\n"
+ "\tmov r3, r10\n"
+ "\tands r1, r3\n"
+ "\tmovs r2, 0x2\n"
+ "_080E7CC6:\n"
+ "\torrs r1, r2\n"
+ "\tstrb r1, [r0]\n"
+ "\tadds r4, r0, 0\n"
+ "\tadds r0, r5, 0\n"
+ "\tadds r0, 0x2C\n"
+ "\tbl IsStringJapanese\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080E7CE2\n"
+ "\tldrb r0, [r4]\n"
+ "\tmovs r1, 0xF\n"
+ "\tands r1, r0\n"
+ "\tmovs r0, 0x10\n"
+ "\tb _080E7CEA\n"
+ "_080E7CE2:\n"
+ "\tldrb r0, [r4]\n"
+ "\tmovs r1, 0xF\n"
+ "\tands r1, r0\n"
+ "\tmovs r0, 0x20\n"
+ "_080E7CEA:\n"
+ "\torrs r1, r0\n"
+ "\tstrb r1, [r4]\n"
+ "_080E7CEE:\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tldr r0, [r7, 0x70]\n"
+ "\tcmp r6, r0\n"
+ "\tbcc _080E7C24\n"
+ "_080E7CFA:\n"
+ "\tmov r0, r8\n"
+ "\tadds r0, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmov r8, r0\n"
+ "_080E7D04:\n"
+ "\tbl GetLinkPlayerCount\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r8, r0\n"
+ "\tbcs _080E7D12\n"
+ "\tb _080E7BF8\n"
+ "_080E7D12:\n"
+ "\tmovs r0, 0\n"
+ "\tstr r0, [sp, 0x34]\n"
+ "\tmov r8, r0\n"
+ "\tldr r1, [sp, 0x54]\n"
+ "\tlsrs r0, r1, 16\n"
+ "\tldr r2, [sp, 0x34]\n"
+ "\tcmp r2, r0\n"
+ "\tbcs _080E7D70\n"
+ "\tadds r5, r0, 0\n"
+ "_080E7D24:\n"
+ "\tldr r3, [sp, 0x30]\n"
+ "\tmov r0, r8\n"
+ "\tmuls r0, r3\n"
+ "\tldr r1, [sp, 0x2C]\n"
+ "\tadds r7, r1, r0\n"
+ "\tldr r0, [r7, 0x70]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080E7D62\n"
+ "\tmovs r6, 0\n"
+ "\tcmp r6, r0\n"
+ "\tbcs _080E7D62\n"
+ "\tadds r3, r7, 0\n"
+ "\tadds r3, 0x74\n"
+ "\tldr r2, [sp, 0x4C]\n"
+ "\tmov r0, r8\n"
+ "\tlsls r1, r0, 1\n"
+ "\tmovs r4, 0x1\n"
+ "_080E7D46:\n"
+ "\tlsls r0, r6, 1\n"
+ "\tadds r0, r3, r0\n"
+ "\tldrh r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080E7D56\n"
+ "\tadds r0, r6, r1\n"
+ "\tadds r0, r2, r0\n"
+ "\tstrb r4, [r0]\n"
+ "_080E7D56:\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tldr r0, [r7, 0x70]\n"
+ "\tcmp r6, r0\n"
+ "\tbcc _080E7D46\n"
+ "_080E7D62:\n"
+ "\tmov r0, r8\n"
+ "\tadds r0, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmov r8, r0\n"
+ "\tcmp r8, r5\n"
+ "\tbcc _080E7D24\n"
+ "_080E7D70:\n"
+ "\tmovs r6, 0\n"
+ "\tmov r8, r6\n"
+ "\tldr r1, [sp, 0x54]\n"
+ "\tcmp r1, 0\n"
+ "\tbeq _080E7E64\n"
+ "\tadd r2, sp, 0x24\n"
+ "\tmov r10, r2\n"
+ "\tmovs r3, 0x25\n"
+ "\tadd r3, sp\n"
+ "\tmov r9, r3\n"
+ "_080E7D84:\n"
+ "\tldr r1, [sp, 0x30]\n"
+ "\tmov r0, r8\n"
+ "\tmuls r0, r1\n"
+ "\tldr r2, [sp, 0x2C]\n"
+ "\tadds r7, r2, r0\n"
+ "\tmov r3, r8\n"
+ "\tlsls r1, r3, 1\n"
+ "\tldr r2, [sp, 0x4C]\n"
+ "\tadds r0, r2, r1\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x1\n"
+ "\tbeq _080E7DA6\n"
+ "\tldr r3, [sp, 0x50]\n"
+ "\tadds r0, r3, r1\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x1\n"
+ "\tbne _080E7DB0\n"
+ "_080E7DA6:\n"
+ "\tldr r0, [sp, 0x34]\n"
+ "\tadds r0, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tstr r0, [sp, 0x34]\n"
+ "_080E7DB0:\n"
+ "\tldr r2, [sp, 0x4C]\n"
+ "\tadds r0, r2, r1\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x1\n"
+ "\tbne _080E7DD4\n"
+ "\tldr r3, [sp, 0x50]\n"
+ "\tadds r0, r3, r1\n"
+ "\tldrb r2, [r0]\n"
+ "\tcmp r2, 0\n"
+ "\tbne _080E7DD4\n"
+ "_080E7DC4:\n"
+ "\tlsls r1, r6, 1\n"
+ "\tmov r3, r10\n"
+ "\tadds r0, r3, r1\n"
+ "\tmov r3, r8\n"
+ "\tstrb r3, [r0]\n"
+ "\tadd r1, r9\n"
+ "\tstrb r2, [r1]\n"
+ "\tb _080E7E4E\n"
+ "_080E7DD4:\n"
+ "\tldr r2, [sp, 0x4C]\n"
+ "\tadds r0, r2, r1\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080E7DE8\n"
+ "\tldr r3, [sp, 0x50]\n"
+ "\tadds r0, r3, r1\n"
+ "\tldrb r2, [r0]\n"
+ "\tcmp r2, 0x1\n"
+ "\tbeq _080E7DC4\n"
+ "_080E7DE8:\n"
+ "\tldr r2, [sp, 0x4C]\n"
+ "\tadds r0, r2, r1\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x1\n"
+ "\tbne _080E7E54\n"
+ "\tldr r3, [sp, 0x50]\n"
+ "\tadds r0, r3, r1\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x1\n"
+ "\tbne _080E7E54\n"
+ "\tlsls r5, r6, 1\n"
+ "\tmov r1, r10\n"
+ "\tadds r0, r1, r5\n"
+ "\tmov r2, r8\n"
+ "\tstrb r2, [r0]\n"
+ "\tadds r0, r7, 0\n"
+ "\tbl sub_80E7A9C\n"
+ "\tadds r4, r0, 0\n"
+ "\tlsls r4, 24\n"
+ "\tlsrs r4, 24\n"
+ "\tadds r0, r7, 0\n"
+ "\tadds r0, 0x38\n"
+ "\tbl sub_80E7A9C\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r1, r0, 24\n"
+ "\tcmp r4, 0\n"
+ "\tbne _080E7E30\n"
+ "\tcmp r1, 0\n"
+ "\tbeq _080E7E34\n"
+ "\tmov r3, r9\n"
+ "\tadds r1, r3, r5\n"
+ "\tmovs r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "\tb _080E7E4E\n"
+ "_080E7E30:\n"
+ "\tcmp r1, 0\n"
+ "\tbeq _080E7E48\n"
+ "_080E7E34:\n"
+ "\tbl Random2\n"
+ "\tmov r1, r9\n"
+ "\tadds r2, r1, r5\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmovs r1, 0x1\n"
+ "\tands r0, r1\n"
+ "\tstrb r0, [r2]\n"
+ "\tb _080E7E4E\n"
+ "_080E7E48:\n"
+ "\tmov r2, r9\n"
+ "\tadds r0, r2, r5\n"
+ "\tstrb r1, [r0]\n"
+ "_080E7E4E:\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "_080E7E54:\n"
+ "\tmov r0, r8\n"
+ "\tadds r0, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r3, r0, 16\n"
+ "\tmov r8, r3\n"
+ "\tldr r1, [sp, 0x54]\n"
+ "\tcmp r0, r1\n"
+ "\tbcc _080E7D84\n"
+ "_080E7E64:\n"
+ "\tmovs r2, 0\n"
+ "\tmov r8, r2\n"
+ "\tldr r3, [sp, 0x44]\n"
+ "\tlsls r0, r3, 4\n"
+ "\tsubs r0, r3\n"
+ "\tlsls r0, 3\n"
+ "\tldr r1, [sp, 0x2C]\n"
+ "\tadds r7, r1, r0\n"
+ "\tldr r1, [sp, 0x48]\n"
+ "_080E7E76:\n"
+ "\tmov r2, r8\n"
+ "\tlsls r0, r2, 2\n"
+ "\tadds r0, r1, r0\n"
+ "\tstr r7, [r0]\n"
+ "\tmov r0, r8\n"
+ "\tadds r0, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmov r8, r0\n"
+ "\tcmp r0, 0x3\n"
+ "\tbls _080E7E76\n"
+ "\tbl sub_80E7B54\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tmovs r1, 0x3\n"
+ "\tbl __umodsi3\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r1, r0, 24\n"
+ "\tldr r3, [sp, 0x34]\n"
+ "\tcmp r3, 0x3\n"
+ "\tbeq _080E7EC8\n"
+ "\tcmp r3, 0x3\n"
+ "\tbgt _080E7EAE\n"
+ "\tcmp r3, 0x2\n"
+ "\tbeq _080E7EB6\n"
+ "\tb _080E7F1C\n"
+ "_080E7EAE:\n"
+ "\tldr r0, [sp, 0x34]\n"
+ "\tcmp r0, 0x4\n"
+ "\tbeq _080E7EE8\n"
+ "\tb _080E7F1C\n"
+ "_080E7EB6:\n"
+ "\tadd r2, sp, 0x24\n"
+ "\tmovs r0, 0x1\n"
+ "\tstr r0, [sp]\n"
+ "\tldr r0, [sp, 0x2C]\n"
+ "\tldr r1, [sp, 0x30]\n"
+ "\tmovs r3, 0\n"
+ "\tbl sub_80E7AA4\n"
+ "\tb _080E7F1C\n"
+ "_080E7EC8:\n"
+ "\tldr r0, =gUnknown_0858CFB8\n"
+ "\tlsls r1, 1\n"
+ "\tadds r2, r1, r0\n"
+ "\tldrb r3, [r2]\n"
+ "\tadds r0, 0x1\n"
+ "\tadds r1, r0\n"
+ "\tldrb r0, [r1]\n"
+ "\tadd r2, sp, 0x24\n"
+ "\tstr r0, [sp]\n"
+ "\tldr r0, [sp, 0x2C]\n"
+ "\tldr r1, [sp, 0x30]\n"
+ "\tbl sub_80E7AA4\n"
+ "\tb _080E7F1C\n"
+ "\t.pool\n"
+ "_080E7EE8:\n"
+ "\tadd r6, sp, 0x24\n"
+ "\tldr r4, =gUnknown_0858CFBE\n"
+ "\tlsls r5, r1, 2\n"
+ "\tadds r0, r5, r4\n"
+ "\tldrb r3, [r0]\n"
+ "\tadds r0, r4, 0x1\n"
+ "\tadds r0, r5, r0\n"
+ "\tldrb r0, [r0]\n"
+ "\tstr r0, [sp]\n"
+ "\tldr r0, [sp, 0x2C]\n"
+ "\tldr r1, [sp, 0x30]\n"
+ "\tadds r2, r6, 0\n"
+ "\tbl sub_80E7AA4\n"
+ "\tadds r0, r4, 0x2\n"
+ "\tadds r0, r5, r0\n"
+ "\tldrb r3, [r0]\n"
+ "\tadds r4, 0x3\n"
+ "\tadds r5, r4\n"
+ "\tldrb r0, [r5]\n"
+ "\tstr r0, [sp]\n"
+ "\tldr r0, [sp, 0x2C]\n"
+ "\tldr r1, [sp, 0x30]\n"
+ "\tadds r2, r6, 0\n"
+ "\tbl sub_80E7AA4\n"
+ "_080E7F1C:\n"
+ "\tldr r1, [sp, 0x2C]\n"
+ "\tldr r2, [sp, 0x44]\n"
+ "\tadds r7, r1, r2\n"
+ "\tldr r4, =gSaveBlock1Ptr\n"
+ "\tldr r0, [r4]\n"
+ "\tmovs r3, 0xC2\n"
+ "\tlsls r3, 6\n"
+ "\tadds r0, r3\n"
+ "\tadds r1, r7, 0\n"
+ "\tmovs r2, 0x38\n"
+ "\tbl memcpy\n"
+ "\tldr r0, [r4]\n"
+ "\tldr r1, =0x0000310c\n"
+ "\tadds r0, r1\n"
+ "\tadds r1, r7, 0\n"
+ "\tadds r1, 0x38\n"
+ "\tmovs r2, 0x38\n"
+ "\tbl memcpy\n"
+ "\tldr r0, [sp, 0x38]\n"
+ "\tbl SeedRng\n"
+ "\tadd sp, 0x58\n"
+ "\tpop {r3-r5}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tmov r10, r5\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.pool");
+}
+#endif // NONMATCHING
+
+static void sub_80E7F68(u16 *item, u8 which)
+{
+ if (which != 0 && *item != ITEM_NONE && GetPocketByItemId(*item) == POCKET_KEY_ITEMS)
+ {
+ if (!CheckBagHasItem(*item, 1) && !CheckPCHasItem(*item, 1) && AddBagItem(*item, 1))
+ {
+ VarSet(VAR_TEMP_1, *item);
+ StringCopy(gStringVar1, gLinkPlayers[0].name);
+ if (*item == ITEM_EON_TICKET)
+ FlagSet(FLAG_SYS_HAS_EON_TICKET);
+ }
+ else
+ {
+ VarSet(VAR_TEMP_1, ITEM_NONE);
+ }
+ }
+}
+
+static void sub_80E7FF8(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[0]++;
+ break;
+ case 1:
+ if (Link_AnyPartnersPlayingRubyOrSapphire())
+ task->data[0]++;
+ else
+ task->data[0] = 6;
+ break;
+ case 2:
+ sub_8076D5C();
+ sub_8153430();
+ task->data[0] ++;
+ break;
+ case 3:
+ if (sub_8153474())
+ {
+ sav2_gender2_inplace_and_xFE();
+ task->data[0] = 4;
+ task->data[1] = 0;
+ }
+ break;
+ case 4:
+ if (++task->data[1] > 10)
+ {
+ sub_800AC34();
+ task->data[0] ++;
+ }
+ break;
+ case 5:
+ if (gReceivedRemoteLinkPlayers == 0)
+ DestroyTask(taskId);
+ break;
+ case 6:
+ if (!sub_801048C(0))
+ {
+ CreateTask(sub_8153688, 5);
+ task->data[0] ++;
+ }
+ break;
+ case 7:
+ if (!FuncIsActiveTask(sub_8153688))
+ {
+ if (gWirelessCommType)
+ {
+ sub_801048C(1);
+ task->data[0] = 8;
+ }
+ else
+ {
+ task->data[0] = 4;
+ }
+ }
+ break;
+ case 8:
+ sub_800ADF8();
+ task->data[0] ++;
+ break;
+ case 9:
+ if (sub_800A520())
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+// New Emerald functions
+
+static void sub_80E8110(struct UnkRecordMixingStruct *dst, struct UnkRecordMixingStruct *src)
+{
+ s32 i, id;
+ s32 var_2C, var_28, var_24, r8;
+
+ dst[0].field_38[0] = 0xFF;
+ dst[1].field_38[0] = 0xFF;
+
+ dst[0] = src[0];
+
+ var_28 = 0;
+ var_24 = 0;
+ var_2C = 0;
+ r8 = 0;
+ for (i = 0; i < 2; i++)
+ {
+ id = ((i + gSaveBlock2Ptr->field_B2_1) % 3) + 1;
+ if (src[id].field_38[0] != 0xFF)
+ {
+ if (ReadUnalignedWord(src[id].playerId) != ReadUnalignedWord(gSaveBlock2Ptr->playerTrainerId))
+ {
+ r8++;
+ var_2C = id;
+ }
+ if (ReadUnalignedWord(src[id].playerId) == ReadUnalignedWord(gSaveBlock2Ptr->playerTrainerId))
+ {
+ var_24++;
+ var_28 = id;
+ }
+ }
+ }
+
+ if (r8 == 0 && var_24 != 0)
+ {
+ r8 = var_24;
+ var_2C = var_28;
+ }
+
+ switch (r8)
+ {
+ case 1:
+ dst[1] = src[var_2C];
+ break;
+ case 2:
+ if (Random2() > 0x3333)
+ {
+ dst[1] = src[gSaveBlock2Ptr->field_B2_1 + 1];
+ }
+ else
+ {
+ dst[1] = src[((gSaveBlock2Ptr->field_B2_1 + 1) % 3 + 1)];
+ }
+ break;
+ }
+}
+
+void sub_80E8260(struct UnkRecordMixingStruct2 *dst)
+{
+ s32 i, j;
+
+ for (i = 0; i < 9; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ CopyUnalignedWord(dst->field_0[i][j].playerId, gSaveBlock2Ptr->playerTrainerId);
+ dst->field_0[i][j].language = GAME_LANGUAGE;
+ StringCopy(dst->field_0[i][j].playerName, gSaveBlock2Ptr->playerName);
+ }
+ }
+
+ for (j = 0; j < 2; j++)
+ {
+ dst->field_120[j].language = GAME_LANGUAGE;
+ CopyUnalignedWord(dst->field_120[j].playerId1, gSaveBlock2Ptr->playerTrainerId);
+ CopyUnalignedWord(dst->field_120[j].playerId2, gSaveBlock2Ptr->field_EF1[j]);
+ StringCopy(dst->field_120[j].playerName1, gSaveBlock2Ptr->playerName);
+ StringCopy(dst->field_120[j].playerName2, gSaveBlock2Ptr->field_EE1[j]);
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ dst->field_0[0][i].field_4 = gSaveBlock2Ptr->field_CF0[i];
+ dst->field_0[1][i].field_4 = gSaveBlock2Ptr->field_CF4[i];
+ dst->field_0[2][i].field_4 = gSaveBlock2Ptr->field_CF8[i];
+ dst->field_0[3][i].field_4 = gSaveBlock2Ptr->field_D14[i];
+ dst->field_0[4][i].field_4 = gSaveBlock2Ptr->field_DD0[i];
+ dst->field_0[5][i].field_4 = gSaveBlock2Ptr->field_DDE[i];
+ dst->field_0[6][i].field_4 = gSaveBlock2Ptr->field_DEA[i];
+ dst->field_0[7][i].field_4 = gSaveBlock2Ptr->field_E08[i];
+ dst->field_0[8][i].field_4 = gSaveBlock2Ptr->field_E1E[i];
+
+ dst->field_120[i].field_8 = gSaveBlock2Ptr->field_CFC[i];
+ }
+}
+
+static bool32 sub_80E841C(struct UnkRecordMixingStruct *arg0, struct UnkRecordMixingStruct *arg1)
+{
+ s32 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (ReadUnalignedWord(arg0->playerId) == ReadUnalignedWord(arg1[i].playerId)
+ && arg0->field_0[2] == arg1[i].field_0[2])
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void sub_80E8468(struct UnkRecordMixingStruct *arg0, size_t arg1, u32 arg2)
+{
+ s32 i, r7, r8;
+ struct UnkRecordMixingStruct *structPtr;
+ u32 mixIndices[4];
+ u32 structId;
+
+ ShufflePlayerIndices(mixIndices);
+ structPtr = (void*)(arg0) + (arg1 * mixIndices[arg2]);
+ r7 = 0;
+ r8 = 0;
+ for (i = 0; i < 2; i++)
+ {
+ if (structPtr[i].field_38[0] != 0xFF && !sub_80E841C(&structPtr[i], gSaveBlock2Ptr->field_DC))
+ {
+ r7++;
+ r8 = i;
+ }
+ }
+
+ switch (r7)
+ {
+ case 1:
+ structId = gSaveBlock2Ptr->field_B2_1 + 1;
+ gSaveBlock2Ptr->field_DC[structId] = structPtr[r8];
+ gSaveBlock2Ptr->field_B2_1 = (gSaveBlock2Ptr->field_B2_1 + 1) % 3;
+ break;
+ case 2:
+ for (i = 0; i < 2; i++)
+ {
+ structId = ((i ^ 1) + gSaveBlock2Ptr->field_B2_1) % 3 + 1;
+ gSaveBlock2Ptr->field_DC[structId] = structPtr[i];
+ }
+ gSaveBlock2Ptr->field_B2_1 = (gSaveBlock2Ptr->field_B2_1 + 2) % 3;
+ break;
+ }
+}
+
+NAKED
+static void sub_80E8578(struct UnknownRecMixingStruct3 *arg0, struct UnkRecordMixingStruct2 *arg1, size_t arg2, u32 arg3, u32 arg4)
+{
+ asm_unified(" push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x54\n\
+ str r0, [sp]\n\
+ ldr r0, [sp, 0x74]\n\
+ movs r4, 0\n\
+ mov r8, r4\n\
+ movs r5, 0\n\
+ str r5, [sp, 0x4]\n\
+ ldr r4, =gUnknown_03001168\n\
+ b _080E85A0\n\
+ .pool\n\
+_080E8598:\n\
+ adds r1, r2\n\
+ ldr r6, [sp, 0x4]\n\
+ adds r6, 0x1\n\
+ str r6, [sp, 0x4]\n\
+_080E85A0:\n\
+ ldr r5, [sp, 0x4]\n\
+ cmp r5, r0\n\
+ bge _080E85B6\n\
+ cmp r5, r3\n\
+ beq _080E85B0\n\
+ stm r4!, {r1}\n\
+ movs r6, 0x1\n\
+ add r8, r6\n\
+_080E85B0:\n\
+ mov r5, r8\n\
+ cmp r5, 0x3\n\
+ bne _080E8598\n\
+_080E85B6:\n\
+ movs r6, 0\n\
+ str r6, [sp, 0x4]\n\
+ subs r0, 0x1\n\
+ str r0, [sp, 0x24]\n\
+_080E85BE:\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x8]\n\
+ ldr r1, [sp, 0x4]\n\
+ adds r1, 0x1\n\
+ str r1, [sp, 0x28]\n\
+ ldr r2, [sp, 0x4]\n\
+ lsls r2, 1\n\
+ str r2, [sp, 0x34]\n\
+ ldr r3, [sp, 0x4]\n\
+ adds r3, r2, r3\n\
+ str r3, [sp, 0x10]\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x44]\n\
+ movs r5, 0\n\
+ str r5, [sp, 0x48]\n\
+_080E85DC:\n\
+ movs r6, 0\n\
+ mov r8, r6\n\
+ ldr r0, =gSaveBlock2Ptr\n\
+ ldr r1, [r0]\n\
+ ldr r2, [sp, 0x10]\n\
+ lsls r0, r2, 5\n\
+ ldr r3, [sp, 0x48]\n\
+ adds r0, r3, r0\n\
+ adds r3, r0, r1\n\
+ lsls r0, r2, 6\n\
+ ldr r4, [sp, 0x44]\n\
+ adds r0, r4, r0\n\
+ ldr r5, [sp]\n\
+ adds r2, r0, r5\n\
+_080E85F8:\n\
+ adds r0, r2, 0\n\
+ movs r6, 0x87\n\
+ lsls r6, 2\n\
+ adds r1, r3, r6\n\
+ ldm r1!, {r4-r6}\n\
+ stm r0!, {r4-r6}\n\
+ ldr r1, [r1]\n\
+ str r1, [r0]\n\
+ adds r3, 0x10\n\
+ adds r2, 0x10\n\
+ movs r0, 0x1\n\
+ add r8, r0\n\
+ mov r1, r8\n\
+ cmp r1, 0x2\n\
+ ble _080E85F8\n\
+ movs r2, 0\n\
+ mov r8, r2\n\
+ ldr r3, [sp, 0x24]\n\
+ cmp r8, r3\n\
+ bge _080E86DC\n\
+ ldr r4, [sp, 0x4]\n\
+ lsls r4, 5\n\
+ mov r9, r4\n\
+ ldr r5, [sp, 0x8]\n\
+ lsls r7, r5, 4\n\
+ ldr r6, [sp, 0x34]\n\
+ ldr r1, [sp, 0x4]\n\
+ adds r0, r6, r1\n\
+ lsls r0, 6\n\
+ str r0, [sp, 0x14]\n\
+ ldr r2, [sp]\n\
+ adds r0, r2, r0\n\
+ ldr r3, [sp, 0x44]\n\
+ str r3, [sp, 0x18]\n\
+ adds r0, r3\n\
+ str r0, [sp, 0x1C]\n\
+ ldr r4, [sp, 0x14]\n\
+ adds r0, r3, r4\n\
+ adds r0, r2\n\
+ adds r0, 0x30\n\
+ mov r10, r0\n\
+_080E864A:\n\
+ movs r5, 0\n\
+ str r5, [sp, 0xC]\n\
+ movs r3, 0\n\
+ mov r6, r8\n\
+ lsls r6, 2\n\
+ str r6, [sp, 0x38]\n\
+ ldr r1, [sp, 0x18]\n\
+ ldr r2, [sp, 0x14]\n\
+ adds r0, r1, r2\n\
+ ldr r4, [sp]\n\
+ adds r5, r0, r4\n\
+ ldr r0, =gUnknown_03001168\n\
+ adds r0, r6, r0\n\
+ str r0, [sp, 0x50]\n\
+_080E8666:\n\
+ lsls r0, r3, 4\n\
+ ldr r6, [sp, 0x1C]\n\
+ adds r0, r6, r0\n\
+ str r3, [sp, 0x4C]\n\
+ bl ReadUnalignedWord\n\
+ adds r4, r0, 0\n\
+ ldr r1, [sp, 0x50]\n\
+ ldr r0, [r1]\n\
+ add r0, r9\n\
+ adds r0, r7\n\
+ bl ReadUnalignedWord\n\
+ ldr r3, [sp, 0x4C]\n\
+ cmp r4, r0\n\
+ bne _080E86A8\n\
+ ldr r2, [sp, 0xC]\n\
+ adds r2, 0x1\n\
+ str r2, [sp, 0xC]\n\
+ ldr r4, [sp, 0x50]\n\
+ ldr r0, [r4]\n\
+ mov r6, r9\n\
+ adds r1, r7, r6\n\
+ adds r1, r0, r1\n\
+ ldrh r0, [r5, 0x4]\n\
+ ldrh r2, [r1, 0x4]\n\
+ cmp r0, r2\n\
+ bcs _080E86A8\n\
+ adds r0, r5, 0\n\
+ ldm r1!, {r2,r4,r6}\n\
+ stm r0!, {r2,r4,r6}\n\
+ ldr r1, [r1]\n\
+ str r1, [r0]\n\
+_080E86A8:\n\
+ adds r5, 0x10\n\
+ adds r3, 0x1\n\
+ cmp r3, 0x2\n\
+ ble _080E8666\n\
+ ldr r3, [sp, 0xC]\n\
+ cmp r3, 0\n\
+ bne _080E86CE\n\
+ ldr r0, =gUnknown_03001168\n\
+ ldr r4, [sp, 0x38]\n\
+ adds r0, r4, r0\n\
+ ldr r0, [r0]\n\
+ mov r5, r9\n\
+ adds r2, r7, r5\n\
+ mov r1, r10\n\
+ adds r0, r2\n\
+ ldm r0!, {r2,r3,r6}\n\
+ stm r1!, {r2,r3,r6}\n\
+ ldr r0, [r0]\n\
+ str r0, [r1]\n\
+_080E86CE:\n\
+ movs r4, 0x10\n\
+ add r10, r4\n\
+ movs r5, 0x1\n\
+ add r8, r5\n\
+ ldr r6, [sp, 0x24]\n\
+ cmp r8, r6\n\
+ blt _080E864A\n\
+_080E86DC:\n\
+ ldr r0, [sp, 0x44]\n\
+ adds r0, 0x60\n\
+ str r0, [sp, 0x44]\n\
+ ldr r1, [sp, 0x48]\n\
+ adds r1, 0x30\n\
+ str r1, [sp, 0x48]\n\
+ ldr r2, [sp, 0x8]\n\
+ adds r2, 0x1\n\
+ str r2, [sp, 0x8]\n\
+ cmp r2, 0x1\n\
+ bgt _080E86F4\n\
+ b _080E85DC\n\
+_080E86F4:\n\
+ ldr r3, [sp, 0x28]\n\
+ str r3, [sp, 0x4]\n\
+ cmp r3, 0x8\n\
+ bgt _080E86FE\n\
+ b _080E85BE\n\
+_080E86FE:\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x8]\n\
+_080E8702:\n\
+ ldr r5, [sp, 0x8]\n\
+ adds r5, 0x1\n\
+ str r5, [sp, 0x2C]\n\
+ ldr r0, =gSaveBlock2Ptr\n\
+ ldr r1, [r0]\n\
+ movs r0, 0x54\n\
+ ldr r6, [sp, 0x8]\n\
+ muls r0, r6\n\
+ adds r3, r0, r1\n\
+ movs r0, 0xA8\n\
+ muls r0, r6\n\
+ ldr r1, [sp]\n\
+ adds r2, r0, r1\n\
+ movs r4, 0x2\n\
+ mov r8, r4\n\
+_080E8720:\n\
+ movs r5, 0xD8\n\
+ lsls r5, 3\n\
+ adds r0, r2, r5\n\
+ ldr r6, =0x0000057c\n\
+ adds r1, r3, r6\n\
+ ldm r1!, {r4-r6}\n\
+ stm r0!, {r4-r6}\n\
+ ldm r1!, {r4-r6}\n\
+ stm r0!, {r4-r6}\n\
+ ldr r1, [r1]\n\
+ str r1, [r0]\n\
+ adds r3, 0x1C\n\
+ adds r2, 0x1C\n\
+ movs r0, 0x1\n\
+ negs r0, r0\n\
+ add r8, r0\n\
+ mov r1, r8\n\
+ cmp r1, 0\n\
+ bge _080E8720\n\
+ movs r2, 0\n\
+ mov r8, r2\n\
+ ldr r3, [sp, 0x24]\n\
+ cmp r8, r3\n\
+ blt _080E8752\n\
+ b _080E885A\n\
+_080E8752:\n\
+ ldr r4, [sp, 0x8]\n\
+ lsls r1, r4, 3\n\
+ movs r0, 0xA8\n\
+ adds r5, r4, 0\n\
+ muls r5, r0\n\
+ str r5, [sp, 0x20]\n\
+ str r5, [sp, 0x3C]\n\
+ subs r1, r4\n\
+ lsls r1, 2\n\
+ mov r10, r1\n\
+_080E8766:\n\
+ movs r6, 0\n\
+ str r6, [sp, 0xC]\n\
+ mov r0, r8\n\
+ lsls r0, 2\n\
+ str r0, [sp, 0x38]\n\
+ mov r1, r8\n\
+ adds r1, 0x1\n\
+ str r1, [sp, 0x30]\n\
+ ldr r0, =gUnknown_03001168\n\
+ ldr r2, [sp, 0x38]\n\
+ adds r2, r0\n\
+ mov r9, r2\n\
+ ldr r3, [sp]\n\
+ movs r4, 0xD8\n\
+ lsls r4, 3\n\
+ adds r0, r3, r4\n\
+ ldr r5, [sp, 0x3C]\n\
+ adds r7, r5, r0\n\
+ str r6, [sp, 0x40]\n\
+ movs r3, 0x2\n\
+_080E878E:\n\
+ ldr r1, [sp, 0x20]\n\
+ movs r2, 0xD8\n\
+ lsls r2, 3\n\
+ adds r0, r1, r2\n\
+ ldr r4, [sp]\n\
+ adds r0, r4, r0\n\
+ ldr r6, [sp, 0x40]\n\
+ adds r5, r0, r6\n\
+ adds r0, r5, 0\n\
+ str r3, [sp, 0x4C]\n\
+ bl ReadUnalignedWord\n\
+ adds r4, r0, 0\n\
+ movs r6, 0x90\n\
+ lsls r6, 1\n\
+ add r6, r10\n\
+ mov r1, r9\n\
+ ldr r0, [r1]\n\
+ adds r0, r6\n\
+ bl ReadUnalignedWord\n\
+ ldr r3, [sp, 0x4C]\n\
+ cmp r4, r0\n\
+ bne _080E8808\n\
+ adds r0, r5, 0x4\n\
+ bl ReadUnalignedWord\n\
+ adds r4, r0, 0\n\
+ mov r2, r9\n\
+ ldr r0, [r2]\n\
+ adds r0, r6\n\
+ adds r0, 0x4\n\
+ bl ReadUnalignedWord\n\
+ ldr r3, [sp, 0x4C]\n\
+ cmp r4, r0\n\
+ bne _080E8808\n\
+ ldr r4, [sp, 0xC]\n\
+ adds r4, 0x1\n\
+ str r4, [sp, 0xC]\n\
+ mov r5, r9\n\
+ ldr r0, [r5]\n\
+ mov r6, r10\n\
+ adds r2, r0, r6\n\
+ movs r0, 0x94\n\
+ lsls r0, 1\n\
+ adds r1, r2, r0\n\
+ ldrh r0, [r7, 0x8]\n\
+ ldrh r1, [r1]\n\
+ cmp r0, r1\n\
+ bcs _080E8808\n\
+ adds r0, r7, 0\n\
+ movs r4, 0x90\n\
+ lsls r4, 1\n\
+ adds r1, r2, r4\n\
+ ldm r1!, {r2,r5,r6}\n\
+ stm r0!, {r2,r5,r6}\n\
+ ldm r1!, {r4-r6}\n\
+ stm r0!, {r4-r6}\n\
+ ldr r1, [r1]\n\
+ str r1, [r0]\n\
+_080E8808:\n\
+ adds r7, 0x1C\n\
+ ldr r0, [sp, 0x40]\n\
+ adds r0, 0x1C\n\
+ str r0, [sp, 0x40]\n\
+ subs r3, 0x1\n\
+ cmp r3, 0\n\
+ bge _080E878E\n\
+ ldr r1, [sp, 0xC]\n\
+ cmp r1, 0\n\
+ bne _080E8850\n\
+ mov r0, r8\n\
+ adds r0, 0x3\n\
+ lsls r1, r0, 3\n\
+ subs r1, r0\n\
+ lsls r1, 2\n\
+ ldr r2, [sp, 0x20]\n\
+ adds r1, r2\n\
+ ldr r3, [sp]\n\
+ adds r1, r3, r1\n\
+ ldr r0, =gUnknown_03001168\n\
+ ldr r4, [sp, 0x38]\n\
+ adds r0, r4, r0\n\
+ ldr r0, [r0]\n\
+ add r0, r10\n\
+ movs r5, 0xD8\n\
+ lsls r5, 3\n\
+ adds r1, r5\n\
+ movs r6, 0x90\n\
+ lsls r6, 1\n\
+ adds r0, r6\n\
+ ldm r0!, {r2-r4}\n\
+ stm r1!, {r2-r4}\n\
+ ldm r0!, {r2,r5,r6}\n\
+ stm r1!, {r2,r5,r6}\n\
+ ldr r0, [r0]\n\
+ str r0, [r1]\n\
+_080E8850:\n\
+ ldr r3, [sp, 0x30]\n\
+ mov r8, r3\n\
+ ldr r4, [sp, 0x24]\n\
+ cmp r8, r4\n\
+ blt _080E8766\n\
+_080E885A:\n\
+ ldr r5, [sp, 0x2C]\n\
+ str r5, [sp, 0x8]\n\
+ cmp r5, 0x1\n\
+ bgt _080E8864\n\
+ b _080E8702\n\
+_080E8864:\n\
+ add sp, 0x54\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n\
+ ");
+}
+
+static void sub_80E8880(struct UnknownRecMixingStruct *arg0, struct UnknownRecMixingStruct *arg1)
+{
+ s32 i, j;
+
+ for (i = 0; i < 3; i++)
+ {
+ s32 r2 = 0;
+ s32 r4 = -1;
+ for (j = 0; j < 6; j++)
+ {
+ if (arg1[j].field_4 > r2)
+ {
+ r4 = j;
+ r2 = arg1[j].field_4;
+ }
+ }
+
+ if (r4 >= 0)
+ {
+ arg0[i] = arg1[r4];
+ arg1[r4].field_4 = 0;
+ }
+ }
+}
+
+static void sub_80E88CC(struct UnknownRecMixingStruct2 *arg0, struct UnknownRecMixingStruct2 *arg1)
+{
+ s32 i, j;
+
+ for (i = 0; i < 3; i++)
+ {
+ s32 r2 = 0;
+ s32 r4 = -1;
+ for (j = 0; j < 6; j++)
+ {
+ if (arg1[j].field_8 > r2)
+ {
+ r4 = j;
+ r2 = arg1[j].field_8;
+ }
+ }
+
+ if (r4 >= 0)
+ {
+ arg0[i] = arg1[r4];
+ arg1[r4].field_8 = 0;
+ }
+ }
+}
+
+NAKED
+static void sub_80E8924(struct UnknownRecMixingStruct3 *arg0)
+{
+ asm_unified("push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ mov r9, r0\n\
+ movs r0, 0\n\
+ ldr r1, =gSaveBlock2Ptr\n\
+ mov r10, r1\n\
+_080E8936:\n\
+ lsls r1, r0, 1\n\
+ adds r2, r0, 0x1\n\
+ mov r8, r2\n\
+ adds r1, r0\n\
+ lsls r0, r1, 5\n\
+ movs r2, 0x87\n\
+ lsls r2, 2\n\
+ adds r7, r0, r2\n\
+ lsls r1, 6\n\
+ mov r0, r9\n\
+ adds r4, r0, r1\n\
+ movs r6, 0\n\
+ movs r5, 0x1\n\
+_080E8950:\n\
+ mov r1, r10\n\
+ ldr r0, [r1]\n\
+ adds r0, r7\n\
+ adds r0, r6\n\
+ adds r1, r4, 0\n\
+ bl sub_80E8880\n\
+ adds r4, 0x60\n\
+ adds r6, 0x30\n\
+ subs r5, 0x1\n\
+ cmp r5, 0\n\
+ bge _080E8950\n\
+ mov r0, r8\n\
+ cmp r0, 0x8\n\
+ ble _080E8936\n\
+ movs r5, 0\n\
+ ldr r4, =gSaveBlock2Ptr\n\
+_080E8972:\n\
+ movs r0, 0x54\n\
+ adds r1, r5, 0\n\
+ muls r1, r0\n\
+ ldr r2, =0x0000057c\n\
+ adds r1, r2\n\
+ ldr r0, [r4]\n\
+ adds r0, r1\n\
+ movs r1, 0xA8\n\
+ muls r1, r5\n\
+ movs r2, 0xD8\n\
+ lsls r2, 3\n\
+ adds r1, r2\n\
+ add r1, r9\n\
+ bl sub_80E88CC\n\
+ adds r5, 0x1\n\
+ cmp r5, 0x1\n\
+ ble _080E8972\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool");
+}
+
+static void sub_80E89AC(struct UnkRecordMixingStruct2 *arg0, size_t arg1, u32 arg2)
+{
+ u8 linkPlayerCount = GetLinkPlayerCount();
+ struct UnknownRecMixingStruct3 *largeStructPtr = AllocZeroed(sizeof(struct UnknownRecMixingStruct3));
+
+ sub_80E8578(largeStructPtr, arg0, arg1, arg2, linkPlayerCount);
+ sub_80E8924(largeStructPtr);
+
+ Free(largeStructPtr);
+}
+
+static void sub_80E89F8(struct RecordMixingDayCareMail *dst)
+{
+ gUnknown_02039F9C.mail[0] = gSaveBlock1Ptr->daycare.mons[0].mail;
+ gUnknown_02039F9C.mail[1] = gSaveBlock1Ptr->daycare.mons[1].mail;
+ InitDaycareMailRecordMixing(&gSaveBlock1Ptr->daycare, &gUnknown_02039F9C);
+ *dst = *gUnknown_03001148;
+}
+
+static void SanitizeDayCareMailForRuby(struct RecordMixingDayCareMail *src)
+{
+ s32 i;
+
+ for (i = 0; i < src->numDaycareMons; i++)
+ {
+ struct DayCareMail *mail = &src->mail[i];
+ if (mail->message.itemId != 0)
+ {
+ if (mail->gameLanguage != LANGUAGE_JAPANESE)
+ PadNameString(mail->OT_name, 0xFC);
+
+ ConvertInternationalString(mail->monName, mail->monLanguage);
+ }
+ }
+}
+
+static void SanitizeRubyBattleTowerRecord(struct RSBattleTowerRecord *src)
+{
+
+}
+
+static void SanitizeEmeraldBattleTowerRecord(struct EmeraldBattleTowerRecord *dst)
+{
+ s32 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ struct UnknownPokemonStruct *towerMon = &dst->party[i];
+ if (towerMon->species != 0)
+ StripExtCtrlCodes(towerMon->nickname);
+ }
+
+ CalcEmeraldBattleTowerChecksum(dst);
+}
diff --git a/src/recorded_battle.c b/src/recorded_battle.c
index 4cb2eab49..eb48ab15a 100644
--- a/src/recorded_battle.c
+++ b/src/recorded_battle.c
@@ -475,7 +475,7 @@ u32 MoveRecordedBattleToSaveData(void)
}
#else
-ASM_DIRECT
+NAKED
u32 MoveRecordedBattleToSaveData(void)
{
asm(".syntax unified\n\
diff --git a/src/rom_8034C54.c b/src/rom_8034C54.c
index 4d4492524..42df51295 100644
--- a/src/rom_8034C54.c
+++ b/src/rom_8034C54.c
@@ -1,5 +1,453 @@
#include "global.h"
+#include "rom_8034C54.h"
+#include "malloc.h"
+#include "decompress.h"
+#include "main.h"
-IWRAM_DATA u32 gUnknown_03000DD4;
-IWRAM_DATA u32 gUnknown_03000DD8;
-IWRAM_DATA u32 gUnknown_03000DDC;
+struct UnkStruct2
+{
+ bool8 isActive;
+ u8 firstOamId;
+ u8 field_2;
+ u8 oamCount;
+ u8 palTagIndex;
+ u8 size;
+ u8 shape;
+ u8 priority;
+ u8 xDelta;
+ u8 field_9;
+ u16 tileStart;
+ s16 x;
+ s16 y;
+ u16 tileTag;
+ u16 palTag;
+ u32 field_14;
+ s32 field_18;
+};
+
+struct UnkStruct1
+{
+ u32 count;
+ struct UnkStruct2 *array;
+};
+
+extern struct UnkStruct1 *gUnknown_02022E10;
+
+extern const struct SpriteTemplate gUnknown_0831AC88;
+
+// this file's functions
+static u8 sub_8035518(u8 arg0);;
+static void sub_8034EFC(struct UnkStruct2 *arg0);
+static void sub_80350B0(struct UnkStruct2 *arg0, s32 arg1, bool32 arg2);
+static void sub_8035164(struct UnkStruct2 *arg0, s32 arg1, bool32 arg2);
+static void sub_80352C0(struct UnkStruct2 *arg0, s32 arg1, bool32 arg2);
+static bool32 SharesTileWithAnyActive(u32 id);
+static bool32 SharesPalWithAnyActive(u32 id);
+static void sub_8035648(void);
+
+// iwram
+static IWRAM_DATA s32 gUnknown_03000DD4;
+static IWRAM_DATA s32 gUnknown_03000DD8;
+static IWRAM_DATA s32 gUnknown_03000DDC;
+
+// const rom data
+static const u8 gUnknown_082FF1C8[][4] =
+{
+ {0x01, 0x04, 0x10, 0x40},
+ {0x02, 0x04, 0x08, 0x20},
+ {0x02, 0x04, 0x08, 0x20},
+ {0x00, 0x00, 0x00, 0x00}
+};
+
+// code
+bool32 sub_8034C54(u32 count)
+{
+ u32 i;
+
+ if (gUnknown_02022E10 != NULL)
+ sub_8034CC8();
+
+ gUnknown_02022E10 = Alloc(sizeof(*gUnknown_02022E10));
+ if (gUnknown_02022E10 == NULL)
+ return FALSE;
+
+ gUnknown_02022E10->array = Alloc(sizeof(struct UnkStruct2) * count);
+ if (gUnknown_02022E10->array == NULL)
+ {
+ Free(gUnknown_02022E10);
+ return FALSE;
+ }
+
+ gUnknown_02022E10->count = count;
+ for (i = 0; i < count; i++)
+ {
+ gUnknown_02022E10->array[i].isActive = FALSE;
+ gUnknown_02022E10->array[i].firstOamId |= 0xFF;
+ }
+
+ return TRUE;
+}
+
+void sub_8034CC8(void)
+{
+ if (gUnknown_02022E10 != NULL)
+ {
+ if (gUnknown_02022E10->array != NULL)
+ {
+ u32 i;
+
+ for (i = 0; i < gUnknown_02022E10->count; i++)
+ sub_80353DC(i);
+
+ Free(gUnknown_02022E10->array);
+ }
+
+ FREE_AND_SET_NULL(gUnknown_02022E10);
+ }
+}
+
+bool32 sub_8034D14(u32 id, s32 arg1, const struct UnkStruct3 *arg2)
+{
+ u32 i;
+
+ if (gUnknown_02022E10 == NULL)
+ return FALSE;
+ if (gUnknown_02022E10->array[id].isActive)
+ return FALSE;
+
+ gUnknown_02022E10->array[id].firstOamId = sub_8035518(arg2->field_1);
+ if (gUnknown_02022E10->array[id].firstOamId == 0xFF)
+ return FALSE;
+
+ gUnknown_02022E10->array[id].tileStart = GetSpriteTileStartByTag(arg2->spriteSheet->tag);
+ if (gUnknown_02022E10->array[id].tileStart == 0xFFFF)
+ {
+ if (arg2->spriteSheet->size != 0)
+ {
+ gUnknown_02022E10->array[id].tileStart = LoadSpriteSheet(arg2->spriteSheet);
+ }
+ else
+ {
+ struct CompressedSpriteSheet compSpriteSheet;
+
+ compSpriteSheet = *(struct CompressedSpriteSheet*)(arg2->spriteSheet);
+ compSpriteSheet.size = GetDecompressedDataSize(arg2->spriteSheet->data);
+ gUnknown_02022E10->array[id].tileStart = LoadCompressedObjectPic(&compSpriteSheet);
+ }
+
+ if (gUnknown_02022E10->array[id].tileStart == 0xFFFF)
+ return FALSE;
+ }
+
+ gUnknown_02022E10->array[id].palTagIndex = IndexOfSpritePaletteTag(arg2->spritePal->tag);
+ if (gUnknown_02022E10->array[id].palTagIndex == 0xFF)
+ gUnknown_02022E10->array[id].palTagIndex = LoadSpritePalette(arg2->spritePal);
+
+ gUnknown_02022E10->array[id].field_2 = arg2->field_0_0;
+ gUnknown_02022E10->array[id].oamCount = arg2->field_1;
+ gUnknown_02022E10->array[id].x = arg2->x;
+ gUnknown_02022E10->array[id].y = arg2->y;
+ gUnknown_02022E10->array[id].shape = arg2->shape;
+ gUnknown_02022E10->array[id].size = arg2->size;
+ gUnknown_02022E10->array[id].priority = arg2->priority;
+ gUnknown_02022E10->array[id].xDelta = arg2->xDelta;
+ gUnknown_02022E10->array[id].field_9 = sub_80355F8(arg2->shape, arg2->size);
+ gUnknown_02022E10->array[id].tileTag = arg2->spriteSheet->tag;
+ gUnknown_02022E10->array[id].palTag = arg2->spritePal->tag;
+ gUnknown_02022E10->array[id].isActive = TRUE;
+ gUnknown_02022E10->array[id].field_14 = 1;
+
+ for (i = 1; i < arg2->field_1; i++)
+ gUnknown_02022E10->array[id].field_14 *= 10;
+
+ sub_8034EFC(&gUnknown_02022E10->array[id]);
+ sub_8035044(id, arg1);
+
+ return TRUE;
+}
+
+static void sub_8034EFC(struct UnkStruct2 *arg0)
+{
+ u32 i;
+ u32 oamId = arg0->firstOamId;
+ u32 x = arg0->x;
+ u32 oamCount = arg0->oamCount + 1;
+
+ CpuFill16(0, &gMain.oamBuffer[oamId], sizeof(struct OamData) * oamCount);
+ for (i = 0, oamId = arg0->firstOamId; i < oamCount; i++, oamId++)
+ {
+ gMain.oamBuffer[oamId].y = arg0->y;
+ gMain.oamBuffer[oamId].x = x;
+ gMain.oamBuffer[oamId].shape = arg0->shape;
+ gMain.oamBuffer[oamId].size = arg0->size;
+ gMain.oamBuffer[oamId].tileNum = arg0->tileStart;
+ gMain.oamBuffer[oamId].priority = arg0->priority;
+ gMain.oamBuffer[oamId].paletteNum = arg0->palTagIndex;
+
+ x += arg0->xDelta;
+ }
+
+ oamId--;
+ gMain.oamBuffer[oamId].x = arg0->x - arg0->xDelta;
+ gMain.oamBuffer[oamId].affineMode = 2;
+ gMain.oamBuffer[oamId].tileNum = arg0->tileStart + (arg0->field_9 * 10);
+}
+
+void sub_8035044(u32 id, s32 arg1)
+{
+ bool32 r2;
+
+ if (gUnknown_02022E10 == NULL)
+ return;
+ if (!gUnknown_02022E10->array[id].isActive)
+ return;
+
+ gUnknown_02022E10->array[id].field_18 = arg1;
+ if (arg1 < 0)
+ {
+ r2 = TRUE;
+ arg1 *= -1;
+ }
+ else
+ {
+ r2 = FALSE;
+ }
+
+ switch (gUnknown_02022E10->array[id].field_2)
+ {
+ case 0:
+ default:
+ sub_80350B0(&gUnknown_02022E10->array[id], arg1, r2);
+ break;
+ case 1:
+ sub_8035164(&gUnknown_02022E10->array[id], arg1, r2);
+ break;
+ case 2:
+ sub_80352C0(&gUnknown_02022E10->array[id], arg1, r2);
+ break;
+ }
+}
+
+static void sub_80350B0(struct UnkStruct2 *arg0, s32 arg1, bool32 arg2)
+{
+ u32 r5 = arg0->field_14;
+ u32 oamId = arg0->firstOamId;
+
+ while (r5 != 0)
+ {
+ u32 r4 = arg1 / r5;
+ arg1 -= (r4 * r5);
+ r5 /= 10;
+
+ gMain.oamBuffer[oamId].tileNum = (r4 * arg0->field_9) + arg0->tileStart;
+ oamId++;
+ }
+
+ if (arg2)
+ gMain.oamBuffer[oamId].affineMode = 0;
+ else
+ gMain.oamBuffer[oamId].affineMode = 2;
+}
+
+static void sub_8035164(struct UnkStruct2 *arg0, s32 arg1, bool32 arg2)
+{
+ u32 r5 = arg0->field_14;
+ gUnknown_03000DD4 = arg0->firstOamId;
+ gUnknown_03000DD8 = 0;
+ gUnknown_03000DDC = -1;
+
+ while (r5 != 0)
+ {
+ u32 r4 = arg1 / r5;
+ arg1 -= (r4 * r5);
+ r5 /= 10;
+
+ if (r4 != 0 || gUnknown_03000DDC != -1 || r5 == 0)
+ {
+ gMain.oamBuffer[gUnknown_03000DD4].tileNum = (r4 * arg0->field_9) + arg0->tileStart;
+ gMain.oamBuffer[gUnknown_03000DD4].affineMode = 0;
+
+ if (gUnknown_03000DDC == -1)
+ gUnknown_03000DDC = gUnknown_03000DD8;
+ }
+ else
+ {
+ gMain.oamBuffer[gUnknown_03000DD4].affineMode = 2;
+ }
+
+ gUnknown_03000DD4++;
+ gUnknown_03000DD8++;
+ }
+
+ if (arg2)
+ {
+ gMain.oamBuffer[gUnknown_03000DD4].affineMode = 0;
+ gMain.oamBuffer[gUnknown_03000DD4].x = arg0->x + ((gUnknown_03000DDC - 1) * arg0->xDelta);
+ }
+ else
+ {
+ gMain.oamBuffer[gUnknown_03000DD4].affineMode = 2;
+ }
+}
+
+static void sub_80352C0(struct UnkStruct2 *arg0, s32 arg1, bool32 arg2)
+{
+ u32 r5 = arg0->field_14;
+ u32 oamId = arg0->firstOamId;
+ u32 var_28 = 0;
+ s32 r9 = 0;
+
+ while (r5 != 0)
+ {
+ u32 r4 = arg1 / r5;
+ arg1 -= (r4 * r5);
+ r5 /= 10;
+
+ if (r4 != 0 || var_28 != 0 || r5 == 0)
+ {
+ var_28 = 1;
+ gMain.oamBuffer[oamId].tileNum = (r4 * arg0->field_9) + arg0->tileStart;
+ gMain.oamBuffer[oamId].affineMode = 0;
+
+ oamId++;
+ r9++;
+ }
+ }
+
+ while (r9 < arg0->oamCount)
+ {
+ gMain.oamBuffer[oamId].affineMode = 2;
+ oamId++;
+ r9++;
+ }
+
+ if (arg2)
+ gMain.oamBuffer[oamId].affineMode = 0;
+ else
+ gMain.oamBuffer[oamId].affineMode = 2;
+}
+
+void sub_80353DC(u32 id)
+{
+ s32 oamId, oamCount, i;
+
+ if (gUnknown_02022E10 == NULL)
+ return;
+ if (!gUnknown_02022E10->array[id].isActive)
+ return;
+
+ oamCount = gUnknown_02022E10->array[id].oamCount + 1;
+ oamId = gUnknown_02022E10->array[id].firstOamId;
+
+ for (i = 0; i < oamCount; i++, oamId++)
+ gMain.oamBuffer[oamId].affineMode = 2;
+
+ if (!SharesTileWithAnyActive(id))
+ FreeSpriteTilesByTag(gUnknown_02022E10->array[id].tileTag);
+ if (!SharesPalWithAnyActive(id))
+ FreeSpritePaletteByTag(gUnknown_02022E10->array[id].palTag);
+
+ gUnknown_02022E10->array[id].isActive = FALSE;
+}
+
+void sub_803547C(u32 id, bool32 arg1)
+{
+ s32 oamId, oamCount, i;
+
+ if (gUnknown_02022E10 == NULL)
+ return;
+ if (!gUnknown_02022E10->array[id].isActive)
+ return;
+
+ oamCount = gUnknown_02022E10->array[id].oamCount + 1;
+ oamId = gUnknown_02022E10->array[id].firstOamId;
+ if (arg1)
+ {
+ for (i = 0; i < oamCount; i++, oamId++)
+ gMain.oamBuffer[oamId].affineMode = 2;
+ }
+ else
+ {
+ for (i = 0; i < oamCount; i++, oamId++)
+ gMain.oamBuffer[oamId].affineMode = 0;
+
+ sub_8035044(id, gUnknown_02022E10->array[id].field_18);
+ }
+}
+
+static u8 sub_8035518(u8 arg0)
+{
+ u32 i;
+ u16 oamCount = 64;
+
+ for (i = 0; i < gUnknown_02022E10->count; i++)
+ {
+ if (!gUnknown_02022E10->array[i].isActive)
+ {
+ if (gUnknown_02022E10->array[i].firstOamId != 0xFF && gUnknown_02022E10->array[i].oamCount <= arg0)
+ return gUnknown_02022E10->array[i].firstOamId;
+ }
+ else
+ {
+ oamCount += 1 + gUnknown_02022E10->array[i].oamCount;
+ }
+ }
+
+ if (oamCount + arg0 + 1 > 128)
+ return 0xFF;
+ else
+ return oamCount;
+}
+
+static bool32 SharesTileWithAnyActive(u32 id)
+{
+ u32 i;
+
+ for (i = 0; i < gUnknown_02022E10->count; i++)
+ {
+ if (gUnknown_02022E10->array[i].isActive && i != id
+ && gUnknown_02022E10->array[i].tileTag == gUnknown_02022E10->array[id].tileTag)
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static bool32 SharesPalWithAnyActive(u32 id)
+{
+ u32 i;
+
+ for (i = 0; i < gUnknown_02022E10->count; i++)
+ {
+ if (gUnknown_02022E10->array[i].isActive && i != id
+ && gUnknown_02022E10->array[i].palTag == gUnknown_02022E10->array[id].palTag)
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+u8 sub_80355F8(u32 arg0, u32 arg1)
+{
+ return gUnknown_082FF1C8[arg0][arg1];
+}
+
+static void sub_8035608(void)
+{
+ u8 spriteId;
+
+ ResetSpriteData();
+ spriteId = CreateSprite(&gUnknown_0831AC88, 0, 0, 0);
+ gSprites[spriteId].invisible = 1;
+ SetMainCallback2(sub_8035648);
+}
+
+static void sub_8035648(void)
+{
+ AnimateSprites();
+ BuildOamBuffer();
+}
diff --git a/src/rotating_gate.c b/src/rotating_gate.c
index db5935fc3..b07814f58 100644
--- a/src/rotating_gate.c
+++ b/src/rotating_gate.c
@@ -646,7 +646,7 @@ static void RotatingGate_ResetAllGateOrientations(void)
s32 i;
u8 *ptr;
- ptr = (u8 *)GetVarPointer(VAR_0x4000);
+ ptr = (u8 *)GetVarPointer(VAR_TEMP_0);
for (i = 0; i < gRotatingGate_PuzzleCount; i++)
{
@@ -656,12 +656,12 @@ static void RotatingGate_ResetAllGateOrientations(void)
static s32 RotatingGate_GetGateOrientation(u8 gateId)
{
- return ((u8 *)GetVarPointer(VAR_0x4000))[gateId];
+ return ((u8 *)GetVarPointer(VAR_TEMP_0))[gateId];
}
static void RotatingGate_SetGateOrientation(u8 gateId, u8 orientation)
{
- ((u8 *)GetVarPointer(VAR_0x4000))[gateId] = orientation;
+ ((u8 *)GetVarPointer(VAR_TEMP_0))[gateId] = orientation;
}
static void RotatingGate_RotateInDirection(u8 gateId, u32 rotationDirection)
@@ -925,7 +925,7 @@ static s32 RotatingGate_CanRotate(u8 gateId, s16 rotationDirection)
}
#else
-ASM_DIRECT
+NAKED
static s32 RotatingGate_CanRotate(u8 a, s16 rotationDirection)
{
asm(".syntax unified\n\
diff --git a/src/secret_base.c b/src/secret_base.c
index cd6143ed0..44e980c43 100644
--- a/src/secret_base.c
+++ b/src/secret_base.c
@@ -10,7 +10,6 @@
#include "list_menu.h"
#include "menu.h"
#include "menu_helpers.h"
-#include "menu_indicators.h"
#include "constants/maps.h"
#include "constants/songs.h"
#include "constants/species.h"
@@ -40,8 +39,6 @@
#include "tv.h"
#include "secret_base.h"
-extern void (*gFieldCallback)(void);
-
extern void mapldr_default(void);
// Static type declarations
@@ -416,7 +413,7 @@ bool8 sub_80E909C(void)
void sub_80E90C8(u8 taskId)
{
FieldObjectTurn(&gMapObjects[gPlayerAvatar.mapObjectId], DIR_NORTH);
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
EnableBothScriptContexts();
DestroyTask(taskId);
@@ -594,7 +591,7 @@ void sub_80E9578(void)
void sub_80E95D4(void)
{
- VarSet(VAR_0x401F, gUnknown_0858D060[sub_80EA20C(VarGet(VAR_0x4054))]);
+ VarSet(VAR_OBJ_GFX_ID_F, gUnknown_0858D060[sub_80EA20C(VarGet(VAR_0x4054))]);
}
void sub_80E9608(struct Coords16 *coords, struct MapEvents *events)
@@ -1676,7 +1673,7 @@ void sub_80EAEF4(struct SecretBaseRecordMixer *mixers)
sub_80EABA4(&mixers[2], 0);
}
-void sub_80EAF80(void *records, size_t recordSize, u8 linkIdx)
+void ReceiveSecretBasesData(void *records, size_t recordSize, u8 linkIdx)
{
struct SecretBaseRecordMixer mixers[3];
u16 i;
diff --git a/src/text.c b/src/text.c
index eacfd2a1f..f7c68f549 100644
--- a/src/text.c
+++ b/src/text.c
@@ -375,7 +375,7 @@ void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor)
*(current++) = (shadowColor << 12) | (shadowColor << 8) | (shadowColor << 4) | shadowColor;
}
#else
-ASM_DIRECT
+NAKED
void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor)
{
asm("push {r4-r7,lr}\n\
@@ -871,7 +871,7 @@ void DecompressGlyphTile(const u16 *src, u16 *dest)
*(dest) = (gFontHalfRowLookupTable[gFontHalfRowOffsets[src[1] & 0xFF]] << 16) | gFontHalfRowLookupTable[gFontHalfRowOffsets[src[1] >> 8]];
}
#else
-ASM_DIRECT
+NAKED
void DecompressGlyphTile(const u16 *src, u16 *dest)
{
asm("push {r4-r7,lr}\n\
@@ -1052,7 +1052,7 @@ u8 GetLastTextColor(u8 colorType)
}
}
-ASM_DIRECT
+NAKED
void CopyGlyphToWindow(struct TextPrinter *x)
{
asm("push {r4-r7,lr}\n\
@@ -2341,7 +2341,7 @@ u16 RenderText(struct TextPrinter *textPrinter)
return 1;
}
#else
-__attribute__((naked))
+NAKED
u16 RenderText(struct TextPrinter *textPrinter)
{
asm("push {r4-r6,lr}\n\
diff --git a/src/time_events.c b/src/time_events.c
index 1f169a5c6..1f46e7705 100644
--- a/src/time_events.c
+++ b/src/time_events.c
@@ -81,7 +81,7 @@ void UpdateShoalTideFlag(void)
1, // 23
};
- if (is_light_level_1_2_3_5_or_6(get_map_light_from_warp0()))
+ if (is_map_type_1_2_3_5_or_6(get_map_light_from_warp0()))
{
RtcCalcLocalTime();
if (tide[gLocalTime.hours])
diff --git a/src/title_screen.c b/src/title_screen.c
index 4e25c8152..15a0482dc 100644
--- a/src/title_screen.c
+++ b/src/title_screen.c
@@ -19,6 +19,7 @@
#include "gpu_regs.h"
#include "trig.h"
#include "constants/rgb.h"
+#include "constants/songs.h"
#define VERSION_BANNER_SHAPE 1
#define VERSION_BANNER_RIGHT_TILEOFFSET 64
@@ -574,7 +575,7 @@ void CB2_InitTitleScreen(void)
| DISPCNT_OBJ_ON
| DISPCNT_WIN0_ON
| DISPCNT_OBJWIN_ON);
- m4aSongNumStart(0x19D);
+ m4aSongNumStart(MUS_TITLE3);
gMain.state = 5;
break;
case 5:
diff --git a/src/tv.c b/src/tv.c
index 8fc95b9b8..e69f6f411 100644
--- a/src/tv.c
+++ b/src/tv.c
@@ -3557,7 +3557,7 @@ void GetMomOrDadStringForTVMessage(void)
if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(LITTLEROOT_TOWN_BRENDANS_HOUSE_1F))
{
StringCopy(gStringVar1, gText_Mom);
- VarSet(VAR_0x4003, 1);
+ VarSet(VAR_TEMP_3, 1);
}
}
else
@@ -3565,21 +3565,21 @@ void GetMomOrDadStringForTVMessage(void)
if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(LITTLEROOT_TOWN_MAYS_HOUSE_1F))
{
StringCopy(gStringVar1, gText_Mom);
- VarSet(VAR_0x4003, 1);
+ VarSet(VAR_TEMP_3, 1);
}
}
}
- if (VarGet(VAR_0x4003) == 1)
+ if (VarGet(VAR_TEMP_3) == 1)
{
StringCopy(gStringVar1, gText_Mom);
}
- else if (VarGet(VAR_0x4003) == 2)
+ else if (VarGet(VAR_TEMP_3) == 2)
{
StringCopy(gStringVar1, gText_Dad);
}
- else if (VarGet(VAR_0x4003) > 2)
+ else if (VarGet(VAR_TEMP_3) > 2)
{
- if (VarGet(VAR_0x4003) % 2 == 0)
+ if (VarGet(VAR_TEMP_3) % 2 == 0)
StringCopy(gStringVar1, gText_Mom);
else
StringCopy(gStringVar1, gText_Dad);
@@ -3589,12 +3589,12 @@ void GetMomOrDadStringForTVMessage(void)
if (Random() % 2 != 0)
{
StringCopy(gStringVar1, gText_Mom);
- VarSet(VAR_0x4003, 1);
+ VarSet(VAR_TEMP_3, 1);
}
else
{
StringCopy(gStringVar1, gText_Dad);
- VarSet(VAR_0x4003, 2);
+ VarSet(VAR_TEMP_3, 2);
}
}
}
@@ -3606,7 +3606,7 @@ void sub_80F01B8(void)
FlagSet(0x396);
}
-void sub_80F01E8(void *src, u32 size, u8 masterIdx)
+void ReceiveTvShowsData(void *src, u32 size, u8 masterIdx)
{
u8 i;
u16 version;
@@ -3931,7 +3931,7 @@ static void sub_80F0708(void) // FIXME: register allocation shenanigans
}
}
#else
-ASM_DIRECT static void sub_80F0708(void)
+NAKED static void sub_80F0708(void)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r9\n"
@@ -4434,7 +4434,7 @@ static void sub_80F0C04(void)
}
}
-void sub_80F0C7C(void *src, u32 size, u8 masterIdx)
+void ReceivePokeNewsData(void *src, u32 size, u8 masterIdx)
{
u8 i;
PokeNews (*rmBuffer2)[4][16];
diff --git a/src/util.c b/src/util.c
index 4f9241b21..88be4e4a1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -230,7 +230,7 @@ void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output)
}
#else
-ASM_DIRECT void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output)
+NAKED void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output)
{
asm("\n\
.syntax unified\n\
diff --git a/src/walda_phrase.c b/src/walda_phrase.c
index 04789bfb5..0aa6f5aca 100644
--- a/src/walda_phrase.c
+++ b/src/walda_phrase.c
@@ -6,8 +6,7 @@
#include "main.h"
#include "text.h"
#include "new_game.h"
-
-extern void (*gFieldCallback)(void);
+#include "overworld.h"
extern const u8 gText_Peekaboo[];