summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2019-10-14 10:41:27 -0400
committerPikalaxALT <pikalaxalt@gmail.com>2019-10-14 10:46:04 -0400
commitb8fec3d9f617ec9a764bb56804c526ff7449631f (patch)
tree2e84d0bf6107a15ebcb94a23c3158e2bc6382f6f /src
parent9fe74ac590f75a0571de8ebcd499fdf892419328 (diff)
parent8efae5c807bf6b27f5c90bfb0c5887dbde24f10d (diff)
Merge branch 'master' into trade
Diffstat (limited to 'src')
-rw-r--r--src/battle_anim_mon_movement.c28
-rw-r--r--src/battle_anim_mons.c2254
-rw-r--r--src/battle_anim_sound_tasks.c313
-rw-r--r--src/battle_anim_utility_funcs.c946
-rw-r--r--src/battle_controller_player.c4
-rw-r--r--src/battle_intro.c495
-rw-r--r--src/battle_transition.c82
-rw-r--r--src/bg.c116
-rw-r--r--src/bug.c462
-rw-r--r--src/dark.c921
-rw-r--r--src/daycare.c4
-rw-r--r--src/dragon.c431
-rw-r--r--src/fame_checker.c4
-rw-r--r--src/field_fadetransition.c14
-rw-r--r--src/flying.c1289
-rw-r--r--src/ghost.c1484
-rw-r--r--src/ground.c724
-rw-r--r--src/help_system_812B1E0.c62
-rw-r--r--src/item_use.c16
-rw-r--r--src/mailbox_pc.c10
-rw-r--r--src/map_preview_screen.c2
-rw-r--r--src/menu2.c2
-rw-r--r--src/mystery_event_script.c2
-rw-r--r--src/new_menu_helpers.c18
-rw-r--r--src/normal.c916
-rw-r--r--src/player_pc.c741
-rw-r--r--src/pokemon.c1
-rw-r--r--src/psychic.c1083
-rw-r--r--src/quest_log.c743
-rw-r--r--src/rock.c830
-rw-r--r--src/save.c6
-rw-r--r--src/scrcmd.c6
-rw-r--r--src/start_menu.c1008
-rw-r--r--src/teachy_tv.c4
-rw-r--r--src/trade.c917
-rw-r--r--src/trainer_tower.c2
36 files changed, 15316 insertions, 624 deletions
diff --git a/src/battle_anim_mon_movement.c b/src/battle_anim_mon_movement.c
index 88fbce6da..21d07246f 100644
--- a/src/battle_anim_mon_movement.c
+++ b/src/battle_anim_mon_movement.c
@@ -92,7 +92,7 @@ const struct SpriteTemplate gUnknown_83D4EB4 =
// arg 4: frame delay
void AnimTask_ShakeMon(u8 taskId)
{
- u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]);
+ u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (spriteId == 0xFF)
DestroyAnimVisualTask(taskId);
@@ -150,7 +150,7 @@ void AnimTask_ShakeMon2(u8 taskId)
if (gBattleAnimArgs[0] < MAX_BATTLERS_COUNT)
{
- spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]);
+ spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (spriteId == 0xFF)
abort = TRUE;
}
@@ -228,7 +228,7 @@ static void AnimTask_ShakeMon2Step(u8 taskId)
// arg 4: delay
void AnimTask_ShakeMonInPlace(u8 taskId)
{
- u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]);
+ u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (spriteId == 0xFF)
DestroyAnimVisualTask(taskId);
@@ -290,7 +290,7 @@ static void AnimTask_ShakeMonInPlaceStep(u8 taskId)
// arg 4: duration
void AnimTask_ShakeAndSinkMon(u8 taskId)
{
- u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]);
+ u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
gSprites[spriteId].pos2.x = gBattleAnimArgs[1];
gTasks[taskId].data[0] = spriteId;
@@ -331,7 +331,7 @@ void AnimTask_TranslateMonElliptical(u8 taskId)
{
u8 wavePeriod = 1;
u8 i;
- u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]);
+ u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (gBattleAnimArgs[4] > 5)
gBattleAnimArgs[4] = 5;
for (i = 0; i < gBattleAnimArgs[4]; i++)
@@ -414,7 +414,7 @@ static void DoVerticalDip(struct Sprite * sprite)
{
u8 spriteId;
sprite->invisible = TRUE;
- spriteId = GetAnimBankSpriteId(gBattleAnimArgs[2]);
+ spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]);
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = 0;
sprite->data[2] = gBattleAnimArgs[1];
@@ -581,7 +581,7 @@ void AnimTask_WindUpLunge(u8 taskId)
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[5] = -gBattleAnimArgs[5];
}
- gTasks[taskId].data[0] = GetAnimBankSpriteId(gBattleAnimArgs[0]);
+ gTasks[taskId].data[0] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
gTasks[taskId].data[1] = gBattleAnimArgs[1] * 256 / gBattleAnimArgs[3];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
gTasks[taskId].data[3] = gBattleAnimArgs[3];
@@ -627,7 +627,7 @@ void sub_80995FC(u8 taskId)
{
case 0:
case 1:
- spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]);
+ spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
break;
case 2:
if (!IsBattlerSpriteVisible(gBattleAnimAttacker ^ BIT_FLANK))
@@ -678,7 +678,7 @@ void AnimTask_SwayMon(u8 taskId)
u8 spriteId;
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
- spriteId = GetAnimBankSpriteId(gBattleAnimArgs[4]);
+ spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[4]);
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].data[1] = gBattleAnimArgs[1];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
@@ -735,7 +735,7 @@ static void AnimTask_SwayMonStep(u8 taskId)
// arg 4: sprite object mode
void AnimTask_ScaleMonAndRestore(u8 taskId)
{
- u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[3]);
+ u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[3]);
PrepareBattlerSpriteForRotScale(spriteId, gBattleAnimArgs[4]);
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].data[1] = gBattleAnimArgs[1];
@@ -773,7 +773,7 @@ static void AnimTask_ScaleMonAndRestoreStep(u8 taskId)
void sub_8099980(u8 taskId)
{
- u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[2]);
+ u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]);
PrepareBattlerSpriteForRotScale(spriteId, 0);
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = gBattleAnimArgs[0];
@@ -806,7 +806,7 @@ void sub_8099980(u8 taskId)
void sub_8099A78(u8 taskId)
{
- u8 spriteId = GetAnimBankSpriteId(gBattleAnimArgs[2]);
+ u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]);
PrepareBattlerSpriteForRotScale(spriteId, 0);
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = gBattleAnimArgs[0];
@@ -844,7 +844,7 @@ static void sub_8099B54(u8 taskId)
gTasks[taskId].data[3] += gTasks[taskId].data[4];
SetSpriteRotScale(gTasks[taskId].data[5], 0x100, 0x100, gTasks[taskId].data[3]);
if (gTasks[taskId].data[7])
- sub_80759DC(gTasks[taskId].data[5]);
+ SetBattlerSpriteYOffsetFromRotation(gTasks[taskId].data[5]);
if (++gTasks[taskId].data[1] >= gTasks[taskId].data[2])
{
switch (gTasks[taskId].data[6])
@@ -888,7 +888,7 @@ void sub_8099BD4(u8 taskId)
gTasks[taskId].data[12] = 0;
gTasks[taskId].data[10] = gBattleAnimArgs[3];
gTasks[taskId].data[11] = gBattleAnimArgs[4];
- gTasks[taskId].data[7] = GetAnimBankSpriteId(1);
+ gTasks[taskId].data[7] = GetAnimBattlerSpriteId(1);
gTasks[taskId].data[8] = gSprites[gTasks[taskId].data[7]].pos2.x;
gTasks[taskId].data[9] = gSprites[gTasks[taskId].data[7]].pos2.y;
gTasks[taskId].data[0] = 0;
diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c
new file mode 100644
index 000000000..e871937e7
--- /dev/null
+++ b/src/battle_anim_mons.c
@@ -0,0 +1,2254 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "bg.h"
+#include "data.h"
+#include "decompress.h"
+#include "dma3.h"
+#include "gpu_regs.h"
+#include "malloc.h"
+#include "palette.h"
+#include "pokemon_icon.h"
+#include "sprite.h"
+#include "task.h"
+#include "trig.h"
+#include "util.h"
+#include "constants/battle_anim.h"
+#include "constants/species.h"
+
+#define GET_UNOWN_LETTER(personality) (( \
+ (((personality & 0x03000000) >> 24) << 6) \
+ | (((personality & 0x00030000) >> 16) << 4) \
+ | (((personality & 0x00000300) >> 8) << 2) \
+ | (((personality & 0x00000003) >> 0) << 0) \
+) % 28)
+
+#define IS_DOUBLE_BATTLE() (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
+
+static u8 GetBattlerSpriteFinal_Y(u8 battlerId, u16 species, bool8 a3);
+static void sub_8075658(struct Sprite *sprite);
+static void sub_80757E8(struct Sprite *sprite);
+static bool8 sub_80758DC(void);
+static void sub_8075EF0(struct Sprite *sprite);
+static void sub_80760D0(u8 taskId);
+static void AnimTask_BlendMonInAndOutSetup(struct Task *task);
+static void AnimTask_BlendMonInAndOutStep(u8 taskId);
+static u16 GetBattlerYDeltaFromSpriteId(u8 spriteId);
+static void sub_8077118(u8 taskId);
+static void sub_80771E4(struct Task *task, u8 taskId);
+static void sub_8077268(struct Sprite *sprite);
+static void sub_80772F4(struct Sprite *sprite);
+
+static EWRAM_DATA union AffineAnimCmd *sAnimTaskAffineAnim = NULL;
+static EWRAM_DATA u32 gUnknown_2037F2C = 0; // not used
+
+static const struct UCoords8 sBattlerCoords[][4] =
+{
+ {
+ { 72, 80 },
+ { 176, 40 },
+ { 48, 40 },
+ { 112, 80 },
+ },
+ {
+ { 32, 80 },
+ { 200, 40 },
+ { 90, 88 },
+ { 152, 32 },
+ },
+};
+
+// One entry for each of the four Castform forms.
+const struct MonCoords gCastformFrontSpriteCoords[] =
+{
+ { .size = 0x44, .y_offset = 17 }, // NORMAL
+ { .size = 0x66, .y_offset = 9 }, // SUN
+ { .size = 0x46, .y_offset = 9 }, // RAIN
+ { .size = 0x86, .y_offset = 8 }, // HAIL
+};
+
+static const u8 sCastformElevations[] =
+{
+ 13, // NORMAL
+ 14, // SUN
+ 13, // RAIN
+ 13, // HAIL
+};
+
+// Y position of the backsprite for each of the four Castform forms.
+static const u8 sCastformBackSpriteYCoords[] =
+{
+ 0, // NORMAL
+ 0, // SUN
+ 0, // RAIN
+ 0, // HAIL
+};
+
+static const struct SpriteTemplate gUnknown_83AE054[] =
+{
+ {
+ .tileTag = 0xD755,
+ .paletteTag = 0xD755,
+ .oam = &gOamData_83ACA40,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+ },
+ {
+ .tileTag = 0xD756,
+ .paletteTag = 0xD756,
+ .oam = &gOamData_83ACA40,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+ }
+};
+
+static const struct SpriteSheet gUnknown_83AE084[] =
+{
+ { gMiscBlank_Gfx, 0x800, 0xD755 },
+ { gMiscBlank_Gfx, 0x800, 0xD756 },
+};
+
+u8 GetBattlerSpriteCoord(u8 battlerId, u8 coordType)
+{
+ u8 retVal;
+ u16 species;
+ struct BattleSpriteInfo *spriteInfo;
+
+ switch (coordType)
+ {
+ case BATTLER_COORD_X:
+ case BATTLER_COORD_X_2:
+ retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].x;
+ break;
+ case BATTLER_COORD_Y:
+ retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y;
+ break;
+ case BATTLER_COORD_Y_PIC_OFFSET:
+ case BATTLER_COORD_Y_PIC_OFFSET_DEFAULT:
+ default:
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ else
+ species = spriteInfo[battlerId].transformSpecies;
+ }
+ else
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ else
+ species = spriteInfo[battlerId].transformSpecies;
+ }
+ if (coordType == BATTLER_COORD_Y_PIC_OFFSET)
+ retVal = GetBattlerSpriteFinal_Y(battlerId, species, TRUE);
+ else
+ retVal = GetBattlerSpriteFinal_Y(battlerId, species, FALSE);
+ break;
+ }
+ return retVal;
+}
+
+static u8 GetBattlerYDelta(u8 battlerId, u16 species)
+{
+ u16 letter;
+ u32 personality;
+ struct BattleSpriteInfo *spriteInfo;
+ u8 ret;
+ u16 coordSpecies;
+
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ {
+ if (species == SPECIES_UNOWN)
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY);
+ else
+ personality = gTransformedPersonalities[battlerId];
+ letter = GET_UNOWN_LETTER(personality);
+ if (!letter)
+ coordSpecies = species;
+ else
+ coordSpecies = letter + SPECIES_UNOWN_B - 1;
+ ret = gMonBackPicCoords[coordSpecies].y_offset;
+ }
+ else if (species == SPECIES_CASTFORM)
+ {
+ ret = sCastformBackSpriteYCoords[gBattleMonForms[battlerId]];
+ }
+ else if (species > NUM_SPECIES)
+ {
+ ret = gMonBackPicCoords[0].y_offset;
+ }
+ else
+ {
+ ret = gMonBackPicCoords[species].y_offset;
+ }
+ }
+ else
+ {
+ if (species == SPECIES_UNOWN)
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY);
+ else
+ personality = gTransformedPersonalities[battlerId];
+ letter = GET_UNOWN_LETTER(personality);
+ if (!letter)
+ coordSpecies = species;
+ else
+ coordSpecies = letter + SPECIES_UNOWN_B - 1;
+ ret = gMonFrontPicCoords[coordSpecies].y_offset;
+ }
+ else if (species == SPECIES_CASTFORM)
+ {
+ ret = gCastformFrontSpriteCoords[gBattleMonForms[battlerId]].y_offset;
+ }
+ else if (species > NUM_SPECIES)
+ {
+ ret = gMonFrontPicCoords[0].y_offset;
+ }
+ else
+ {
+ ret = gMonFrontPicCoords[species].y_offset;
+ }
+ }
+ return ret;
+}
+
+static u8 GetBattlerElevation(u8 battlerId, u16 species)
+{
+ u8 ret = 0;
+
+ if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
+ {
+ if (species == SPECIES_CASTFORM)
+ ret = sCastformElevations[gBattleMonForms[battlerId]];
+ else if (species > NUM_SPECIES)
+ ret = gEnemyMonElevation[0];
+ else
+ ret = gEnemyMonElevation[species];
+ }
+ return ret;
+}
+
+static u8 GetBattlerSpriteFinal_Y(u8 battlerId, u16 species, bool8 a3)
+{
+ u16 offset;
+ u8 y;
+
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ {
+ offset = GetBattlerYDelta(battlerId, species);
+ }
+ else
+ {
+ offset = GetBattlerYDelta(battlerId, species);
+ offset -= GetBattlerElevation(battlerId, species);
+ }
+ y = offset + sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y;
+ if (a3)
+ {
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ y += 8;
+ if (y > 104)
+ y = 104;
+ }
+ return y;
+}
+
+u8 GetBattlerSpriteCoord2(u8 battlerId, u8 coordType)
+{
+ u16 species;
+ struct BattleSpriteInfo *spriteInfo;
+
+ if (coordType == BATTLER_COORD_Y_PIC_OFFSET || coordType == BATTLER_COORD_Y_PIC_OFFSET_DEFAULT)
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ species = gAnimBattlerSpecies[battlerId];
+ else
+ species = spriteInfo[battlerId].transformSpecies;
+ if (coordType == BATTLER_COORD_Y_PIC_OFFSET)
+ return GetBattlerSpriteFinal_Y(battlerId, species, TRUE);
+ else
+ return GetBattlerSpriteFinal_Y(battlerId, species, FALSE);
+ }
+ else
+ {
+ return GetBattlerSpriteCoord(battlerId, coordType);
+ }
+}
+
+u8 GetBattlerSpriteDefault_Y(u8 battlerId)
+{
+ return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET_DEFAULT);
+}
+
+u8 GetSubstituteSpriteDefault_Y(u8 battlerId)
+{
+ u16 y;
+
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 16;
+ else
+ y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 17;
+ return y;
+}
+
+u8 GetGhostSpriteDefault_Y(u8 battlerId)
+{
+ if (GetBattlerSide(battlerId) != B_SIDE_OPPONENT)
+ return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET_DEFAULT);
+ else
+ return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y);
+}
+
+u8 GetBattlerYCoordWithElevation(u8 battlerId)
+{
+ u16 species;
+ u8 y;
+ struct BattleSpriteInfo *spriteInfo;
+
+ y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y);
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ else
+ species = spriteInfo[battlerId].transformSpecies;
+ }
+ else
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ else
+ species = spriteInfo[battlerId].transformSpecies;
+ }
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ y -= GetBattlerElevation(battlerId, species);
+ return y;
+}
+
+u8 GetAnimBattlerSpriteId(u8 animBattler)
+{
+ u8 *sprites;
+
+ if (animBattler == ANIM_ATTACKER)
+ {
+ if (IsBattlerSpritePresent(gBattleAnimAttacker))
+ {
+ sprites = gBattlerSpriteIds;
+ return sprites[gBattleAnimAttacker];
+ }
+ else
+ {
+ return 0xFF;
+ }
+ }
+ else if (animBattler == ANIM_TARGET)
+ {
+ if (IsBattlerSpritePresent(gBattleAnimTarget))
+ {
+ sprites = gBattlerSpriteIds;
+ return sprites[gBattleAnimTarget];
+ }
+ else
+ {
+ return 0xFF;
+ }
+ }
+ else if (animBattler == ANIM_ATK_PARTNER)
+ {
+ if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
+ return 0xFF;
+ else
+ return gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)];
+ }
+ else
+ {
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
+ return gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)];
+ else
+ return 0xFF;
+ }
+}
+
+void StoreSpriteCallbackInData6(struct Sprite *sprite, SpriteCallback callback)
+{
+ sprite->data[6] = (u32)(callback) & 0xFFFF;
+ sprite->data[7] = (u32)(callback) >> 16;
+}
+
+static void SetCallbackToStoredInData6(struct Sprite *sprite)
+{
+ u32 callback = (u16)sprite->data[6] | (sprite->data[7] << 16);
+
+ sprite->callback = (SpriteCallback)callback;
+}
+
+void TranslateSpriteInCircleOverDuration(struct Sprite *sprite)
+{
+ if (sprite->data[3])
+ {
+ sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]);
+ sprite->pos2.y = Cos(sprite->data[0], sprite->data[1]);
+ sprite->data[0] += sprite->data[2];
+ if (sprite->data[0] >= 0x100)
+ sprite->data[0] -= 0x100;
+ else if (sprite->data[0] < 0)
+ sprite->data[0] += 0x100;
+ --sprite->data[3];
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+}
+
+void TranslateSpriteInGrowingCircleOverDuration(struct Sprite *sprite)
+{
+ if (sprite->data[3])
+ {
+ sprite->pos2.x = Sin(sprite->data[0], (sprite->data[5] >> 8) + sprite->data[1]);
+ sprite->pos2.y = Cos(sprite->data[0], (sprite->data[5] >> 8) + sprite->data[1]);
+ sprite->data[0] += sprite->data[2];
+ sprite->data[5] += sprite->data[4];
+ if (sprite->data[0] >= 0x100)
+ sprite->data[0] -= 0x100;
+ else if (sprite->data[0] < 0)
+ sprite->data[0] += 0x100;
+ --sprite->data[3];
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+}
+
+// not used
+static void sub_8074B5C(struct Sprite *sprite)
+{
+ if (sprite->data[3])
+ {
+ sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]);
+ sprite->pos2.y = Cos(sprite->data[4], sprite->data[1]);
+ sprite->data[0] += sprite->data[2];
+ sprite->data[4] += sprite->data[5];
+ if (sprite->data[0] >= 0x100)
+ sprite->data[0] -= 0x100;
+ else if (sprite->data[0] < 0)
+ sprite->data[0] += 0x100;
+ if (sprite->data[4] >= 0x100)
+ sprite->data[4] -= 0x100;
+ else if (sprite->data[4] < 0)
+ sprite->data[4] += 0x100;
+ --sprite->data[3];
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+}
+
+void TranslateSpriteInEllipseOverDuration(struct Sprite *sprite)
+{
+ if (sprite->data[3])
+ {
+ sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]);
+ sprite->pos2.y = Cos(sprite->data[0], sprite->data[4]);
+ sprite->data[0] += sprite->data[2];
+ if (sprite->data[0] >= 0x100)
+ sprite->data[0] -= 0x100;
+ else if (sprite->data[0] < 0)
+ sprite->data[0] += 0x100;
+ --sprite->data[3];
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+}
+
+// Simply waits until the sprite's data[0] hits zero.
+// This is used to let sprite anims or affine anims to run for a designated
+// duration.
+void WaitAnimForDuration(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 0)
+ --sprite->data[0];
+ else
+ SetCallbackToStoredInData6(sprite);
+}
+
+static void sub_8074C64(struct Sprite *sprite)
+{
+ sub_8074C80(sprite);
+ sprite->callback = TranslateSpriteLinear;
+ sprite->callback(sprite);
+}
+
+void sub_8074C80(struct Sprite *sprite)
+{
+ s16 old;
+ s32 xDiff;
+
+ if (sprite->data[1] > sprite->data[2])
+ sprite->data[0] = -sprite->data[0];
+ xDiff = sprite->data[2] - sprite->data[1];
+ old = sprite->data[0];
+ sprite->data[0] = abs(xDiff / sprite->data[0]);
+ sprite->data[2] = (sprite->data[4] - sprite->data[3]) / sprite->data[0];
+ sprite->data[1] = old;
+}
+
+void TranslateSpriteLinear(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ sprite->pos2.x += sprite->data[1];
+ sprite->pos2.y += sprite->data[2];
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+}
+
+void TranslateSpriteLinearFixedPoint(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ sprite->pos2.x = sprite->data[3] >> 8;
+ sprite->pos2.y = sprite->data[4] >> 8;
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+}
+
+static void TranslateSpriteLinearFixedPointIconFrame(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ sprite->pos2.x = sprite->data[3] >> 8;
+ sprite->pos2.y = sprite->data[4] >> 8;
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+
+ UpdateMonIconFrame(sprite);
+}
+
+// not used
+static void sub_8074D80(struct Sprite *sprite)
+{
+ sprite->data[1] = sprite->pos1.x + sprite->pos2.x;
+ sprite->data[3] = sprite->pos1.y + sprite->pos2.y;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ sprite->callback = sub_8074C64;
+}
+
+void TranslateMonSpriteLinear(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ gSprites[sprite->data[3]].pos2.x += sprite->data[1];
+ gSprites[sprite->data[3]].pos2.y += sprite->data[2];
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+}
+
+void TranslateMonSpriteLinearFixedPoint(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ gSprites[sprite->data[5]].pos2.x = sprite->data[3] >> 8;
+ gSprites[sprite->data[5]].pos2.y = sprite->data[4] >> 8;
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+}
+
+void TranslateSpriteLinearAndFlicker(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ sprite->pos2.x = sprite->data[2] >> 8;
+ sprite->data[2] += sprite->data[1];
+ sprite->pos2.y = sprite->data[4] >> 8;
+ sprite->data[4] += sprite->data[3];
+ if (sprite->data[0] % sprite->data[5] == 0)
+ {
+ if (sprite->data[5])
+ sprite->invisible ^= 1;
+ }
+ }
+ else
+ {
+ SetCallbackToStoredInData6(sprite);
+ }
+}
+
+void DestroySpriteAndMatrix(struct Sprite *sprite)
+{
+ FreeSpriteOamMatrix(sprite);
+ DestroyAnimSprite(sprite);
+}
+
+// not used
+static void sub_8074EF4(struct Sprite *sprite)
+{
+ sprite->data[1] = sprite->pos1.x + sprite->pos2.x;
+ sprite->data[3] = sprite->pos1.y + sprite->pos2.y;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ sprite->callback = sub_8074C64;
+}
+
+// not used
+static void sub_8074F38(struct Sprite *sprite)
+{
+ ResetPaletteStructByUid(sprite->data[5]);
+ DestroySpriteAndMatrix(sprite);
+}
+
+void RunStoredCallbackWhenAffineAnimEnds(struct Sprite *sprite)
+{
+ if (sprite->affineAnimEnded)
+ SetCallbackToStoredInData6(sprite);
+}
+
+void RunStoredCallbackWhenAnimEnds(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ SetCallbackToStoredInData6(sprite);
+}
+
+void DestroyAnimSpriteAndDisableBlend(struct Sprite *sprite)
+{
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimSprite(sprite);
+}
+
+void DestroyAnimVisualTaskAndDisableBlend(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimVisualTask(taskId);
+}
+
+void SetSpriteCoordsToAnimAttackerCoords(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+}
+
+// Sets the initial x offset of the anim sprite depending on the horizontal orientation
+// of the two involved mons.
+void SetAnimSpriteInitialXOffset(struct Sprite *sprite, s16 xOffset)
+{
+ u16 attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
+ u16 targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
+
+ if (attackerX > targetX)
+ {
+ sprite->pos1.x -= xOffset;
+ }
+ else if (attackerX < targetX)
+ {
+ sprite->pos1.x += xOffset;
+ }
+ else
+ {
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->pos1.x -= xOffset;
+ else
+ sprite->pos1.x += xOffset;
+ }
+}
+
+void InitAnimArcTranslation(struct Sprite *sprite)
+{
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ InitAnimLinearTranslation(sprite);
+ sprite->data[6] = 0x8000 / sprite->data[0];
+ sprite->data[7] = 0;
+}
+
+bool8 TranslateAnimHorizontalArc(struct Sprite *sprite)
+{
+ if (AnimTranslateLinear(sprite))
+ return TRUE;
+ sprite->data[7] += sprite->data[6];
+ sprite->pos2.y += Sin((u8)(sprite->data[7] >> 8), sprite->data[5]);
+ return FALSE;
+}
+
+bool8 TranslateAnimVerticalArc(struct Sprite *sprite)
+{
+ if (AnimTranslateLinear(sprite))
+ return TRUE;
+ sprite->data[7] += sprite->data[6];
+ sprite->pos2.x += Sin((u8)(sprite->data[7] >> 8), sprite->data[5]);
+ return FALSE;
+}
+
+void SetSpritePrimaryCoordsFromSecondaryCoords(struct Sprite *sprite)
+{
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+}
+
+void InitSpritePosToAnimTarget(struct Sprite *sprite, bool8 respectMonPicOffsets)
+{
+ // Battle anim sprites are automatically created at the anim target's center, which
+ // is why there is no else clause for the "respectMonPicOffsets" check.
+ if (!respectMonPicOffsets)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_X);
+ sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_Y);
+ }
+ SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
+ sprite->pos1.y += gBattleAnimArgs[1];
+}
+
+void InitSpritePosToAnimAttacker(struct Sprite *sprite, bool8 respectMonPicOffsets)
+{
+ if (!respectMonPicOffsets)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_X);
+ sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_Y);
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
+ sprite->pos1.y += gBattleAnimArgs[1];
+}
+
+u8 GetBattlerSide(u8 battlerId)
+{
+ return GET_BATTLER_SIDE2(battlerId);
+}
+
+u8 GetBattlerPosition(u8 battlerId)
+{
+ return GET_BATTLER_POSITION(battlerId);
+}
+
+u8 GetBattlerAtPosition(u8 position)
+{
+ u8 i;
+
+ for (i = 0; i < gBattlersCount; ++i)
+ if (gBattlerPositions[i] == position)
+ break;
+ return i;
+}
+
+bool8 IsBattlerSpritePresent(u8 battlerId)
+{
+ if (gBattlerPositions[battlerId] == 0xFF)
+ {
+ return FALSE;
+ }
+ else if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ {
+ if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_HP) != 0)
+ return TRUE;
+ }
+ else
+ {
+ if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_HP) != 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 IsDoubleBattle(void)
+{
+ return IS_DOUBLE_BATTLE();
+}
+
+void sub_80752A0(struct BattleAnimBgData *animBgData)
+{
+ animBgData->bgTiles = gUnknown_2022BB8;
+ animBgData->bgTilemap = (u16 *)gUnknown_2022BBC;
+ animBgData->paletteId = 8;
+ animBgData->bgId = 1;
+ animBgData->tilesOffset = 0x200;
+ animBgData->unused = 0;
+}
+
+void sub_80752C8(struct BattleAnimBgData *animBgData, u32 arg1)
+{
+ if (arg1 == 1)
+ {
+ sub_80752A0(animBgData);
+ }
+ else
+ {
+ animBgData->bgTiles = gUnknown_2022BB8;
+ animBgData->bgTilemap = (u16 *)gUnknown_2022BBC;
+ animBgData->paletteId = 9;
+ animBgData->bgId = 2;
+ animBgData->tilesOffset = 0x300;
+ animBgData->unused = 0;
+ }
+}
+
+void sub_8075300(struct BattleAnimBgData *animBgData, u8 unused)
+{
+ animBgData->bgTiles = gUnknown_2022BB8;
+ animBgData->bgTilemap = (u16 *)gUnknown_2022BBC;
+ if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
+ {
+ animBgData->paletteId = 8;
+ animBgData->bgId = 1;
+ animBgData->tilesOffset = 0x200;
+ animBgData->unused = 0;
+ }
+ else
+ {
+ animBgData->paletteId = 9;
+ animBgData->bgId = 2;
+ animBgData->tilesOffset = 0x300;
+ animBgData->unused = 0;
+ }
+}
+
+void sub_8075358(u32 bgId)
+{
+ struct BattleAnimBgData animBgData;
+
+ sub_80752C8(&animBgData, bgId);
+ CpuFill32(0, animBgData.bgTiles, 0x2000);
+ LoadBgTiles(bgId, animBgData.bgTiles, 0x2000, animBgData.tilesOffset);
+ FillBgTilemapBufferRect(bgId, 0, 0, 0, 32, 64, 17);
+ CopyBgTilemapBufferToVram(bgId);
+}
+
+void AnimLoadCompressedBgGfx(u32 bgId, const u32 *src, u32 tilesOffset)
+{
+ CpuFill32(0, gUnknown_2022BB8, 0x2000);
+ LZDecompressWram(src, gUnknown_2022BB8);
+ LoadBgTiles(bgId, gUnknown_2022BB8, 0x2000, tilesOffset);
+}
+
+void InitAnimBgTilemapBuffer(u32 bgId, const void *src)
+{
+ FillBgTilemapBufferRect(bgId, 0, 0, 0, 32, 64, 17);
+ CopyToBgTilemapBuffer(bgId, src, 0, 0);
+}
+
+void AnimLoadCompressedBgTilemap(u32 bgId, const u32 *src)
+{
+ InitAnimBgTilemapBuffer(bgId, src);
+ CopyBgTilemapBufferToVram(bgId);
+}
+
+u8 sub_8075454(void)
+{
+ return 2;
+}
+
+void sub_8075458(bool8 arg0)
+{
+ if (!arg0)
+ {
+ SetAnimBgAttribute(3, BG_ANIM_SCREEN_SIZE, 0);
+ SetAnimBgAttribute(3, BG_ANIM_AREA_OVERFLOW_MODE, 1);
+ }
+ else
+ {
+ SetAnimBgAttribute(3, BG_ANIM_SCREEN_SIZE, 1);
+ SetAnimBgAttribute(3, BG_ANIM_AREA_OVERFLOW_MODE, 0);
+ }
+}
+
+void sub_8075490(struct Sprite *sprite)
+{
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ InitSpriteDataForLinearTranslation(sprite);
+ sprite->callback = TranslateSpriteLinearFixedPointIconFrame;
+ sprite->callback(sprite);
+}
+
+void InitSpriteDataForLinearTranslation(struct Sprite *sprite)
+{
+ s16 x = (sprite->data[2] - sprite->data[1]) << 8;
+ s16 y = (sprite->data[4] - sprite->data[3]) << 8;
+
+ sprite->data[1] = x / sprite->data[0];
+ sprite->data[2] = y / sprite->data[0];
+ sprite->data[4] = 0;
+ sprite->data[3] = 0;
+}
+
+void InitAnimLinearTranslation(struct Sprite *sprite)
+{
+ s32 x = sprite->data[2] - sprite->data[1];
+ s32 y = sprite->data[4] - sprite->data[3];
+ bool8 movingLeft = x < 0;
+ bool8 movingUp = y < 0;
+ u16 xDelta = abs(x) << 8;
+ u16 yDelta = abs(y) << 8;
+
+ xDelta = xDelta / sprite->data[0];
+ yDelta = yDelta / sprite->data[0];
+
+ if (movingLeft)
+ xDelta |= 1;
+ else
+ xDelta &= ~1;
+
+ if (movingUp)
+ yDelta |= 1;
+ else
+ yDelta &= ~1;
+
+ sprite->data[1] = xDelta;
+ sprite->data[2] = yDelta;
+ sprite->data[4] = 0;
+ sprite->data[3] = 0;
+}
+
+void StartAnimLinearTranslation(struct Sprite *sprite)
+{
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ InitAnimLinearTranslation(sprite);
+ sprite->callback = sub_807563C;
+ sprite->callback(sprite);
+}
+
+void sub_80755B8(struct Sprite *sprite)
+{
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ InitAnimLinearTranslation(sprite);
+ sprite->callback = sub_8075658;
+ sprite->callback(sprite);
+}
+
+bool8 AnimTranslateLinear(struct Sprite *sprite)
+{
+ u16 v1, v2, x, y;
+
+ if (!sprite->data[0])
+ return TRUE;
+ v1 = sprite->data[1];
+ v2 = sprite->data[2];
+ x = sprite->data[3];
+ y = sprite->data[4];
+ x += v1;
+ y += v2;
+ if (v1 & 1)
+ sprite->pos2.x = -(x >> 8);
+ else
+ sprite->pos2.x = x >> 8;
+
+ if (v2 & 1)
+ sprite->pos2.y = -(y >> 8);
+ else
+ sprite->pos2.y = y >> 8;
+ sprite->data[3] = x;
+ sprite->data[4] = y;
+ --sprite->data[0];
+ return FALSE;
+}
+
+void sub_807563C(struct Sprite *sprite)
+{
+ if (AnimTranslateLinear(sprite))
+ SetCallbackToStoredInData6(sprite);
+}
+
+static void sub_8075658(struct Sprite *sprite)
+{
+ sub_801236C(sprite);
+ if (AnimTranslateLinear(sprite))
+ SetCallbackToStoredInData6(sprite);
+}
+
+void sub_8075678(struct Sprite *sprite)
+{
+ s32 v1 = abs(sprite->data[2] - sprite->data[1]) << 8;
+
+ sprite->data[0] = v1 / sprite->data[0];
+ InitAnimLinearTranslation(sprite);
+}
+
+void sub_80756A4(struct Sprite *sprite)
+{
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ sub_8075678(sprite);
+ sprite->callback = sub_807563C;
+ sprite->callback(sprite);
+}
+
+static void InitAnimFastLinearTranslation(struct Sprite *sprite)
+{
+ s32 xDiff = sprite->data[2] - sprite->data[1];
+ s32 yDiff = sprite->data[4] - sprite->data[3];
+ bool8 xSign = xDiff < 0;
+ bool8 ySign = yDiff < 0;
+ u16 x2 = abs(xDiff) << 4;
+ u16 y2 = abs(yDiff) << 4;
+
+ x2 /= sprite->data[0];
+ y2 /= sprite->data[0];
+ if (xSign)
+ x2 |= 1;
+ else
+ x2 &= ~1;
+ if (ySign)
+ y2 |= 1;
+ else
+ y2 &= ~1;
+ sprite->data[1] = x2;
+ sprite->data[2] = y2;
+ sprite->data[4] = 0;
+ sprite->data[3] = 0;
+}
+
+void InitAndRunAnimFastLinearTranslation(struct Sprite *sprite)
+{
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ InitAnimFastLinearTranslation(sprite);
+ sprite->callback = sub_80757E8;
+ sprite->callback(sprite);
+}
+
+bool8 AnimFastTranslateLinear(struct Sprite *sprite)
+{
+ u16 v1, v2, x, y;
+
+ if (!sprite->data[0])
+ return TRUE;
+ v1 = sprite->data[1];
+ v2 = sprite->data[2];
+ x = sprite->data[3];
+ y = sprite->data[4];
+ x += v1;
+ y += v2;
+ if (v1 & 1)
+ sprite->pos2.x = -(x >> 4);
+ else
+ sprite->pos2.x = x >> 4;
+ if (v2 & 1)
+ sprite->pos2.y = -(y >> 4);
+ else
+ sprite->pos2.y = y >> 4;
+ sprite->data[3] = x;
+ sprite->data[4] = y;
+ --sprite->data[0];
+ return FALSE;
+}
+
+static void sub_80757E8(struct Sprite *sprite)
+{
+ if (AnimFastTranslateLinear(sprite))
+ SetCallbackToStoredInData6(sprite);
+}
+
+void InitAnimFastLinearTranslationWithSpeed(struct Sprite *sprite)
+{
+ s32 xDiff = abs(sprite->data[2] - sprite->data[1]) << 4;
+
+ sprite->data[0] = xDiff / sprite->data[0];
+ InitAnimFastLinearTranslation(sprite);
+}
+
+void sub_8075830(struct Sprite *sprite)
+{
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ InitAnimFastLinearTranslationWithSpeed(sprite);
+ sprite->callback = sub_80757E8;
+ sprite->callback(sprite);
+}
+
+void SetSpriteRotScale(u8 spriteId, s16 xScale, s16 yScale, u16 rotation)
+{
+ s32 i;
+ struct ObjAffineSrcData src;
+ struct OamMatrix matrix;
+
+ src.xScale = xScale;
+ src.yScale = yScale;
+ src.rotation = rotation;
+ if (sub_80758DC())
+ src.xScale = -src.xScale;
+ i = gSprites[spriteId].oam.matrixNum;
+ ObjAffineSet(&src, &matrix, 1, 2);
+ gOamMatrices[i].a = matrix.a;
+ gOamMatrices[i].b = matrix.b;
+ gOamMatrices[i].c = matrix.c;
+ gOamMatrices[i].d = matrix.d;
+}
+
+static bool8 sub_80758DC(void)
+{
+ return FALSE;
+}
+
+void PrepareBattlerSpriteForRotScale(u8 spriteId, u8 objMode)
+{
+ u8 battlerId = gSprites[spriteId].data[0];
+
+ if (IsBattlerSpriteVisible(battlerId))
+ gSprites[spriteId].invisible = FALSE;
+ gSprites[spriteId].oam.objMode = objMode;
+ gSprites[spriteId].affineAnimPaused = TRUE;
+ if (!gSprites[spriteId].oam.affineMode)
+ gSprites[spriteId].oam.matrixNum = gBattleSpritesDataPtr->healthBoxesData[battlerId].matrixNum;
+ gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_DOUBLE;
+ CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
+}
+
+void ResetSpriteRotScale(u8 spriteId)
+{
+ SetSpriteRotScale(spriteId, 0x100, 0x100, 0);
+ gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
+ gSprites[spriteId].oam.objMode = 0;
+ gSprites[spriteId].affineAnimPaused = FALSE;
+ CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
+}
+
+// Sets the sprite's y offset equal to the y displacement caused by the
+// matrix's rotation.
+void SetBattlerSpriteYOffsetFromRotation(u8 spriteId)
+{
+ u16 matrixNum = gSprites[spriteId].oam.matrixNum;
+ // The "c" component of the battler sprite matrix contains the sine of the rotation angle divided by some scale amount.
+ s16 c = gOamMatrices[matrixNum].c;
+
+ if (c < 0)
+ c = -c;
+ gSprites[spriteId].pos2.y = c >> 3;
+}
+
+void TrySetSpriteRotScale(struct Sprite *sprite, bool8 recalcCenterVector, s16 xScale, s16 yScale, u16 rotation)
+{
+ s32 i;
+ struct ObjAffineSrcData src;
+ struct OamMatrix matrix;
+
+ if (sprite->oam.affineMode & 1)
+ {
+ sprite->affineAnimPaused = TRUE;
+ if (recalcCenterVector)
+ CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode);
+ src.xScale = xScale;
+ src.yScale = yScale;
+ src.rotation = rotation;
+ if (sub_80758DC())
+ src.xScale = -src.xScale;
+ i = sprite->oam.matrixNum;
+ ObjAffineSet(&src, &matrix, 1, 2);
+ gOamMatrices[i].a = matrix.a;
+ gOamMatrices[i].b = matrix.b;
+ gOamMatrices[i].c = matrix.c;
+ gOamMatrices[i].d = matrix.d;
+ }
+}
+
+void sub_8075AD8(struct Sprite *sprite)
+{
+ TrySetSpriteRotScale(sprite, TRUE, 0x100, 0x100, 0);
+ sprite->affineAnimPaused = FALSE;
+ CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode);
+}
+
+static u16 ArcTan2_(s16 a, s16 b)
+{
+ return ArcTan2(a, b);
+}
+
+u16 ArcTan2Neg(s16 a, s16 b)
+{
+ u16 var = ArcTan2_(a, b);
+ return -var;
+}
+
+void SetGreyscaleOrOriginalPalette(u16 paletteNum, bool8 restoreOriginalColor)
+{
+ s32 i;
+ struct PlttData *originalColor;
+ struct PlttData *destColor;
+ u16 average;
+
+ paletteNum *= 16;
+
+ if (!restoreOriginalColor)
+ {
+ for (i = 0; i < 16; ++i)
+ {
+ originalColor = (struct PlttData *)&gPlttBufferUnfaded[paletteNum + i];
+ average = originalColor->r + originalColor->g + originalColor->b;
+ average /= 3;
+ destColor = (struct PlttData *)&gPlttBufferFaded[paletteNum + i];
+ destColor->r = average;
+ destColor->g = average;
+ destColor->b = average;
+ }
+ }
+ else
+ {
+ CpuCopy32(&gPlttBufferUnfaded[paletteNum], &gPlttBufferFaded[paletteNum], 32);
+ }
+}
+
+u32 sub_8075BE8(u8 battleBackground, u8 attacker, u8 target, u8 attackerPartner, u8 targetPartner, u8 a6, u8 a7)
+{
+ u32 selectedPalettes = 0;
+ u32 shift;
+
+ if (battleBackground)
+ {
+ selectedPalettes = 0xe;
+ }
+ if (attacker)
+ {
+ shift = gBattleAnimAttacker + 16;
+ selectedPalettes |= 1 << shift;
+ }
+ if (target)
+ {
+ shift = gBattleAnimTarget + 16;
+ selectedPalettes |= 1 << shift;
+ }
+ if (attackerPartner)
+ {
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
+ {
+ shift = BATTLE_PARTNER(gBattleAnimAttacker) + 16;
+ selectedPalettes |= 1 << shift;
+ }
+ }
+ if (targetPartner)
+ {
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
+ {
+ shift = BATTLE_PARTNER(gBattleAnimTarget) + 16;
+ selectedPalettes |= 1 << shift;
+ }
+ }
+ if (a6)
+ {
+ selectedPalettes |= 0x100;
+ }
+ if (a7)
+ {
+ selectedPalettes |= 0x200;
+ }
+ return selectedPalettes;
+}
+
+u32 sub_8075CB8(u8 a1, u8 a2, u8 a3, u8 a4)
+{
+ u32 var = 0;
+ u32 shift;
+
+ if (a1)
+ {
+ if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)))
+ {
+ var |= 1 << (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) + 16);
+ }
+ }
+ if (a2)
+ {
+ if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)))
+ {
+ shift = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT) + 16;
+ var |= 1 << shift;
+ }
+ }
+ if (a3)
+ {
+ if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)))
+ {
+ shift = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT) + 16;
+ var |= 1 << shift;
+ }
+ }
+ if (a4)
+ {
+ if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)))
+ {
+ shift = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT) + 16;
+ var |= 1 << shift;
+ }
+ }
+ return var;
+}
+
+u8 sub_8075D80(u8 a1)
+{
+ return a1;
+}
+
+// not used
+static u8 GetBattlerAtPosition_(u8 position)
+{
+ return GetBattlerAtPosition(position);
+}
+
+void sub_8075D9C(struct Sprite *sprite)
+{
+ bool8 var;
+
+ if (!sprite->data[0])
+ {
+ if (!gBattleAnimArgs[3])
+ var = TRUE;
+ else
+ var = FALSE;
+ if (!gBattleAnimArgs[2])
+ InitSpritePosToAnimAttacker(sprite, var);
+ else
+ InitSpritePosToAnimTarget(sprite, var);
+ ++sprite->data[0];
+
+ }
+ else if (sprite->animEnded || sprite->affineAnimEnded)
+ {
+ DestroySpriteAndMatrix(sprite);
+ }
+}
+
+// Linearly translates a sprite to a target position on the
+// other mon's sprite.
+// arg 0: initial x offset
+// arg 1: initial y offset
+// arg 2: target x offset
+// arg 3: target y offset
+// arg 4: duration
+// arg 5: lower 8 bits = location on attacking mon, upper 8 bits = location on target mon pick to target
+void TranslateAnimSpriteToTargetMonLocation(struct Sprite *sprite)
+{
+ bool8 respectMonPicOffsets;
+ u8 coordType;
+
+ if (!(gBattleAnimArgs[5] & 0xFF00))
+ respectMonPicOffsets = TRUE;
+ else
+ respectMonPicOffsets = FALSE;
+ if (!(gBattleAnimArgs[5] & 0xFF))
+ coordType = BATTLER_COORD_Y_PIC_OFFSET;
+ else
+ coordType = BATTLER_COORD_Y;
+ InitSpritePosToAnimAttacker(sprite, respectMonPicOffsets);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, coordType) + gBattleAnimArgs[3];
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+void sub_8075E80(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, 1);
+ if (GetBattlerSide(gBattleAnimAttacker))
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
+ sprite->data[5] = gBattleAnimArgs[5];
+ InitAnimArcTranslation(sprite);
+ sprite->callback = sub_8075EF0;
+}
+
+static void sub_8075EF0(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ DestroyAnimSprite(sprite);
+}
+
+void sub_8075F0C(struct Sprite *sprite)
+{
+ bool8 r4;
+ u8 battlerId, coordType;
+
+ if (!gBattleAnimArgs[6])
+ {
+ r4 = TRUE;
+ coordType = BATTLER_COORD_Y_PIC_OFFSET;
+ }
+ else
+ {
+ r4 = FALSE;
+ coordType = BATTLER_COORD_Y;
+ }
+ if (!gBattleAnimArgs[5])
+ {
+ InitSpritePosToAnimAttacker(sprite, r4);
+ battlerId = gBattleAnimAttacker;
+ }
+ else
+ {
+ InitSpritePosToAnimTarget(sprite, r4);
+ battlerId = gBattleAnimTarget;
+ }
+ if (GetBattlerSide(gBattleAnimAttacker))
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ InitSpritePosToAnimTarget(sprite, r4);
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(battlerId, coordType) + gBattleAnimArgs[3];
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+s16 CloneBattlerSpriteWithBlend(u8 animBattler)
+{
+ u16 i;
+ u8 spriteId = GetAnimBattlerSpriteId(animBattler);
+
+ if (spriteId != 0xFF)
+ {
+ for (i = 0; i < MAX_SPRITES; ++i)
+ {
+ if (!gSprites[i].inUse)
+ {
+ gSprites[i] = gSprites[spriteId];
+ gSprites[i].oam.objMode = ST_OAM_OBJ_BLEND;
+ gSprites[i].invisible = FALSE;
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+void obj_delete_but_dont_free_vram(struct Sprite *sprite)
+{
+ sprite->usingSheet = TRUE;
+ DestroySprite(sprite);
+}
+
+void sub_8076048(u8 taskId)
+{
+ s16 v1 = 0, v2 = 0;
+
+ if (gBattleAnimArgs[2] > gBattleAnimArgs[0])
+ v2 = 1;
+ if (gBattleAnimArgs[2] < gBattleAnimArgs[0])
+ v2 = -1;
+ if (gBattleAnimArgs[3] > gBattleAnimArgs[1])
+ v1 = 1;
+ if (gBattleAnimArgs[3] < gBattleAnimArgs[1])
+ v1 = -1;
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = gBattleAnimArgs[4];
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = gBattleAnimArgs[0];
+ gTasks[taskId].data[4] = gBattleAnimArgs[1];
+ gTasks[taskId].data[5] = v2;
+ gTasks[taskId].data[6] = v1;
+ gTasks[taskId].data[7] = gBattleAnimArgs[2];
+ gTasks[taskId].data[8] = gBattleAnimArgs[3];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gBattleAnimArgs[0], gBattleAnimArgs[1]));
+ gTasks[taskId].func = sub_80760D0;
+}
+
+static void sub_80760D0(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (++task->data[0] > task->data[1])
+ {
+ task->data[0] = 0;
+ if (++task->data[2] & 1)
+ {
+ if (task->data[3] != task->data[7])
+ task->data[3] += task->data[5];
+ }
+ else
+ {
+ if (task->data[4] != task->data[8])
+ task->data[4] += task->data[6];
+ }
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
+ if (task->data[3] == task->data[7] && task->data[4] == task->data[8])
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ }
+}
+
+// Linearly blends a mon's sprite colors with a target color with increasing
+// strength, and then blends out to the original color.
+// arg 0: anim bank
+// arg 1: blend color
+// arg 2: target blend coefficient
+// arg 3: initial delay
+// arg 4: number of times to blend in and out
+void AnimTask_BlendMonInAndOut(u8 task)
+{
+ u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
+
+ if (spriteId == 0xFF)
+ {
+ DestroyAnimVisualTask(task);
+ return;
+ }
+ gTasks[task].data[0] = (gSprites[spriteId].oam.paletteNum * 0x10) + 0x101;
+ AnimTask_BlendMonInAndOutSetup(&gTasks[task]);
+}
+
+static void AnimTask_BlendMonInAndOutSetup(struct Task *task)
+{
+ task->data[1] = gBattleAnimArgs[1];
+ task->data[2] = 0;
+ task->data[3] = gBattleAnimArgs[2];
+ task->data[4] = 0;
+ task->data[5] = gBattleAnimArgs[3];
+ task->data[6] = 0;
+ task->data[7] = gBattleAnimArgs[4];
+ task->func = AnimTask_BlendMonInAndOutStep;
+}
+
+static void AnimTask_BlendMonInAndOutStep(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (++task->data[4] >= task->data[5])
+ {
+ task->data[4] = 0;
+ if (!task->data[6])
+ {
+ ++task->data[2];
+ BlendPalette(task->data[0], 15, task->data[2], task->data[1]);
+ if (task->data[2] == task->data[3])
+ task->data[6] = 1;
+ }
+ else
+ {
+ --task->data[2];
+ BlendPalette(task->data[0], 15, task->data[2], task->data[1]);
+ if (!task->data[2])
+ {
+ if (--task->data[7])
+ {
+ task->data[4] = 0;
+ task->data[6] = 0;
+ }
+ else
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ }
+ }
+ }
+}
+
+void sub_8076288(u8 taskId)
+{
+ u8 palette = IndexOfSpritePaletteTag(gBattleAnimArgs[0]);
+
+ if (palette == 0xFF)
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ gTasks[taskId].data[0] = (palette * 0x10) + 0x101;
+ AnimTask_BlendMonInAndOutSetup(&gTasks[taskId]);
+}
+
+void PrepareAffineAnimInTaskData(struct Task *task, u8 spriteId, const union AffineAnimCmd *affineAnimCmds)
+{
+ task->data[7] = 0;
+ task->data[8] = 0;
+ task->data[9] = 0;
+ task->data[15] = spriteId;
+ task->data[10] = 0x100;
+ task->data[11] = 0x100;
+ task->data[12] = 0;
+ StorePointerInVars(&task->data[13], &task->data[14], affineAnimCmds);
+ PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL);
+}
+
+bool8 RunAffineAnimFromTaskData(struct Task *task)
+{
+ sAnimTaskAffineAnim = LoadPointerFromVars(task->data[13], task->data[14]) + (task->data[7] << 3);
+ switch (sAnimTaskAffineAnim->type)
+ {
+ default:
+ if (!sAnimTaskAffineAnim->frame.duration)
+ {
+ task->data[10] = sAnimTaskAffineAnim->frame.xScale;
+ task->data[11] = sAnimTaskAffineAnim->frame.yScale;
+ task->data[12] = sAnimTaskAffineAnim->frame.rotation;
+ ++task->data[7];
+ ++sAnimTaskAffineAnim;
+ }
+ task->data[10] += sAnimTaskAffineAnim->frame.xScale;
+ task->data[11] += sAnimTaskAffineAnim->frame.yScale;
+ task->data[12] += sAnimTaskAffineAnim->frame.rotation;
+ SetSpriteRotScale(task->data[15], task->data[10], task->data[11], task->data[12]);
+ SetBattlerSpriteYOffsetFromYScale(task->data[15]);
+ if (++task->data[8] >= sAnimTaskAffineAnim->frame.duration)
+ {
+ task->data[8] = 0;
+ ++task->data[7];
+ }
+ break;
+ case AFFINEANIMCMDTYPE_JUMP:
+ task->data[7] = sAnimTaskAffineAnim->jump.target;
+ break;
+ case AFFINEANIMCMDTYPE_LOOP:
+ if (sAnimTaskAffineAnim->loop.count)
+ {
+ if (task->data[9])
+ {
+ if (!--task->data[9])
+ {
+ ++task->data[7];
+ break;
+ }
+ }
+ else
+ {
+ task->data[9] = sAnimTaskAffineAnim->loop.count;
+ }
+ if (!task->data[7])
+ {
+ break;
+ }
+ while (TRUE)
+ {
+ --task->data[7];
+ --sAnimTaskAffineAnim;
+ if (sAnimTaskAffineAnim->type == AFFINEANIMCMDTYPE_LOOP)
+ {
+ ++task->data[7];
+ return TRUE;
+ }
+ if (!task->data[7])
+ return TRUE;
+ }
+ }
+ ++task->data[7];
+ break;
+ case AFFINEANIMCMDTYPE_END:
+ gSprites[task->data[15]].pos2.y = 0;
+ ResetSpriteRotScale(task->data[15]);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+// Sets the sprite's y offset equal to the y displacement caused by the
+// matrix's scale in the y dimension.
+void SetBattlerSpriteYOffsetFromYScale(u8 spriteId)
+{
+ s32 var = 64 - GetBattlerYDeltaFromSpriteId(spriteId) * 2;
+ u16 matrix = gSprites[spriteId].oam.matrixNum;
+ s32 var2 = (var << 8) / gOamMatrices[matrix].d;
+
+ if (var2 > 128)
+ var2 = 128;
+ gSprites[spriteId].pos2.y = (var - var2) / 2;
+}
+
+// Sets the sprite's y offset equal to the y displacement caused by another sprite
+// matrix's scale in the y dimension.
+void SetBattlerSpriteYOffsetFromOtherYScale(u8 spriteId, u8 otherSpriteId)
+{
+ s32 var = 64 - GetBattlerYDeltaFromSpriteId(otherSpriteId) * 2;
+ u16 matrix = gSprites[spriteId].oam.matrixNum;
+ s32 var2 = (var << 8) / gOamMatrices[matrix].d;
+
+ if (var2 > 128)
+ var2 = 128;
+ gSprites[spriteId].pos2.y = (var - var2) / 2;
+}
+
+static u16 GetBattlerYDeltaFromSpriteId(u8 spriteId)
+{
+ struct BattleSpriteInfo *spriteInfo;
+ u8 battlerId = gSprites[spriteId].data[0];
+ u16 species;
+ u16 i;
+
+ for (i = 0; i < MAX_BATTLERS_COUNT; ++i)
+ {
+ if (gBattlerSpriteIds[i] == spriteId)
+ {
+ if (GetBattlerSide(i) == B_SIDE_PLAYER)
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
+ else
+ species = spriteInfo[battlerId].transformSpecies;
+ return gMonBackPicCoords[species].y_offset;
+ }
+ else
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
+ else
+ species = spriteInfo[battlerId].transformSpecies;
+ return gMonFrontPicCoords[species].y_offset;
+ }
+ }
+ }
+ return 64;
+}
+
+void StorePointerInVars(s16 *lo, s16 *hi, const void *ptr)
+{
+ *lo = ((intptr_t)ptr) & 0xffff;
+ *hi = (((intptr_t)ptr) >> 16) & 0xffff;
+}
+
+void *LoadPointerFromVars(s16 lo, s16 hi)
+{
+ return (void *)((u16)lo | ((u16)hi << 16));
+}
+
+void sub_80765D4(struct Task *task, u8 spriteId, s16 a3, s16 a4, s16 a5, s16 a6, u16 a7)
+{
+ task->data[8] = a7;
+ task->data[15] = spriteId;
+ task->data[9] = a3;
+ task->data[10] = a4;
+ task->data[13] = a5;
+ task->data[14] = a6;
+ task->data[11] = (a5 - a3) / a7;
+ task->data[12] = (a6 - a4) / a7;
+}
+
+u8 sub_8076640(struct Task *task)
+{
+ if (!task->data[8])
+ return 0;
+ if (--task->data[8] != 0)
+ {
+ task->data[9] += task->data[11];
+ task->data[10] += task->data[12];
+ }
+ else
+ {
+ task->data[9] = task->data[13];
+ task->data[10] = task->data[14];
+ }
+ SetSpriteRotScale(task->data[15], task->data[9], task->data[10], 0);
+ if (task->data[8])
+ SetBattlerSpriteYOffsetFromYScale(task->data[15]);
+ else
+ gSprites[task->data[15]].pos2.y = 0;
+ return task->data[8];
+}
+
+void AnimTask_GetFrustrationPowerLevel(u8 taskId)
+{
+ u16 powerLevel;
+
+ if (gAnimFriendship <= 30)
+ powerLevel = 0;
+ else if (gAnimFriendship <= 100)
+ powerLevel = 1;
+ else if (gAnimFriendship <= 200)
+ powerLevel = 2;
+ else
+ powerLevel = 3;
+ gBattleAnimArgs[7] = powerLevel;
+ DestroyAnimVisualTask(taskId);
+}
+
+// not used
+static void sub_80766EC(u8 priority)
+{
+ if (IsBattlerSpriteVisible(gBattleAnimTarget))
+ gSprites[gBattlerSpriteIds[gBattleAnimTarget]].oam.priority = priority;
+ if (IsBattlerSpriteVisible(gBattleAnimAttacker))
+ gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].oam.priority = priority;
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
+ gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)]].oam.priority = priority;
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
+ gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority = priority;
+}
+
+void sub_80767F0(void)
+{
+ s32 i;
+
+ for (i = 0; i < gBattlersCount; ++i)
+ {
+ if (IsBattlerSpriteVisible(i))
+ {
+ gSprites[gBattlerSpriteIds[i]].subpriority = GetBattlerSpriteSubpriority(i);
+ gSprites[gBattlerSpriteIds[i]].oam.priority = 2;
+ }
+ }
+}
+
+u8 GetBattlerSpriteSubpriority(u8 battlerId)
+{
+ u8 subpriority;
+ u8 position = GetBattlerPosition(battlerId);
+
+ if (position == B_POSITION_PLAYER_LEFT)
+ subpriority = 30;
+ else if (position == B_POSITION_PLAYER_RIGHT)
+ subpriority = 20;
+ else if (position == B_POSITION_OPPONENT_LEFT)
+ subpriority = 40;
+ else
+ subpriority = 50;
+ return subpriority;
+}
+
+u8 GetBattlerSpriteBGPriority(u8 battlerId)
+{
+ u8 position = GetBattlerPosition(battlerId);
+
+ if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_OPPONENT_RIGHT)
+ return GetAnimBgAttribute(2, BG_ANIM_PRIORITY);
+ else
+ return GetAnimBgAttribute(1, BG_ANIM_PRIORITY);
+}
+
+u8 GetBattlerSpriteBGPriorityRank(u8 battlerId)
+{
+ u8 position = GetBattlerPosition(battlerId);
+
+ if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_OPPONENT_RIGHT)
+ return 2;
+ else
+ return 1;
+}
+
+u8 sub_80768D0(u16 species, bool8 isBackpic, u8 a3, s16 x, s16 y, u8 subpriority, u32 personality, u32 trainerId, u32 battlerId, u32 a10)
+{
+ u8 spriteId;
+ u16 sheet = LoadSpriteSheet(&gUnknown_83AE084[a3]);
+ u16 palette = AllocSpritePalette(gUnknown_83AE054[a3].paletteTag);
+
+ if (gMonSpritesGfxPtr != NULL && gMonSpritesGfxPtr->field_17C == NULL)
+ gMonSpritesGfxPtr->field_17C = AllocZeroed(0x2000);
+ if (!isBackpic)
+ {
+ LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20);
+ if (a10 == 1 || sub_804455C(5, battlerId) == 1 || gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != 0)
+ LoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species],
+ gMonSpritesGfxPtr->field_17C,
+ species,
+ personality,
+ TRUE);
+ else
+ LoadSpecialPokePic(&gMonFrontPicTable[species],
+ gMonSpritesGfxPtr->field_17C,
+ species,
+ personality,
+ TRUE);
+ }
+ else
+ {
+ LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20);
+ if (a10 == 1 || sub_804455C(5, battlerId) == 1 || gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != 0)
+ LoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[species],
+ gMonSpritesGfxPtr->field_17C,
+ species,
+ personality,
+ FALSE);
+ else
+ LoadSpecialPokePic(&gMonBackPicTable[species],
+ gMonSpritesGfxPtr->field_17C,
+ species,
+ personality,
+ FALSE);
+ }
+ RequestDma3Copy(gMonSpritesGfxPtr->field_17C, (void *)(OBJ_VRAM0 + (sheet * 0x20)), 0x800, 1);
+ FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_17C);
+ if (!isBackpic)
+ spriteId = CreateSprite(&gUnknown_83AE054[a3], x, y + gMonFrontPicCoords[species].y_offset, subpriority);
+ else
+ spriteId = CreateSprite(&gUnknown_83AE054[a3], x, y + gMonBackPicCoords[species].y_offset, subpriority);
+ return spriteId;
+}
+
+void DestroySpriteAndFreeResources_(struct Sprite *sprite)
+{
+ DestroySpriteAndFreeResources(sprite);
+}
+
+s16 GetBattlerSpriteCoordAttr(u8 battlerId, u8 attr)
+{
+ u16 species;
+ u32 personality;
+ u16 letter;
+ u16 unownSpecies;
+ s32 ret;
+ const struct MonCoords *coords;
+ struct BattleSpriteInfo *spriteInfo;
+
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ {
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY);
+ }
+ else
+ {
+ species = spriteInfo[battlerId].transformSpecies;
+ personality = gTransformedPersonalities[battlerId];
+ }
+ if (species == SPECIES_UNOWN)
+ {
+ letter = GET_UNOWN_LETTER(personality);
+ if (!letter)
+ unownSpecies = SPECIES_UNOWN;
+ else
+ unownSpecies = letter + SPECIES_UNOWN_B - 1;
+ coords = &gMonBackPicCoords[unownSpecies];
+ }
+ else if (species > NUM_SPECIES)
+ {
+ coords = &gMonBackPicCoords[0];
+ }
+ else
+ {
+ coords = &gMonBackPicCoords[species];
+ }
+ }
+ else
+ {
+ spriteInfo = gBattleSpritesDataPtr->battlerData;
+ if (!spriteInfo[battlerId].transformSpecies)
+ {
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY);
+ }
+ else
+ {
+ species = spriteInfo[battlerId].transformSpecies;
+ personality = gTransformedPersonalities[battlerId];
+ }
+
+ if (species == SPECIES_UNOWN)
+ {
+ letter = GET_UNOWN_LETTER(personality);
+ if (!letter)
+ unownSpecies = SPECIES_UNOWN;
+ else
+ unownSpecies = letter + SPECIES_UNOWN_B - 1;
+ coords = &gMonFrontPicCoords[unownSpecies];
+ }
+ else if (species == SPECIES_CASTFORM)
+ {
+ coords = &gCastformFrontSpriteCoords[gBattleMonForms[battlerId]];
+ }
+ else if (species > NUM_SPECIES)
+ {
+ coords = &gMonFrontPicCoords[0];
+ }
+ else
+ {
+ coords = &gMonFrontPicCoords[species];
+ }
+ }
+ switch (attr)
+ {
+ case BATTLER_COORD_ATTR_HEIGHT:
+ return (coords->size & 0xf) * 8;
+ case BATTLER_COORD_ATTR_WIDTH:
+ return (coords->size >> 4) * 8;
+ case BATTLER_COORD_ATTR_LEFT:
+ return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) - ((coords->size >> 4) * 4);
+ case BATTLER_COORD_ATTR_RIGHT:
+ return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) + ((coords->size >> 4) * 4);
+ case BATTLER_COORD_ATTR_TOP:
+ return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET) - ((coords->size & 0xf) * 4);
+ case BATTLER_COORD_ATTR_BOTTOM:
+ return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET) + ((coords->size & 0xf) * 4);
+ case BATTLER_COORD_ATTR_RAW_BOTTOM:
+ ret = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 31;
+ return ret - coords->y_offset;
+ default:
+ return 0;
+ }
+}
+
+void SetAverageBattlerPositions(u8 battlerId, bool8 respectMonPicOffsets, s16 *x, s16 *y)
+{
+ u8 xCoordType, yCoordType;
+ s16 battlerX, battlerY;
+ s16 partnerX, partnerY;
+
+ if (!respectMonPicOffsets)
+ {
+ xCoordType = BATTLER_COORD_X;
+ yCoordType = BATTLER_COORD_Y;
+ }
+ else
+ {
+ xCoordType = BATTLER_COORD_X_2;
+ yCoordType = BATTLER_COORD_Y_PIC_OFFSET;
+ }
+ battlerX = GetBattlerSpriteCoord(battlerId, xCoordType);
+ battlerY = GetBattlerSpriteCoord(battlerId, yCoordType);
+ if (IsDoubleBattle())
+ {
+ partnerX = GetBattlerSpriteCoord(BATTLE_PARTNER(battlerId), xCoordType);
+ partnerY = GetBattlerSpriteCoord(BATTLE_PARTNER(battlerId), yCoordType);
+ }
+ else
+ {
+ partnerX = battlerX;
+ partnerY = battlerY;
+ }
+ *x = (battlerX + partnerX) / 2;
+ *y = (battlerY + partnerY) / 2;
+}
+
+u8 sub_8076E34(s32 battlerId, u8 spriteId, s32 species)
+{
+ u8 newSpriteId = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy);
+
+ gSprites[newSpriteId] = gSprites[spriteId];
+ gSprites[newSpriteId].usingSheet = TRUE;
+ gSprites[newSpriteId].oam.priority = 0;
+ gSprites[newSpriteId].oam.objMode = 2;
+ gSprites[newSpriteId].oam.tileNum = gSprites[spriteId].oam.tileNum;
+ gSprites[newSpriteId].callback = SpriteCallbackDummy;
+ return newSpriteId;
+}
+
+void sub_8076ED8(struct Sprite *sprite)
+{
+ SetSpriteCoordsToAnimAttackerCoords(sprite);
+ if (GetBattlerSide(gBattleAnimAttacker))
+ {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ sprite->hFlip = TRUE;
+ }
+ else
+ {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ }
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->data[3] = gBattleAnimArgs[4];
+ sprite->data[5] = gBattleAnimArgs[5];
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = TranslateSpriteLinearAndFlicker;
+}
+
+void sub_8076F58(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ gBattleAnimArgs[3] *= -1;
+ }
+ else
+ {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ }
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->data[3] = gBattleAnimArgs[4];
+ sprite->data[5] = gBattleAnimArgs[5];
+ StartSpriteAnim(sprite, gBattleAnimArgs[6]);
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = TranslateSpriteLinearAndFlicker;
+}
+
+void sub_8076FD0(struct Sprite *sprite)
+{
+ SetSpriteCoordsToAnimAttackerCoords(sprite);
+ if (GetBattlerSide(gBattleAnimAttacker))
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+void sub_8077030(u8 taskId)
+{
+ u16 src;
+ u16 dest;
+ struct Task *task = &gTasks[taskId];
+
+ task->data[0] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
+ task->data[1] = ((GetBattlerSide(gBattleAnimAttacker)) != B_SIDE_PLAYER) ? -8 : 8;
+ task->data[2] = 0;
+ task->data[3] = 0;
+ gSprites[task->data[0]].pos2.x -= task->data[0];
+ task->data[4] = AllocSpritePalette(10097);
+ task->data[5] = 0;
+ dest = (task->data[4] + 0x10) * 0x10;
+ src = (gSprites[task->data[0]].oam.paletteNum + 0x10) * 0x10;
+ task->data[6] = GetBattlerSpriteSubpriority(gBattleAnimAttacker);
+ if (task->data[6] == 20 || task->data[6] == 40)
+ task->data[6] = 2;
+ else
+ task->data[6] = 3;
+ CpuCopy32(&gPlttBufferUnfaded[src], &gPlttBufferFaded[dest], 0x20);
+ BlendPalette(dest, 16, gBattleAnimArgs[1], gBattleAnimArgs[0]);
+ task->func = sub_8077118;
+}
+
+static void sub_8077118(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ switch (task->data[2])
+ {
+ case 0:
+ sub_80771E4(task, taskId);
+ gSprites[task->data[0]].pos2.x += task->data[1];
+ if (++task->data[3] == 5)
+ {
+ --task->data[3];
+ ++task->data[2];
+ }
+ break;
+ case 1:
+ sub_80771E4(task, taskId);
+ gSprites[task->data[0]].pos2.x -= task->data[1];
+ if (--task->data[3] == 0)
+ {
+ gSprites[task->data[0]].pos2.x = 0;
+ ++task->data[2];
+ }
+ break;
+ case 2:
+ if (!task->data[5])
+ {
+ FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON);
+ DestroyAnimVisualTask(taskId);
+ }
+ break;
+ }
+}
+
+static void sub_80771E4(struct Task *task, u8 taskId)
+{
+ s16 spriteId = CloneBattlerSpriteWithBlend(0);
+
+ if (spriteId >= 0)
+ {
+ gSprites[spriteId].oam.priority = task->data[6];
+ gSprites[spriteId].oam.paletteNum = task->data[4];
+ gSprites[spriteId].data[0] = 8;
+ gSprites[spriteId].data[1] = taskId;
+ gSprites[spriteId].data[2] = spriteId;
+ gSprites[spriteId].pos2.x = gSprites[task->data[0]].pos2.x;
+ gSprites[spriteId].callback = sub_8077268;
+ ++task->data[5];
+ }
+}
+
+static void sub_8077268(struct Sprite *sprite)
+{
+ if (--sprite->data[0] == 0)
+ {
+ --gTasks[sprite->data[1]].data[5];
+ obj_delete_but_dont_free_vram(sprite);
+ }
+}
+
+void sub_807729C(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ if (!GetBattlerSide(gBattleAnimAttacker))
+ sprite->data[0] = 5;
+ else
+ sprite->data[0] = -10;
+ sprite->data[1] = -40;
+ sprite->callback = sub_80772F4;
+}
+
+static void sub_80772F4(struct Sprite *sprite)
+{
+ sprite->data[2] += sprite->data[0];
+ sprite->data[3] += sprite->data[1];
+ sprite->pos2.x = sprite->data[2] / 10;
+ sprite->pos2.y = sprite->data[3] / 10;
+ if (sprite->data[1] < -20)
+ ++sprite->data[1];
+ if (sprite->pos1.y + sprite->pos2.y < -32)
+ DestroyAnimSprite(sprite);
+}
+
+void sub_8077350(struct Sprite *sprite)
+{
+ s32 x;
+
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[4];
+ sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[5];
+ if (!GetBattlerSide(gBattleAnimTarget))
+ {
+ x = (u16)gBattleAnimArgs[4] + 30;
+ sprite->pos1.x += x;
+ sprite->pos1.y = gBattleAnimArgs[5] - 20;
+ }
+ else
+ {
+ x = (u16)gBattleAnimArgs[4] - 30;
+ sprite->pos1.x += x;
+ sprite->pos1.y = gBattleAnimArgs[5] - 80;
+ }
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
diff --git a/src/battle_anim_sound_tasks.c b/src/battle_anim_sound_tasks.c
new file mode 100644
index 000000000..d74b743e8
--- /dev/null
+++ b/src/battle_anim_sound_tasks.c
@@ -0,0 +1,313 @@
+#include "global.h"
+#include "battle.h"
+#include "battle_anim.h"
+#include "sound.h"
+#include "task.h"
+#include "constants/battle_anim.h"
+#include "constants/species.h"
+
+static void sub_80DCE78(u8 taskId);
+static void sub_80DCEE4(u8 taskId);
+static void sub_80DCFE8(u8 taskId);
+static void sub_80DD270(u8 taskId);
+static void sub_80DD390(u8 taskId);
+static void sub_80DD4D4(u8 taskId);
+
+void sub_80DCE10(u8 taskId)
+{
+ s8 pan1, pan2, panIncrement;
+
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = gBattleAnimArgs[1];
+ pan1 = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
+ pan2 = BattleAnimAdjustPanning(SOUND_PAN_TARGET);
+ panIncrement = CalculatePanIncrement(pan1, pan2, 2);
+ gTasks[taskId].data[2] = pan1;
+ gTasks[taskId].data[3] = pan2;
+ gTasks[taskId].data[4] = panIncrement;
+ gTasks[taskId].data[10] = 10;
+ gTasks[taskId].func = sub_80DCE78;
+}
+
+static void sub_80DCE78(u8 taskId)
+{
+ s16 pan = gTasks[taskId].data[2];
+ s8 panIncrement = gTasks[taskId].data[4];
+
+ if (++gTasks[taskId].data[11] == 111)
+ {
+ gTasks[taskId].data[10] = 5;
+ gTasks[taskId].data[11] = 0;
+ gTasks[taskId].func = sub_80DCEE4;
+ }
+ else
+ {
+ if (++gTasks[taskId].data[10] == 11)
+ {
+ gTasks[taskId].data[10] = 0;
+ PlaySE12WithPanning(gTasks[taskId].data[0], pan);
+ }
+ pan += panIncrement;
+ gTasks[taskId].data[2] = KeepPanInRange(pan, panIncrement);
+ }
+}
+
+static void sub_80DCEE4(u8 taskId)
+{
+ if (++gTasks[taskId].data[10] == 6)
+ {
+ s8 pan;
+
+ gTasks[taskId].data[10] = 0;
+ pan = BattleAnimAdjustPanning(SOUND_PAN_TARGET);
+ PlaySE12WithPanning(gTasks[taskId].data[1], pan);
+ if (++gTasks[taskId].data[11] == 2)
+ DestroyAnimSoundTask(taskId);
+ }
+}
+
+void mas_80DCF38(u8 taskId)
+{
+ u16 songId = gBattleAnimArgs[0];
+ s8 targetPan = gBattleAnimArgs[2];
+ s8 panIncrement = gBattleAnimArgs[3];
+ u8 r10 = gBattleAnimArgs[4];
+ u8 r7 = gBattleAnimArgs[5];
+ u8 r9 = gBattleAnimArgs[6];
+ s8 sourcePan = BattleAnimAdjustPanning(gBattleAnimArgs[1]);
+
+ targetPan = BattleAnimAdjustPanning(targetPan);
+ panIncrement = CalculatePanIncrement(sourcePan, targetPan, panIncrement);
+ gTasks[taskId].data[0] = songId;
+ gTasks[taskId].data[1] = sourcePan;
+ gTasks[taskId].data[2] = targetPan;
+ gTasks[taskId].data[3] = panIncrement;
+ gTasks[taskId].data[4] = r10;
+ gTasks[taskId].data[5] = r7;
+ gTasks[taskId].data[6] = r9;
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].data[11] = sourcePan;
+ gTasks[taskId].data[12] = r9;
+ gTasks[taskId].func = sub_80DCFE8;
+ sub_80DCFE8(taskId);
+}
+
+static void sub_80DCFE8(u8 taskId)
+{
+ if (gTasks[taskId].data[12]++ == gTasks[taskId].data[6])
+ {
+ gTasks[taskId].data[12] = 0;
+ PlaySE12WithPanning(gTasks[taskId].data[0], gTasks[taskId].data[11]);
+ if (--gTasks[taskId].data[4] == 0)
+ {
+ DestroyAnimSoundTask(taskId);
+ return;
+ }
+ }
+ if (gTasks[taskId].data[10]++ == gTasks[taskId].data[5])
+ {
+ u16 dPan, oldPan;
+
+ gTasks[taskId].data[10] = 0;
+ dPan = gTasks[taskId].data[3];
+ oldPan = gTasks[taskId].data[11];
+ gTasks[taskId].data[11] = dPan + oldPan;
+ gTasks[taskId].data[11] = KeepPanInRange(gTasks[taskId].data[11], oldPan);
+ }
+}
+
+void sub_80DD06C(u8 taskId)
+{
+ u16 species = SPECIES_NONE;
+ u8 battlerId;
+ s8 pan = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
+
+ // Get wanted battler.
+ if (gBattleAnimArgs[0] == ANIM_ATTACKER)
+ battlerId = gBattleAnimAttacker;
+ else if (gBattleAnimArgs[0] == ANIM_TARGET)
+ battlerId = gBattleAnimTarget;
+ else if (gBattleAnimArgs[0] == ANIM_ATK_PARTNER)
+ battlerId = BATTLE_PARTNER(gBattleAnimAttacker);
+ else
+ battlerId = BATTLE_PARTNER(gBattleAnimTarget);
+ // Check if battler is visible.
+ if ((gBattleAnimArgs[0] == ANIM_TARGET || gBattleAnimArgs[0] == ANIM_DEF_PARTNER)
+ && !IsBattlerSpriteVisible(battlerId))
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ else
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ if (species != SPECIES_NONE)
+ PlayCry3(species, pan, 3);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80DD148(u8 taskId)
+{
+ u16 species = SPECIES_NONE;
+ u8 battlerId;
+ s8 pan = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
+
+ // Get wanted battler.
+ if (gBattleAnimArgs[0] == ANIM_ATTACKER)
+ battlerId = gBattleAnimAttacker;
+ else if (gBattleAnimArgs[0] == ANIM_TARGET)
+ battlerId = gBattleAnimTarget;
+ else if (gBattleAnimArgs[0] == ANIM_ATK_PARTNER)
+ battlerId = BATTLE_PARTNER(gBattleAnimAttacker);
+ else
+ battlerId = BATTLE_PARTNER(gBattleAnimTarget);
+ // Check if battler is visible.
+ if ((gBattleAnimArgs[0] == ANIM_TARGET || gBattleAnimArgs[0] == ANIM_DEF_PARTNER)
+ && !IsBattlerSpriteVisible(battlerId))
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ else
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gTasks[taskId].data[0] = gBattleAnimArgs[1];
+ gTasks[taskId].data[1] = species;
+ gTasks[taskId].data[2] = pan;
+ if (species != SPECIES_NONE)
+ {
+ if (gBattleAnimArgs[1] == TASK_NONE)
+ PlayCry3(species, pan, 9);
+ else
+ PlayCry3(species, pan, 7);
+ gTasks[taskId].func = sub_80DD270;
+ }
+ else
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+static void sub_80DD270(u8 taskId)
+{
+ u16 species = gTasks[taskId].data[1];
+ s8 pan = gTasks[taskId].data[2];
+
+ if (gTasks[taskId].data[9] < 2)
+ {
+ ++gTasks[taskId].data[9];
+ }
+ else if (gTasks[taskId].data[0] == TASK_NONE)
+ {
+ if (!IsCryPlaying())
+ {
+ PlayCry3(species, pan, 10);
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ else if (!IsCryPlaying())
+ {
+ PlayCry3(species, pan, 8);
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+void sub_80DD2F4(u8 taskId)
+{
+ if (gTasks[taskId].data[9] < 2)
+ ++gTasks[taskId].data[9];
+ else if (!IsCryPlaying())
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80DD334(u8 taskId)
+{
+ u16 species;
+ s8 pan;
+
+ pan = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
+ species = gAnimBattlerSpecies[gBattleAnimAttacker];
+ gTasks[taskId].data[1] = species;
+ gTasks[taskId].data[2] = pan;
+ if (species != SPECIES_NONE)
+ {
+ PlayCry3(species, pan, 4);
+ gTasks[taskId].func = sub_80DD390;
+ }
+ else
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+static void sub_80DD390(u8 taskId)
+{
+
+ if (gTasks[taskId].data[9] < 2)
+ {
+ ++gTasks[taskId].data[9];
+ }
+ else if (!IsCryPlaying())
+ {
+ u16 species = gTasks[taskId].data[1];
+ s8 pan = gTasks[taskId].data[2];
+
+ PlayCry3(species, pan, 6);
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+void sub_80DD3DC(u8 taskId)
+{
+ u16 songId = gBattleAnimArgs[0];
+ s8 pan = BattleAnimAdjustPanning(gBattleAnimArgs[1]);
+
+ PlaySE1WithPanning(songId, pan);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80DD410(u8 taskId)
+{
+ u16 songId = gBattleAnimArgs[0];
+ s8 pan = BattleAnimAdjustPanning(gBattleAnimArgs[1]);
+
+ PlaySE2WithPanning(songId, pan);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80DD444(u8 taskId)
+{
+ s8 targetPan = gBattleAnimArgs[1];
+ s8 panIncrement = gBattleAnimArgs[2];
+ u16 r9 = gBattleAnimArgs[3];
+ s8 sourcePan = BattleAnimAdjustPanning(gBattleAnimArgs[0]);
+
+ targetPan = BattleAnimAdjustPanning(targetPan);
+ panIncrement = CalculatePanIncrement(sourcePan, targetPan, panIncrement);
+ gTasks[taskId].data[1] = sourcePan;
+ gTasks[taskId].data[2] = targetPan;
+ gTasks[taskId].data[3] = panIncrement;
+ gTasks[taskId].data[5] = r9;
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].data[11] = sourcePan;
+ gTasks[taskId].func = sub_80DD4D4;
+ sub_80DD4D4(taskId);
+}
+
+static void sub_80DD4D4(u8 taskId)
+{
+ u16 oldPan, panIncrement = gTasks[taskId].data[3];
+
+ if (gTasks[taskId].data[10]++ == gTasks[taskId].data[5])
+ {
+ gTasks[taskId].data[10] = 0;
+ oldPan = gTasks[taskId].data[11];
+ gTasks[taskId].data[11] = panIncrement + oldPan;
+ gTasks[taskId].data[11] = KeepPanInRange(gTasks[taskId].data[11], oldPan);
+ }
+ gUnknown_2037F24 = gTasks[taskId].data[11];
+ if (gTasks[taskId].data[11] == gTasks[taskId].data[2])
+ DestroyAnimVisualTask(taskId);
+}
diff --git a/src/battle_anim_utility_funcs.c b/src/battle_anim_utility_funcs.c
new file mode 100644
index 000000000..14c5ef6c8
--- /dev/null
+++ b/src/battle_anim_utility_funcs.c
@@ -0,0 +1,946 @@
+#include "global.h"
+#include "battle.h"
+#include "battle_anim.h"
+#include "gpu_regs.h"
+#include "graphics.h"
+#include "malloc.h"
+#include "palette.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+#include "util.h"
+#include "constants/songs.h"
+
+struct AnimStatsChangeData
+{
+ u8 battler1;
+ u8 battler2;
+ u8 higherPriority;
+ s16 data[8];
+ u16 species;
+};
+
+static void StartBlendAnimSpriteColor(u8 taskId, u32 selectedPalettes);
+static void AnimTask_BlendSpriteColor_Step2(u8 taskId);
+static void sub_80BAB78(u8 taskId);
+static void sub_80BABD0(u8 taskId);
+static void sub_80BACA8(struct Sprite *sprite);
+static void sub_80BAF38(u8 taskId);
+static void sub_80BB0D8(u8 taskId);
+static void sub_80BB2A0(u8 taskId);
+static void sub_80BB4B8(u8 taskId);
+static void sub_80BB6CC(u8 taskId);
+static void sub_80BB790(u32 selectedPalettes, u16 color);
+static void sub_80BB8A4(u8 taskId);
+static void sub_80BBC2C(u8 taskId);
+static void sub_80BC19C(u8 taskId);
+
+static EWRAM_DATA struct AnimStatsChangeData *sAnimStatsChangeData = NULL;
+
+static const u16 gUnknown_83E7CC8[] = { RGB(31, 31, 31) };
+const u8 gUnknown_83E7CCA[] = { REG_OFFSET_BG0CNT, REG_OFFSET_BG1CNT, REG_OFFSET_BG2CNT, REG_OFFSET_BG3CNT };
+const u8 gUnknown_83E7CCE[] = { REG_OFFSET_BG0CNT, REG_OFFSET_BG1CNT, REG_OFFSET_BG2CNT, REG_OFFSET_BG3CNT };
+
+void sub_80BA7F8(u8 taskId)
+{
+ u32 selectedPalettes = UnpackSelectedBattleAnimPalettes(gBattleAnimArgs[0]);
+
+ selectedPalettes |= sub_8075CB8((gBattleAnimArgs[0] >> 7) & 1,
+ (gBattleAnimArgs[0] >> 8) & 1,
+ (gBattleAnimArgs[0] >> 9) & 1,
+ (gBattleAnimArgs[0] >> 10) & 1);
+ StartBlendAnimSpriteColor(taskId, selectedPalettes);
+}
+
+void sub_80BA83C(u8 taskId)
+{
+ u8 battler;
+ u32 selectedPalettes;
+ u8 animBattlers[2];
+
+ animBattlers[1] = 0xFF;
+ selectedPalettes = UnpackSelectedBattleAnimPalettes(1);
+ switch (gBattleAnimArgs[0])
+ {
+ case 2:
+ selectedPalettes = 0;
+ // fall through
+ case 0:
+ animBattlers[0] = gBattleAnimAttacker;
+ break;
+ case 3:
+ selectedPalettes = 0;
+ // fall through
+ case 1:
+ animBattlers[0] = gBattleAnimTarget;
+ break;
+ case 4:
+ animBattlers[0] = gBattleAnimAttacker;
+ animBattlers[1] = gBattleAnimTarget;
+ break;
+ case 5:
+ animBattlers[0] = 0xFF;
+ break;
+ case 6:
+ selectedPalettes = 0;
+ animBattlers[0] = BATTLE_PARTNER(gBattleAnimAttacker);
+ break;
+ case 7:
+ selectedPalettes = 0;
+ animBattlers[0] = BATTLE_PARTNER(gBattleAnimTarget);
+ break;
+ }
+ for (battler = 0; battler < MAX_BATTLERS_COUNT; ++battler)
+ {
+ if (battler != animBattlers[0]
+ && battler != animBattlers[1]
+ && IsBattlerSpriteVisible(battler))
+ selectedPalettes |= 0x10000 << sub_8075D80(battler);
+ }
+ StartBlendAnimSpriteColor(taskId, selectedPalettes);
+}
+
+void AnimTask_SetCamouflageBlend(u8 taskId)
+{
+ u32 selectedPalettes = UnpackSelectedBattleAnimPalettes(gBattleAnimArgs[0]);
+
+ switch (gBattleTerrain)
+ {
+ case BATTLE_TERRAIN_GRASS:
+ gBattleAnimArgs[4] = RGB(12, 24, 2);
+ break;
+ case BATTLE_TERRAIN_LONG_GRASS:
+ gBattleAnimArgs[4] = RGB(0, 15, 2);
+ break;
+ case BATTLE_TERRAIN_SAND:
+ gBattleAnimArgs[4] = RGB(30, 24, 11);
+ break;
+ case BATTLE_TERRAIN_UNDERWATER:
+ gBattleAnimArgs[4] = RGB(0, 0, 18);
+ break;
+ case BATTLE_TERRAIN_WATER:
+ gBattleAnimArgs[4] = RGB(11, 22, 31);
+ break;
+ case BATTLE_TERRAIN_POND:
+ gBattleAnimArgs[4] = RGB(11, 22, 31);
+ break;
+ case BATTLE_TERRAIN_MOUNTAIN:
+ gBattleAnimArgs[4] = RGB(22, 16, 10);
+ break;
+ case BATTLE_TERRAIN_CAVE:
+ gBattleAnimArgs[4] = RGB(14, 9, 3);
+ break;
+ case BATTLE_TERRAIN_BUILDING:
+ gBattleAnimArgs[4] = RGB(31, 31, 31);
+ break;
+ case BATTLE_TERRAIN_PLAIN:
+ gBattleAnimArgs[4] = RGB(31, 31, 31);
+ break;
+ }
+ StartBlendAnimSpriteColor(taskId, selectedPalettes);
+}
+
+void AnimTask_BlendParticle(u8 taskId)
+{
+ u8 paletteIndex = IndexOfSpritePaletteTag(gBattleAnimArgs[0]);
+ u32 selectedPalettes = 1 << (paletteIndex + 16);
+
+ StartBlendAnimSpriteColor(taskId, selectedPalettes);
+}
+
+static void StartBlendAnimSpriteColor(u8 taskId, u32 selectedPalettes)
+{
+ gTasks[taskId].data[0] = selectedPalettes;
+ gTasks[taskId].data[1] = selectedPalettes >> 16;
+ gTasks[taskId].data[2] = gBattleAnimArgs[1];
+ gTasks[taskId].data[3] = gBattleAnimArgs[2];
+ gTasks[taskId].data[4] = gBattleAnimArgs[3];
+ gTasks[taskId].data[5] = gBattleAnimArgs[4];
+ gTasks[taskId].data[10] = gBattleAnimArgs[2];
+ gTasks[taskId].func = AnimTask_BlendSpriteColor_Step2;
+ gTasks[taskId].func(taskId);
+}
+
+static void AnimTask_BlendSpriteColor_Step2(u8 taskId)
+{
+ u32 selectedPalettes;
+ u16 singlePaletteMask = 0;
+
+ if (gTasks[taskId].data[9] == gTasks[taskId].data[2])
+ {
+ gTasks[taskId].data[9] = 0;
+ selectedPalettes = gTasks[taskId].data[0] | (gTasks[taskId].data[1] << 16);
+ while (selectedPalettes)
+ {
+ if (selectedPalettes & 1)
+ BlendPalette(singlePaletteMask, 16, gTasks[taskId].data[10], gTasks[taskId].data[5]);
+ singlePaletteMask += 0x10;
+ selectedPalettes >>= 1;
+ }
+ if (gTasks[taskId].data[10] < gTasks[taskId].data[4])
+ ++gTasks[taskId].data[10];
+ else if (gTasks[taskId].data[10] > gTasks[taskId].data[4])
+ --gTasks[taskId].data[10];
+ else
+ DestroyAnimVisualTask(taskId);
+ }
+ else
+ {
+ ++gTasks[taskId].data[9];
+ }
+}
+
+void sub_80BAB38(u8 taskId)
+{
+ BeginHardwarePaletteFade(gBattleAnimArgs[0],
+ gBattleAnimArgs[1],
+ gBattleAnimArgs[2],
+ gBattleAnimArgs[3],
+ gBattleAnimArgs[4]);
+ gTasks[taskId].func = sub_80BAB78;
+}
+
+static void sub_80BAB78(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BAB98(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->data[0] = gBattleAnimArgs[0];
+ task->data[1] = 0;
+ task->data[2] = gBattleAnimArgs[1];
+ task->data[3] = gBattleAnimArgs[2];
+ task->data[4] = gBattleAnimArgs[3];
+ task->data[5] = 0;
+ task->func = sub_80BABD0;
+}
+static void sub_80BABD0(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (task->data[4])
+ {
+ if (task->data[1])
+ {
+ --task->data[1];
+ }
+ else
+ {
+ task->data[6] = CloneBattlerSpriteWithBlend(task->data[0]);
+ if (task->data[6] >= 0)
+ {
+ gSprites[task->data[6]].oam.priority = task->data[0] ? 1 : 2;
+ gSprites[task->data[6]].data[0] = task->data[3];
+ gSprites[task->data[6]].data[1] = taskId;
+ gSprites[task->data[6]].data[2] = 5;
+ gSprites[task->data[6]].callback = sub_80BACA8;
+ ++task->data[5];
+ }
+ --task->data[4];
+ task->data[1] = task->data[2];
+ }
+ }
+ else if (task->data[5] == 0)
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+static void sub_80BACA8(struct Sprite *sprite)
+{
+ if (sprite->data[0])
+ {
+ --sprite->data[0];
+ }
+ else
+ {
+ --gTasks[sprite->data[1]].data[sprite->data[2]];
+ obj_delete_but_dont_free_vram(sprite);
+ }
+}
+
+void sub_80BACEC(u8 taskId)
+{
+ u16 species;
+ s32 newSpriteId;
+ u16 var0;
+ u16 bg1Cnt;
+ u8 spriteId;
+ struct BattleAnimBgData animBgData;
+
+ var0 = 0;
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR
+ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR
+ | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 12));
+ bg1Cnt = GetGpuReg(REG_OFFSET_BG1CNT);
+ ((struct BgCnt *)&bg1Cnt)->priority = 0;
+ ((struct BgCnt *)&bg1Cnt)->screenSize = 0;
+ SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt);
+ if (!IsContest())
+ {
+ ((struct BgCnt *)&bg1Cnt)->charBaseBlock = 1;
+ SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt);
+ }
+ if (IsDoubleBattle() && !IsContest())
+ {
+ if (GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_OPPONENT_RIGHT
+ || GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_PLAYER_LEFT)
+ {
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)) == TRUE)
+ {
+ gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority -= 1;
+ ((struct BgCnt *)&bg1Cnt)->priority = 1;
+ SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt);
+ var0 = 1;
+ }
+ }
+ }
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
+ else
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
+ spriteId = GetAnimBattlerSpriteId(0);
+ newSpriteId = sub_8076E34(gBattleAnimAttacker, spriteId, species);
+ sub_80752A0(&animBgData);
+ AnimLoadCompressedBgTilemap(animBgData.bgId, gFile_graphics_battle_anims_masks_curse_tilemap);
+ if (IsContest())
+ sub_80730C0(animBgData.paletteId, animBgData.bgTilemap, 0, 0);
+ AnimLoadCompressedBgGfx(animBgData.bgId, gFile_graphics_battle_anims_masks_curse_sheet, animBgData.tilesOffset);
+ LoadPalette(gUnknown_83E7CC8, animBgData.paletteId * 16 + 1, 2);
+ gBattle_BG1_X = -gSprites[spriteId].pos1.x + 32;
+ gBattle_BG1_Y = -gSprites[spriteId].pos1.y + 32;
+ gTasks[taskId].data[0] = newSpriteId;
+ gTasks[taskId].data[6] = var0;
+ gTasks[taskId].func = sub_80BAF38;
+}
+
+static void sub_80BAF38(u8 taskId)
+{
+ struct BattleAnimBgData animBgData;
+ struct Sprite *sprite;
+ u16 bg1Cnt;
+
+ gTasks[taskId].data[10] += 4;
+ gBattle_BG1_Y -= 4;
+ if (gTasks[taskId].data[10] == 64)
+ {
+ gTasks[taskId].data[10] = 0;
+ gBattle_BG1_Y += 64;
+ if (++gTasks[taskId].data[11] == 4)
+ {
+ sub_8073128(0);
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR
+ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR
+ | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
+ if (!IsContest())
+ {
+ bg1Cnt = GetGpuReg(REG_OFFSET_BG1CNT);
+ ((struct BgCnt *)&bg1Cnt)->charBaseBlock = 0;
+ SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt);
+ }
+ SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ sprite = &gSprites[GetAnimBattlerSpriteId(0)]; // unused
+ sprite = &gSprites[gTasks[taskId].data[0]];
+ DestroySprite(sprite);
+ sub_80752A0(&animBgData);
+ sub_8075358(animBgData.bgId);
+ if (gTasks[taskId].data[6] == 1)
+ ++gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority;
+ gBattle_BG1_Y = 0;
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+}
+
+void sub_80BB088(u8 taskId)
+{
+ u8 i;
+
+ sAnimStatsChangeData = AllocZeroed(sizeof(struct AnimStatsChangeData));
+ for (i = 0; i < 8; ++i)
+ sAnimStatsChangeData->data[i] = gBattleAnimArgs[i];
+ gTasks[taskId].func = sub_80BB0D8;
+}
+
+static void sub_80BB0D8(u8 taskId)
+{
+ if (sAnimStatsChangeData->data[2] == 0)
+ sAnimStatsChangeData->battler1 = gBattleAnimAttacker;
+ else
+ sAnimStatsChangeData->battler1 = gBattleAnimTarget;
+ sAnimStatsChangeData->battler2 = BATTLE_PARTNER(sAnimStatsChangeData->battler1);
+ if (IsContest() || (sAnimStatsChangeData->data[3] && !IsBattlerSpriteVisible(sAnimStatsChangeData->battler2)))
+ sAnimStatsChangeData->data[3] = 0;
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR
+ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR
+ | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 0);
+ SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
+ if (IsDoubleBattle() && sAnimStatsChangeData->data[3] == 0)
+ {
+ if (GetBattlerPosition(sAnimStatsChangeData->battler1) == B_POSITION_OPPONENT_RIGHT
+ || GetBattlerPosition(sAnimStatsChangeData->battler1) == B_POSITION_PLAYER_LEFT)
+ {
+ if (IsBattlerSpriteVisible(sAnimStatsChangeData->battler2) == TRUE)
+ {
+ gSprites[gBattlerSpriteIds[sAnimStatsChangeData->battler2]].oam.priority -= 1;
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ sAnimStatsChangeData->higherPriority = 1;
+ }
+ }
+ }
+ if (GetBattlerSide(sAnimStatsChangeData->battler1) != B_SIDE_PLAYER)
+ sAnimStatsChangeData->species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[sAnimStatsChangeData->battler1]], MON_DATA_SPECIES);
+ else
+ sAnimStatsChangeData->species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[sAnimStatsChangeData->battler1]], MON_DATA_SPECIES);
+ gTasks[taskId].func = sub_80BB2A0;
+}
+
+static void sub_80BB2A0(u8 taskId)
+{
+ struct BattleAnimBgData animBgData;
+ u8 spriteId, newSpriteId = 0;
+ u8 battlerSpriteId;
+
+ battlerSpriteId = gBattlerSpriteIds[sAnimStatsChangeData->battler1];
+ spriteId = sub_8076E34(sAnimStatsChangeData->battler1, battlerSpriteId, sAnimStatsChangeData->species);
+ if (sAnimStatsChangeData->data[3])
+ {
+ battlerSpriteId = gBattlerSpriteIds[sAnimStatsChangeData->battler2];
+ newSpriteId = sub_8076E34(sAnimStatsChangeData->battler2, battlerSpriteId, sAnimStatsChangeData->species);
+ }
+ sub_80752A0(&animBgData);
+ if (sAnimStatsChangeData->data[0] == 0)
+ AnimLoadCompressedBgTilemap(animBgData.bgId, gBattleStatMask1_Tilemap);
+ else
+ AnimLoadCompressedBgTilemap(animBgData.bgId, gBattleStatMask2_Tilemap);
+ if (IsContest())
+ sub_80730C0(animBgData.paletteId, animBgData.bgTilemap, 0, 0);
+ AnimLoadCompressedBgGfx(animBgData.bgId, gBattleStatMask_Gfx, animBgData.tilesOffset);
+ switch (sAnimStatsChangeData->data[1])
+ {
+ case 0:
+ LoadCompressedPalette(gBattleStatMask2_Pal, animBgData.paletteId * 16, 32);
+ break;
+ case 1:
+ LoadCompressedPalette(gBattleStatMask1_Pal, animBgData.paletteId * 16, 32);
+ break;
+ case 2:
+ LoadCompressedPalette(gBattleStatMask3_Pal, animBgData.paletteId * 16, 32);
+ break;
+ case 3:
+ LoadCompressedPalette(gBattleStatMask4_Pal, animBgData.paletteId * 16, 32);
+ break;
+ case 4:
+ LoadCompressedPalette(gBattleStatMask6_Pal, animBgData.paletteId * 16, 32);
+ break;
+ case 5:
+ LoadCompressedPalette(gBattleStatMask7_Pal, animBgData.paletteId * 16, 32);
+ break;
+ case 6:
+ LoadCompressedPalette(gBattleStatMask8_Pal, animBgData.paletteId * 16, 32);
+ break;
+ default:
+ LoadCompressedPalette(gBattleStatMask5_Pal, animBgData.paletteId * 16, 32);
+ break;
+ }
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ if (sAnimStatsChangeData->data[0] == 1)
+ {
+ gBattle_BG1_X = 64;
+ gTasks[taskId].data[1] = -3;
+ }
+ else
+ {
+ gTasks[taskId].data[1] = 3;
+ }
+
+ if (sAnimStatsChangeData->data[4] == 0)
+ {
+ gTasks[taskId].data[4] = 10;
+ gTasks[taskId].data[5] = 20;
+ }
+ else
+ {
+ gTasks[taskId].data[4] = 13;
+ gTasks[taskId].data[5] = 30;
+ }
+ gTasks[taskId].data[0] = spriteId;
+ gTasks[taskId].data[2] = sAnimStatsChangeData->data[3];
+ gTasks[taskId].data[3] = newSpriteId;
+ gTasks[taskId].data[6] = sAnimStatsChangeData->higherPriority;
+ gTasks[taskId].data[7] = gBattlerSpriteIds[sAnimStatsChangeData->battler2];
+ gTasks[taskId].func = sub_80BB4B8;
+ if (sAnimStatsChangeData->data[0] == 0)
+ PlaySE12WithPanning(SE_W287, BattleAnimAdjustPanning2(PAN_SIDE_PLAYER));
+ else
+ PlaySE12WithPanning(SE_W287B, BattleAnimAdjustPanning2(PAN_SIDE_PLAYER));
+}
+
+static void sub_80BB4B8(u8 taskId)
+{
+ gBattle_BG1_Y += gTasks[taskId].data[1];
+ switch (gTasks[taskId].data[15])
+ {
+ case 0:
+ if (gTasks[taskId].data[11]++ > 0)
+ {
+ gTasks[taskId].data[11] = 0;
+ ++gTasks[taskId].data[12];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12]));
+ if (gTasks[taskId].data[12] == gTasks[taskId].data[4])
+ ++gTasks[taskId].data[15];
+ }
+ break;
+ case 1:
+ if (++gTasks[taskId].data[10] == gTasks[taskId].data[5])
+ ++gTasks[taskId].data[15];
+ break;
+ case 2:
+ if (gTasks[taskId].data[11]++ > 0)
+ {
+ gTasks[taskId].data[11] = 0;
+ --gTasks[taskId].data[12];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12]));
+ if (gTasks[taskId].data[12] == 0)
+ {
+ sub_8073128(0);
+ ++gTasks[taskId].data[15];
+ }
+ }
+ break;
+ case 3:
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR
+ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR
+ | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
+ SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroySprite(&gSprites[gTasks[taskId].data[0]]);
+ if (gTasks[taskId].data[2])
+ DestroySprite(&gSprites[gTasks[taskId].data[3]]);
+ if (gTasks[taskId].data[6] == 1)
+ ++gSprites[gTasks[taskId].data[7]].oam.priority;
+ Free(sAnimStatsChangeData);
+ sAnimStatsChangeData = NULL;
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80BB660(u8 taskId)
+{
+ u32 selectedPalettes = sub_8075CB8(1, 1, 1, 1);
+
+ sub_80BB790(selectedPalettes, 0);
+ gTasks[taskId].data[14] = selectedPalettes >> 16;
+ selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0) & 0xFFFF;
+ sub_80BB790(selectedPalettes, 0xFFFF);
+ gTasks[taskId].data[15] = selectedPalettes;
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].func = sub_80BB6CC;
+}
+
+static void sub_80BB6CC(u8 taskId)
+{
+ u16 i;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[1] > 6)
+ {
+ task->data[1] = 0;
+ task->data[2] = 16;
+ ++task->data[0];
+ }
+ break;
+ case 1:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ --task->data[2];
+ for (i = 0; i < 16; ++i)
+ {
+ if ((task->data[15] >> i) & 1)
+ {
+ u16 paletteOffset = i * 16;
+ BlendPalette(paletteOffset, 16, task->data[2], 0xFFFF);
+ }
+
+ if ((task->data[14] >> i) & 1)
+ {
+ u16 paletteOffset = i * 16 + 0x100;
+ BlendPalette(paletteOffset, 16, task->data[2], 0);
+ }
+ }
+
+ if (task->data[2] == 0)
+ ++task->data[0];
+ }
+ break;
+ case 2:
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80BB790(u32 selectedPalettes, u16 color)
+{
+ u16 i, curOffset, paletteOffset;
+
+ for (i = 0; i < 32; selectedPalettes >>= 1, ++i)
+ if (selectedPalettes & 1)
+ for (curOffset = i * 16, paletteOffset = curOffset; curOffset < paletteOffset + 16; ++curOffset)
+ gPlttBufferFaded[curOffset] = color;
+}
+
+void sub_80BB7DC(u8 taskId)
+{
+ s32 j;
+ u32 battler, selectedPalettes = 0;
+
+ for (battler = 0; battler < MAX_BATTLERS_COUNT; ++battler)
+ if (gBattleAnimAttacker != battler)
+ selectedPalettes |= 1 << (battler + 16);
+ for (j = 5; j != 0; --j)
+ gBattleAnimArgs[j] = gBattleAnimArgs[j - 1];
+ StartBlendAnimSpriteColor(taskId, selectedPalettes);
+}
+
+void sub_80BB82C(u8 taskId)
+{
+ u8 newTaskId;
+
+ sub_8075458(0);
+ newTaskId = CreateTask(sub_80BB8A4, 5);
+ if (gBattleAnimArgs[2] && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ }
+ gTasks[newTaskId].data[1] = gBattleAnimArgs[0];
+ gTasks[newTaskId].data[2] = gBattleAnimArgs[1];
+ gTasks[newTaskId].data[3] = gBattleAnimArgs[3];
+ ++gTasks[newTaskId].data[0];
+ DestroyAnimVisualTask(taskId);
+}
+
+static void sub_80BB8A4(u8 taskId)
+{
+ gTasks[taskId].data[10] += gTasks[taskId].data[1];
+ gTasks[taskId].data[11] += gTasks[taskId].data[2];
+ gBattle_BG3_X += gTasks[taskId].data[10] >> 8;
+ gBattle_BG3_Y += gTasks[taskId].data[11] >> 8;
+ gTasks[taskId].data[10] &= 0xFF;
+ gTasks[taskId].data[11] &= 0xFF;
+ if (gBattleAnimArgs[7] == gTasks[taskId].data[3])
+ {
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
+ sub_8075458(1);
+ DestroyTask(taskId);
+ }
+}
+
+void AnimTask_GetAttackerSide(u8 taskId)
+{
+ gBattleAnimArgs[7] = GetBattlerSide(gBattleAnimAttacker);
+ DestroyAnimVisualTask(taskId);
+}
+
+void AnimTask_GetTargetSide(u8 taskId)
+{
+ gBattleAnimArgs[7] = GetBattlerSide(gBattleAnimTarget);
+ DestroyAnimVisualTask(taskId);
+}
+
+void AnimTask_GetTargetIsAttackerPartner(u8 taskId)
+{
+ gBattleAnimArgs[7] = BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget;
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BB9B0(u8 taskId)
+{
+ u16 battler;
+
+ for (battler = 0; battler < MAX_BATTLERS_COUNT; ++battler)
+ if (battler != gBattleAnimAttacker && IsBattlerSpriteVisible(battler))
+ gSprites[gBattlerSpriteIds[battler]].invisible = gBattleAnimArgs[0];
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BBA20(u8 taskId, s32 unused, u16 arg2, u8 battler1, u8 arg4, u8 arg5, u8 arg6, u8 arg7, const u32 *gfx, const u32 *tilemap, const u32 *palette)
+{
+ u16 species;
+ u8 spriteId, newSpriteId = 0;
+ u16 bg1Cnt;
+ struct BattleAnimBgData animBgData;
+ u8 battler2 = BATTLE_PARTNER(battler1);
+
+ if (IsContest() || (arg4 && !IsBattlerSpriteVisible(battler2)))
+ arg4 = 0;
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR
+ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR
+ | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
+ bg1Cnt = GetGpuReg(REG_OFFSET_BG1CNT);
+ ((vBgCnt *)&bg1Cnt)->priority = 0;
+ ((vBgCnt *)&bg1Cnt)->screenSize = 0;
+ ((vBgCnt *)&bg1Cnt)->areaOverflowMode = 1;
+ if (!IsContest())
+ ((vBgCnt *)&bg1Cnt)->charBaseBlock = 1;
+ SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt);
+ if (GetBattlerSide(battler1) != B_SIDE_PLAYER)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler1]], MON_DATA_SPECIES);
+ else
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler1]], MON_DATA_SPECIES);
+ spriteId = sub_8076E34(battler1, gBattlerSpriteIds[battler1], species);
+ if (arg4)
+ newSpriteId = sub_8076E34(battler2, gBattlerSpriteIds[battler2], species);
+ sub_80752A0(&animBgData);
+ AnimLoadCompressedBgTilemap(animBgData.bgId, tilemap);
+ if (IsContest())
+ sub_80730C0(animBgData.paletteId, animBgData.bgTilemap, 0, 0);
+ AnimLoadCompressedBgGfx(animBgData.bgId, gfx, animBgData.tilesOffset);
+ LoadCompressedPalette(palette, animBgData.paletteId * 16, 32);
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ gTasks[taskId].data[1] = arg2;
+ gTasks[taskId].data[4] = arg5;
+ gTasks[taskId].data[5] = arg7;
+ gTasks[taskId].data[6] = arg6;
+ gTasks[taskId].data[0] = spriteId;
+ gTasks[taskId].data[2] = arg4;
+ gTasks[taskId].data[3] = newSpriteId;
+ gTasks[taskId].func = sub_80BBC2C;
+}
+
+static void sub_80BBC2C(u8 taskId)
+{
+ gTasks[taskId].data[13] += gTasks[taskId].data[1] < 0 ? -gTasks[taskId].data[1] : gTasks[taskId].data[1];
+ if (gTasks[taskId].data[1] < 0)
+ gBattle_BG1_Y -= gTasks[taskId].data[13] >> 8;
+ else
+ gBattle_BG1_Y += gTasks[taskId].data[13] >> 8;
+ gTasks[taskId].data[13] &= 0xFF;
+ switch (gTasks[taskId].data[15])
+ {
+ case 0:
+ if (gTasks[taskId].data[11]++ >= gTasks[taskId].data[6])
+ {
+ gTasks[taskId].data[11] = 0;
+ ++gTasks[taskId].data[12];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12]));
+ if (gTasks[taskId].data[12] == gTasks[taskId].data[4])
+ ++gTasks[taskId].data[15];
+ }
+ break;
+ case 1:
+ if (++gTasks[taskId].data[10] == gTasks[taskId].data[5])
+ ++gTasks[taskId].data[15];
+ break;
+ case 2:
+ if (gTasks[taskId].data[11]++ >= gTasks[taskId].data[6])
+ {
+ gTasks[taskId].data[11] = 0;
+ --gTasks[taskId].data[12];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12]));
+ if (gTasks[taskId].data[12] == 0)
+ {
+ sub_8073128(0);
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR
+ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR
+ | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
+ if (!IsContest())
+ {
+ u16 bg1Cnt = GetGpuReg(REG_OFFSET_BG1CNT);
+ ((vBgCnt *)&bg1Cnt)->charBaseBlock = 0;
+ SetGpuReg(REG_OFFSET_BG1CNT, bg1Cnt);
+ }
+ SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroySprite(&gSprites[gTasks[taskId].data[0]]);
+ if (gTasks[taskId].data[2])
+ DestroySprite(&gSprites[gTasks[taskId].data[3]]);
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ break;
+ }
+}
+
+void AnimTask_GetBattleTerrain(u8 taskId)
+{
+ gBattleAnimArgs[0] = gBattleTerrain;
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BBE10(u8 taskId)
+{
+ gMonSpritesGfxPtr->field_17C = AllocZeroed(0x2000);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BBE3C(u8 taskId)
+{
+ FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_17C);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BBE6C(u8 taskId)
+{
+ u32 selectedPalettes;
+ s32 paletteIndex = 0;
+
+ if (gBattleAnimArgs[0] == 0)
+ for (selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0);
+ (selectedPalettes & 1) == 0;
+ ++paletteIndex)
+ selectedPalettes >>= 1;
+ else if (gBattleAnimArgs[0] == 1)
+ paletteIndex = gBattleAnimAttacker + 16;
+ else if (gBattleAnimArgs[0] == 2)
+ paletteIndex = gBattleAnimTarget + 16;
+ memcpy(&gMonSpritesGfxPtr->field_17C[gBattleAnimArgs[1] * 16], &gPlttBufferUnfaded[paletteIndex * 16], 32);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BBF08(u8 taskId)
+{
+ u32 selectedPalettes;
+ s32 paletteIndex = 0;
+
+ if (gBattleAnimArgs[0] == 0)
+ for (selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0);
+ (selectedPalettes & 1) == 0;
+ ++paletteIndex)
+ selectedPalettes >>= 1;
+ else if (gBattleAnimArgs[0] == 1)
+ paletteIndex = gBattleAnimAttacker + 16;
+ else if (gBattleAnimArgs[0] == 2)
+ paletteIndex = gBattleAnimTarget + 16;
+ memcpy(&gPlttBufferUnfaded[paletteIndex * 16], &gMonSpritesGfxPtr->field_17C[gBattleAnimArgs[1] * 16], 32);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BBFA4(u8 taskId)
+{
+ u32 selectedPalettes;
+ s32 paletteIndex = 0;
+
+ if (gBattleAnimArgs[0] == 0)
+ for (selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0);
+ (selectedPalettes & 1) == 0;
+ ++paletteIndex)
+ selectedPalettes >>= 1;
+ else if (gBattleAnimArgs[0] == 1)
+ paletteIndex = gBattleAnimAttacker + 16;
+ else if (gBattleAnimArgs[0] == 2)
+ paletteIndex = gBattleAnimTarget + 16;
+ memcpy(&gPlttBufferUnfaded[paletteIndex * 16], &gPlttBufferFaded[paletteIndex * 16], 32);
+ DestroyAnimVisualTask(taskId);
+}
+
+void AnimTask_IsContest(u8 taskId)
+{
+ if (IsContest())
+ gBattleAnimArgs[7] = 1;
+ else
+ gBattleAnimArgs[7] = 0;
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BC060(u8 taskId)
+{
+ gBattleAnimAttacker = gBattlerTarget;
+ gBattleAnimTarget = gEffectBattler;
+ DestroyAnimVisualTask(taskId);
+}
+
+void AnimTask_IsTargetSameSide(u8 taskId)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget))
+ gBattleAnimArgs[7] = 1;
+ else
+ gBattleAnimArgs[7] = 0;
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BC0DC(u8 taskId)
+{
+ gBattleAnimTarget = gBattlerTarget;
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BC0FC(u8 taskId)
+{
+ gBattleAnimAttacker = gBattlerAttacker;
+ gBattleAnimTarget = gEffectBattler;
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80BC12C(u8 taskId)
+{
+ if (IsContest())
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+ else
+ {
+ gTasks[taskId].data[0] = gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].invisible;
+ gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].invisible = 1;
+ gTasks[taskId].func = sub_80BC19C;
+ --gAnimVisualTaskCount;
+ }
+}
+
+static void sub_80BC19C(u8 taskId)
+{
+ if (gBattleAnimArgs[7] == 0x1000)
+ {
+ gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].invisible = (u8)gTasks[taskId].data[0] & 1;
+ DestroyTask(taskId);
+ }
+}
diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c
index 0d827c8db..a9bb5bc6e 100644
--- a/src/battle_controller_player.c
+++ b/src/battle_controller_player.c
@@ -1191,7 +1191,7 @@ static void sub_80303A8(u8 taskId)
{
s16 *data = gTasks[taskId].data;
u8 battlerId = tExpTask_battler;
- u16 v5 = sub_80768B0(battlerId);
+ u16 v5 = GetBattlerSpriteBGPriorityRank(battlerId);
bool32 v6 = ((v5 ^ BIT_SIDE)) != B_SIDE_PLAYER;
struct Sprite *sprite = &gSprites[gBattlerSpriteIds[battlerId]];
@@ -1222,7 +1222,7 @@ static void sub_80303A8(u8 taskId)
u32 battlerIdAlt = battlerId;
bool32 v6Alt = v6;
- sub_8072E48(battlerIdAlt, v6Alt);
+ MoveBattlerSpriteToBG(battlerIdAlt, v6Alt);
}
++data[15];
break;
diff --git a/src/battle_intro.c b/src/battle_intro.c
new file mode 100644
index 000000000..93141f2ca
--- /dev/null
+++ b/src/battle_intro.c
@@ -0,0 +1,495 @@
+#include "global.h"
+#include "battle.h"
+#include "battle_anim.h"
+#include "battle_setup.h"
+#include "bg.h"
+#include "gpu_regs.h"
+#include "main.h"
+#include "scanline_effect.h"
+#include "task.h"
+#include "trig.h"
+#include "constants/trainers.h"
+
+static EWRAM_DATA u16 sBgCnt = 0;
+
+extern const u8 gUnknown_83E7CCA[];
+extern const u8 gUnknown_83E7CCE[];
+
+static void BattleIntroSlide1(u8 taskId);
+static void BattleIntroSlide2(u8 taskId);
+static void BattleIntroSlide3(u8 taskId);
+static void BattleIntroSlideLink(u8 taskId);
+
+static const TaskFunc sBattleIntroSlideFuncs[] =
+{
+ BattleIntroSlide1, // BATTLE_TERRAIN_GRASS
+ BattleIntroSlide1, // BATTLE_TERRAIN_LONG_GRASS
+ BattleIntroSlide2, // BATTLE_TERRAIN_SAND
+ BattleIntroSlide2, // BATTLE_TERRAIN_UNDERWATER
+ BattleIntroSlide2, // BATTLE_TERRAIN_WATER
+ BattleIntroSlide1, // BATTLE_TERRAIN_POND
+ BattleIntroSlide1, // BATTLE_TERRAIN_MOUNTAIN
+ BattleIntroSlide1, // BATTLE_TERRAIN_CAVE
+ BattleIntroSlide3, // BATTLE_TERRAIN_BUILDING
+ BattleIntroSlide3, // BATTLE_TERRAIN_PLAIN
+};
+
+void SetAnimBgAttribute(u8 bgId, u8 attributeId, u8 value)
+{
+ if (bgId < 4)
+ {
+ sBgCnt = GetGpuReg(gUnknown_83E7CCA[bgId]);
+ switch (attributeId)
+ {
+ case BG_ANIM_SCREEN_SIZE:
+ ((struct BgCnt *)&sBgCnt)->screenSize = value;
+ break;
+ case BG_ANIM_AREA_OVERFLOW_MODE:
+ ((struct BgCnt *)&sBgCnt)->areaOverflowMode = value;
+ break;
+ case BG_ANIM_MOSAIC:
+ ((struct BgCnt *)&sBgCnt)->mosaic = value;
+ break;
+ case BG_ANIM_CHAR_BASE_BLOCK:
+ ((struct BgCnt *)&sBgCnt)->charBaseBlock = value;
+ break;
+ case BG_ANIM_PRIORITY:
+ ((struct BgCnt *)&sBgCnt)->priority = value;
+ break;
+ case BG_ANIM_PALETTES_MODE:
+ ((struct BgCnt *)&sBgCnt)->palettes = value;
+ break;
+ case BG_ANIM_SCREEN_BASE_BLOCK:
+ ((struct BgCnt *)&sBgCnt)->screenBaseBlock = value;
+ break;
+ }
+ SetGpuReg(gUnknown_83E7CCA[bgId], sBgCnt);
+ }
+}
+
+s32 GetAnimBgAttribute(u8 bgId, u8 attributeId)
+{
+ u16 bgCnt;
+
+ if (bgId < 4)
+ {
+ bgCnt = GetGpuReg(gUnknown_83E7CCE[bgId]);
+ switch (attributeId)
+ {
+ case BG_ANIM_SCREEN_SIZE:
+ return ((struct BgCnt *)&bgCnt)->screenSize;
+ case BG_ANIM_AREA_OVERFLOW_MODE:
+ return ((struct BgCnt *)&bgCnt)->areaOverflowMode;
+ case BG_ANIM_MOSAIC:
+ return ((struct BgCnt *)&bgCnt)->mosaic;
+ case BG_ANIM_CHAR_BASE_BLOCK:
+ return ((struct BgCnt *)&bgCnt)->charBaseBlock;
+ case BG_ANIM_PRIORITY:
+ return ((struct BgCnt *)&bgCnt)->priority;
+ case BG_ANIM_PALETTES_MODE:
+ return ((struct BgCnt *)&bgCnt)->palettes;
+ case BG_ANIM_SCREEN_BASE_BLOCK:
+ return ((struct BgCnt *)&bgCnt)->screenBaseBlock;
+ }
+ }
+ return 0;
+}
+
+void HandleIntroSlide(u8 terrain)
+{
+ u8 taskId;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ taskId = CreateTask(BattleIntroSlideLink, 0);
+ }
+ else if ((gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) && gGameVersion != VERSION_RUBY)
+ {
+ terrain = BATTLE_TERRAIN_UNDERWATER;
+ taskId = CreateTask(BattleIntroSlide2, 0);
+ }
+ else
+ {
+ taskId = CreateTask(sBattleIntroSlideFuncs[terrain], 0);
+ }
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = terrain;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].data[4] = 0;
+ gTasks[taskId].data[5] = 0;
+ gTasks[taskId].data[6] = 0;
+}
+
+void sub_80BC41C(u8 taskId)
+{
+ DestroyTask(taskId);
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ gBattle_BG2_X = 0;
+ gBattle_BG2_Y = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
+}
+
+static void BattleIntroSlide1(u8 taskId)
+{
+ s32 i;
+
+ gBattle_BG1_X += 6;
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ gTasks[taskId].data[2] = 16;
+ ++gTasks[taskId].data[0];
+ }
+ else
+ {
+ gTasks[taskId].data[2] = 1;
+ ++gTasks[taskId].data[0];
+ }
+ break;
+ case 1:
+ if (--gTasks[taskId].data[2] == 0)
+ {
+ ++gTasks[taskId].data[0];
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
+ }
+ break;
+ case 2:
+ gBattle_WIN0V -= 0xFF;
+ if ((gBattle_WIN0V & 0xFF00) == 0x3000)
+ {
+ ++gTasks[taskId].data[0];
+ gTasks[taskId].data[2] = 240;
+ gTasks[taskId].data[3] = 32;
+ gIntroSlideFlags &= ~1;
+ }
+ break;
+ case 3:
+ if (gTasks[taskId].data[3])
+ {
+ --gTasks[taskId].data[3];
+ }
+ else
+ {
+ if (gTasks[taskId].data[1] == 1)
+ {
+ if (gBattle_BG1_Y != 0xFFB0)
+ gBattle_BG1_Y -= 2;
+ }
+ else if (gBattle_BG1_Y != 0xFFC8)
+ {
+ gBattle_BG1_Y -= 1;
+ }
+ }
+ if (gBattle_WIN0V & 0xFF00)
+ gBattle_WIN0V -= 0x3FC;
+ if (gTasks[taskId].data[2])
+ gTasks[taskId].data[2] -= 2;
+ // Scanline settings have already been set in CB2_InitBattleInternal
+ for (i = 0; i < 80; ++i)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].data[2];
+ while (i < 160)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i++] = -gTasks[taskId].data[2];
+ if (!gTasks[taskId].data[2])
+ {
+ gScanlineEffect.state = 3;
+ ++gTasks[taskId].data[0];
+ CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE);
+ SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0);
+ SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256);
+ }
+ break;
+ case 4:
+ sub_80BC41C(taskId);
+ break;
+ }
+}
+
+static void BattleIntroSlide2(u8 taskId)
+{
+ s32 i;
+
+ switch (gTasks[taskId].data[1])
+ {
+ case 2:
+ case 4:
+ gBattle_BG1_X += 8;
+ break;
+ case 3:
+ gBattle_BG1_X += 6;
+ break;
+ }
+ if (gTasks[taskId].data[1] == 4)
+ {
+ gBattle_BG1_Y = Cos2(gTasks[taskId].data[6]) / 512 - 8;
+ if (gTasks[taskId].data[6] < 180)
+ gTasks[taskId].data[6] += 4;
+ else
+ gTasks[taskId].data[6] += 6;
+ if (gTasks[taskId].data[6] == 360)
+ gTasks[taskId].data[6] = 0;
+ }
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ gTasks[taskId].data[4] = 16;
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ gTasks[taskId].data[2] = 16;
+ ++gTasks[taskId].data[0];
+ }
+ else
+ {
+ gTasks[taskId].data[2] = 1;
+ ++gTasks[taskId].data[0];
+ }
+ break;
+ case 1:
+ if (--gTasks[taskId].data[2] == 0)
+ {
+ ++gTasks[taskId].data[0];
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
+ }
+ break;
+ case 2:
+ gBattle_WIN0V -= 0xFF;
+ if ((gBattle_WIN0V & 0xFF00) == 0x3000)
+ {
+ ++gTasks[taskId].data[0];
+ gTasks[taskId].data[2] = 240;
+ gTasks[taskId].data[3] = 32;
+ gTasks[taskId].data[5] = 1;
+ gIntroSlideFlags &= ~1;
+ }
+ break;
+ case 3:
+ if (gTasks[taskId].data[3])
+ {
+ if (--gTasks[taskId].data[3] == 0)
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(15, 0));
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ }
+ }
+ else if ((gTasks[taskId].data[4] & 0x1F) && --gTasks[taskId].data[5] == 0)
+ {
+ gTasks[taskId].data[4] += 0xFF;
+ gTasks[taskId].data[5] = 4;
+ }
+ if (gBattle_WIN0V & 0xFF00)
+ gBattle_WIN0V -= 0x3FC;
+
+ if (gTasks[taskId].data[2])
+ gTasks[taskId].data[2] -= 2;
+ // Scanline settings have already been set in CB2_InitBattleInternal()
+ for (i = 0; i < 80; ++i)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].data[2];
+ while (i < 160)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i++] = -gTasks[taskId].data[2];
+ if (!gTasks[taskId].data[2])
+ {
+ gScanlineEffect.state = 3;
+ ++gTasks[taskId].data[0];
+ CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE);
+ SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0);
+ SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256);
+ }
+ break;
+ case 4:
+ sub_80BC41C(taskId);
+ break;
+ }
+ if (gTasks[taskId].data[0] != 4)
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[4], 0));
+}
+
+static void BattleIntroSlide3(u8 taskId)
+{
+ s32 i;
+
+ gBattle_BG1_X += 8;
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 8));
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ gTasks[taskId].data[4] = BLDALPHA_BLEND(8, 8);
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ gTasks[taskId].data[2] = 16;
+ ++gTasks[taskId].data[0];
+ }
+ else
+ {
+ gTasks[taskId].data[2] = 1;
+ ++gTasks[taskId].data[0];
+ }
+ break;
+ case 1:
+ if (--gTasks[taskId].data[2] == 0)
+ {
+ ++gTasks[taskId].data[0];
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
+ }
+ break;
+ case 2:
+ gBattle_WIN0V -= 0xFF;
+ if ((gBattle_WIN0V & 0xFF00) == 0x3000)
+ {
+ ++gTasks[taskId].data[0];
+ gTasks[taskId].data[2] = 240;
+ gTasks[taskId].data[3] = 32;
+ gTasks[taskId].data[5] = 1;
+ gIntroSlideFlags &= ~1;
+ }
+ break;
+ case 3:
+ if (gTasks[taskId].data[3])
+ {
+ --gTasks[taskId].data[3];
+ }
+ else if ((gTasks[taskId].data[4] & 0xF) && --gTasks[taskId].data[5] == 0)
+ {
+ gTasks[taskId].data[4] += 0xFF;
+ gTasks[taskId].data[5] = 6;
+ }
+ if (gBattle_WIN0V & 0xFF00)
+ gBattle_WIN0V -= 0x3FC;
+ if (gTasks[taskId].data[2])
+ gTasks[taskId].data[2] -= 2;
+ // Scanline settings have already been set in CB2_InitBattleInternal()
+ for (i = 0; i < 80; ++i)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].data[2];
+ while (i < 160)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i++] = -gTasks[taskId].data[2];
+ if (!gTasks[taskId].data[2])
+ {
+ gScanlineEffect.state = 3;
+ ++gTasks[taskId].data[0];
+ CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE);
+ SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0);
+ SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256);
+ }
+ break;
+ case 4:
+ sub_80BC41C(taskId);
+ break;
+ }
+ if (gTasks[taskId].data[0] != 4)
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[4], 0));
+}
+
+static void BattleIntroSlideLink(u8 taskId)
+{
+ s32 i;
+
+ if (gTasks[taskId].data[0] > 1 && !gTasks[taskId].data[4])
+ {
+ u16 var0 = gBattle_BG1_X & 0x8000;
+
+ if (var0 || gBattle_BG1_X < 80)
+ {
+ gBattle_BG1_X += 3;
+ gBattle_BG2_X -= 3;
+ }
+ else
+ {
+ CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE);
+ CpuFill32(0, (void *)BG_SCREEN_ADDR(30), BG_SCREEN_SIZE);
+ gTasks[taskId].data[4] = 1;
+ }
+ }
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ gTasks[taskId].data[2] = 32;
+ ++gTasks[taskId].data[0];
+ break;
+ case 1:
+ if (--gTasks[taskId].data[2] == 0)
+ {
+ ++gTasks[taskId].data[0];
+ gSprites[gBattleStruct->linkBattleVsSpriteId_V].oam.objMode = ST_OAM_OBJ_WINDOW;
+ gSprites[gBattleStruct->linkBattleVsSpriteId_V].callback = sub_801182C;
+ gSprites[gBattleStruct->linkBattleVsSpriteId_S].oam.objMode = ST_OAM_OBJ_WINDOW;
+ gSprites[gBattleStruct->linkBattleVsSpriteId_S].callback = sub_801182C;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2);
+ }
+ break;
+ case 2:
+ gBattle_WIN0V -= 0xFF;
+ if ((gBattle_WIN0V & 0xFF00) == 0x3000)
+ {
+ ++gTasks[taskId].data[0];
+ gTasks[taskId].data[2] = 240;
+ gTasks[taskId].data[3] = 32;
+ gIntroSlideFlags &= ~1;
+ }
+ break;
+ case 3:
+ if (gBattle_WIN0V & 0xFF00)
+ gBattle_WIN0V -= 0x3FC;
+ if (gTasks[taskId].data[2])
+ gTasks[taskId].data[2] -= 2;
+ // Scanline settings have already been set in CB2_InitBattleInternal()
+ for (i = 0; i < 80; ++i)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].data[2];
+ while (i < 160)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i++] = -gTasks[taskId].data[2];
+ if (!gTasks[taskId].data[2])
+ {
+ gScanlineEffect.state = 3;
+ ++gTasks[taskId].data[0];
+ SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0);
+ SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256);
+ }
+ break;
+ case 4:
+ sub_80BC41C(taskId);
+ break;
+ }
+}
+
+void sub_80BCEF4(s32 bgId, u8 arg1, u8 arg2, u8 battlerPosition, u8 arg4, u8 *arg5, u16 *arg6, u16 tilesOffset)
+{
+ s32 i, j;
+ u8 battler = GetBattlerAtPosition(battlerPosition);
+ s32 offset = tilesOffset;
+
+ CpuCopy16(gMonSpritesGfxPtr->sprites[battlerPosition] + BG_SCREEN_SIZE * gBattleMonForms[battler], arg5, BG_SCREEN_SIZE);
+ LoadBgTiles(bgId, arg5, 0x1000, tilesOffset);
+ for (i = arg2; i < arg2 + 8; ++i)
+ for (j = arg1; j < arg1 + 8; ++j)
+ arg6[i * 32 + j] = offset++ | (arg4 << 12);
+ LoadBgTilemap(bgId, arg6, BG_SCREEN_SIZE, 0);
+}
+
+// not used
+static void sub_80BCFCC(u8 arg0, u8 arg1, u8 battlerPosition, u8 arg3, u8 arg4, u16 arg5, u8 arg6, u8 arg7)
+{
+ s32 i, j, offset;
+
+ DmaCopy16(3, gMonSpritesGfxPtr->sprites[battlerPosition] + BG_SCREEN_SIZE * arg3, (void *)BG_SCREEN_ADDR(0) + arg5, BG_SCREEN_SIZE);
+ offset = (arg5 >> 5) - (arg7 << 9);
+ for (i = arg1; i < arg1 + 8; ++i)
+ for (j = arg0; j < arg0 + 8; ++j)
+ *((u16 *)(BG_VRAM) + (i * 32) + (j + (arg6 << 10))) = offset++ | (arg4 << 12);
+}
diff --git a/src/battle_transition.c b/src/battle_transition.c
index d391b3ed4..19d76fed1 100644
--- a/src/battle_transition.c
+++ b/src/battle_transition.c
@@ -857,14 +857,14 @@ static bool8 BT_Phase2BigPokeball_Init(struct Task *task)
task->tEva = 0;
task-> tTheta = 0;
task-> tAmplitude = 0x4000;
- sTransitionStructPtr->winIn = 0x3F;
+ sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
sTransitionStructPtr->winOut = 0;
- sTransitionStructPtr->win0H = 240;
- sTransitionStructPtr->win0V = 160;
+ sTransitionStructPtr->win0H = WIN_RANGE(0, 0xF0);
+ sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD;
sTransitionStructPtr->bldAlpha = (task->tEvb << 8) | task->tEva;
for (i = 0; i < 160; ++i)
- gScanlineEffectRegBuffers[1][i] = 240;
+ gScanlineEffectRegBuffers[1][i] = 0xF0;
SetVBlankCallback(VBCB_BT_Phase2BigPokeball1);
BT_GetBg0TilemapAndTilesetBase(&tilemapAddr, &tilesetAddr);
CpuFill16(0, tilemapAddr, 0x800);
@@ -897,7 +897,7 @@ static bool8 BT_Phase2BigPokeball_UpdateWave1IncEva(struct Task *task)
++task->tEva;
task->tInterval = 1; // Broken logic. This makes the condition always TRUE.
}
- sTransitionStructPtr->bldAlpha = (task->tEvb << 8) | task->tEva;
+ sTransitionStructPtr->bldAlpha = BLDALPHA_BLEND(task->tEva, task->tEvb);
// Increment eva until it reaches 50% coeff
if (task->tEva > 15)
++task->tState;
@@ -1148,13 +1148,11 @@ static bool8 BT_Phase2ClockwiseBlackFade_Init(struct Task *task)
BT_InitCtrlBlk();
ScanlineEffect_Clear();
sTransitionStructPtr->winIn = 0;
- sTransitionStructPtr->winOut = 0x3F;
- sTransitionStructPtr->win0H = 0xF0F1;
- sTransitionStructPtr->win0V = 0x00A0;
+ sTransitionStructPtr->winOut = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR;
+ sTransitionStructPtr->win0H = WIN_RANGE(0xF0, 0xF1);
+ sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
for (i = 0; i < 160; ++i)
- {
- gScanlineEffectRegBuffers[1][i] = 0xF3F4;
- }
+ gScanlineEffectRegBuffers[1][i] = WIN_RANGE(0xF3, 0xF4);
SetVBlankCallback(VBCB_BT_Phase2ClockwiseBlackFade);
sTransitionStructPtr->trEndPtX = 120;
++task->tState;
@@ -1167,7 +1165,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step1(struct Task *task)
BT_DiagonalSegment_InitParams(sTransitionStructPtr->data, 120, 80, sTransitionStructPtr->trEndPtX, -1, 1, 1);
do
{
- gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = (sTransitionStructPtr->trCurrentPtX + 1) | 0x7800;
+ gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE(0x78, sTransitionStructPtr->trCurrentPtX + 1);
}
while (!BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE));
@@ -1197,7 +1195,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step2(struct Task *task)
left = sTransitionStructPtr->trCurrentPtX;
right = 240;
}
- gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = right | (left << 8);
+ gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
if (finished)
break;
finished = BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE);
@@ -1211,7 +1209,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step2(struct Task *task)
else
{
while (sTransitionStructPtr->trCurrentPtY < sTransitionStructPtr->trEndPtY)
- gScanlineEffectRegBuffers[0][++sTransitionStructPtr->trCurrentPtY] = right | (left << 8);
+ gScanlineEffectRegBuffers[0][++sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
}
++sTransitionStructPtr->vblankDma;
return FALSE;
@@ -1265,7 +1263,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step4(struct Task *task)
left = 120;
right = sTransitionStructPtr->trCurrentPtX;
}
- win0H = right | (left << 8);
+ win0H = WIN_RANGE2(left, right);
gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = win0H;
if (finished)
break;
@@ -1280,7 +1278,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step4(struct Task *task)
else
{
while (sTransitionStructPtr->trCurrentPtY > sTransitionStructPtr->trEndPtY)
- gScanlineEffectRegBuffers[0][--sTransitionStructPtr->trCurrentPtY] = right | (left << 8);
+ gScanlineEffectRegBuffers[0][--sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
}
++sTransitionStructPtr->vblankDma;
return FALSE;
@@ -1301,7 +1299,7 @@ static bool8 BT_Phase2ClockwiseBlackFade_Step5(struct Task *task)
left = 0;
right = 240;
}
- gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = right | (left << 8);
+ gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
}
while (!BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE));
sTransitionStructPtr->trEndPtX += 32;
@@ -1431,12 +1429,12 @@ static bool8 BT_Phase2BlackWaveToRight_Init(struct Task *task)
BT_InitCtrlBlk();
ScanlineEffect_Clear();
- sTransitionStructPtr->winIn = 0x3F;
+ sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
sTransitionStructPtr->winOut = 0;
- sTransitionStructPtr->win0H = 240;
- sTransitionStructPtr->win0V = 160;
+ sTransitionStructPtr->win0H = WIN_RANGE(0, 0xF0);
+ sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
for (i = 0; i < 160; ++i)
- gScanlineEffectRegBuffers[1][i] = 242;
+ gScanlineEffectRegBuffers[1][i] = WIN_RANGE(0, 0xF2);
SetVBlankCallback(VBCB_BT_Phase2BlackWaveToRight);
++task->tState;
return TRUE;
@@ -1460,7 +1458,7 @@ static bool8 BT_Phase2BlackWaveToRight_UpdateWave(struct Task *task)
left = 0;
if (left > 240)
left = 240;
- *winVal = (left << 8) | (0xF1);
+ *winVal = WIN_RANGE(left, 0xF1);
if (left < 240)
nextFunc = FALSE;
}
@@ -2529,10 +2527,10 @@ static bool8 BT_Phase2AntiClockwiseSpiral_Init(struct Task *task)
BT_InitCtrlBlk();
ScanlineEffect_Clear();
sTransitionStructPtr->winIn = 0;
- sTransitionStructPtr->winOut = 0x3F;
- sTransitionStructPtr->win0H = 0x7878;
- sTransitionStructPtr->win0V = 0x3070;
- sTransitionStructPtr->win1V = 0x1090;
+ sTransitionStructPtr->winOut = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
+ sTransitionStructPtr->win0H = WIN_RANGE(0x78, 0x78);
+ sTransitionStructPtr->win0V = WIN_RANGE(0x30, 0x70);
+ sTransitionStructPtr->win1V = WIN_RANGE(0x10, 0x90);
sTransitionStructPtr->counter = 0;
sub_80D1F64(0, 0, FALSE);
sub_80D1F64(0, 0, TRUE);
@@ -2665,11 +2663,11 @@ static bool8 BT_Phase2Mugshot_Init(struct Task *task)
task->tTheta = 0;
task->tbg0HOfsOpponent = 1;
task->tbg0HOfsPlayer = 239;
- sTransitionStructPtr->winIn = 0x3F;
- sTransitionStructPtr->winOut = 0x3E;
- sTransitionStructPtr->win0V = 160;
+ sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
+ sTransitionStructPtr->winOut = WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3 | WININ_WIN0_OBJ | WININ_WIN0_CLR;
+ sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
for (i = 0; i < 160; ++i)
- gScanlineEffectRegBuffers[1][i] = 0xF0F1;
+ gScanlineEffectRegBuffers[1][i] = WIN_RANGE(0xF0, 0xF1);
SetVBlankCallback(VBCB_BT_Phase2Mugshot1_Slide);
++task->tState;
return FALSE;
@@ -2784,7 +2782,7 @@ static bool8 BT_Phase2Mugshot_WaitForPlayerInPlace(struct Task *task)
DmaStop(0);
memset(gScanlineEffectRegBuffers[0], 0, 320);
memset(gScanlineEffectRegBuffers[1], 0, 320);
- SetGpuReg(REG_OFFSET_WIN0H, 0xF0);
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, 0xF0));
SetGpuReg(REG_OFFSET_BLDY, 0);
++task->tState;
task->tCounter = 0;
@@ -3026,9 +3024,9 @@ static bool8 BT_Phase2SlicedScreen_Init(struct Task *task)
ScanlineEffect_Clear();
task->tAcc = 256;
task->tJerk = 1;
- sTransitionStructPtr->winIn = 0x3F;
+ sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
sTransitionStructPtr->winOut = 0;
- sTransitionStructPtr->win0V = 160;
+ sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
for (i = 0; i < 160; ++i)
{
gScanlineEffectRegBuffers[1][i] = sTransitionStructPtr->bg123HOfs;
@@ -3065,7 +3063,7 @@ static bool8 BT_Phase2SlicedScreen_UpdateOffsets(struct Task *task)
else
{
*ofsBuffer = sTransitionStructPtr->bg123HOfs - task->tSpeed;
- *win0HBuffer = (task->tSpeed << 8) | 0xF1;
+ *win0HBuffer = WIN_RANGE(task->tSpeed, 0xF1);
}
}
if (task->tSpeed > 0xEF)
@@ -3126,9 +3124,9 @@ static bool8 BT_Phase2WhiteFadeInStripes_Init(struct Task *task)
ScanlineEffect_Clear();
sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_LIGHTEN;
sTransitionStructPtr->bldY = 0;
- sTransitionStructPtr->winIn = 0x1E;
- sTransitionStructPtr->winOut = 0x3F;
- sTransitionStructPtr->win0V = 160;
+ sTransitionStructPtr->winIn = WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ;
+ sTransitionStructPtr->winOut = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WININ_WIN0_CLR;
+ sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
for (i = 0; i < 160; ++i)
{
gScanlineEffectRegBuffers[1][i] = 0;
@@ -3180,7 +3178,7 @@ static bool8 BT_Phase2WhiteFadeInStripes_Stop(struct Task *task)
sTransitionStructPtr->win0H = 240;
sTransitionStructPtr->bldY = 0;
sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN;
- sTransitionStructPtr->winIn = 0x3F;
+ sTransitionStructPtr->winIn = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WININ_WIN0_CLR;
sTransitionStructPtr->counter = 0;
SetVBlankCallback(VBCB_BT_Phase2WhiteFadeInStripes2);
++task->tState;
@@ -3351,11 +3349,11 @@ static bool8 BT_Phase2BlackDoodles_Init(struct Task *task)
BT_InitCtrlBlk();
ScanlineEffect_Clear();
- sTransitionStructPtr->winIn = 0x3F;
+ sTransitionStructPtr->winIn = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR;
sTransitionStructPtr->winOut = 0;
- sTransitionStructPtr->win0V = 0xA0;
+ sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
for (i = 0; i < 160; ++i)
- gScanlineEffectRegBuffers[0][i] = 0x00F0;
+ gScanlineEffectRegBuffers[0][i] = WIN_RANGE(0, 0xF0);
CpuSet(gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 160);
SetVBlankCallback(VBCB_BT_Phase2BlackDoodles);
++task->tState;
@@ -3394,7 +3392,7 @@ static bool8 BT_Phase2BlackDoodles_DrawSingleBrush(struct Task *task)
if (right <= left)
right = left;
}
- gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = right | (left << 8);
+ gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
if (nextFunc)
{
++task->tState;
diff --git a/src/bg.c b/src/bg.c
index 33a462707..4ad2bebd6 100644
--- a/src/bg.c
+++ b/src/bg.c
@@ -356,7 +356,6 @@ void ResetBgsAndClearDma3BusyFlags(bool32 enableWindowTileAutoAlloc)
}
}
-#ifdef NONMATCHING
void InitBgsFromTemplates(u8 bgMode, const struct BgTemplate *templates, u8 numTemplates)
{
int i;
@@ -390,121 +389,6 @@ void InitBgsFromTemplates(u8 bgMode, const struct BgTemplate *templates, u8 numT
}
}
}
-#else
-NAKED
-void InitBgsFromTemplates(u8 bgMode, const struct BgTemplate *templates, u8 numTemplates)
-{
- asm(".syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r10\n\
- mov r6, r9\n\
- mov r5, r8\n\
- push {r5-r7}\n\
- sub sp, 0x10\n\
- adds r5, r1, 0\n\
- lsls r0, 24\n\
- lsrs r0, 24\n\
- lsls r2, 24\n\
- lsrs r4, r2, 24\n\
- bl SetBgModeInternal\n\
- bl ResetBgControlStructs\n\
- cmp r4, 0\n\
- beq _08001712\n\
- movs r7, 0\n\
- ldr r0, _08001724 @ =sGpuBgConfigs2\n\
- mov r9, r0\n\
- adds r6, r5, 0\n\
- ldr r2, _08001728 @ =gpu_tile_allocation_map_bg\n\
- mov r10, r2\n\
- mov r8, r4\n\
-_08001688:\n\
- ldr r4, [r6]\n\
- lsls r0, r4, 30\n\
- lsrs r5, r0, 30\n\
- cmp r5, 0x3\n\
- bhi _08001704\n\
- lsls r1, r4, 28\n\
- lsrs r1, 30\n\
- lsls r2, r4, 23\n\
- lsrs r2, 27\n\
- lsls r3, r4, 21\n\
- lsrs r3, 30\n\
- lsls r0, r4, 20\n\
- lsrs r0, 31\n\
- str r0, [sp]\n\
- lsls r0, r4, 18\n\
- lsrs r0, 30\n\
- str r0, [sp, 0x4]\n\
- str r7, [sp, 0x8]\n\
- str r7, [sp, 0xC]\n\
- adds r0, r5, 0\n\
- bl SetBgControlAttributes\n\
- lsls r4, r5, 4\n\
- mov r5, r9\n\
- adds r3, r4, r5\n\
- ldr r2, [r6]\n\
- lsls r2, 8\n\
- lsrs r2, 22\n\
- ldrh r0, [r3]\n\
- ldr r5, _0800172C @ =0xfffffc00\n\
- adds r1, r5, 0\n\
- ands r0, r1\n\
- orrs r0, r2\n\
- strh r0, [r3]\n\
- ldrb r0, [r3, 0x1]\n\
- movs r2, 0x3D\n\
- negs r2, r2\n\
- adds r1, r2, 0\n\
- ands r0, r1\n\
- strb r0, [r3, 0x1]\n\
- ldr r0, [r3]\n\
- ldr r1, _08001730 @ =0x00003fff\n\
- ands r0, r1\n\
- str r0, [r3]\n\
- mov r0, r9\n\
- adds r0, 0x4\n\
- adds r0, r4, r0\n\
- str r7, [r0]\n\
- mov r0, r9\n\
- adds r0, 0x8\n\
- adds r0, r4, r0\n\
- str r7, [r0]\n\
- ldr r5, _08001734 @ =sGpuBgConfigs2 + 0xC\n\
- adds r4, r5\n\
- str r7, [r4]\n\
- ldr r0, [r6]\n\
- lsls r0, 28\n\
- lsrs r0, 30\n\
- lsls r0, 6\n\
- add r0, r10\n\
- movs r1, 0x1\n\
- strb r1, [r0]\n\
-_08001704:\n\
- adds r6, 0x4\n\
- movs r0, 0x1\n\
- negs r0, r0\n\
- add r8, r0\n\
- mov r2, r8\n\
- cmp r2, 0\n\
- bne _08001688\n\
-_08001712:\n\
- add sp, 0x10\n\
- pop {r3-r5}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- mov r10, r5\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0\n\
- .align 2, 0\n\
-_08001724: .4byte sGpuBgConfigs2\n\
-_08001728: .4byte gpu_tile_allocation_map_bg\n\
-_0800172C: .4byte 0xfffffc00\n\
-_08001730: .4byte 0x00003fff\n\
-_08001734: .4byte sGpuBgConfigs2 + 0xC\n\
-.syntax divided");
-}
-#endif // NONMATCHING
void InitBgFromTemplate(const struct BgTemplate *template)
{
diff --git a/src/bug.c b/src/bug.c
new file mode 100644
index 000000000..9b8935744
--- /dev/null
+++ b/src/bug.c
@@ -0,0 +1,462 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "gpu_regs.h"
+#include "trig.h"
+
+static void sub_80B3FAC(struct Sprite *sprite);
+static void sub_80B407C(struct Sprite *sprite);
+static void AnimTranslateWebThread(struct Sprite *sprite);
+static void sub_80B41F8(struct Sprite *sprite);
+static void sub_80B42C0(struct Sprite *sprite);
+static void AnimTranslateStinger(struct Sprite *sprite);
+static void AnimMissileArc(struct Sprite *sprite);
+static void sub_80B45D8(struct Sprite *sprite);
+static void sub_80B41C0(struct Sprite *sprite);
+static void sub_80B4274(struct Sprite *sprite);
+static void sub_80B42E8(struct Sprite *sprite);
+static void sub_80B4344(struct Sprite *sprite);
+static void AnimMissileArcStep(struct Sprite *sprite);
+
+static const union AffineAnimCmd gUnknown_83E71E8[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 30, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E71F8[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -99, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E7208[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 94, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7218[] =
+{
+ gUnknown_83E71E8,
+ gUnknown_83E71F8,
+ gUnknown_83E7208,
+};
+
+const struct SpriteTemplate gUnknown_83E7224 =
+{
+ .tileTag = ANIM_TAG_HORN_HIT_2,
+ .paletteTag = ANIM_TAG_HORN_HIT_2,
+ .oam = &gOamData_83ACAB8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7218,
+ .callback = sub_80B3FAC,
+};
+
+static const union AffineAnimCmd gUnknown_83E723C[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -33, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E724C[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 96, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E725C[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -96, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E726C[] =
+{
+ gUnknown_83E723C,
+ gUnknown_83E724C,
+ gUnknown_83E725C,
+};
+
+const struct SpriteTemplate gUnknown_83E7278 =
+{
+ .tileTag = ANIM_TAG_NEEDLE,
+ .paletteTag = ANIM_TAG_NEEDLE,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E726C,
+ .callback = sub_80B407C,
+};
+
+const struct SpriteTemplate gWebThreadSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_WEB_THREAD,
+ .paletteTag = ANIM_TAG_WEB_THREAD,
+ .oam = &gOamData_83AC9C8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimTranslateWebThread,
+};
+
+const struct SpriteTemplate gUnknown_83E72A8 =
+{
+ .tileTag = ANIM_TAG_STRING,
+ .paletteTag = ANIM_TAG_STRING,
+ .oam = &gOamData_83ACA00,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B41F8,
+};
+
+static const union AffineAnimCmd gUnknown_83E72C0[] =
+{
+ AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
+ AFFINEANIMCMD_FRAME(0x6, 0x6, 0, 1),
+ AFFINEANIMCMD_JUMP(1),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E72D8[] =
+{
+ gUnknown_83E72C0,
+};
+
+const struct SpriteTemplate gSpiderWebSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_SPIDER_WEB,
+ .paletteTag = ANIM_TAG_SPIDER_WEB,
+ .oam = &gOamData_83ACBC0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E72D8,
+ .callback = sub_80B42C0,
+};
+
+const struct SpriteTemplate gLinearStingerSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_NEEDLE,
+ .paletteTag = ANIM_TAG_NEEDLE,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimTranslateStinger,
+};
+
+const struct SpriteTemplate gPinMissileSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_NEEDLE,
+ .paletteTag = ANIM_TAG_NEEDLE,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimMissileArc,
+};
+
+const struct SpriteTemplate gIcicleSpearSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_ICICLE_SPEAR,
+ .paletteTag = ANIM_TAG_ICICLE_SPEAR,
+ .oam = &gOamData_83ACA38,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimMissileArc,
+};
+
+static const union AffineAnimCmd gUnknown_83E733C[] =
+{
+ AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
+ AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 18),
+ AFFINEANIMCMD_LOOP(0),
+ AFFINEANIMCMD_FRAME(0xFFFB, 0xFFFB, 0, 8),
+ AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 8),
+ AFFINEANIMCMD_LOOP(5),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7374[] =
+{
+ gUnknown_83E733C,
+};
+
+const struct SpriteTemplate gUnknown_83E7378 =
+{
+ .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .oam = &gOamData_83ACB60,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7374,
+ .callback = sub_80B45D8,
+};
+
+static void sub_80B3FAC(struct Sprite *sprite)
+{
+ if (IsContest())
+ {
+ StartSpriteAffineAnim(sprite, 2);
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ }
+ else if (!GetBattlerSide(gBattleAnimTarget))
+ {
+ StartSpriteAffineAnim(sprite, 1);
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ }
+ sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimTarget, 2) + gBattleAnimArgs[0];
+ sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimTarget, 3) + gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3];
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+static void sub_80B407C(struct Sprite *sprite)
+{
+ if (IsContest())
+ {
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ StartSpriteAffineAnim(sprite, 2);
+ }
+ else if (!GetBattlerSide(gBattleAnimTarget))
+ {
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ }
+ sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimTarget, 2) + gBattleAnimArgs[0];
+ sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimTarget, 3) + gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+// Creates a single web thread that travels from attacker to target.
+// Used by MOVE_STRING_SHOT and MOVE_SPIDER_WEB in their first move phase.
+// arg 0: x
+// arg 1: y
+// arg 2: controls the left-to-right movement
+// arg 3: amplitude
+// arg 4: if targets both opponents
+static void AnimTranslateWebThread(struct Sprite *sprite)
+{
+ if (IsContest())
+ gBattleAnimArgs[2] /= 2;
+ InitSpritePosToAnimAttacker(sprite, TRUE);
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ if (!gBattleAnimArgs[4])
+ {
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->data[2], &sprite->data[4]);
+ }
+ sub_8075678(sprite);
+ sprite->data[5] = gBattleAnimArgs[3];
+ sprite->callback = sub_80B41C0;
+}
+
+static void sub_80B41C0(struct Sprite *sprite)
+{
+ if (AnimTranslateLinear(sprite))
+ {
+ DestroyAnimSprite(sprite);
+ return;
+ }
+ sprite->pos2.x += Sin(sprite->data[6], sprite->data[5]);
+ sprite->data[6] = (sprite->data[6] + 13) & 0xFF;
+}
+
+static void sub_80B41F8(struct Sprite *sprite)
+{
+ SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBattlerSide(gBattleAnimAttacker))
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ if (!GetBattlerSide(gBattleAnimTarget))
+ sprite->pos1.y += 8;
+ sprite->callback = sub_80B4274;
+}
+
+static void sub_80B4274(struct Sprite *sprite)
+{
+ if (++sprite->data[0] == 3)
+ {
+ sprite->data[0] = 0;
+ sprite->invisible ^= 1;
+ }
+ if (++sprite->data[1] == 51)
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+static void sub_80B42C0(struct Sprite *sprite)
+{
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
+ sprite->data[0] = 16;
+ sprite->callback = sub_80B42E8;
+}
+
+static void sub_80B42E8(struct Sprite *sprite)
+{
+ if (sprite->data[2] < 20)
+ {
+ ++sprite->data[2];
+ }
+ else if (sprite->data[1]++ & 1)
+ {
+ --sprite->data[0];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 16 - sprite->data[0]));
+
+ if (sprite->data[0] == 0)
+ {
+ sprite->invisible = TRUE;
+ sprite->callback = sub_80B4344;
+ }
+ }
+}
+
+static void sub_80B4344(struct Sprite *sprite)
+{
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimSprite(sprite);
+}
+
+// Translates a stinger sprite linearly to a destination location. The sprite is
+// initially rotated so that it appears to be traveling in a straight line.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x pixel offset
+// arg 3: target y pixel offset
+// arg 4: duration
+static void AnimTranslateStinger(struct Sprite *sprite)
+{
+ s16 lVarX, lVarY;
+ u16 rot;
+
+ if (IsContest())
+ {
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ }
+ else if (GetBattlerSide(gBattleAnimAttacker))
+ {
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ }
+ if (!IsContest() && GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget))
+ {
+ if (GetBattlerPosition(gBattleAnimTarget) == B_POSITION_PLAYER_LEFT
+ || GetBattlerPosition(gBattleAnimTarget) == B_POSITION_OPPONENT_LEFT)
+ {
+ s16 temp1, temp2;
+
+ temp1 = gBattleAnimArgs[2];
+ gBattleAnimArgs[2] = -temp1;
+
+ temp2 = gBattleAnimArgs[0];
+ gBattleAnimArgs[0] = -temp2;
+ }
+ }
+ InitSpritePosToAnimAttacker(sprite, 1);
+ lVarX = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2];
+ lVarY = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3];
+ rot = ArcTan2Neg(lVarX - sprite->pos1.x, lVarY - sprite->pos1.y);
+ rot += 0xC000;
+ TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rot);
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = lVarX;
+ sprite->data[4] = lVarY;
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+// Rotates sprite and moves it in an arc, so that it appears like a missle or arrow traveling.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x pixel offset
+// arg 3: target y pixel offset
+// arg 4: duration
+// arg 5: wave amplitude
+static void AnimMissileArc(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, 1);
+ if (GetBattlerSide(gBattleAnimAttacker))
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3];
+ sprite->data[5] = gBattleAnimArgs[5];
+ InitAnimArcTranslation(sprite);
+ sprite->callback = AnimMissileArcStep;
+ sprite->invisible = TRUE;
+}
+
+static void AnimMissileArcStep(struct Sprite *sprite)
+{
+ sprite->invisible = FALSE;
+
+ if (TranslateAnimHorizontalArc(sprite))
+ {
+ DestroyAnimSprite(sprite);
+ }
+ else
+ {
+ s16 tempData[8];
+ u16 *data = sprite->data;
+ u16 x1 = sprite->pos1.x;
+ s16 x2 = sprite->pos2.x;
+ u16 y1 = sprite->pos1.y;
+ s16 y2 = sprite->pos2.y;
+ s32 i;
+
+ for (i = 0; i < 8; ++i)
+ tempData[i] = data[i];
+ x2 += x1;
+ y2 += y1;
+ if (!TranslateAnimHorizontalArc(sprite))
+ {
+ u16 rotation = ArcTan2Neg(sprite->pos1.x + sprite->pos2.x - x2,
+ sprite->pos1.y + sprite->pos2.y - y2);
+
+ rotation += 0xC000;
+ TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rotation);
+ for (i = 0; i < 8; ++i)
+ data[i] = tempData[i];
+ }
+ }
+}
+
+static void sub_80B45D8(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + 18;
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + 18;
+ }
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
+}
diff --git a/src/dark.c b/src/dark.c
new file mode 100644
index 000000000..cb34b991e
--- /dev/null
+++ b/src/dark.c
@@ -0,0 +1,921 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "gpu_regs.h"
+#include "graphics.h"
+#include "palette.h"
+#include "scanline_effect.h"
+#include "trig.h"
+#include "util.h"
+
+static void sub_80B7ACC(struct Sprite *sprite);
+static void sub_80B7BD4(struct Sprite *sprite);
+static void sub_80B7C88(struct Sprite *sprite);
+static void sub_80B86B0(struct Sprite *sprite);
+static void sub_80B7954(u8 taskId);
+static void sub_80B7A14(u8 taskId);
+static void sub_80B7B48(struct Sprite *sprite);
+static void sub_80B7C10(struct Sprite *sprite);
+static void sub_80B7C50(struct Sprite *sprite);
+static void sub_80B7D88(struct Sprite *sprite);
+static void sub_80B856C(u8 priority);
+static void sub_80B7F58(u8 taskId);
+static void sub_80B843C(struct Task *task);
+static void sub_80B82C0(u8 taskId);
+static void sub_80B8920(u8 taskId);
+
+const struct SpriteTemplate gUnknown_83E7878 =
+{
+ .tileTag = ANIM_TAG_TIED_BAG,
+ .paletteTag = ANIM_TAG_TIED_BAG,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B7ACC,
+};
+
+static const union AffineAnimCmd gUnknown_83E7890[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E78A0[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 32, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E78B0[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 64, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E78C0[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 96, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E78D0[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -128, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E78E0[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -96, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E78F0[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -64, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E7900[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -32, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7910[] =
+{
+ gUnknown_83E7890,
+ gUnknown_83E78A0,
+ gUnknown_83E78B0,
+ gUnknown_83E78C0,
+ gUnknown_83E78D0,
+ gUnknown_83E78E0,
+ gUnknown_83E78F0,
+ gUnknown_83E7900,
+};
+
+const struct SpriteTemplate gUnknown_83E7930 =
+{
+ .tileTag = ANIM_TAG_SHARP_TEETH,
+ .paletteTag = ANIM_TAG_SHARP_TEETH,
+ .oam = &gOamData_83ACB60,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7910,
+ .callback = sub_80B7BD4,
+};
+
+const struct SpriteTemplate gUnknown_83E7948 =
+{
+ .tileTag = ANIM_TAG_CLAMP,
+ .paletteTag = ANIM_TAG_CLAMP,
+ .oam = &gOamData_83ACB60,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7910,
+ .callback = sub_80B7BD4,
+};
+
+static const union AffineAnimCmd gUnknown_83E7960[] =
+{
+ AFFINEANIMCMD_FRAME(0xC0, 0xC0, 80, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -2, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E7978[] =
+{
+ AFFINEANIMCMD_FRAME(0xC0, 0xC0, -80, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 2, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7990[] =
+{
+ gUnknown_83E7960,
+ gUnknown_83E7978,
+};
+
+const struct SpriteTemplate gUnknown_83E7998 =
+{
+ .tileTag = ANIM_TAG_SMALL_BUBBLES,
+ .paletteTag = ANIM_TAG_SMALL_BUBBLES,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7990,
+ .callback = sub_80B7C88,
+};
+
+static const union AnimCmd gUnknown_83E79B0[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(32, 4),
+ ANIMCMD_FRAME(48, 4),
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E79C8[] =
+{
+ ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
+ ANIMCMD_FRAME(16, 4, .hFlip = TRUE),
+ ANIMCMD_FRAME(32, 4, .hFlip = TRUE),
+ ANIMCMD_FRAME(48, 4, .hFlip = TRUE),
+ ANIMCMD_FRAME(64, 4, .hFlip = TRUE),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E79E0[] =
+{
+ gUnknown_83E79B0,
+ gUnknown_83E79C8,
+};
+
+const struct SpriteTemplate gUnknown_83E79E8 =
+{
+ .tileTag = ANIM_TAG_CLAW_SLASH,
+ .paletteTag = ANIM_TAG_CLAW_SLASH,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E79E0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B86B0,
+};
+
+void sub_80B78E0(u8 taskId)
+{
+ s32 battler;
+
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ battler = gBattleAnimAttacker;
+ gTasks[taskId].data[1] = 16;
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
+ if (GetBattlerSpriteBGPriorityRank(battler) == 1)
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
+ else
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2);
+ gTasks[taskId].func = sub_80B7954;
+}
+
+static void sub_80B7954(u8 taskId)
+{
+ u8 blendA = gTasks[taskId].data[1] >> 8;
+ u8 blendB = gTasks[taskId].data[1];
+
+ if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0])
+ {
+ ++blendA;
+ --blendB;
+ gTasks[taskId].data[1] = BLDALPHA_BLEND(blendB, blendA);
+ SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1]);
+ gTasks[taskId].data[2] = 0;
+ if (blendA == 16)
+ {
+ gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].invisible = TRUE;
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ else
+ {
+ ++gTasks[taskId].data[2];
+ }
+}
+
+void sub_80B79DC(u8 taskId)
+{
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = BLDALPHA_BLEND(0, 16);
+ gTasks[taskId].func = sub_80B7A14;
+ SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1]);
+}
+
+static void sub_80B7A14(u8 taskId)
+{
+ u8 blendA = gTasks[taskId].data[1] >> 8;
+ u8 blendB = gTasks[taskId].data[1];
+
+ if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0])
+ {
+ --blendA;
+ ++blendB;
+ gTasks[taskId].data[1] = (blendA << 8) | blendB;
+ SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1]);
+ gTasks[taskId].data[2] = 0;
+ if (blendA == 0)
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ else
+ {
+ ++gTasks[taskId].data[2];
+ }
+}
+
+void sub_80B7A80(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
+ if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
+ else
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2);
+ DestroyAnimVisualTask(taskId);
+}
+
+static void sub_80B7ACC(struct Sprite *sprite)
+{
+ sprite->data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->data[3] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ sprite->data[0] = 0x7E;
+ InitSpriteDataForLinearTranslation(sprite);
+ sprite->data[3] = -sprite->data[1];
+ sprite->data[4] = -sprite->data[2];
+ sprite->data[6] = 0xFFD8;
+ sprite->callback = sub_80B7B48;
+ sprite->callback(sprite);
+}
+
+static void sub_80B7B48(struct Sprite *sprite)
+{
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ sprite->pos2.x = sprite->data[3] >> 8;
+ sprite->pos2.y = sprite->data[4] >> 8;
+ if (sprite->data[7] == 0)
+ {
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ sprite->pos2.x = sprite->data[3] >> 8;
+ sprite->pos2.y = sprite->data[4] >> 8;
+ --sprite->data[0];
+ }
+ sprite->pos2.y += Sin(sprite->data[5], sprite->data[6]);
+ sprite->data[5] = (sprite->data[5] + 3) & 0xFF;
+ if (sprite->data[5] > 0x7F)
+ {
+ sprite->data[5] = 0;
+ sprite->data[6] += 20;
+ ++sprite->data[7];
+ }
+ if (--sprite->data[0] == 0)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B7BD4(struct Sprite *sprite)
+{
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ StartSpriteAffineAnim(sprite, gBattleAnimArgs[2]);
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->data[1] = gBattleAnimArgs[4];
+ sprite->data[2] = gBattleAnimArgs[5];
+ sprite->callback = sub_80B7C10;
+}
+
+static void sub_80B7C10(struct Sprite *sprite)
+{
+ sprite->data[4] += sprite->data[0];
+ sprite->data[5] += sprite->data[1];
+ sprite->pos2.x = sprite->data[4] >> 8;
+ sprite->pos2.y = sprite->data[5] >> 8;
+ if (++sprite->data[3] == sprite->data[2])
+ sprite->callback = sub_80B7C50;
+}
+
+static void sub_80B7C50(struct Sprite *sprite)
+{
+ sprite->data[4] -= sprite->data[0];
+ sprite->data[5] -= sprite->data[1];
+ sprite->pos2.x = sprite->data[4] >> 8;
+ sprite->pos2.y = sprite->data[5] >> 8;
+ if (--sprite->data[3] == 0)
+ DestroySpriteAndMatrix(sprite);
+}
+
+static void sub_80B7C88(struct Sprite *sprite)
+{
+ u8 battler;
+ s8 xOffset;
+
+ if (gBattleAnimArgs[0] == 0)
+ battler = gBattleAnimAttacker;
+ else
+ battler = gBattleAnimTarget;
+ xOffset = 20;
+ sprite->oam.tileNum += 4;
+ switch (gBattleAnimArgs[1])
+ {
+ case 0:
+ sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) - 8;
+ sprite->pos1.y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 8;
+ break;
+ case 1:
+ sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) - 14;
+ sprite->pos1.y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 16;
+ break;
+ case 2:
+ sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) + 8;
+ sprite->pos1.y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 8;
+ StartSpriteAffineAnim(sprite, 1);
+ xOffset = -20;
+ break;
+ case 3:
+ sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) + 14;
+ sprite->pos1.y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 16;
+ StartSpriteAffineAnim(sprite, 1);
+ xOffset = -20;
+ break;
+ }
+ sprite->data[0] = 32;
+ sprite->data[2] = sprite->pos1.x + xOffset;
+ sprite->data[4] = sprite->pos1.y + 12;
+ sprite->data[5] = -12;
+ InitAnimArcTranslation(sprite);
+ sprite->callback = sub_80B7D88;
+}
+
+static void sub_80B7D88(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ DestroySpriteAndMatrix(sprite);
+}
+
+void sub_80B7DA4(u8 taskId)
+{
+ struct ScanlineEffectParams scanlineParams;
+ struct BattleAnimBgData animBg;
+ u16 i;
+ u8 pos;
+ s32 var0;
+ struct Task *task = &gTasks[taskId];
+
+ task->data[7] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + 31;
+ task->data[6] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) - 7;
+ task->data[5] = task->data[7];
+ task->data[4] = task->data[6];
+ task->data[13] = (task->data[7] - task->data[6]) << 8;
+ pos = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
+ task->data[14] = pos - 32;
+ task->data[15] = pos + 32;
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
+ task->data[8] = -12;
+ else
+ task->data[8] = -64;
+ task->data[3] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
+ if (task->data[3] == 1)
+ {
+ sub_80752A0(&animBg);
+ task->data[10] = gBattle_BG1_Y;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
+ FillPalette(0, animBg.paletteId * 16, 32);
+ scanlineParams.dmaDest = &REG_BG1VOFS;
+ var0 = WINOUT_WIN01_BG1;
+ if (!IsContest())
+ gBattle_BG2_X += 240;
+ }
+ else
+ {
+ task->data[10] = gBattle_BG2_Y;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2);
+ FillPalette(0, 144, 32);
+ scanlineParams.dmaDest = &REG_BG2VOFS;
+ var0 = WINOUT_WIN01_BG2;
+ if (!IsContest())
+ gBattle_BG1_X += 240;
+ }
+ scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
+ scanlineParams.initState = 1;
+ scanlineParams.unused9 = 0;
+ task->data[11] = 0;
+ task->data[12] = 16;
+ task->data[0] = 0;
+ task->data[1] = 0;
+ task->data[2] = 0;
+ sub_80B856C(3);
+ for (i = 0; i < 112; ++i)
+ {
+ gScanlineEffectRegBuffers[0][i] = task->data[10];
+ gScanlineEffectRegBuffers[1][i] = task->data[10];
+ }
+ ScanlineEffect_SetParams(scanlineParams);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | (var0 ^ (WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR)));
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
+ gBattle_WIN0V = 160;
+
+ task->func = sub_80B7F58;
+}
+
+static void sub_80B7F58(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ if (++task->data[2] & 1)
+ {
+ if (task->data[11] != 12)
+ ++task->data[11];
+ }
+ else if (task->data[12] != 8)
+ {
+ --task->data[12];
+ }
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[11], task->data[12]));
+ if (task->data[11] == 12 && task->data[12] == 8)
+ ++task->data[0];
+ }
+ break;
+ case 1:
+ task->data[4] -= 8;
+ sub_80B843C(task);
+ if (task->data[4] < task->data[8])
+ ++task->data[0];
+ break;
+ case 2:
+ task->data[4] -= 8;
+ sub_80B843C(task);
+ task->data[14] += 4;
+ task->data[15] -= 4;
+ if (task->data[14] >= task->data[15])
+ task->data[14] = task->data[15];
+ gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
+ if (task->data[14] == task->data[15])
+ ++task->data[0];
+ break;
+ case 3:
+ gScanlineEffect.state = 3;
+ ++task->data[0];
+ break;
+ case 4:
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80B8070(u8 taskId)
+{
+ struct BattleAnimBgData animBg;
+ struct ScanlineEffectParams scanlineParams;
+ u8 x;
+ u16 i;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (IsContest() == TRUE)
+ {
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
+ DestroyAnimVisualTask(taskId);
+ }
+ else
+ {
+ task->data[3] = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget);
+ if (task->data[3] == 1)
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
+ gBattle_BG2_X += 240;
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2);
+ gBattle_BG1_X += 240;
+ }
+ ++task->data[0];
+ }
+ break;
+ case 1:
+ if (task->data[3] == 1)
+ {
+ sub_80752A0(&animBg);
+ task->data[10] = gBattle_BG1_Y;
+ FillPalette(0, animBg.paletteId * 16, 32);
+ }
+ else
+ {
+ task->data[10] = gBattle_BG2_Y;
+ FillPalette(0, 9 * 16, 32);
+ }
+ sub_80B856C(3);
+ ++task->data[0];
+ break;
+ case 2:
+ task->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 31;
+ task->data[6] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) - 7;
+ task->data[13] = (task->data[7] - task->data[6]) << 8;
+ x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
+ task->data[14] = x - 4;
+ task->data[15] = x + 4;
+ if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
+ task->data[8] = -12;
+ else
+ task->data[8] = -64;
+ task->data[4] = task->data[8];
+ task->data[5] = task->data[8];
+ task->data[11] = 12;
+ task->data[12] = 8;
+ ++task->data[0];
+ break;
+ case 3:
+ if (task->data[3] == 1)
+ scanlineParams.dmaDest = &REG_BG1VOFS;
+ else
+ scanlineParams.dmaDest = &REG_BG2VOFS;
+ for (i = 0; i < 112; ++i)
+ {
+ gScanlineEffectRegBuffers[0][i] = task->data[10] + (159 - i);
+ gScanlineEffectRegBuffers[1][i] = task->data[10] + (159 - i);
+ }
+ scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
+ scanlineParams.initState = 1;
+ scanlineParams.unused9 = 0;
+ ScanlineEffect_SetParams(scanlineParams);
+ ++task->data[0];
+ break;
+ case 4:
+ if (task->data[3] == 1)
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
+ else
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
+ gBattle_WIN0V = 160;
+ task->data[0] = 0;
+ task->data[1] = 0;
+ task->data[2] = 0;
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 8));
+ task->func = sub_80B82C0;
+ break;
+ }
+}
+
+static void sub_80B82C0(u8 taskId)
+{
+ u8 pos;
+ u16 i;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[5] += 8;
+ if (task->data[5] >= task->data[7])
+ task->data[5] = task->data[7];
+ sub_80B843C(task);
+ if (task->data[5] == task->data[7])
+ ++task->data[0];
+ break;
+ case 1:
+ if (task->data[15] - task->data[14] < 0x40)
+ {
+ task->data[14] -= 4;
+ task->data[15] += 4;
+ }
+ else
+ {
+ task->data[1] = 1;
+ }
+ gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
+ task->data[4] += 8;
+ if (task->data[4] >= task->data[6])
+ task->data[4] = task->data[6];
+ sub_80B843C(task);
+ if (task->data[4] == task->data[6] && task->data[1])
+ {
+ task->data[1] = 0;
+ ++task->data[0];
+ }
+ break;
+ case 2:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ ++task->data[2];
+ if (task->data[2] & 1)
+ {
+ if (task->data[11])
+ --task->data[11];
+ }
+ else if (task->data[12] < 16)
+ {
+ ++task->data[12];
+ }
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[11], task->data[12]));
+ if (task->data[11] == 0 && task->data[12] == 16)
+ ++task->data[0];
+ }
+ break;
+ case 3:
+ gScanlineEffect.state = 3;
+ ++task->data[0];
+ break;
+ case 4:
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B843C(struct Task *task)
+{
+ s32 var0, var1, var4;
+ s16 var2, i;
+
+ var2 = task->data[5] - task->data[4];
+ if (var2 != 0)
+ {
+ var0 = task->data[13] / var2;
+ var1 = task->data[6] << 8;
+ for (i = 0; i < task->data[4]; ++i)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = task->data[10] - (i - 159);
+ for (i = task->data[4]; i <= task->data[5]; ++i)
+ {
+ if (i >= 0)
+ {
+ s16 var3 = (var1 >> 8) - i;
+
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = var3 + task->data[10];
+ }
+ var1 += var0;
+ }
+ var4 = task->data[10] - (i - 159);
+ for (; i < task->data[7]; ++i)
+ if (i >= 0)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = var4--;
+ }
+ else
+ {
+ var4 = task->data[10] + 159;
+ for (i = 0; i < 112; ++i)
+ {
+ gScanlineEffectRegBuffers[0][i] = var4;
+ gScanlineEffectRegBuffers[1][i] = var4;
+ --var4;
+ }
+ }
+}
+
+static void sub_80B856C(u8 priority)
+{
+ u16 i;
+
+ for (i = 0; i < MAX_BATTLERS_COUNT; ++i)
+ {
+ u8 spriteId = GetAnimBattlerSpriteId(i);
+
+ if (spriteId != 0xFF)
+ gSprites[spriteId].oam.priority = priority;
+ }
+}
+
+void sub_80B85B8(u8 taskId)
+{
+ bool8 toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) ^ 1 ? TRUE : FALSE;
+
+ MoveBattlerSpriteToBG(gBattleAnimAttacker, toBG2);
+ gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].invisible = FALSE;
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
+ {
+ MoveBattlerSpriteToBG(gBattleAnimAttacker ^ 2, toBG2 ^ 1);
+ gSprites[gBattlerSpriteIds[gBattleAnimAttacker ^ 2]].invisible = FALSE;
+ }
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80B8664(u8 taskId)
+{
+ bool8 toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) ^ 1 ? TRUE : FALSE;
+
+ sub_8073128(toBG2);
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
+ sub_8073128(toBG2 ^ 1);
+ DestroyAnimVisualTask(taskId);
+}
+
+static void sub_80B86B0(struct Sprite *sprite)
+{
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ StartSpriteAnim(sprite, gBattleAnimArgs[2]);
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+// Makes the attacker metallic and shining.
+// Used by MOVE_HARDEN and MOVE_IRON_DEFENSE.
+// arg0: if true won't change battler's palette back
+// arg1: if true, use custom color
+// arg2: custom color
+// Custom color argument is used in MOVE_POISON_TAIL to make the mon turn purplish/pinkish as if became cloaked in poison.
+void AnimTask_MetallicShine(u8 taskId)
+{
+ u16 species;
+ u8 spriteId, newSpriteId;
+ u16 paletteNum;
+ struct BattleAnimBgData animBg;
+ bool32 priorityChanged = FALSE;
+
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 12));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 0);
+ SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
+ if (IsDoubleBattle() && !IsContest())
+ {
+ if (GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_OPPONENT_RIGHT || GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_PLAYER_LEFT)
+ {
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)) == TRUE)
+ {
+ gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority--;
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ priorityChanged = TRUE;
+ }
+ }
+ }
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
+ else
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
+ spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
+ newSpriteId = sub_8076E34(gBattleAnimAttacker, spriteId, species);
+ sub_80752A0(&animBg);
+ AnimLoadCompressedBgTilemap(animBg.bgId, gMetalShineTilemap);
+ AnimLoadCompressedBgGfx(animBg.bgId, gMetalShineGfx, animBg.tilesOffset);
+ LoadCompressedPalette(gMetalShinePalette, animBg.paletteId * 16, 32);
+ gBattle_BG1_X = -gSprites[spriteId].pos1.x + 96;
+ gBattle_BG1_Y = -gSprites[spriteId].pos1.y + 32;
+ paletteNum = 16 + gSprites[spriteId].oam.paletteNum;
+ if (gBattleAnimArgs[1] == 0)
+ SetGreyscaleOrOriginalPalette(paletteNum, FALSE);
+ else
+ BlendPalette(paletteNum * 16, 16, 11, gBattleAnimArgs[2]);
+ gTasks[taskId].data[0] = newSpriteId;
+ gTasks[taskId].data[1] = gBattleAnimArgs[0];
+ gTasks[taskId].data[2] = gBattleAnimArgs[1];
+ gTasks[taskId].data[3] = gBattleAnimArgs[2];
+ gTasks[taskId].data[6] = priorityChanged;
+ gTasks[taskId].func = sub_80B8920;
+}
+
+static void sub_80B8920(u8 taskId)
+{
+ struct BattleAnimBgData animBg;
+ u16 paletteNum;
+ u8 spriteId;
+
+ gTasks[taskId].data[10] += 4;
+ gBattle_BG1_X -= 4;
+ if (gTasks[taskId].data[10] == 128)
+ {
+ gTasks[taskId].data[10] = 0;
+ gBattle_BG1_X += 128;
+ gTasks[taskId].data[11]++;
+ if (gTasks[taskId].data[11] == 2)
+ {
+ spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
+ paletteNum = 16 + gSprites[spriteId].oam.paletteNum;
+ if (gTasks[taskId].data[1] == 0)
+ SetGreyscaleOrOriginalPalette(paletteNum, 1);
+ DestroySprite(&gSprites[gTasks[taskId].data[0]]);
+ sub_80752A0(&animBg);
+ sub_8075358(animBg.bgId);
+ if (gTasks[taskId].data[6] == 1)
+ gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority++;
+ }
+ else if (gTasks[taskId].data[11] == 3)
+ {
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
+ SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+}
+
+// Changes battler's palette to either greyscale or original.
+// arg0: which battler
+// arg1: 0 grayscale, 1 original
+void AnimTask_SetGreyscaleOrOriginalPal(u8 taskId)
+{
+ u8 spriteId, battler;
+ bool8 calcSpriteId = FALSE;
+ u8 position = B_POSITION_PLAYER_LEFT;
+
+ switch (gBattleAnimArgs[0])
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
+ break;
+ case 4:
+ position = B_POSITION_PLAYER_LEFT;
+ calcSpriteId = TRUE;
+ break;
+ case 5:
+ position = B_POSITION_PLAYER_RIGHT;
+ calcSpriteId = TRUE;
+ break;
+ case 6:
+ position = B_POSITION_OPPONENT_LEFT;
+ calcSpriteId = TRUE;
+ break;
+ case 7:
+ position = B_POSITION_OPPONENT_RIGHT;
+ calcSpriteId = TRUE;
+ break;
+ default:
+ spriteId = 0xFF;
+ break;
+ }
+ if (calcSpriteId)
+ {
+ battler = GetBattlerAtPosition(position);
+ if (IsBattlerSpriteVisible(battler))
+ spriteId = gBattlerSpriteIds[battler];
+ else
+ spriteId = 0xFF;
+ }
+ if (spriteId != 0xFF)
+ SetGreyscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, gBattleAnimArgs[1]);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80B8B38(u8 taskId)
+{
+ if (gAnimMoveTurn < 2)
+ gBattleAnimArgs[7] = 0;
+ if (gAnimMoveTurn == 2)
+ gBattleAnimArgs[7] = 1;
+ DestroyAnimVisualTask(taskId);
+}
diff --git a/src/daycare.c b/src/daycare.c
index 837a2c4e6..fede86156 100644
--- a/src/daycare.c
+++ b/src/daycare.c
@@ -2087,7 +2087,7 @@ struct UnkStruct_82349CC
u8 field_3;
};
-extern const struct UnkStruct_82349CC gUnknown_82349CC[NUM_SPECIES];
+extern const struct UnkStruct_82349CC gMonFrontPicCoords[NUM_SPECIES];
static void SpriteCB_Egg_2(struct Sprite* sprite)
{
@@ -2101,7 +2101,7 @@ static void SpriteCB_Egg_2(struct Sprite* sprite)
sprite->data[0] = 0;
species = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES);
gSprites[sEggHatchData->pokeSpriteID].pos2.x = 0;
- gSprites[sEggHatchData->pokeSpriteID].pos2.y = gUnknown_82349CC[species].field_1;
+ gSprites[sEggHatchData->pokeSpriteID].pos2.y = gMonFrontPicCoords[species].field_1;
}
else
{
diff --git a/src/dragon.c b/src/dragon.c
new file mode 100644
index 000000000..34f97ba74
--- /dev/null
+++ b/src/dragon.c
@@ -0,0 +1,431 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "scanline_effect.h"
+#include "task.h"
+#include "trig.h"
+
+static void sub_80B725C(struct Sprite *sprite);
+static void sub_80B741C(struct Sprite *sprite);
+static void sub_80B73AC(struct Sprite *sprite);
+static void sub_80B7448(struct Sprite *sprite);
+static void sub_80B77E4(struct Sprite *sprite);
+static void sub_80B74D8(struct Sprite *sprite);
+static void sub_80B76B0(u8 taskId);
+static void sub_80B776C(struct Task *task);
+static void sub_80B7894(struct Sprite *sprite);
+
+static EWRAM_DATA u16 gUnknown_20399A4[7] = {0};
+
+static const union AnimCmd gUnknown_83E7710[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(32, 4),
+ ANIMCMD_FRAME(48, 4),
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E7728[] =
+{
+ gUnknown_83E7710,
+};
+
+const struct SpriteTemplate gUnknown_83E772C =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E7728,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B725C,
+};
+
+static const union AnimCmd gUnknown_83E7744[] =
+{
+ ANIMCMD_FRAME(16, 3),
+ ANIMCMD_FRAME(32, 3),
+ ANIMCMD_FRAME(48, 3),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd gUnknown_83E7754[] =
+{
+ ANIMCMD_FRAME(16, 3, .vFlip = TRUE, .hFlip = TRUE),
+ ANIMCMD_FRAME(32, 3, .vFlip = TRUE, .hFlip = TRUE),
+ ANIMCMD_FRAME(48, 3, .vFlip = TRUE, .hFlip = TRUE),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E7764[] =
+{
+ gUnknown_83E7744,
+ gUnknown_83E7754,
+};
+
+static const union AffineAnimCmd gUnknown_83E776C[] =
+{
+ AFFINEANIMCMD_FRAME(0x50, 0x50, 127, 0),
+ AFFINEANIMCMD_FRAME(0xD, 0xD, 0, 100),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E7784[] =
+{
+ AFFINEANIMCMD_FRAME(0x50, 0x50, 0, 0),
+ AFFINEANIMCMD_FRAME(0xD, 0xD, 0, 100),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E779C[] =
+{
+ gUnknown_83E776C,
+ gUnknown_83E7784,
+};
+
+const struct SpriteTemplate gUnknown_83E77A4 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83ACA98,
+ .anims = gUnknown_83E7764,
+ .images = NULL,
+ .affineAnims = gUnknown_83E779C,
+ .callback = sub_80B741C,
+};
+
+const union AnimCmd gUnknown_83E77BC[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_FRAME(32, 5),
+ ANIMCMD_FRAME(48, 5),
+ ANIMCMD_FRAME(64, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E77D4[] =
+{
+ gUnknown_83E77BC,
+};
+
+const struct SpriteTemplate gUnknown_83E77D8 =
+{
+ .tileTag = ANIM_TAG_FIRE_PLUME,
+ .paletteTag = ANIM_TAG_FIRE_PLUME,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E77D4,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B73AC,
+};
+
+static const union AnimCmd gUnknown_83E77F0[] =
+{
+ ANIMCMD_FRAME(16, 3),
+ ANIMCMD_FRAME(32, 3),
+ ANIMCMD_FRAME(48, 3),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E7800[] =
+{
+ gUnknown_83E77F0,
+ gUnknown_83E77F0,
+};
+
+static const union AffineAnimCmd gUnknown_83E7808[] =
+{
+ AFFINEANIMCMD_FRAME(0x64, 0x64, 127, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E7818[] =
+{
+ AFFINEANIMCMD_FRAME(0x64, 0x64, 0, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7828[] =
+{
+ gUnknown_83E7808,
+ gUnknown_83E7818,
+};
+
+const struct SpriteTemplate gUnknown_83E7830 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83ACA98,
+ .anims = gUnknown_83E7800,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7828,
+ .callback = sub_80B741C,
+};
+
+const struct SpriteTemplate gUnknown_83E7848 =
+{
+ .tileTag = ANIM_TAG_HOLLOW_ORB,
+ .paletteTag = ANIM_TAG_HOLLOW_ORB,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B7448,
+};
+
+const struct SpriteTemplate gUnknown_83E7860 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E7728,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B77E4,
+};
+
+static void sub_80B725C(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ gBattleAnimArgs[4] = -gBattleAnimArgs[4];
+ }
+ else
+ {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ }
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->data[3] = gBattleAnimArgs[4];
+ sprite->data[5] = gBattleAnimArgs[5];
+ sprite->invisible = TRUE;
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = TranslateSpriteLinearAndFlicker;
+}
+
+static void sub_80B72F8(struct Sprite *sprite)
+{
+ SetSpriteCoordsToAnimAttackerCoords(sprite);
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->pos1.x -= gBattleAnimArgs[1];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[2] -= gBattleAnimArgs[2];
+ sprite->data[4] += gBattleAnimArgs[3];
+ }
+ else
+ {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[2] += gBattleAnimArgs[2];
+ sprite->data[4] += gBattleAnimArgs[3];
+ StartSpriteAnim(sprite, 1);
+ }
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+}
+
+static void sub_80B73AC(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1);
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1);
+ }
+ SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[1]);
+ sprite->pos1.y += gBattleAnimArgs[2];
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+}
+
+static void sub_80B741C(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ StartSpriteAffineAnim(sprite, 1);
+ sub_80B72F8(sprite);
+}
+
+static void sub_80B7448(struct Sprite *sprite)
+{
+ u16 r5;
+ u16 r0;
+
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ sprite->data[4] = 0;
+ sprite->data[5] = 1;
+ sprite->data[6] = gBattleAnimArgs[0];
+ r5 = GetBattlerSpriteCoordAttr(gBattlerAttacker, BATTLER_COORD_ATTR_HEIGHT);
+ r0 = GetBattlerSpriteCoordAttr(gBattlerAttacker, BATTLER_COORD_ATTR_WIDTH);
+ if (r5 > r0)
+ sprite->data[7] = r5 / 2;
+ else
+ sprite->data[7] = r0 / 2;
+ sprite->pos2.x = Cos(sprite->data[6], sprite->data[7]);
+ sprite->pos2.y = Sin(sprite->data[6], sprite->data[7]);
+ sprite->callback = sub_80B74D8;
+}
+
+static void sub_80B74D8(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->data[6] = (sprite->data[6] - sprite->data[5]) & 0xFF;
+ sprite->pos2.x = Cos(sprite->data[6], sprite->data[7]);
+ sprite->pos2.y = Sin(sprite->data[6], sprite->data[7]);
+ if (++sprite->data[4] > 5)
+ {
+ sprite->data[4] = 0;
+ if (sprite->data[5] <= 15 && ++sprite->data[5] > 15)
+ sprite->data[5] = 16;
+ }
+ if (++sprite->data[3] > 0x3C)
+ {
+ sprite->data[3] = 0;
+ ++sprite->data[0];
+ }
+ break;
+ case 1:
+ sprite->data[6] = (sprite->data[6] - sprite->data[5]) & 0xFF;
+ if (sprite->data[7] <= 0x95 && (sprite->data[7] += 8) > 0x95)
+ sprite->data[7] = 0x96;
+ sprite->pos2.x = Cos(sprite->data[6], sprite->data[7]);
+ sprite->pos2.y = Sin(sprite->data[6], sprite->data[7]);
+ if (++sprite->data[4] > 5)
+ {
+ sprite->data[4] = 0;
+ if (sprite->data[5] <= 15 && ++sprite->data[5] > 15)
+ sprite->data[5] = 16;
+ }
+ if (++sprite->data[3] > 20)
+ DestroyAnimSprite(sprite);
+ break;
+ }
+}
+
+void sub_80B75E0(u8 taskId)
+{
+ struct ScanlineEffectParams sp;
+ struct Task *task = &gTasks[taskId];
+ u16 i;
+ u8 r1;
+
+ if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
+ {
+ sp.dmaDest = &REG_BG1HOFS;
+ task->data[2] = gBattle_BG1_X;
+ }
+ else
+ {
+ sp.dmaDest = &REG_BG2HOFS;
+ task->data[2] = gBattle_BG2_X;
+ }
+ sp.dmaControl = 0xA2600001;
+ sp.initState = 1;
+ sp.unused9 = 0;
+ r1 = GetBattlerYCoordWithElevation(gBattleAnimAttacker);
+ task->data[3] = r1 - 32;
+ task->data[4] = r1 + 32;
+ if (task->data[3] < 0)
+ task->data[3] = 0;
+ for (i = task->data[3]; i <= task->data[4]; ++i)
+ {
+ gScanlineEffectRegBuffers[0][i] = task->data[2];
+ gScanlineEffectRegBuffers[1][i] = task->data[2];
+ }
+ ScanlineEffect_SetParams(sp);
+ task->func = sub_80B76B0;
+}
+
+static void sub_80B76B0(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[7] > 1)
+ {
+ task->data[7] = 0;
+ if (++task->data[6] == 3)
+ ++task->data[0];
+ }
+ sub_80B776C(task);
+ break;
+ case 1:
+ if (++task->data[1] > 0x3C)
+ ++task->data[0];
+ sub_80B776C(task);
+ break;
+ case 2:
+ if (++task->data[7] > 1)
+ {
+ task->data[7] = 0;
+ if (--task->data[6] == 0)
+ ++task->data[0];
+ }
+ sub_80B776C(task);
+ break;
+ case 3:
+ gScanlineEffect.state = 3;
+ ++task->data[0];
+ break;
+ case 4:
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B776C(struct Task *task)
+{
+ u16 i, r3 = task->data[5];
+
+ for (i = task->data[3]; i <= task->data[4]; ++i)
+ {
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = ((gSineTable[r3] * task->data[6]) >> 7) + task->data[2];
+ r3 = (r3 + 8) & 0xFF;
+ }
+ task->data[5] = (task->data[5] + 9) & 0xFF;
+}
+
+static void sub_80B77E4(struct Sprite *sprite)
+{
+ s32 i, r6 = (gBattleAnimArgs[2] * 3) / 5;
+
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[4];
+ sprite->data[1] = Cos(gBattleAnimArgs[1], gBattleAnimArgs[2]);
+ sprite->data[2] = Sin(gBattleAnimArgs[1], r6);
+ sprite->pos1.x += sprite->data[1] * gBattleAnimArgs[0];
+ sprite->pos1.y += sprite->data[2] * gBattleAnimArgs[0];
+ sprite->data[3] = gBattleAnimArgs[3];
+ sprite->callback = sub_80B7894;
+ for (i = 0; i < 7; ++i)
+ gUnknown_20399A4[i] = sprite->data[i];
+}
+
+static void sub_80B7894(struct Sprite *sprite)
+{
+ sprite->data[4] += sprite->data[1];
+ sprite->data[5] += sprite->data[2];
+ sprite->pos2.x = sprite->data[4] / 10;
+ sprite->pos2.y = sprite->data[5] / 10;
+ if (++sprite->data[0] > sprite->data[3])
+ DestroyAnimSprite(sprite);
+}
diff --git a/src/fame_checker.c b/src/fame_checker.c
index 0278fda18..e803a9700 100644
--- a/src/fame_checker.c
+++ b/src/fame_checker.c
@@ -552,7 +552,7 @@ static void Task_TopMenuHandleInput(u8 taskId)
if (FindTaskIdByFunc(Task_FCOpenOrCloseInfoBox) == 0xFF)
{
RunTextPrinters();
- if ((JOY_NEW(SELECT_BUTTON)) && !sFameCheckerData->inPickMode && sFameCheckerData->savedCallback != ReturnToBagFromKeyItem)
+ if ((JOY_NEW(SELECT_BUTTON)) && !sFameCheckerData->inPickMode && sFameCheckerData->savedCallback != CB2_BagMenuFromStartMenu)
task->func = Task_StartToCloseFameChecker;
else if (JOY_NEW(START_BUTTON))
{
@@ -802,7 +802,7 @@ static void WipeMsgBoxAndTransfer(void)
static void Setup_DrawMsgAndListBoxes(void)
{
- sub_80F6E9C();
+ LoadStdWindowFrameGfx();
DrawDialogueFrame(FCWINDOWID_MSGBOX, TRUE);
FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_MSGBOX);
FC_PutWindowTilemapAndCopyWindowToVramMode3(FCWINDOWID_LIST);
diff --git a/src/field_fadetransition.c b/src/field_fadetransition.c
index 62254a559..6a539b60e 100644
--- a/src/field_fadetransition.c
+++ b/src/field_fadetransition.c
@@ -475,25 +475,25 @@ static void sub_807E31C(u8 taskId)
}
}
-static void sub_807E378(u8 taskId)
+static void Task_WaitFadeAndCreateStartMenuTask(u8 taskId)
{
if (sub_807E418() == TRUE)
{
DestroyTask(taskId);
- CreateTask(sub_806F1F0, 80);
+ CreateTask(Task_StartMenuHandleInput, 80);
}
}
-void sub_807E3A0(void)
+void FadeTransition_FadeInOnReturnToStartMenu(void)
{
sub_807DC00();
- CreateTask(sub_807E378, 80);
+ CreateTask(Task_WaitFadeAndCreateStartMenuTask, 80);
ScriptContext2_Enable();
}
-bool32 sub_807E3BC(void)
+bool8 FieldCB2_ReturnToStartMenuInit(void)
{
- sub_806F1D4();
+ SetUpReturnToStartMenu();
return FALSE;
}
@@ -522,7 +522,7 @@ static bool32 sub_807E40C(void)
bool32 sub_807E418(void)
{
- if (sub_807AA70() == TRUE && sub_80F83B0())
+ if (field_weather_is_fade_finished() == TRUE && sub_80F83B0())
return TRUE;
else
return FALSE;
diff --git a/src/flying.c b/src/flying.c
new file mode 100644
index 000000000..8c3ccb52a
--- /dev/null
+++ b/src/flying.c
@@ -0,0 +1,1289 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "palette.h"
+#include "trig.h"
+#include "constants/battle_anim.h"
+#include "random.h"
+
+static void sub_80B18E4(struct Sprite *sprite);
+static void sub_80B1A1C(struct Sprite *sprite);
+static void sub_80B1AB8(struct Sprite *sprite);
+static void sub_80B1BB0(struct Sprite *sprite);
+static void sub_80B1C3C(struct Sprite *sprite);
+static void sub_80B1D88(struct Sprite *sprite);
+static void sub_80B24C0(struct Sprite *sprite);
+static void sub_80B2514(struct Sprite *sprite);
+static void sub_80B2780(struct Sprite *sprite);
+static void sub_80B2914(struct Sprite *sprite);
+static void sub_80B2974(struct Sprite *sprite);
+static void sub_80B2A08(struct Sprite *sprite);
+static void sub_80B2AF4(struct Sprite *sprite);
+static void sub_80B2BD8(struct Sprite *sprite);
+static void sub_80B2CE4(struct Sprite *sprite);
+static void sub_80B2D64(struct Sprite *sprite);
+static void sub_80B190C(struct Sprite *sprite);
+static void sub_80B198C(u8 taskId);
+static void sub_80B1A9C(struct Sprite *sprite);
+static void sub_80B1BF8(struct Sprite *sprite);
+static void sub_80B1CC0(struct Sprite *sprite);
+static void sub_80B1F94(struct Sprite *sprite);
+static void sub_80B268C(struct Sprite *sprite);
+static void sub_80B2820(struct Sprite *sprite);
+static void sub_80B2A50(struct Sprite *sprite);
+static void sub_80B2AB0(struct Sprite *sprite);
+static void sub_80B2C88(struct Sprite *sprite);
+static void sub_80B2CF8(struct Sprite *sprite);
+static void sub_80B2E20(struct Sprite *sprite);
+
+const struct SpriteTemplate gUnknown_83E6AE8 =
+{
+ .tileTag = ANIM_TAG_GUST,
+ .paletteTag = ANIM_TAG_GUST,
+ .oam = &gOamData_83ACA20,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B18E4,
+};
+
+static const union AffineAnimCmd gUnknown_83E6B00[] =
+{
+ AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0xA, 0x0, 0, 24),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6B18[] =
+{
+ gUnknown_83E6B00,
+};
+
+const struct SpriteTemplate gUnknown_83E6B1C =
+{
+ .tileTag = ANIM_TAG_GUST,
+ .paletteTag = ANIM_TAG_GUST,
+ .oam = &gOamData_83ACA80,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6B18,
+ .callback = sub_80B1A1C,
+};
+
+static const union AnimCmd gUnknown_83E6B34[] =
+{
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_FRAME(0, 3, .hFlip = TRUE),
+ ANIMCMD_FRAME(0, 3, .vFlip = TRUE),
+ ANIMCMD_FRAME(0, 3, .vFlip = TRUE, .hFlip = TRUE),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E6B48[] =
+{
+ gUnknown_83E6B34,
+};
+
+const struct SpriteTemplate gUnknown_83E6B4C =
+{
+ .tileTag = ANIM_TAG_AIR_WAVE_2,
+ .paletteTag = ANIM_TAG_AIR_WAVE_2,
+ .oam = &gOamData_83AC9F8,
+ .anims = gUnknown_83E6B48,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B1AB8,
+};
+
+static const union AffineAnimCmd gUnknown_83E6B64[] =
+{
+ AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6),
+ AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5),
+ AFFINEANIMCMD_FRAME(0xFFF0, 0x20, 0, 10),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6B8C[] =
+{
+ gUnknown_83E6B64,
+};
+
+static const union AffineAnimCmd gUnknown_83E6B90[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 50, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E6B9C[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -40, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6BB0[] =
+{
+ gUnknown_83E6B90,
+ gUnknown_83E6B9C,
+};
+
+const struct SpriteTemplate gUnknown_83E6BB8 =
+{
+ .tileTag = ANIM_TAG_ROUND_SHADOW,
+ .paletteTag = ANIM_TAG_ROUND_SHADOW,
+ .oam = &gOamData_83ACAA0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6B8C,
+ .callback = sub_80B1BB0,
+};
+
+const struct SpriteTemplate gUnknown_83E6BD0 =
+{
+ .tileTag = ANIM_TAG_ROUND_SHADOW,
+ .paletteTag = ANIM_TAG_ROUND_SHADOW,
+ .oam = &gOamData_83ACA40,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6BB0,
+ .callback = sub_80B1C3C,
+};
+
+static const union AnimCmd gUnknown_83E6BE8[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E6BF0[] =
+{
+ ANIMCMD_FRAME(16, 0, .hFlip = TRUE),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6BF8[] =
+{
+ gUnknown_83E6BE8,
+ gUnknown_83E6BF0,
+};
+
+const struct SpriteTemplate gUnknown_83E6C00 =
+{
+ .tileTag = ANIM_TAG_WHITE_FEATHER,
+ .paletteTag = ANIM_TAG_WHITE_FEATHER,
+ .oam = &gOamData_83ACA38,
+ .anims = gUnknown_83E6BF8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B1D88,
+};
+
+// not used
+static const u16 gUnknown_83E6C18[] = INCBIN_U16("graphics/battle_anims/sprites/unk_83E6C18.gbapal");
+
+const struct SpriteTemplate gUnknown_83E6C38 =
+{
+ .tileTag = ANIM_TAG_SMALL_BUBBLES,
+ .paletteTag = ANIM_TAG_SMALL_BUBBLES,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B24C0,
+};
+
+const struct SpriteTemplate gUnknown_83E6C50 =
+{
+ .tileTag = ANIM_TAG_WHITE_FEATHER,
+ .paletteTag = ANIM_TAG_WHITE_FEATHER,
+ .oam = &gOamData_83ACA38,
+ .anims = gUnknown_83E6BF8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2514,
+};
+
+static const union AnimCmd gUnknown_83E6C68[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_FRAME(8, 1),
+ ANIMCMD_FRAME(16, 1),
+ ANIMCMD_FRAME(8, 1, .hFlip = TRUE),
+ ANIMCMD_FRAME(0, 1, .hFlip = TRUE),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6C80[] =
+{
+ gUnknown_83E6C68,
+};
+
+const struct SpriteTemplate gUnknown_83E6C84 =
+{
+ .tileTag = ANIM_TAG_WHIRLWIND_LINES,
+ .paletteTag = ANIM_TAG_WHIRLWIND_LINES,
+ .oam = &gOamData_83AC9F8,
+ .anims = gUnknown_83E6C80,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2780,
+};
+
+static const union AffineAnimCmd gUnknown_83E6C9C[] =
+{
+ AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6),
+ AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5),
+ AFFINEANIMCMD_FRAME(0xFFEC, 0x0, 0, 7),
+ AFFINEANIMCMD_FRAME(0xFFEC, 0xFFEC, 0, 5),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6CCC[] =
+{
+ gUnknown_83E6C9C,
+};
+
+const struct SpriteTemplate gUnknown_83E6CD0 =
+{
+ .tileTag = ANIM_TAG_ROUND_SHADOW,
+ .paletteTag = ANIM_TAG_ROUND_SHADOW,
+ .oam = &gOamData_83ACAA0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6CCC,
+ .callback = sub_80B2914,
+};
+
+static const union AffineAnimCmd gUnknown_83E6CE8[] =
+{
+ AFFINEANIMCMD_FRAME(0xA0, 0x100, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6CF8[] =
+{
+ gUnknown_83E6CE8,
+};
+
+const struct SpriteTemplate gUnknown_83E6CFC =
+{
+ .tileTag = ANIM_TAG_ROUND_SHADOW,
+ .paletteTag = ANIM_TAG_ROUND_SHADOW,
+ .oam = &gOamData_83ACAA0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6CF8,
+ .callback = sub_80B2974,
+};
+
+static const union AffineAnimCmd gUnknown_83E6D14[] =
+{
+ AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6),
+ AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5),
+ AFFINEANIMCMD_FRAME(0xFFF0, 0x20, 0, 10),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6D3C[] =
+{
+ gUnknown_83E6D14,
+};
+
+const struct SpriteTemplate gUnknown_83E6D40 =
+{
+ .tileTag = ANIM_TAG_ROUND_SHADOW,
+ .paletteTag = ANIM_TAG_ROUND_SHADOW,
+ .oam = &gOamData_83ACAA0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6D3C,
+ .callback = sub_80B2A08,
+};
+
+// not used
+static const union AffineAnimCmd gUnknown_83E6D58[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x0, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x20, 0, 12),
+ AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 11),
+ AFFINEANIMCMD_END,
+};
+
+// not used
+static const union AffineAnimCmd *const gUnknown_83E6D80[] =
+{
+ gUnknown_83E6D58,
+};
+
+const struct SpriteTemplate gUnknown_83E6D7C =
+{
+ .tileTag = ANIM_TAG_SPLASH,
+ .paletteTag = ANIM_TAG_SPLASH,
+ .oam = &gOamData_83ACAA0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2AF4,
+};
+
+const struct SpriteTemplate gUnknown_83E6D94 =
+{
+ .tileTag = ANIM_TAG_SWEAT_BEAD,
+ .paletteTag = ANIM_TAG_SWEAT_BEAD,
+ .oam = &gOamData_83AC9C8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2BD8,
+};
+
+const struct SpriteTemplate gUnknown_83E6DAC =
+{
+ .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .oam = &gOamData_83ACB00,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2CE4,
+};
+
+const struct SpriteTemplate gUnknown_83E6DB4 =
+{
+ .tileTag = ANIM_TAG_BIRD,
+ .paletteTag = ANIM_TAG_BIRD,
+ .oam = &gOamData_83ACAA0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2D64,
+};
+
+static void sub_80B18E4(struct Sprite *sprite)
+{
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ sprite->pos1.y += 20;
+ sprite->data[1] = 191;
+ sprite->callback = sub_80B190C;
+ sprite->callback(sprite);
+}
+
+static void sub_80B190C(struct Sprite *sprite)
+{
+ sprite->pos2.x = Sin(sprite->data[1], 32);
+ sprite->pos2.y = Cos(sprite->data[1], 8);
+ sprite->data[1] += 5;
+ sprite->data[1] &= 0xFF;
+ if (++sprite->data[0] == 71)
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80B194C(u8 taskId)
+{
+ gTasks[taskId].data[0] = gBattleAnimArgs[1];
+ gTasks[taskId].data[1] = gBattleAnimArgs[0];
+ gTasks[taskId].data[2] = IndexOfSpritePaletteTag(ANIM_TAG_GUST);
+ gTasks[taskId].func = sub_80B198C;
+}
+
+static void sub_80B198C(u8 taskId)
+{
+ u8 data2;
+ u16 temp;
+ s32 i, base;
+
+ if (gTasks[taskId].data[10]++ == gTasks[taskId].data[1])
+ {
+ gTasks[taskId].data[10] = 0;
+ data2 = gTasks[taskId].data[2];
+ temp = gPlttBufferFaded[16 * data2 + 0x108];
+ i = 7;
+ base = data2 * 16;
+ do
+ {
+ gPlttBufferFaded[base + 0x101 + i] = gPlttBufferFaded[base + 0x100 + i];
+ } while (--i > 0);
+
+ gPlttBufferFaded[base + 0x101] = temp;
+ }
+ if (--gTasks[taskId].data[0] == 0)
+ DestroyAnimVisualTask(taskId);
+}
+
+static void sub_80B1A1C(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, TRUE);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
+ InitAnimLinearTranslation(sprite);
+ sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
+ StoreSpriteCallbackInData6(sprite, sub_80B1A9C);
+}
+
+static void sub_80B1A9C(struct Sprite *sprite)
+{
+ if (AnimTranslateLinear(sprite))
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B1AB8(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ }
+ if (IsContest())
+ {
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ }
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[4];
+ if (gBattleAnimArgs[6] == 0)
+ {
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->data[2], &sprite->data[4]);
+ }
+ sprite->data[2] = sprite->data[2] + gBattleAnimArgs[2];
+ sprite->data[4] = sprite->data[4] + gBattleAnimArgs[3];
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ SeekSpriteAnim(sprite, gBattleAnimArgs[5]);
+}
+
+static void sub_80B1BB0(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, TRUE);
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->callback = sub_80B1BF8;
+ gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = TRUE;
+}
+
+static void sub_80B1BF8(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ }
+ else
+ {
+ sprite->data[2] += sprite->data[1];
+ sprite->pos2.y -= (sprite->data[2] >> 8);
+ }
+ if (sprite->pos1.y + sprite->pos2.y < -32)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B1C3C(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->pos1.x = 272;
+ sprite->pos1.y = -32;
+ StartSpriteAffineAnim(sprite, 1);
+ }
+ else
+ {
+ sprite->pos1.x = -32;
+ sprite->pos1.y = -32;
+ }
+ sprite->data[0] = gBattleAnimArgs[0];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ InitAnimLinearTranslation(sprite);
+ sprite->callback = sub_80B1CC0;
+}
+
+static void sub_80B1CC0(struct Sprite *sprite)
+{
+ sprite->data[0] = 1;
+ AnimTranslateLinear(sprite);
+ if (((u16)sprite->data[3] >> 8) > 200)
+ {
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos2.x = 0;
+ sprite->data[3] &= 0xFF;
+ }
+ if (sprite->pos1.x + sprite->pos2.x < -32
+ || sprite->pos1.x + sprite->pos2.x > 272
+ || sprite->pos1.y + sprite->pos2.y > 160)
+ {
+ gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = FALSE;
+ DestroyAnimSprite(sprite);
+ }
+}
+
+void sub_80B1D3C(struct Sprite *sprite)
+{
+ if (sprite->data[0]-- <= 0)
+ {
+ if (sprite->oam.affineMode & ST_OAM_AFFINE_ON_MASK)
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->oam.affineMode = 0;
+ }
+ DestroySprite(sprite);
+ --gAnimVisualTaskCount;
+ }
+}
+
+struct FeatherDanceData
+{
+ u16 unk0_0a:1;
+ u16 unk0_0b:1;
+ u16 unk0_0c:1;
+ u16 unk0_0d:1;
+ u16 unk0_1:4;
+ u16 unk1:8;
+ u16 unk2;
+ s16 unk4;
+ u16 unk6;
+ u16 unk8;
+ u16 unkA;
+ u8 unkC[2];
+ u16 unkE_0:1;
+ u16 unkE_1:15;
+};
+
+static void sub_80B1D88(struct Sprite *sprite)
+{
+ u8 battler, matrixNum, sinIndex;
+ s16 spriteCoord, sinVal;
+ struct FeatherDanceData *data = (struct FeatherDanceData *)sprite->data;
+
+ if (gBattleAnimArgs[7] & 0x100)
+ battler = gBattleAnimAttacker;
+ else
+ battler = gBattleAnimTarget;
+ if (GetBattlerSide(battler) == B_SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ sprite->pos1.x = GetBattlerSpriteCoord(battler, BATTLER_COORD_ATTR_HEIGHT) + gBattleAnimArgs[0];
+ spriteCoord = GetBattlerSpriteCoord(battler, BATTLER_COORD_ATTR_WIDTH);
+ sprite->pos1.y = spriteCoord + gBattleAnimArgs[1];
+ data->unk8 = sprite->pos1.y << 8;
+ data->unkE_1 = spriteCoord + gBattleAnimArgs[6];
+ data->unk0_0c = 1;
+ data->unk2 = gBattleAnimArgs[2] & 0xFF;
+ data->unkA = (gBattleAnimArgs[2] >> 8) & 0xFF;
+ data->unk4 = gBattleAnimArgs[3];
+ data->unk6 = gBattleAnimArgs[4];
+ *(u16 *)(data->unkC) = gBattleAnimArgs[5];
+ if (data->unk2 >= 64 && data->unk2 <= 191)
+ {
+ if (!IsContest())
+ sprite->oam.priority = GetBattlerSpriteBGPriority(battler) + 1;
+ else
+ sprite->oam.priority = GetBattlerSpriteBGPriority(battler);
+ data->unkE_0 = 0;
+ if (!(data->unk4 & 0x8000))
+ {
+ sprite->hFlip ^= 1;
+ sprite->animNum = sprite->hFlip;
+ sprite->animBeginning = TRUE;
+ sprite->animEnded = FALSE;
+ }
+ }
+ else
+ {
+ sprite->oam.priority = GetBattlerSpriteBGPriority(battler);
+ data->unkE_0 = 1;
+ if (data->unk4 & 0x8000)
+ {
+ sprite->hFlip ^= 1;
+ sprite->animNum = sprite->hFlip;
+
+ sprite->animBeginning = TRUE;
+ sprite->animEnded = FALSE;
+ }
+ }
+ data->unk0_1 = data->unk2 >> 6;
+ sprite->pos2.x = (gSineTable[data->unk2] * data->unkC[0]) >> 8;
+ matrixNum = sprite->oam.matrixNum;
+ sinIndex = (-sprite->pos2.x >> 1) + data->unkA;
+ sinVal = gSineTable[sinIndex];
+ gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[sinIndex + 64];
+ if (sprite)
+ {
+ gOamMatrices[matrixNum].b = sinVal;
+ gOamMatrices[matrixNum].c = -sinVal;
+ }
+ else // pointless, exactly the same
+ {
+ gOamMatrices[matrixNum].b = sinVal;
+ gOamMatrices[matrixNum].c = -sinVal;
+ }
+ sprite->callback = sub_80B1F94;
+}
+
+static void sub_80B1F94(struct Sprite *sprite)
+{
+ u8 matrixNum, sinIndex;
+ s16 sinVal = 0;
+ struct FeatherDanceData *data = (struct FeatherDanceData *)sprite->data;
+
+ if (data->unk0_0a)
+ {
+ if (data->unk1-- % 256 == 0)
+ {
+ data->unk0_0a = 0;
+ data->unk1 = 0;
+ }
+ }
+ else
+ {
+ switch (data->unk2 / 64)
+ {
+ case 0:
+ if (data->unk0_1 << 24 >> 24 == 1) // the shifts have to be here
+ {
+ data->unk0_0d = 1;
+ data->unk0_0a = 1;
+ data->unk1 = 0;
+ }
+ else if (data->unk0_1 << 24 >> 24 == 3)
+ {
+ data->unk0_0b ^= 1;
+ data->unk0_0a = 1;
+ data->unk1 = 0;
+ }
+ else if (data->unk0_0d)
+ {
+ sprite->hFlip ^= 1;
+ sprite->animNum = sprite->hFlip;
+ sprite->animBeginning = TRUE;
+ sprite->animEnded = FALSE;
+ if (data->unk0_0c)
+ {
+ if (!IsContest())
+ {
+ if (!data->unkE_0)
+ {
+ --sprite->oam.priority;
+ data->unkE_0 ^= 1;
+ }
+ else
+ {
+ ++sprite->oam.priority;
+ data->unkE_0 ^= 1;
+ }
+ }
+ else
+ {
+ if (!data->unkE_0)
+ {
+ sprite->subpriority -= 12;
+ data->unkE_0 ^= 1;
+ }
+ else
+ {
+ sprite->subpriority += 12;
+ data->unkE_0 ^= 1;
+ }
+ }
+ }
+ data->unk0_0d = 0;
+ data->unk2;
+ }
+ data->unk0_1 = 0;
+ break;
+ case 1:
+ if (data->unk0_1 << 24 >> 24 == 0)
+ {
+ data->unk0_0d = 1;
+ data->unk0_0a = 1;
+ data->unk1 = 0;
+ }
+ else if (data->unk0_1 << 24 >> 24 == 2)
+ {
+ data->unk0_0a = 1;
+ data->unk1 = 0;
+ }
+ else if (data->unk0_0d)
+ {
+ sprite->hFlip ^= 1;
+ sprite->animNum = sprite->hFlip;
+ sprite->animBeginning = TRUE;
+ sprite->animEnded = FALSE;
+ if (data->unk0_0c)
+ {
+ if (!IsContest())
+ {
+ if (!data->unkE_0)
+ {
+ --sprite->oam.priority;
+ data->unkE_0 ^= 1;
+ }
+ else
+ {
+ ++sprite->oam.priority;
+ data->unkE_0 ^= 1;
+ }
+ }
+ else
+ {
+ if (!data->unkE_0)
+ {
+ sprite->subpriority -= 12;
+ data->unkE_0 ^= 1;
+ }
+ else
+ {
+ sprite->subpriority += 12;
+ data->unkE_0 ^= 1;
+ }
+ }
+ }
+ data->unk0_0d = 0;
+ }
+ data->unk0_1 = 1;
+ break;
+ case 2:
+ if (data->unk0_1 << 24 >> 24 == 3)
+ {
+ data->unk0_0d = 1;
+ data->unk0_0a = 1;
+ data->unk1 = 0;
+ }
+ else if (data->unk0_1 << 24 >> 24 == 1)
+ {
+ data->unk0_0a = 1;
+ data->unk1 = 0;
+ }
+ else if (data->unk0_0d)
+ {
+ sprite->hFlip ^= 1;
+ sprite->animNum = sprite->hFlip;
+ sprite->animBeginning = TRUE;
+ sprite->animEnded = FALSE;
+ if (data->unk0_0c)
+ {
+ if (!IsContest())
+ {
+ if (!data->unkE_0)
+ {
+ --sprite->oam.priority;
+ data->unkE_0 ^= 1;
+ }
+ else
+ {
+ ++sprite->oam.priority;
+ data->unkE_0 ^= 1;
+ }
+ }
+ else
+ {
+ if (!data->unkE_0)
+ {
+ sprite->subpriority -= 12;
+ data->unkE_0 ^= 1;
+ }
+ else
+ {
+ sprite->subpriority += 12;
+ data->unkE_0 ^= 1;
+ }
+ }
+ }
+ data->unk0_0d = 0;
+ }
+ data->unk0_1 = 2;
+ break;
+ case 3:
+ if (data->unk0_1 << 24 >> 24 == 2)
+ {
+ data->unk0_0d = 1;
+ }
+ else if (data->unk0_1 << 24 >> 24 == 0)
+ {
+ data->unk0_0b ^= 1;
+ data->unk0_0a = 1;
+ data->unk1 = 0;
+ }
+ else if (data->unk0_0d)
+ {
+ sprite->hFlip ^= 1;
+ sprite->animNum = sprite->hFlip;
+ sprite->animBeginning = TRUE;
+ sprite->animEnded = FALSE;
+ if (data->unk0_0c)
+ {
+ if (!IsContest())
+ {
+ if (!data->unkE_0)
+ {
+ --sprite->oam.priority;
+ data->unkE_0 ^= 1;
+ }
+ else
+ {
+ ++sprite->oam.priority;
+ data->unkE_0 ^= 1;
+ }
+ }
+ else
+ {
+ if (!data->unkE_0)
+ {
+ sprite->subpriority -= 12;
+ data->unkE_0 ^= 1;
+ }
+ else
+ {
+ sprite->subpriority += 12;
+ data->unkE_0 ^= 1;
+ }
+ }
+ }
+ data->unk0_0d = 0;
+ }
+ data->unk0_1 = 3;
+ break;
+ }
+ #ifndef NONMATCHING
+ asm("":::"r8");
+ #endif
+ sprite->pos2.x = (data->unkC[data->unk0_0b] * gSineTable[data->unk2]) >> 8;
+ matrixNum = sprite->oam.matrixNum;
+ sinIndex = (-sprite->pos2.x >> 1) + data->unkA;
+ sinVal = gSineTable[sinIndex];
+ gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[sinIndex + 64];
+ gOamMatrices[matrixNum].b = sinVal;
+ gOamMatrices[matrixNum].c = -sinVal;
+ data->unk8 += data->unk6;
+ sprite->pos1.y = data->unk8 >> 8;
+ if (data->unk4 & 0x8000)
+ data->unk2 = (data->unk2 - (data->unk4 & 0x7FFF)) & 0xFF;
+ else
+ data->unk2 = (data->unk2 + (data->unk4 & 0x7FFF)) & 0xFF;
+ if (sprite->pos1.y + sprite->pos2.y >= data->unkE_1)
+ {
+ sprite->data[0] = 0;
+ sprite->callback = sub_80B1D3C;
+ }
+ }
+}
+
+static void sub_80B24C0(struct Sprite *sprite)
+{
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ sprite->callback = TranslateAnimSpriteToTargetMonLocation;
+}
+
+static void sub_80B2514(struct Sprite *sprite)
+{
+ u8 matrixNum;
+ s16 rn, sinVal;
+
+ sprite->data[1] = gBattleAnimArgs[0];
+ sprite->data[2] = gBattleAnimArgs[1];
+ sprite->data[3] = gBattleAnimArgs[2];
+ if (!IsContest())
+ {
+ if (gBattlerPositions[gBattleAnimTarget] & B_POSITION_OPPONENT_LEFT)
+ sprite->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_ATTR_WIDTH) + gBattleAnimArgs[3];
+ else
+ sprite->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_ATTR_WIDTH) + 40;
+ if (gBattleAnimArgs[4])
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) + 1;
+ else
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
+ }
+ else
+ {
+ sprite->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_ATTR_WIDTH) + gBattleAnimArgs[3];
+ }
+ sprite->data[4] = gSineTable[sprite->data[1] & 0xFF];
+ sprite->data[5] = -gSineTable[(sprite->data[1] & 0xFF) + 64];
+ sprite->data[6] = 0;
+ sprite->pos2.y = 0;
+ sprite->pos2.x = 0;
+ matrixNum = sprite->oam.matrixNum;
+ sprite->data[1] = (u16)sprite->data[1] >> 8;
+ rn = Random();
+ if (rn & 0x8000)
+ sprite->data[1] = 0xFF - sprite->data[1];
+ sinVal = gSineTable[sprite->data[1]];
+ gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[sprite->data[1] + 64];
+ gOamMatrices[matrixNum].b = sinVal;
+ gOamMatrices[matrixNum].c = -sinVal;
+ sprite->animBeginning = TRUE;
+ sprite->animEnded = FALSE;
+ if (rn & 1)
+ {
+ sprite->animNum = 1;
+ sprite->hFlip = TRUE;
+ }
+ sprite->callback = sub_80B268C;
+}
+
+static void sub_80B268C(struct Sprite *sprite)
+{
+ struct FeatherDanceData fData;
+ struct FeatherDanceData *tData = (struct FeatherDanceData *)sprite->data;
+ u8 item;
+ u32 x, y;
+
+ ++sprite->data[0];
+ if (sprite->data[0] <= 4)
+ return;
+ sprite->pos2.x = (sprite->data[4] * sprite->data[6]) >> 8;
+ sprite->pos2.y = (sprite->data[5] * sprite->data[6]) >> 8;
+ sprite->data[6] += sprite->data[3] & 0xFF;
+ if (sprite->data[6] < (sprite->data[2] & 0xFF))
+ return;
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ memcpy(&fData, tData, sizeof(struct FeatherDanceData));
+ memset(tData, 0, sizeof(struct FeatherDanceData));
+ tData->unk8 = sprite->pos1.y << 8;
+ tData->unk6 = fData.unk6 >> 8;
+ tData->unk2 = 0;
+ tData->unkA = fData.unk2;
+ if (sprite->animNum != 0)
+ {
+ if (tData->unk6 & 8)
+ tData->unk4 = 0x8001;
+ else
+ tData->unk4 = 0x8002;
+ }
+ else if (tData->unk6 & 8)
+ {
+ tData->unk4 = 1;
+ }
+ else
+ {
+ tData->unk4 = 2;
+ }
+ item = fData.unk4 >> 8;
+ tData->unkC[0] = item;
+ tData->unkC[1] = item - 2;
+ x = (((u16 *)&fData)[7] << 1);
+ y = (((u16 *)tData)[7] & 1);
+ ((u16 *)tData)[7] = y | x;
+ sprite->callback = sub_80B1F94;
+}
+
+static void sub_80B2780(struct Sprite *sprite)
+{
+ u16 arg;
+ u8 mult;
+
+ if (!gBattleAnimArgs[2])
+ InitSpritePosToAnimAttacker(sprite, 0);
+ else
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ if ((!gBattleAnimArgs[2] && !GetBattlerSide(gBattleAnimAttacker))
+ || (gBattleAnimArgs[2] == 1 && !GetBattlerSide(gBattleAnimTarget)))
+ sprite->pos1.x += 8;
+ SeekSpriteAnim(sprite, gBattleAnimArgs[4]);
+ sprite->pos1.x -= 32;
+ sprite->data[1] = 0x0ccc;
+ arg = gBattleAnimArgs[4];
+ mult = 12;
+ sprite->pos2.x += mult * arg;
+ sprite->data[0] = arg;
+ sprite->data[7] = gBattleAnimArgs[3];
+ sprite->callback = sub_80B2820;
+}
+
+static void sub_80B2820(struct Sprite *sprite)
+{
+ sprite->pos2.x += sprite->data[1] >> 8;
+ if (++sprite->data[0] == 6)
+ {
+ sprite->data[0] = 0;
+ sprite->pos2.x = 0;
+ StartSpriteAnim(sprite, 0);
+ }
+
+ if (--sprite->data[7] == -1)
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80B2868(u8 taskId)
+{
+ if (!(gTasks[taskId].data[0] % 32))
+ {
+ ++gAnimVisualTaskCount;
+ gBattleAnimArgs[0] = Sin(gTasks[taskId].data[0], -13);
+ gBattleAnimArgs[1] = Cos(gTasks[taskId].data[0], -13);
+ gBattleAnimArgs[2] = 1;
+ gBattleAnimArgs[3] = 3;
+ CreateSpriteAndAnimate(&gUnknown_83E7C98,
+ GetBattlerSpriteCoord(gBattleAnimTarget, 2),
+ GetBattlerSpriteCoord(gBattleAnimTarget, 3),
+ 3);
+ }
+ gTasks[taskId].data[0] += 8;
+ if (gTasks[taskId].data[0] > 255)
+ DestroyAnimVisualTask(taskId);
+}
+
+static void sub_80B2914(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ InitSpritePosToAnimAttacker(sprite, 1);
+ gSprites[GetAnimBattlerSpriteId(0)].invisible = TRUE;
+ ++sprite->data[0];
+ break;
+ case 1:
+ if (sprite->affineAnimEnded)
+ DestroyAnimSprite(sprite);
+ break;
+ }
+}
+
+static void sub_80B2974(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1);
+ sprite->pos2.y = -sprite->pos1.y - 32;
+ ++sprite->data[0];
+ break;
+ case 1:
+ sprite->pos2.y += 10;
+ if (sprite->pos2.y >= 0)
+ ++sprite->data[0];
+ break;
+ case 2:
+ sprite->pos2.y -= 10;
+ if (sprite->pos1.y + sprite->pos2.y < -32)
+ {
+ gSprites[GetAnimBattlerSpriteId(0)].invisible = FALSE;
+ DestroyAnimSprite(sprite);
+ }
+ break;
+ }
+}
+
+static void sub_80B2A08(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, 1);
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->callback = sub_80B2A50;
+ gSprites[GetAnimBattlerSpriteId(0)].invisible = TRUE;
+}
+
+static void sub_80B2A50(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ }
+ else if (sprite->pos1.y + sprite->pos2.y > -32)
+ {
+ sprite->data[2] += sprite->data[1];
+ sprite->pos2.y -= (sprite->data[2] >> 8);
+ }
+ else
+ {
+ sprite->invisible = TRUE;
+ if (sprite->data[3]++ > 20)
+ sprite->callback = sub_80B2AB0;
+ }
+}
+
+static void sub_80B2AB0(struct Sprite *sprite)
+{
+ sprite->pos2.y += sprite->data[2] >> 8;
+ if (sprite->pos1.y + sprite->pos2.y > -32)
+ sprite->invisible = FALSE;
+ if (sprite->pos2.y > 0)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B2AF4(struct Sprite *sprite)
+{
+ u32 matrixNum;
+ s32 t1, t2;
+
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (!gBattleAnimArgs[0])
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1);
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1);
+ }
+ sprite->data[1] = 512;
+ TrySetSpriteRotScale(sprite, 0, 256, sprite->data[1], 0);
+ ++sprite->data[0];
+ break;
+ case 1:
+ if (sprite->data[2] <= 11)
+ sprite->data[1] -= 40;
+ else
+ sprite->data[1] += 40;
+ ++sprite->data[2];
+ TrySetSpriteRotScale(sprite, 0, 256, sprite->data[1], 0);
+ matrixNum = sprite->oam.matrixNum;
+ t1 = 15616;
+ t2 = t1 / gOamMatrices[matrixNum].d + 1;
+ if (t2 > 128)
+ t2 = 128;
+ t2 = (64 - t2) / 2;
+ sprite->pos2.y = t2;
+ if (sprite->data[2] == 24)
+ {
+ sub_8075AD8(sprite);
+ DestroyAnimSprite(sprite);
+ }
+ break;
+ }
+}
+
+static void sub_80B2BD8(struct Sprite *sprite)
+{
+ s32 v1 = 0x1FF & Random();
+ s32 v2 = 0x7F & Random();
+
+ if (v1 % 2)
+ sprite->data[0] = 736 + v1;
+ else
+ sprite->data[0] = 736 - v1;
+
+ if (v2 % 2)
+ sprite->data[1] = 896 + v2;
+ else
+ sprite->data[1] = 896 - v2;
+ sprite->data[2] = gBattleAnimArgs[0];
+ if (sprite->data[2])
+ sprite->oam.matrixNum = ST_OAM_HFLIP;
+ if (gBattleAnimArgs[1] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 32;
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + 32;
+ }
+ sprite->callback = sub_80B2C88;
+}
+
+static void sub_80B2C88(struct Sprite *sprite)
+{
+ if (sprite->data[2] == 0)
+ {
+ sprite->pos2.x += sprite->data[0] >> 8;
+ sprite->pos2.y -= sprite->data[1] >> 8;
+ }
+ else
+ {
+ sprite->pos2.x -= sprite->data[0] >> 8;
+ sprite->pos2.y -= sprite->data[1] >> 8;
+ }
+ sprite->data[0] = sprite->data[0];
+ sprite->data[1] -= 32;
+ if (sprite->data[0] < 0)
+ sprite->data[0] = 0;
+ if (++sprite->data[3] == 31)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B2CE4(struct Sprite *sprite)
+{
+ sprite->data[6] = 0;
+ sprite->data[7] = 64;
+ sprite->callback = sub_80B2CF8;
+}
+
+static void sub_80B2CF8(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (++sprite->data[1] > 8)
+ {
+ sprite->data[1] = 0;
+ sprite->invisible ^= 1;
+ if (++sprite->data[2] > 5 && sprite->invisible != FALSE)
+ ++sprite->data[0];
+ }
+ break;
+ case 1:
+ DestroyAnimSprite(sprite);
+ break;
+ }
+}
+
+static void sub_80B2D64(struct Sprite *sprite)
+{
+ u16 rotation;
+ s16 posx = sprite->pos1.x;
+ s16 posy = sprite->pos1.y;
+
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ sprite->data[4] = sprite->pos1.x << 4;
+ sprite->data[5] = sprite->pos1.y << 4;
+ sprite->data[6] = ((posx - sprite->pos1.x) << 4) / 12;
+ sprite->data[7] = ((posy - sprite->pos1.y) << 4) / 12;
+ rotation = ArcTan2Neg(posx - sprite->pos1.x, posy - sprite->pos1.y);
+ rotation += 49152;
+ TrySetSpriteRotScale(sprite, 1, 0x100, 0x100, rotation);
+ sprite->callback = sub_80B2E20;
+}
+
+static void sub_80B2E20(struct Sprite *sprite)
+{
+ sprite->data[4] += sprite->data[6];
+ sprite->data[5] += sprite->data[7];
+ sprite->pos1.x = sprite->data[4] >> 4;
+ sprite->pos1.y = sprite->data[5] >> 4;
+ if (sprite->pos1.x > 285 || sprite->pos1.x < -45
+ || sprite->pos1.y > 157 || sprite->pos1.y < -45)
+ DestroySpriteAndMatrix(sprite);
+}
+
+// not used
+static void sub_80B2E64(u8 taskId)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ u8 spriteId = GetAnimBattlerSpriteId(0);
+
+ gSprites[spriteId].invisible = TRUE;
+ }
+ else
+ {
+ u8 spriteId = GetAnimBattlerSpriteId(0);
+
+ gSprites[spriteId].invisible = FALSE;
+ }
+ DestroyAnimVisualTask(taskId);
+}
diff --git a/src/ghost.c b/src/ghost.c
new file mode 100644
index 000000000..fbf452af6
--- /dev/null
+++ b/src/ghost.c
@@ -0,0 +1,1484 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "bg.h"
+#include "gpu_regs.h"
+#include "palette.h"
+#include "scanline_effect.h"
+#include "malloc.h"
+#include "graphics.h"
+#include "sound.h"
+#include "trig.h"
+#include "util.h"
+#include "decompress.h"
+#include "constants/songs.h"
+
+static void sub_80B5268(struct Sprite *sprite);
+static void sub_80B52D0(struct Sprite *sprite);
+static void sub_80B5344(struct Sprite *sprite);
+static void sub_80B53C0(struct Sprite *sprite);
+static void sub_80B5450(struct Sprite *sprite);
+static void sub_80B5470(struct Sprite *sprite);
+static void sub_80B5570(u8 taskId);
+static void sub_80B55C8(u8 taskId);
+static void InitAnimShadowBall(struct Sprite *sprite);
+static void AnimShadowBallStep(struct Sprite *sprite);
+static void sub_80B57F8(struct Sprite *sprite);
+static void sub_80B5810(struct Sprite *sprite);
+static void sub_80B59D4(u8 taskId);
+static void sub_80B5AD4(u8 taskId);
+static void sub_80B5D38(u8 taskId);
+static void sub_80B5DCC(u8 taskId);
+static void sub_80B5EC0(struct Sprite *sprite);
+static void sub_80B5FE0(struct Sprite *sprite);
+static void sub_80B623C(u8 taskId);
+static void sub_80B6468(u8 taskId);
+static void sub_80B65F0(u8 taskId);
+static void sub_80B664C(struct Sprite *sprite);
+static void sub_80B66A8(struct Sprite *sprite);
+static void sub_80B6728(struct Sprite *sprite);
+static void sub_80B67A0(struct Sprite *sprite);
+static void sub_80B67D4(struct Sprite *sprite);
+static void sub_80B68A8(struct Sprite *sprite);
+static void sub_80B696C(u8 taskId);
+static void sub_80B6AF8(struct Sprite *sprite);
+static void sub_80B7158(struct Sprite *sprite);
+static void sub_80B6BE4(u8 taskId);
+static void sub_80B6F30(u8 taskId);
+static void sub_80B6FC4(u8 taskId);
+static void sub_80B71B0(struct Sprite *sprite);
+
+static const union AffineAnimCmd gUnknown_83E75A8[] =
+{
+ AFFINEANIMCMD_FRAME(0x1E, 0x1E, 10, 5),
+ AFFINEANIMCMD_FRAME(0xFFE2, 0xFFE2, 10, 5),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E75C0[] =
+{
+ gUnknown_83E75A8,
+};
+
+const struct SpriteTemplate gUnknown_83E75C4 =
+{
+ .tileTag = ANIM_TAG_YELLOW_BALL,
+ .paletteTag = ANIM_TAG_YELLOW_BALL,
+ .oam = &gOamData_83ACA90,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E75C0,
+ .callback = sub_80B5268,
+};
+
+const struct SpriteTemplate gUnknown_83E75DC =
+{
+ .tileTag = ANIM_TAG_YELLOW_BALL,
+ .paletteTag = ANIM_TAG_YELLOW_BALL,
+ .oam = &gOamData_83ACAF0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B5450,
+};
+
+static const union AffineAnimCmd gUnknown_83E75F4[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 1),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7604[] =
+{
+ gUnknown_83E75F4,
+};
+
+const struct SpriteTemplate gShadowBallSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_SHADOW_BALL,
+ .paletteTag = ANIM_TAG_SHADOW_BALL,
+ .oam = &gOamData_83ACA38,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7604,
+ .callback = InitAnimShadowBall,
+};
+
+const union AnimCmd gUnknown_83E7620[] =
+{
+ ANIMCMD_FRAME(0, 2),
+ ANIMCMD_FRAME(8, 2),
+ ANIMCMD_FRAME(16, 2),
+ ANIMCMD_FRAME(24, 2),
+ ANIMCMD_FRAME(32, 2),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E7638[] =
+{
+ gUnknown_83E7620,
+};
+
+const struct SpriteTemplate gUnknown_83E763C =
+{
+ .tileTag = ANIM_TAG_LICK,
+ .paletteTag = ANIM_TAG_LICK,
+ .oam = &gOamData_83ACA18,
+ .anims = gUnknown_83E7638,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B57F8,
+};
+
+// not used
+static const union AffineAnimCmd gUnknown_83E7654[] =
+{
+ AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+// not used
+static const union AffineAnimCmd *const gUnknown_83E7664[] =
+{
+ gUnknown_83E7654,
+};
+
+const struct SpriteTemplate gUnknown_83E7668 =
+{
+ .tileTag = ANIM_TAG_WHITE_SHADOW,
+ .paletteTag = ANIM_TAG_WHITE_SHADOW,
+ .oam = &gOamData_83ACB20,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B5EC0,
+};
+
+const struct SpriteTemplate gUnknown_83E7680 =
+{
+ .tileTag = ANIM_TAG_NAIL,
+ .paletteTag = ANIM_TAG_NAIL,
+ .oam = &gOamData_83ACB18,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B664C,
+};
+
+const struct SpriteTemplate gUnknown_83E7698 =
+{
+ .tileTag = ANIM_TAG_GHOSTLY_SPIRIT,
+ .paletteTag = ANIM_TAG_GHOSTLY_SPIRIT,
+ .oam = &gOamData_83ACAF8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B67D4,
+};
+
+const struct SpriteTemplate gUnknown_83E76B0 =
+{
+ .tileTag = ANIM_TAG_DEVIL,
+ .paletteTag = ANIM_TAG_DEVIL,
+ .oam = &gOamData_83ACAF8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B67D4,
+};
+
+static const union AnimCmd gUnknown_83E76C8[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(8, 4),
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(24, 4),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E76DC[] =
+{
+ gUnknown_83E76C8,
+};
+
+const struct SpriteTemplate gUnknown_83E76E0 =
+{
+ .tileTag = ANIM_TAG_PURPLE_FLAME,
+ .paletteTag = ANIM_TAG_PURPLE_FLAME,
+ .oam = &gOamData_83ACB38,
+ .anims = gUnknown_83E76DC,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B6AF8,
+};
+
+const struct SpriteTemplate gUnknown_83E76F8 =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B7158,
+};
+
+static void sub_80B5268(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, 1);
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sub_8075678(sprite);
+ sprite->callback = sub_80B52D0;
+ sprite->data[6] = 16;
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
+ SetGpuReg(REG_OFFSET_BLDALPHA, sprite->data[6]);
+}
+
+static void sub_80B52D0(struct Sprite *sprite)
+{
+ s16 r0, r2;
+
+ sub_80B53C0(sprite);
+ if (AnimTranslateLinear(sprite))
+ {
+ sprite->callback = sub_80B5344;
+ return;
+ }
+ sprite->pos2.x += Sin(sprite->data[5], 10);
+ sprite->pos2.y += Cos(sprite->data[5], 15);
+ r2 = sprite->data[5];
+ sprite->data[5] = (sprite->data[5] + 5) & 0xFF;
+ r0 = sprite->data[5];
+ if (r2 != 0 && r2 <= 196)
+ return;
+ if (r0 <= 0)
+ return;
+ PlaySE12WithPanning(SE_W109, gUnknown_2037F24);
+}
+
+static void sub_80B5344(struct Sprite *sprite)
+{
+ s16 r2, r0;
+
+ sprite->data[0] = 1;
+ AnimTranslateLinear(sprite);
+ sprite->pos2.x += Sin(sprite->data[5], 10);
+ sprite->pos2.y += Cos(sprite->data[5], 15);
+ r2 = sprite->data[5];
+ sprite->data[5] = (sprite->data[5] + 5) & 0xFF;
+ r0 = sprite->data[5];
+ if ((r2 == 0 || r2 > 196) && r0 > 0)
+ PlaySE(SE_W109);
+ if (sprite->data[6] == 0)
+ {
+ sprite->invisible = TRUE;
+ sprite->callback = DestroyAnimSpriteAndDisableBlend;
+ }
+ else
+ {
+ sub_80B53C0(sprite);
+ }
+}
+
+static void sub_80B53C0(struct Sprite *sprite)
+{
+ s16 r0;
+
+ if (sprite->data[6] > 0xFF)
+ {
+ if (++sprite->data[6] == 0x10d)
+ sprite->data[6] = 0;
+ return;
+ }
+ r0 = sprite->data[7];
+ ++sprite->data[7];
+ if ((r0 & 0xFF) == 0)
+ {
+ sprite->data[7] &= 0xff00;
+ if ((sprite->data[7] & 0x100) != 0)
+ ++sprite->data[6];
+ else
+ --sprite->data[6];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], 16 - sprite->data[6]));
+ if (sprite->data[6] == 0 || sprite->data[6] == 16)
+ sprite->data[7] ^= 0x100;
+ if (sprite->data[6] == 0)
+ sprite->data[6] = 0x100;
+ }
+}
+
+static void sub_80B5450(struct Sprite *sprite)
+{
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->callback = sub_80B5470;
+ sprite->callback(sprite);
+}
+
+static void sub_80B5470(struct Sprite *sprite)
+{
+ u16 temp1;
+
+ sprite->pos2.x = Sin(sprite->data[0], 32);
+ sprite->pos2.y = Cos(sprite->data[0], 8);
+ temp1 = sprite->data[0] - 65;
+ if (temp1 <= 130)
+ sprite->oam.priority = 2;
+ else
+ sprite->oam.priority = 1;
+ sprite->data[0] = (sprite->data[0] + 19) & 0xFF;
+ sprite->data[2] += 80;
+ sprite->pos2.y += sprite->data[2] >> 8;
+ sprite->data[7] += 1;
+ if (sprite->data[7] == 61)
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80B54E8(u8 taskId)
+{
+ u8 spriteId;
+
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
+ spriteId = GetAnimBattlerSpriteId(0);
+ PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_BLEND);
+ SetSpriteRotScale(spriteId, 128, 128, 0);
+ gSprites[spriteId].invisible = FALSE;
+ gTasks[taskId].data[0] = 128;
+ gTasks[taskId].data[1] = *gBattleAnimArgs;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 16;
+ gTasks[taskId].func = sub_80B5570;
+}
+
+static void sub_80B5570(u8 taskId)
+{
+ gTasks[taskId].data[10] += 1;
+ if (gTasks[taskId].data[10] == 3)
+ {
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].data[2] += 1;
+ gTasks[taskId].data[3] -= 1;
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[2], gTasks[taskId].data[3]));
+ if (gTasks[taskId].data[2] != 9)
+ return;
+ gTasks[taskId].func = sub_80B55C8;
+ }
+}
+
+static void sub_80B55C8(u8 taskId)
+{
+ u8 spriteId;
+
+ if (gTasks[taskId].data[1] > 0)
+ {
+ gTasks[taskId].data[1] -= 1;
+ return;
+ }
+ spriteId = GetAnimBattlerSpriteId(0);
+ gTasks[taskId].data[0] += 8;
+ if (gTasks[taskId].data[0] <= 0xFF)
+ {
+ SetSpriteRotScale(spriteId, gTasks[taskId].data[0], gTasks[taskId].data[0], 0);
+ }
+ else
+ {
+ ResetSpriteRotScale(spriteId);
+ DestroyAnimVisualTask(taskId);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ }
+}
+
+// Spins a sprite towards the target, pausing in the middle.
+// Used in Shadow Ball.
+// arg 0: duration step 1 (attacker -> center)
+// arg 1: duration step 2 (spin center)
+// arg 2: duration step 3 (center -> target)
+static void InitAnimShadowBall(struct Sprite *sprite)
+{
+ s16 oldPosX = sprite->pos1.x;
+ s16 oldPosY = sprite->pos1.y;
+
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ sprite->data[0] = 0;
+ sprite->data[1] = gBattleAnimArgs[0];
+ sprite->data[2] = gBattleAnimArgs[1];
+ sprite->data[3] = gBattleAnimArgs[2];
+ sprite->data[4] = sprite->pos1.x << 4;
+ sprite->data[5] = sprite->pos1.y << 4;
+ sprite->data[6] = ((oldPosX - sprite->pos1.x) << 4) / (gBattleAnimArgs[0] << 1);
+ sprite->data[7] = ((oldPosY - sprite->pos1.y) << 4) / (gBattleAnimArgs[0] << 1);
+ sprite->callback = AnimShadowBallStep;
+}
+
+static void AnimShadowBallStep(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->data[4] += sprite->data[6];
+ sprite->data[5] += sprite->data[7];
+ sprite->pos1.x = sprite->data[4] >> 4;
+ sprite->pos1.y = sprite->data[5] >> 4;
+ sprite->data[1] -= 1;
+ if (sprite->data[1] > 0)
+ break;
+ sprite->data[0] += 1;
+ break;
+ case 1:
+ sprite->data[2] -= 1;
+ if (sprite->data[2] > 0)
+ break;
+ sprite->data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sprite->data[4] = sprite->pos1.x << 4;
+ sprite->data[5] = sprite->pos1.y << 4;
+ sprite->data[6] = ((sprite->data[1] - sprite->pos1.x) << 4) / sprite->data[3];
+ sprite->data[7] = ((sprite->data[2] - sprite->pos1.y) << 4) / sprite->data[3];
+ sprite->data[0] += 1;
+ break;
+ case 2:
+ sprite->data[4] += sprite->data[6];
+ sprite->data[5] += sprite->data[7];
+ sprite->pos1.x = sprite->data[4] >> 4;
+ sprite->pos1.y = sprite->data[5] >> 4;
+ sprite->data[3] -= 1;
+ if (sprite->data[3] > 0)
+ break;
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sprite->data[0] += 1;
+ break;
+ case 3:
+ DestroySpriteAndMatrix(sprite);
+ break;
+ }
+}
+
+static void sub_80B57F8(struct Sprite *sprite)
+{
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->callback = sub_80B5810;
+}
+
+static void sub_80B5810(struct Sprite *sprite)
+{
+ bool8 r5 = FALSE;
+ bool8 r6 = FALSE;
+
+ if (sprite->animEnded)
+ {
+ if (!sprite->invisible)
+ sprite->invisible = TRUE;
+
+ switch (sprite->data[0])
+ {
+ default:
+ r6 = TRUE;
+ break;
+ case 0:
+ if (sprite->data[1] == 2)
+ r5 = TRUE;
+ break;
+ case 1:
+ if (sprite->data[1] == 4)
+ r5 = TRUE;
+ break;
+ }
+ if (r5)
+ {
+ sprite->invisible ^= 1;
+ ++sprite->data[2];
+ sprite->data[1] = 0;
+ if (sprite->data[2] == 5)
+ {
+ sprite->data[2] = 0;
+ ++sprite->data[0];
+ }
+ }
+ else if (r6)
+ {
+ DestroyAnimSprite(sprite);
+ }
+ else
+ {
+ ++sprite->data[1];
+ }
+ }
+}
+
+void sub_80B58AC(u8 taskId)
+{
+ struct Task *task;
+
+ task = &gTasks[taskId];
+ task->data[0] = CloneBattlerSpriteWithBlend(1);
+ if (task->data[0] < 0)
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ task->data[1] = 0;
+ task->data[2] = 15;
+ task->data[3] = 2;
+ task->data[4] = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3]));
+ gSprites[task->data[0]].data[0] = 80;
+ if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
+ {
+ gSprites[task->data[0]].data[1] = -144;
+ gSprites[task->data[0]].data[2] = 112;
+ }
+ else
+ {
+ gSprites[task->data[0]].data[1] = 144;
+ gSprites[task->data[0]].data[2] = -112;
+ }
+ gSprites[task->data[0]].data[3] = 0;
+ gSprites[task->data[0]].data[4] = 0;
+ StoreSpriteCallbackInData6(&gSprites[task->data[0]], SpriteCallbackDummy);
+ gSprites[task->data[0]].callback = TranslateSpriteLinearFixedPoint;
+ task->func = sub_80B59D4;
+}
+
+static void sub_80B59D4(u8 taskId)
+{
+ struct Task *task;
+
+ task = &gTasks[taskId];
+ switch (task->data[4])
+ {
+ case 0:
+ task->data[1] += 1;
+ task->data[5] = task->data[1] & 3;
+ if (task->data[5] == 1)
+ if (task->data[2] > 0)
+ task->data[2] -= 1;
+ if (task->data[5] == 3)
+ if (task->data[3] <= 15)
+ task->data[3] += 1;
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3]));
+ if (task->data[3] != 16 || task->data[2] != 0)
+ break;
+ if (task->data[1] <= 80)
+ break;
+ obj_delete_but_dont_free_vram(&gSprites[task->data[0]]);
+ task->data[4] = 1;
+ break;
+ case 1:
+ if (++task->data[6] <= 1)
+ break;
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ task->data[4] += 1;
+ break;
+ case 2:
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80B5AAC(u8 taskId)
+{
+ struct Task *task;
+
+ task = &gTasks[taskId];
+ task->data[15] = 0;
+ task->func = sub_80B5AD4;
+ task->func(taskId);
+}
+
+static void sub_80B5AD4(u8 taskId)
+{
+ s16 startLine;
+ struct Task *task = &gTasks[taskId];
+ u8 position = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget);
+
+ switch (task->data[15])
+ {
+ case 0:
+ task->data[14] = AllocSpritePalette(ANIM_TAG_BENT_SPOON);
+ if (task->data[14] == 0xFF || task->data[14] == 0xF)
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+ else
+ {
+ task->data[0] = CloneBattlerSpriteWithBlend(1);
+ if (task->data[0] < 0)
+ {
+ FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON);
+ DestroyAnimVisualTask(taskId);
+ }
+ else
+ {
+ s16 mask2;
+
+ gSprites[task->data[0]].oam.paletteNum = task->data[14];
+ gSprites[task->data[0]].oam.objMode = ST_OAM_OBJ_NORMAL;
+ gSprites[task->data[0]].oam.priority = 3;
+ gSprites[task->data[0]].invisible = (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].invisible);
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->data[3] = 16;
+ task->data[13] = GetAnimBattlerSpriteId(1);
+ task->data[4] = (gSprites[task->data[13]].oam.paletteNum + 16) * 16;
+ if (position == 1)
+ {
+ u16 mask = DISPCNT_BG1_ON;
+
+ mask2 = mask;
+ }
+ else
+ {
+ u16 mask = DISPCNT_BG2_ON;
+
+ mask2 = mask;
+ }
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, mask2);
+ ++task->data[15];
+ }
+ }
+ break;
+ case 1:
+ task->data[14] = (task->data[14] + 16) * 16;
+ CpuSet(&gPlttBufferUnfaded[task->data[4]], &gPlttBufferFaded[task->data[14]], 0x4000008);
+ BlendPalette(task->data[4], 16, 10, RGB(13, 0, 15));
+ ++task->data[15];
+ break;
+ case 2:
+ startLine = gSprites[task->data[13]].pos1.y + gSprites[task->data[13]].pos2.y - 32;
+ if (startLine < 0)
+ startLine = 0;
+ if (position == 1)
+ task->data[10] = ScanlineEffect_InitWave(startLine, startLine + 64, 2, 6, 0, 4, 1);
+ else
+ task->data[10] = ScanlineEffect_InitWave(startLine, startLine + 64, 2, 6, 0, 8, 1);
+ ++task->data[15];
+ break;
+ case 3:
+ if (position == 1)
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG1));
+ else
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG2));
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
+ ++task->data[15];
+ break;
+ case 4:
+ if (position == 1)
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
+ else
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
+ task->func = sub_80B5D38;
+ ++task->data[15];
+ break;
+ default:
+ ++task->data[15];
+ break;
+ }
+}
+
+static void sub_80B5D38(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ ++task->data[1];
+ task->data[5] = task->data[1] & 1;
+ if (task->data[5] == 0)
+ task->data[2] = gSineTable[task->data[1]] / 18;
+ if (task->data[5] == 1)
+ task->data[3] = 16 - (gSineTable[task->data[1]] / 18);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3]));
+ if (task->data[1] == 128)
+ {
+ task->data[15] = 0;
+ task->func = sub_80B5DCC;
+ task->func(taskId);
+ }
+}
+
+static void sub_80B5DCC(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ u8 rank = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget);
+
+ switch (task->data[15])
+ {
+ case 0:
+ gScanlineEffect.state = 3;
+ task->data[14] = GetAnimBattlerSpriteId(1);
+ if (rank == 1)
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
+ else
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
+ break;
+ case 1:
+ BlendPalette(task->data[4], 16, 0, RGB(13, 0, 15));
+ break;
+ case 2:
+ gSprites[task->data[14]].invisible = TRUE;
+ obj_delete_but_dont_free_vram(&gSprites[task->data[0]]);
+ FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ if (rank == 1)
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
+ else
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+ ++task->data[15];
+}
+
+static void sub_80B5EC0(struct Sprite *sprite)
+{
+ s16 battler1X, battler1Y;
+ s16 battler2X, battler2Y;
+ s16 yDiff;
+
+ if (gBattleAnimArgs[0] == 0)
+ {
+ battler1X = GetBattlerSpriteCoord(gBattleAnimAttacker, 0);
+ battler1Y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 28;
+ battler2X = GetBattlerSpriteCoord(gBattleAnimTarget, 0);
+ battler2Y = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + 28;
+ }
+ else
+ {
+ battler1X = GetBattlerSpriteCoord(gBattleAnimTarget, 0);
+ battler1Y = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + 28;
+ battler2X = GetBattlerSpriteCoord(gBattleAnimAttacker, 0);
+ battler2Y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 28;
+ }
+ yDiff = battler2Y - battler1Y;
+ sprite->data[0] = battler1X * 16;
+ sprite->data[1] = battler1Y * 16;
+ sprite->data[2] = ((battler2X - battler1X) * 16) / gBattleAnimArgs[1];
+ sprite->data[3] = (yDiff * 16) / gBattleAnimArgs[1];
+ sprite->data[4] = gBattleAnimArgs[1];
+ sprite->data[5] = battler2X;
+ sprite->data[6] = battler2Y;
+ sprite->data[7] = sprite->data[4] / 2;
+ sprite->oam.priority = 2;
+ sprite->pos1.x = battler1X;
+ sprite->pos1.y = battler1Y;
+ sprite->callback = sub_80B5FE0;
+ sprite->invisible = TRUE;
+}
+
+static void sub_80B5FE0(struct Sprite *sprite)
+{
+ if (sprite->data[4])
+ {
+ sprite->data[0] += sprite->data[2];
+ sprite->data[1] += sprite->data[3];
+ sprite->pos1.x = sprite->data[0] >> 4;
+ sprite->pos1.y = sprite->data[1] >> 4;
+ if (--sprite->data[4] == 0)
+ sprite->data[0] = 0;
+ }
+}
+
+void sub_80B6020(u8 taskId)
+{
+ struct Task *task;
+ s16 battler;
+ u8 spriteId;
+ s16 baseX, baseY;
+ s16 x, y;
+
+ task = &gTasks[taskId];
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
+ task->data[5] = 0;
+ task->data[6] = 0;
+ task->data[7] = 0;
+ task->data[8] = 0;
+ task->data[9] = 16;
+ task->data[10] = gBattleAnimArgs[0];
+ baseX = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ baseY = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM);
+ if (!IsContest())
+ {
+ for (battler = 0; battler < 4; ++battler)
+ {
+ if (battler != gBattleAnimAttacker
+ && battler != (gBattleAnimAttacker ^ 2)
+ && IsBattlerSpriteVisible(battler))
+ {
+ spriteId = CreateSprite(&gUnknown_83E7668, baseX, baseY, 55);
+ if (spriteId != MAX_SPRITES)
+ {
+ x = GetBattlerSpriteCoord(battler, 2);
+ y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_BOTTOM);
+ gSprites[spriteId].data[0] = baseX << 4;
+ gSprites[spriteId].data[1] = baseY << 4;
+ gSprites[spriteId].data[2] = ((x - baseX) << 4) / gBattleAnimArgs[1];
+ gSprites[spriteId].data[3] = ((y - baseY) << 4) / gBattleAnimArgs[1];
+ gSprites[spriteId].data[4] = gBattleAnimArgs[1];
+ gSprites[spriteId].data[5] = x;
+ gSprites[spriteId].data[6] = y;
+ gSprites[spriteId].callback = sub_80B5FE0;
+ task->data[task->data[12] + 13] = spriteId;
+ ++task->data[12];
+ }
+ }
+ }
+ }
+ else
+ {
+ spriteId = CreateSprite(&gUnknown_83E7668, baseX, baseY, 55);
+ if (spriteId != MAX_SPRITES)
+ {
+ x = 48;
+ y = 40;
+ gSprites[spriteId].data[0] = baseX << 4;
+ gSprites[spriteId].data[1] = baseY << 4;
+ gSprites[spriteId].data[2] = ((x - baseX) << 4) / gBattleAnimArgs[1];
+ gSprites[spriteId].data[3] = ((y - baseY) << 4) / gBattleAnimArgs[1];
+ gSprites[spriteId].data[4] = gBattleAnimArgs[1];
+ gSprites[spriteId].data[5] = x;
+ gSprites[spriteId].data[6] = y;
+ gSprites[spriteId].callback = sub_80B5FE0;
+ task->data[13] = spriteId;
+ task->data[12] = 1;
+ }
+ }
+ task->func = sub_80B623C;
+}
+
+static void sub_80B623C(u8 taskId)
+{
+ u16 i;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (task->data[6] == 0)
+ {
+ if (++task->data[5] > 1)
+ {
+ task->data[5] = 0;
+ ++task->data[7];
+ if (task->data[7] & 1)
+ {
+ if (task->data[8] < 16)
+ ++task->data[8];
+ }
+ else
+ {
+ if (task->data[9])
+ --task->data[9];
+ }
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[8], task->data[9]));
+ if (task->data[7] >= 24)
+ {
+ task->data[7] = 0;
+ task->data[6] = 1;
+ }
+ }
+ }
+ if (task->data[10])
+ --task->data[10];
+ else if (task->data[6])
+ ++task->data[0];
+ break;
+ case 1:
+ if (++task->data[5] > 1)
+ {
+ task->data[5] = 0;
+ ++task->data[7];
+ if (task->data[7] & 1)
+ {
+ if (task->data[8])
+ --task->data[8];
+ }
+ else if (task->data[9] < 16)
+ {
+ ++task->data[9];
+ }
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[8], task->data[9]));
+ if (task->data[8] == 0 && task->data[9] == 16)
+ {
+ for (i = 0; i < task->data[12]; ++i)
+ DestroySprite(&gSprites[task->data[i + 13]]);
+ ++task->data[0];
+ }
+ }
+ break;
+ case 2:
+ if (++task->data[5] > 0)
+ ++task->data[0];
+ break;
+ case 3:
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80B63B4(u8 taskId)
+{
+ s16 startX, startY;
+ s16 leftDistance, topDistance, bottomDistance, rightDistance;
+
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, ((WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR) |
+ (WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR)));
+ SetGpuReg(REG_OFFSET_WINOUT, ((WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ) |
+ (WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR)));
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_DARKEN));
+ SetGpuReg(REG_OFFSET_BLDY, 0x10);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER || IsContest())
+ startX = 40;
+ else
+ startX = 200;
+ gBattle_WIN0H = WIN_RANGE(startX, startX);
+ startY = 40;
+ gBattle_WIN0V = WIN_RANGE(startY, startY);
+ leftDistance = startX;
+ rightDistance = 240 - startX;
+ topDistance = startY;
+ bottomDistance = 72;
+ gTasks[taskId].data[1] = leftDistance;
+ gTasks[taskId].data[2] = rightDistance;
+ gTasks[taskId].data[3] = topDistance;
+ gTasks[taskId].data[4] = bottomDistance;
+ gTasks[taskId].data[5] = startX;
+ gTasks[taskId].data[6] = startY;
+ gTasks[taskId].func = sub_80B6468;
+}
+
+static void sub_80B6468(u8 taskId)
+{
+ s16 step, leftDistance, rightDistance, topDistance, bottomDistance, startX, startY;
+ u16 left, right, top, bottom, selectedPalettes;
+
+ step = gTasks[taskId].data[0];
+ ++gTasks[taskId].data[0];
+ leftDistance = gTasks[taskId].data[1];
+ rightDistance = gTasks[taskId].data[2];
+ topDistance = gTasks[taskId].data[3];
+ bottomDistance = gTasks[taskId].data[4];
+ startX = gTasks[taskId].data[5];
+ startY = gTasks[taskId].data[6];
+ if (step < 16)
+ {
+ left = startX - (leftDistance * 0.0625) * step;
+ right = startX + (rightDistance * 0.0625) * step;
+ top = startY - (topDistance * 0.0625) * step;
+ bottom = startY + (bottomDistance * 0.0625) * step;
+ }
+ else
+ {
+ left = 0;
+ right = 240;
+ top = 0;
+ bottom = 112;
+ selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0);
+ BeginNormalPaletteFade(selectedPalettes, 0, 16, 16, RGB(0, 0, 0));
+ gTasks[taskId].func = sub_80B65F0;
+ }
+ gBattle_WIN0H = WIN_RANGE(left, right);
+ gBattle_WIN0V = WIN_RANGE(top, bottom);
+}
+
+static void sub_80B65F0(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ SetGpuReg(REG_OFFSET_WININ, ((WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR) |
+ (WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR)));
+ SetGpuReg(REG_OFFSET_WINOUT, ((WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR) |
+ (WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR)));
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+static void sub_80B664C(struct Sprite *sprite)
+{
+ s16 xDelta, xDelta2;
+
+ InitSpritePosToAnimAttacker(sprite, 1);
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
+ {
+ xDelta = 24;
+ xDelta2 = -2;
+ sprite->oam.matrixNum = ST_OAM_HFLIP;
+ }
+ else
+ {
+ xDelta = -24;
+ xDelta2 = 2;
+ }
+ sprite->pos1.x += xDelta;
+ sprite->data[1] = xDelta2;
+ sprite->data[0] = 60;
+ sprite->callback = sub_80B66A8;
+}
+
+static void sub_80B66A8(struct Sprite *sprite)
+{
+ u16 var0;
+
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ }
+ else
+ {
+ sprite->pos2.x += sprite->data[1];
+ var0 = sprite->pos2.x + 7;
+ if (var0 > 14)
+ {
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos2.x = 0;
+ sprite->oam.tileNum += 8;
+ if (++sprite->data[2] == 3)
+ {
+ sprite->data[0] = 30;
+ sprite->callback = WaitAnimForDuration;
+ StoreSpriteCallbackInData6(sprite, sub_80B6728);
+ }
+ else
+ {
+ sprite->data[0] = 40;
+ }
+ }
+ }
+}
+
+static void sub_80B6728(struct Sprite *sprite)
+{
+ if (sprite->data[0] == 0)
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
+ ++sprite->data[0];
+ sprite->data[1] = 0;
+ sprite->data[2] = 0;
+ }
+ else if (sprite->data[1] < 2)
+ {
+ ++sprite->data[1];
+ }
+ else
+ {
+ sprite->data[1] = 0;
+ ++sprite->data[2];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND2(16 - sprite->data[2], sprite->data[2]));
+ if (sprite->data[2] == 16)
+ {
+ sprite->invisible = TRUE;
+ sprite->callback = sub_80B67A0;
+ }
+ }
+}
+
+static void sub_80B67A0(struct Sprite *sprite)
+{
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B67D4(struct Sprite *sprite)
+{
+ u16 coeffB, coeffA;
+
+ sprite->pos2.x = Sin(sprite->data[0], 12);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->pos2.x = -sprite->pos2.x;
+ sprite->data[0] = (sprite->data[0] + 6) & 0xFF;
+ sprite->data[1] += 0x100;
+ sprite->pos2.y = -(sprite->data[1] >> 8);
+ ++sprite->data[7];
+ if (sprite->data[7] == 1)
+ {
+ sprite->data[6] = 0x050B;
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
+ SetGpuReg(REG_OFFSET_BLDALPHA, sprite->data[6]);
+ }
+ else if (sprite->data[7] > 30)
+ {
+ ++sprite->data[2];
+ coeffB = sprite->data[6] >> 8;
+ coeffA = sprite->data[6] & 0xFF;
+ if (++coeffB > 16)
+ coeffB = 16;
+ --coeffA;
+ if ((s16)coeffA < 0)
+ coeffA = 0;
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(coeffA, coeffB));
+ sprite->data[6] = BLDALPHA_BLEND(coeffA, coeffB);
+ if (coeffB == 16 && coeffA == 0)
+ {
+ sprite->invisible = TRUE;
+ sprite->callback = sub_80B68A8;
+ }
+ }
+}
+
+static void sub_80B68A8(struct Sprite *sprite)
+{
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80B68C8(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->data[0] = 0;
+ task->data[1] = 16;
+ task->data[9] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ task->data[10] = GetBattlerYCoordWithElevation(gBattleAnimAttacker);
+ task->data[11] = (GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_WIDTH) / 2) + 8;
+ task->data[7] = 0;
+ task->data[5] = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
+ task->data[6] = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 2;
+ task->data[3] = 0;
+ task->data[4] = 16;
+ SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
+ task->data[8] = 0;
+ task->func = sub_80B696C;
+}
+
+static void sub_80B696C(u8 taskId)
+{
+ u16 i;
+ u8 spriteId;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ for (i = 0; i < 6; ++i)
+ {
+ spriteId = CreateSprite(&gUnknown_83E76E0, task->data[9], task->data[10], task->data[6]);
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].data[0] = taskId;
+ gSprites[spriteId].data[1] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER;
+ gSprites[spriteId].data[2] = (i * 42) & 0xFF;
+ gSprites[spriteId].data[3] = task->data[11];
+ gSprites[spriteId].data[5] = i * 6;
+ ++task->data[7];
+ }
+ }
+ ++task->data[0];
+ break;
+ case 1:
+ if (++task->data[1] & 1)
+ {
+ if (task->data[3] < 14)
+ ++task->data[3];
+ }
+ else if (task->data[4] > 4)
+ {
+ --task->data[4];
+ }
+ if (task->data[3] == 14 && task->data[4] == 4)
+ {
+ task->data[1] = 0;
+ ++task->data[0];
+ }
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
+ break;
+ case 2:
+ if (++task->data[1] > 30)
+ {
+ task->data[1] = 0;
+ ++task->data[0];
+ }
+ break;
+ case 3:
+ if (++task->data[1] & 1)
+ {
+ if (task->data[3] > 0)
+ --task->data[3];
+ }
+ else if (task->data[4] < 16)
+ {
+ ++task->data[4];
+ }
+
+ if (task->data[3] == 0 && task->data[4] == 16)
+ {
+ task->data[8] = 1;
+ ++task->data[0];
+ }
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
+ break;
+ case 4:
+ if (task->data[7] == 0)
+ ++task->data[0];
+ break;
+ case 5:
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B6AF8(struct Sprite *sprite)
+{
+ u16 index;
+
+ if (sprite->data[1] == 0)
+ sprite->data[2] += 2;
+ else
+ sprite->data[2] -= 2;
+ sprite->data[2] &= 0xFF;
+ sprite->pos2.x = Sin(sprite->data[2], sprite->data[3]);
+ index = sprite->data[2] - 65;
+ if (index < 127)
+ sprite->oam.priority = gTasks[sprite->data[0]].data[5] + 1;
+ else
+ sprite->oam.priority = gTasks[sprite->data[0]].data[5];
+ ++sprite->data[5];
+ sprite->data[6] = (sprite->data[5] * 8) & 0xFF;
+ sprite->pos2.y = Sin(sprite->data[6], 7);
+ if (gTasks[sprite->data[0]].data[8])
+ {
+ --gTasks[sprite->data[0]].data[7];
+ DestroySprite(sprite);
+ }
+}
+
+void sub_80B6BBC(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->data[15] = 0;
+ task->func = sub_80B6BE4;
+ sub_80B6BE4(taskId);
+}
+
+static void sub_80B6BE4(u8 taskId)
+{
+ s16 y;
+ struct BattleAnimBgData animBgData;
+ struct Task *task = &gTasks[taskId];
+ u8 rank = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
+
+ switch (task->data[15])
+ {
+ case 0:
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 2);
+ SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 1);
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->data[3] = 16;
+ task->data[4] = GetAnimBattlerSpriteId(0);
+ task->data[5] = gSprites[task->data[4]].oam.priority;
+ task->data[6] = (gSprites[task->data[4]].oam.paletteNum + 16) << 4;
+ gSprites[task->data[4]].oam.objMode = ST_OAM_OBJ_BLEND;
+ gSprites[task->data[4]].oam.priority = 3;
+ task->data[7] = 128;
+ break;
+ case 1:
+ ++task->data[1];
+ if (task->data[1] & 1)
+ return;
+ BlendPalette(task->data[6], 0x10, task->data[2], RGB(0, 23, 25));
+ BlendPalette(task->data[7], 0x10, task->data[2], RGB(0, 23, 25));
+ if (task->data[2] <= 11)
+ {
+ ++task->data[2];
+ return;
+ }
+ task->data[1] = 0;
+ task->data[2] = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
+ break;
+ case 2:
+ SetAnimBgAttribute(2, BG_ANIM_CHAR_BASE_BLOCK, 1);
+ SetAnimBgAttribute(2, BG_ANIM_SCREEN_SIZE, 0);
+ gBattle_BG2_X = 0;
+ gBattle_BG2_Y = 0;
+ SetGpuReg(REG_OFFSET_BG2HOFS, gBattle_BG2_X);
+ SetGpuReg(REG_OFFSET_BG2VOFS, gBattle_BG2_Y);
+ sub_80752C8(&animBgData, 2);
+ AnimLoadCompressedBgGfx(animBgData.bgId, gFile_graphics_battle_anims_backgrounds_scary_face_sheet, animBgData.tilesOffset);
+ LoadCompressedPalette(gFile_graphics_battle_anims_backgrounds_scary_face_palette, 16 * animBgData.paletteId, 0x20);
+ break;
+ case 3:
+ sub_80752C8(&animBgData, 2);
+ gMonSpritesGfxPtr->field_17C = AllocZeroed(0x2000);
+ LZDecompressWram(gFile_graphics_battle_anims_backgrounds_scary_face_player_tilemap, gMonSpritesGfxPtr->field_17C);
+ sub_80730C0(animBgData.paletteId, gMonSpritesGfxPtr->field_17C, 256, 0);
+ CopyToBgTilemapBufferRect_ChangePalette(animBgData.bgId, gMonSpritesGfxPtr->field_17C, 0, 0, 0x20, 0x20, 0x11);
+ CopyBgTilemapBufferToVram(2);
+ FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_17C);
+ break;
+ case 4:
+ ++task->data[1];
+ if (task->data[1] & 1)
+ return;
+ ++task->data[2];
+ --task->data[3];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3]));
+ if (task->data[3])
+ return;
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->data[3] = 16;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2);
+ break;
+ case 5:
+ if (rank == 1)
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
+ else
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
+ break;
+ case 6:
+ y = gSprites[task->data[4]].pos1.y + gSprites[task->data[4]].pos2.y - 0x20;
+ if (y < 0)
+ y = 0;
+ if (rank == 1)
+ task->data[10] = ScanlineEffect_InitWave(y, y + 0x40, 4, 8, 0, 4, 1);
+ else
+ task->data[10] = ScanlineEffect_InitWave(y, y + 0x40, 4, 8, 0, 8, 1);
+ break;
+ case 7:
+ BlendPalette(task->data[7], 0x10, 0xC, RGB(31, 31, 29));
+ if (rank == 1)
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
+ else
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
+ task->func = sub_80B6F30;
+ task->data[15] = 0;
+ break;
+ }
+ ++task->data[15];
+}
+
+static void sub_80B6F30(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ ++task->data[1];
+ task->data[8] = task->data[1] & 1;
+ if (!task->data[8])
+ task->data[2] = gSineTable[task->data[1]] / 18;
+ if (task->data[8] == 1)
+ task->data[3] = 16 - gSineTable[task->data[1]] / 18;
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3]));
+ if (task->data[1] == 128)
+ {
+ task->data[15] = 0;
+ task->func = sub_80B6FC4;
+ sub_80B6FC4(taskId);
+ }
+}
+
+static void sub_80B6FC4(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[15])
+ {
+ case 0:
+ gScanlineEffect.state = 3;
+ BlendPalette(task->data[7], 0x10, 0xC, RGB(0, 23, 25));
+ break;
+ case 1:
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0x10, 0));
+ task->data[2] = 16;
+ task->data[3] = 0;
+ break;
+ case 2:
+ --task->data[2];
+ ++task->data[3];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3]));
+ if (task->data[3] <= 15)
+ return;
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 2);
+ SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2);
+ break;
+ case 3:
+ sub_8075358(2);
+ FillPalette(0, 0x90, 0x20);
+ SetAnimBgAttribute(2, BG_ANIM_CHAR_BASE_BLOCK, 0);
+ task->data[1] = 12;
+ break;
+ case 4:
+ BlendPalette(task->data[6], 0x10, task->data[1], RGB(0, 23, 25));
+ BlendPalette(task->data[7], 0x10, task->data[1], RGB(0, 23, 25));
+ if ( task->data[1] )
+ {
+ --task->data[1];
+ return;
+ }
+ task->data[1] = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
+ break;
+ case 5:
+ gSprites[task->data[4]].oam.priority = task->data[5];
+ gSprites[task->data[4]].oam.objMode = ST_OAM_OBJ_NORMAL;
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 1);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_NONE);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+ ++task->data[15];
+}
+
+static void sub_80B7158(struct Sprite *sprite)
+{
+ sprite->invisible = TRUE;
+ sprite->data[5] = gBattlerSpriteIds[gBattleAnimAttacker];
+ sprite->data[0] = 128;
+ sprite->data[1] = 10;
+ sprite->data[2] = gBattleAnimArgs[0];
+ sprite->data[3] = gBattleAnimArgs[1];
+ sprite->callback = sub_80B71B0;
+ gSprites[sprite->data[5]].pos1.y += 8;
+}
+
+static void sub_80B71B0(struct Sprite *sprite)
+{
+ if (sprite->data[3])
+ {
+ --sprite->data[3];
+ gSprites[sprite->data[5]].pos2.x = Sin(sprite->data[0], sprite->data[1]);
+ gSprites[sprite->data[5]].pos2.y = Cos(sprite->data[0], sprite->data[1]);
+ sprite->data[0] += sprite->data[2];
+ if (sprite->data[0] > 255)
+ sprite->data[0] -= 256;
+ }
+ else
+ {
+ gSprites[sprite->data[5]].pos2.x = 0;
+ gSprites[sprite->data[5]].pos2.y = 0;
+ gSprites[sprite->data[5]].pos1.y -= 8;
+ sprite->callback = DestroySpriteAndMatrix;
+ }
+}
diff --git a/src/ground.c b/src/ground.c
new file mode 100644
index 000000000..4ae4d8370
--- /dev/null
+++ b/src/ground.c
@@ -0,0 +1,724 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "random.h"
+#include "scanline_effect.h"
+#include "task.h"
+#include "trig.h"
+
+static void AnimBonemerangProjectile(struct Sprite *sprite);
+static void AnimBoneHitProjectile(struct Sprite *sprite);
+static void AnimDirtScatter(struct Sprite *sprite);
+static void AnimMudSportDirt(struct Sprite *sprite);
+static void AnimFissureDirtPlumeParticle(struct Sprite *sprite);
+static void AnimDigDirtMound(struct Sprite *sprite);
+static void AnimBonemerangProjectileStep(struct Sprite *sprite);
+static void AnimBonemerangProjectileEnd(struct Sprite *sprite);
+static void AnimMudSportDirtRising(struct Sprite *sprite);
+static void AnimMudSportDirtFalling(struct Sprite *sprite);
+static void sub_80B8ED4(u8 taskId);
+static void sub_80B908C(u8 taskId);
+static void sub_80B92B8(u8 useBg1, s16 y, s16 endY);
+static void sub_80B912C(u8 taskId);
+static void sub_80B91B0(u8 taskId);
+static void AnimFissureDirtPlumeParticleStep(struct Sprite *sprite);
+static void sub_80B9584(u8 taskId);
+static void sub_80B967C(u8 taskId);
+static void sub_80B9760(struct Task *task);
+static void sub_80B98A8(u8 taskId);
+
+static const union AffineAnimCmd gUnknown_83E7A00[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 15, 1),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd gUnknown_83E7A10[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 20, 1),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7A20[] =
+{
+ gUnknown_83E7A00,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7A24[] =
+{
+ gUnknown_83E7A10,
+};
+
+const struct SpriteTemplate gUnknown_83E7A28 =
+{
+ .tileTag = ANIM_TAG_BONE,
+ .paletteTag = ANIM_TAG_BONE,
+ .oam = &gOamData_83ACA38,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7A20,
+ .callback = AnimBonemerangProjectile,
+};
+
+const struct SpriteTemplate gUnknown_83E7A40 =
+{
+ .tileTag = ANIM_TAG_BONE,
+ .paletteTag = ANIM_TAG_BONE,
+ .oam = &gOamData_83ACA38,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7A24,
+ .callback = AnimBoneHitProjectile,
+};
+
+const struct SpriteTemplate gUnknown_83E7A58 =
+{
+ .tileTag = ANIM_TAG_MUD_SAND,
+ .paletteTag = ANIM_TAG_MUD_SAND,
+ .oam = &gOamData_83AC9C8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimDirtScatter,
+};
+
+static const union AnimCmd gUnknown_83E7A70[] =
+{
+ ANIMCMD_FRAME(1, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E7A78[] =
+{
+ gUnknown_83E7A70,
+};
+
+const struct SpriteTemplate gUnknown_83E7A7C =
+{
+ .tileTag = ANIM_TAG_MUD_SAND,
+ .paletteTag = ANIM_TAG_MUD_SAND,
+ .oam = &gOamData_83AC9D0,
+ .anims = gUnknown_83E7A78,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimDirtScatter,
+};
+
+const struct SpriteTemplate gUnknown_83E7A94 =
+{
+ .tileTag = ANIM_TAG_MUD_SAND,
+ .paletteTag = ANIM_TAG_MUD_SAND,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimMudSportDirt,
+};
+
+const struct SpriteTemplate gUnknown_83E7AAC =
+{
+ .tileTag = ANIM_TAG_MUD_SAND,
+ .paletteTag = ANIM_TAG_MUD_SAND,
+ .oam = &gOamData_83AC9C8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimFissureDirtPlumeParticle,
+};
+
+const struct SpriteTemplate gUnknown_83E7AC4 =
+{
+ .tileTag = ANIM_TAG_DIRT_MOUND,
+ .paletteTag = ANIM_TAG_DIRT_MOUND,
+ .oam = &gOamData_83AC9F8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimDigDirtMound,
+};
+
+// Moves a bone projectile towards the target mon, which moves like
+// a boomerang. After hitting the target mon, it comes back to the user.
+static void AnimBonemerangProjectile(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ sprite->data[0] = 20;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sprite->data[5] = -40;
+ InitAnimArcTranslation(sprite);
+ sprite->callback = AnimBonemerangProjectileStep;
+}
+
+static void AnimBonemerangProjectileStep(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ {
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.y = 0;
+ sprite->pos2.x = 0;
+ sprite->data[0] = 20;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ sprite->data[5] = 40;
+ InitAnimArcTranslation(sprite);
+ sprite->callback = AnimBonemerangProjectileEnd;
+ }
+}
+
+static void AnimBonemerangProjectileEnd(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ DestroyAnimSprite(sprite);
+}
+
+// Moves a bone projectile towards the target mon, starting right next to
+// the target mon.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x pixel offset
+// arg 3: target y pixel offset
+// arg 4: duration
+static void AnimBoneHitProjectile(struct Sprite *sprite)
+{
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3];
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+// Moves a small dirt projectile towards the target mon.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: duration
+// arg 3: target x pixel offset
+// arg 4: target y pixel offset
+static void AnimDirtScatter(struct Sprite *sprite)
+{
+ u8 targetXPos, targetYPos;
+ s16 xOffset, yOffset;
+
+ InitSpritePosToAnimAttacker(sprite, 1);
+ targetXPos = GetBattlerSpriteCoord2(gBattleAnimTarget, 2);
+ targetYPos = GetBattlerSpriteCoord2(gBattleAnimTarget, 3);
+ xOffset = Random() & 0x1F;
+ yOffset = Random() & 0x1F;
+ if (xOffset > 16)
+ xOffset = 16 - xOffset;
+ if (yOffset > 16)
+ yOffset = 16 - yOffset;
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[2] = targetXPos + xOffset;
+ sprite->data[4] = targetYPos + yOffset;
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+}
+
+// Moves a particle of dirt in the Mud Sport animation.
+// The dirt can either be rising upward, or falling down.
+// arg 0: 0 = dirt is rising into the air, 1 = dirt is falling down
+// arg 1: initial x pixel offset
+// arg 2: initial y pixel offset
+static void AnimMudSportDirt(struct Sprite *sprite)
+{
+ ++sprite->oam.tileNum;
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + gBattleAnimArgs[1];
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[2];
+ sprite->data[0] = gBattleAnimArgs[1] > 0 ? 1 : -1;
+ sprite->callback = AnimMudSportDirtRising;
+ }
+ else
+ {
+ sprite->pos1.x = gBattleAnimArgs[1];
+ sprite->pos1.y = gBattleAnimArgs[2];
+ sprite->pos2.y = -gBattleAnimArgs[2];
+ sprite->callback = AnimMudSportDirtFalling;
+ }
+}
+
+static void AnimMudSportDirtRising(struct Sprite *sprite)
+{
+ if (++sprite->data[1] > 1)
+ {
+ sprite->data[1] = 0;
+ sprite->pos1.x += sprite->data[0];
+ }
+ sprite->pos1.y -= 4;
+ if (sprite->pos1.y < -4)
+ DestroyAnimSprite(sprite);
+}
+
+static void AnimMudSportDirtFalling(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->pos2.y += 4;
+ if (sprite->pos2.y >= 0)
+ {
+ sprite->pos2.y = 0;
+ ++sprite->data[0];
+ }
+ break;
+ case 1:
+ if (++sprite->data[1] > 0)
+ {
+ sprite->data[1] = 0;
+ sprite->invisible ^= 1;
+ if (++sprite->data[2] == 10)
+ DestroyAnimSprite(sprite);
+ }
+ break;
+ }
+}
+
+void sub_80B8E94(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (gBattleAnimArgs[0] == 0)
+ task->func = sub_80B8ED4;
+ else
+ task->func = sub_80B908C;
+ task->func(taskId);
+}
+
+static void sub_80B8ED4(u8 taskId)
+{
+ u8 var0;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[10] = GetAnimBattlerSpriteId(0);
+ task->data[11] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
+ if (task->data[11] == 1)
+ {
+ task->data[12] = gBattle_BG1_X;
+ task->data[13] = gBattle_BG1_Y;
+ }
+ else
+ {
+ task->data[12] = gBattle_BG2_X;
+ task->data[13] = gBattle_BG2_Y;
+ }
+ var0 = GetBattlerYCoordWithElevation(gBattleAnimAttacker);
+ task->data[14] = var0 - 32;
+ task->data[15] = var0 + 32;
+ if (task->data[14] < 0)
+ task->data[14] = 0;
+ gSprites[task->data[10]].invisible = TRUE;
+ ++task->data[0];
+ break;
+ case 1:
+ sub_80B92B8(task->data[11], task->data[14], task->data[15]);
+ ++task->data[0];
+ break;
+ case 2:
+ task->data[2] = (task->data[2] + 6) & 0x7F;
+ if (++task->data[4] > 2)
+ {
+ task->data[4] = 0;
+ ++task->data[3];
+ }
+ task->data[5] = task->data[3] + (gSineTable[task->data[2]] >> 4);
+ if (task->data[11] == 1)
+ gBattle_BG1_Y = task->data[13] - task->data[5];
+ else
+ gBattle_BG2_Y = task->data[13] - task->data[5];
+
+ if (task->data[5] > 63)
+ {
+ task->data[5] = 120 - task->data[14];
+ if (task->data[11] == 1)
+ gBattle_BG1_Y = task->data[13] - task->data[5];
+ else
+ gBattle_BG2_Y = task->data[13] - task->data[5];
+
+ gSprites[task->data[10]].pos2.x = 272 - gSprites[task->data[10]].pos1.x;
+ ++task->data[0];
+ }
+ break;
+ case 3:
+ gScanlineEffect.state = 3;
+ ++task->data[0];
+ break;
+ case 4:
+ DestroyAnimVisualTask(taskId);
+ gSprites[task->data[10]].invisible = TRUE;
+ break;
+ }
+}
+
+static void sub_80B908C(u8 taskId)
+{
+ u8 spriteId = GetAnimBattlerSpriteId(0);
+
+ gSprites[spriteId].invisible = TRUE;
+ gSprites[spriteId].pos2.x = 0;
+ gSprites[spriteId].pos2.y = 0;
+ if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
+ gBattle_BG1_Y = 0;
+ else
+ gBattle_BG2_Y = 0;
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80B90EC(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (gBattleAnimArgs[0] == 0)
+ task->func = sub_80B912C;
+ else
+ task->func = sub_80B91B0;
+
+ task->func(taskId);
+}
+
+static void sub_80B912C(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[10] = GetAnimBattlerSpriteId(0);
+ gSprites[task->data[10]].invisible = FALSE;
+ gSprites[task->data[10]].pos2.x = 0;
+ gSprites[task->data[10]].pos2.y = 160 - gSprites[task->data[10]].pos1.y;
+ ++task->data[0];
+ break;
+ case 1:
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+static void sub_80B91B0(u8 taskId)
+{
+ u8 var0;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[10] = GetAnimBattlerSpriteId(0);
+ task->data[11] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
+ if (task->data[11] == 1)
+ task->data[12] = gBattle_BG1_X;
+ else
+ task->data[12] = gBattle_BG2_X;
+
+ var0 = GetBattlerYCoordWithElevation(gBattleAnimAttacker);
+ task->data[14] = var0 - 32;
+ task->data[15] = var0 + 32;
+ ++task->data[0];
+ break;
+ case 1:
+ sub_80B92B8(task->data[11], 0, task->data[15]);
+ ++task->data[0];
+ break;
+ case 2:
+ gSprites[task->data[10]].pos2.y = 96;
+ ++task->data[0];
+ break;
+ case 3:
+ gSprites[task->data[10]].pos2.y -= 8;
+ if (gSprites[task->data[10]].pos2.y == 0)
+ {
+ gScanlineEffect.state = 3;
+ ++task->data[0];
+ }
+ break;
+ case 4:
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B92B8(u8 useBG1, s16 y, s16 endY)
+{
+ s16 bgX;
+ struct ScanlineEffectParams scanlineParams;
+
+ if (useBG1 == 1)
+ {
+ bgX = gBattle_BG1_X;
+ scanlineParams.dmaDest = &REG_BG1HOFS;
+ }
+ else
+ {
+ bgX = gBattle_BG2_X;
+ scanlineParams.dmaDest = &REG_BG2HOFS;
+ }
+ if (y < 0)
+ y = 0;
+ while (y < endY)
+ {
+ gScanlineEffectRegBuffers[0][y] = bgX;
+ gScanlineEffectRegBuffers[1][y] = bgX;
+ ++y;
+ }
+ while (y < 160)
+ {
+ gScanlineEffectRegBuffers[0][y] = bgX + 240;
+ gScanlineEffectRegBuffers[1][y] = bgX + 240;
+ ++y;
+ }
+ scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
+ scanlineParams.initState = 1;
+ scanlineParams.unused9 = 0;
+ ScanlineEffect_SetParams(scanlineParams);
+}
+
+// Moves a particle of dirt in a plume of dirt. Used in Fissure and Dig.
+// arg 0: which mon (0 = attacker, 1 = target)
+// arg 1: which side of mon (0 = left, 1 = right)
+// arg 2: target x offset
+// arg 3: target y offset
+// arg 4: wave amplitude
+// arg 5: duration
+static void AnimFissureDirtPlumeParticle(struct Sprite *sprite)
+{
+ s8 battler;
+ s16 xOffset;
+
+ if (gBattleAnimArgs[0] == 0)
+ battler = gBattleAnimAttacker;
+ else
+ battler = gBattleAnimTarget;
+ xOffset = 24;
+ if (gBattleAnimArgs[1] == 1)
+ {
+ xOffset *= -1;
+ gBattleAnimArgs[2] *= -1;
+ }
+ sprite->pos1.x = GetBattlerSpriteCoord(battler, 2) + xOffset;
+ sprite->pos1.y = GetBattlerYCoordWithElevation(battler) + 30;
+ sprite->data[0] = gBattleAnimArgs[5];
+ sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2];
+ sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[3];
+ sprite->data[5] = gBattleAnimArgs[4];
+ InitAnimArcTranslation(sprite);
+ sprite->callback = AnimFissureDirtPlumeParticleStep;
+}
+
+static void AnimFissureDirtPlumeParticleStep(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ DestroyAnimSprite(sprite);
+}
+
+// Displays the dirt mound seen in the move Dig for set duration.
+// The dirt mound image is too large for a single sprite, so two
+// sprites are lined up next to each other.
+// arg 0: which mon (0 = attacker, 1 = target)
+// arg 1: oam tile num (0 = left half of image, 1 = right half of image)
+// arg 2: duration
+static void AnimDigDirtMound(struct Sprite *sprite)
+{
+ s8 battler;
+
+ if (gBattleAnimArgs[0] == 0)
+ battler = gBattleAnimAttacker;
+ else
+ battler = gBattleAnimTarget;
+ sprite->pos1.x = GetBattlerSpriteCoord(battler, 0) - 16 + (gBattleAnimArgs[1] * 32);
+ sprite->pos1.y = GetBattlerYCoordWithElevation(battler) + 32;
+ sprite->oam.tileNum += gBattleAnimArgs[1] * 8;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->callback = WaitAnimForDuration;
+}
+
+void sub_80B94B4(u8 taskId)
+{
+ u16 i;
+ struct Task *task = &gTasks[taskId];
+
+ if (gBattleAnimArgs[1])
+ task->data[14] = task->data[15] = gBattleAnimArgs[1] + 3;
+ else
+ task->data[14] = task->data[15] = (gAnimMovePower / 10) + 3;
+
+ task->data[3] = gBattleAnimArgs[2];
+ switch (gBattleAnimArgs[0])
+ {
+ case 5:
+ task->data[13] = gBattle_BG3_X;
+ task->func = sub_80B9584;
+ break;
+ case 4:
+ task->data[13] = 0;
+ for (i = 0; i < MAX_BATTLERS_COUNT; ++i)
+ {
+ if (IsBattlerSpriteVisible(i))
+ {
+ task->data[task->data[13] + 9] = gBattlerSpriteIds[i];
+ ++task->data[13];
+ }
+ }
+ task->func = sub_80B967C;
+ break;
+ default:
+ task->data[9] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
+ if (task->data[9] == 0xFF)
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+ else
+ {
+ task->data[13] = 1;
+ task->func = sub_80B967C;
+ }
+
+ break;
+ }
+}
+
+static void sub_80B9584(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ if ((task->data[2] & 1) == 0)
+ gBattle_BG3_X = task->data[13] + task->data[15];
+ else
+ gBattle_BG3_X = task->data[13] - task->data[15];
+
+ if (++task->data[2] == task->data[3])
+ {
+ task->data[2] = 0;
+ --task->data[14];
+ ++task->data[0];
+ }
+ }
+ break;
+ case 1:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ if ((task->data[2] & 1) == 0)
+ gBattle_BG3_X = task->data[13] + task->data[14];
+ else
+ gBattle_BG3_X = task->data[13] - task->data[14];
+
+ if (++task->data[2] == 4)
+ {
+ task->data[2] = 0;
+ if (--task->data[14] == 0)
+ ++task->data[0];
+ }
+ }
+ break;
+ case 2:
+ gBattle_BG3_X = task->data[13];
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B967C(u8 taskId)
+{
+ u16 i;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ sub_80B9760(task);
+ if (++task->data[2] == task->data[3])
+ {
+ task->data[2] = 0;
+ --task->data[14];
+ ++task->data[0];
+ }
+ }
+ break;
+ case 1:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ sub_80B9760(task);
+ if (++task->data[2] == 4)
+ {
+ task->data[2] = 0;
+ if (--task->data[14] == 0)
+ ++task->data[0];
+ }
+ }
+ break;
+ case 2:
+ for (i = 0; i < task->data[13]; ++i)
+ gSprites[task->data[9 + i]].pos2.x = 0;
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B9760(struct Task *task)
+{
+ u16 i, xOffset;
+
+ if ((task->data[2] & 1) == 0)
+ xOffset = (task->data[14] / 2) + (task->data[14] & 1);
+ else
+ xOffset = -(task->data[14] / 2);
+ for (i = 0; i < task->data[13]; ++i)
+ gSprites[task->data[9 + i]].pos2.x = xOffset;
+}
+
+void AnimTask_IsPowerOver99(u8 taskId)
+{
+ gBattleAnimArgs[15] = gAnimMovePower > 99;
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80B9800(u8 taskId)
+{
+ struct Task *newTask;
+ u8 battler = (gBattleAnimArgs[0] & 1) ? gBattleAnimTarget : gBattleAnimAttacker;
+
+ if (gBattleAnimArgs[0] > 1)
+ battler ^= BIT_FLANK;
+ newTask = &gTasks[CreateTask(sub_80B98A8, gBattleAnimArgs[1])];
+ newTask->data[1] = (32 - GetBattlerSpriteCoord(battler, 2)) & 0x1FF;
+ newTask->data[2] = (64 - GetBattlerSpriteCoord(battler, 3)) & 0xFF;
+ gBattle_BG3_X = newTask->data[1];
+ gBattle_BG3_Y = newTask->data[2];
+ newTask->data[3] = gBattleAnimArgs[2];
+ DestroyAnimVisualTask(taskId);
+}
+
+static void sub_80B98A8(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (gBattleAnimArgs[7] == task->data[3])
+ {
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
+ DestroyTask(taskId);
+ }
+ else
+ {
+ gBattle_BG3_X = task->data[1];
+ gBattle_BG3_Y = task->data[2];
+ }
+}
diff --git a/src/help_system_812B1E0.c b/src/help_system_812B1E0.c
index a527525f8..afb792072 100644
--- a/src/help_system_812B1E0.c
+++ b/src/help_system_812B1E0.c
@@ -16,13 +16,13 @@
#include "constants/maps.h"
#include "constants/songs.h"
-static EWRAM_DATA u16 gUnknown_203B0EC = 0;
+static EWRAM_DATA u16 sSomeVariable = 0;
static EWRAM_DATA u8 gUnknown_203B0EE = 0;
u8 gUnknown_3005E9C[4];
-u16 gUnknown_3005EA0;
+u16 gSomeVariableBackup;
-static bool32 sub_812B27C(const u16 * mapIdxs);
+static bool32 IsCurrentMapInArray(const u16 * mapIdxs);
static void sub_812B520(struct HelpSystemListMenu * a0, struct ListMenuItem * a1);
static void sub_812B614(struct HelpSystemListMenu * a0, struct ListMenuItem * a1);
static bool8 sub_812B754(void);
@@ -824,7 +824,7 @@ static const u8 gUnknown_845C4B6[][6] = {
{0, 0, 0, 0, 0, 0}
};
-static const u16 gUnknown_845C594[] = {
+static const u16 sMartMaps[] = {
MAP_VIRIDIAN_CITY_MART,
MAP_PEWTER_CITY_MART,
MAP_CERULEAN_CITY_MART,
@@ -847,7 +847,7 @@ static const u16 gUnknown_845C594[] = {
MAP_UNDEFINED
};
-static const u16 gUnknown_845C5BC[] = {
+static const u16 sGymMaps[] = {
MAP_PEWTER_CITY_GYM,
MAP_CERULEAN_CITY_GYM,
MAP_VERMILION_CITY_GYM,
@@ -859,7 +859,7 @@ static const u16 gUnknown_845C5BC[] = {
MAP_UNDEFINED
};
-static const u8 gUnknown_845C5CE[][3] = {
+static const u8 sDungeonMaps[][3] = {
{ MAP_GROUP(VIRIDIAN_FOREST), MAP_NUM(VIRIDIAN_FOREST), 1 },
{ MAP_GROUP(MT_MOON_1F), MAP_NUM(MT_MOON_1F), 3 },
{ MAP_GROUP(ROCK_TUNNEL_1F), MAP_NUM(ROCK_TUNNEL_1F), 2 },
@@ -878,14 +878,14 @@ static const u8 gUnknown_845C5CE[][3] = {
{ MAP_GROUP(SEVEN_ISLAND_TANOBY_RUINS_MONEAN_CHAMBER), MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_MONEAN_CHAMBER), 7 }
};
-void sub_812B1E0(u8 a0)
+void HelpSystem_SetSomeVariable(u8 a0)
{
- gUnknown_203B0EC = a0;
+ sSomeVariable = a0;
}
void HelpSystem_SetSomeVariable2(u8 a0)
{
- switch (gUnknown_203B0EC)
+ switch (sSomeVariable)
{
case 23:
case 24:
@@ -895,37 +895,37 @@ void HelpSystem_SetSomeVariable2(u8 a0)
break;
// fallthrough
default:
- gUnknown_203B0EC = a0;
+ sSomeVariable = a0;
break;
}
}
-void sub_812B220(void)
+void Special_SetSomeVariable(void)
{
- gUnknown_203B0EC = gSpecialVar_0x8004;
+ sSomeVariable = gSpecialVar_0x8004;
}
-void sub_812B234(void)
+void HelpSystem_BackupSomeVariable(void)
{
- gUnknown_3005EA0 = gUnknown_203B0EC;
+ gSomeVariableBackup = sSomeVariable;
}
-void sub_812B248(void)
+void HelpSystem_RestoreSomeVariable(void)
{
- gUnknown_203B0EC = gUnknown_3005EA0;
+ sSomeVariable = gSomeVariableBackup;
}
-static bool32 sub_812B25C(void)
+static bool32 IsInMartMap(void)
{
- return sub_812B27C(gUnknown_845C594);
+ return IsCurrentMapInArray(sMartMaps);
}
-static bool32 sub_812B26C(void)
+static bool32 IsInGymMap(void)
{
- return sub_812B27C(gUnknown_845C5BC);
+ return IsCurrentMapInArray(sGymMaps);
}
-static bool32 sub_812B27C(const u16 * mapIdxs)
+static bool32 IsCurrentMapInArray(const u16 * mapIdxs)
{
u16 mapIdx = (gSaveBlock1Ptr->location.mapGroup << 8) + gSaveBlock1Ptr->location.mapNum;
s32 i;
@@ -939,18 +939,18 @@ static bool32 sub_812B27C(const u16 * mapIdxs)
return FALSE;
}
-static bool8 sub_812B2C4(void)
+static bool8 IsInDungeonMap(void)
{
u8 i, j;
for (i = 0; i < 16; i++)
{
- for (j = 0; j < gUnknown_845C5CE[i][2]; j++)
+ for (j = 0; j < sDungeonMaps[i][2]; j++)
{
if (
- gUnknown_845C5CE[i][0] == gSaveBlock1Ptr->location.mapGroup
- && gUnknown_845C5CE[i][1] + j == gSaveBlock1Ptr->location.mapNum
- && (i != 15 || FlagGet(FLAG_0x849) == TRUE)
+ sDungeonMaps[i][0] == gSaveBlock1Ptr->location.mapGroup
+ && sDungeonMaps[i][1] + j == gSaveBlock1Ptr->location.mapNum
+ && (i != 15 /* TANOBY */ || FlagGet(FLAG_0x849) == TRUE)
)
return TRUE;
}
@@ -964,7 +964,7 @@ void sub_812B35C(void)
sub_812B4B8();
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
HelpSystem_SetSomeVariable2(0x16);
- else if (sub_812B2C4())
+ else if (IsInDungeonMap())
HelpSystem_SetSomeVariable2(0x15);
else if (is_light_level_8_or_9(gMapHeader.mapType))
{
@@ -974,9 +974,9 @@ void sub_812B35C(void)
HelpSystem_SetSomeVariable2(0x0F);
else if (IsCurMapPokeCenter() == TRUE)
HelpSystem_SetSomeVariable2(0x10);
- else if (sub_812B25C() == TRUE)
+ else if (IsInMartMap() == TRUE)
HelpSystem_SetSomeVariable2(0x11);
- else if (sub_812B26C() == TRUE)
+ else if (IsInGymMap() == TRUE)
HelpSystem_SetSomeVariable2(0x12);
else
HelpSystem_SetSomeVariable2(0x13);
@@ -1055,7 +1055,7 @@ static void sub_812B520(struct HelpSystemListMenu * a0, struct ListMenuItem * a1
u8 r4 = 0;
for (i = 0; i < 6; i++)
{
- if (gUnknown_845C4B6[gUnknown_203B0EC][gUnknown_845C4B0[i]] == 1)
+ if (gUnknown_845C4B6[sSomeVariable][gUnknown_845C4B0[i]] == 1)
{
a1[r4].label = gUnknown_845B080[gUnknown_845C4B0[i]];
a1[r4].index = gUnknown_845C4B0[i];
@@ -1085,7 +1085,7 @@ static void sub_812B5A8(struct HelpSystemListMenu * a0, struct ListMenuItem * a1
static void sub_812B614(struct HelpSystemListMenu * a0, struct ListMenuItem * a1)
{
u8 r6 = 0;
- const u8 * r3 = gUnknown_845B9E0[gUnknown_203B0EC * 5 + gUnknown_3005E9C[1]];
+ const u8 * r3 = gUnknown_845B9E0[sSomeVariable * 5 + gUnknown_3005E9C[1]];
u8 i;
for (i = 0; r3[i] != 0xFF; i++)
{
diff --git a/src/item_use.c b/src/item_use.c
index f8a99cb1d..3a189d84a 100644
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -117,7 +117,7 @@ void sub_80A1084(void)
void sub_80A109C(u8 taskId)
{
- if (sub_807AA70() == TRUE)
+ if (field_weather_is_fade_finished() == TRUE)
{
sItemUseOnFieldCB(taskId);
}
@@ -172,7 +172,7 @@ bool8 sub_80A1194(void)
void sub_80A11C0(u8 taskId)
{
- if (sub_807AA70() == TRUE)
+ if (field_weather_is_fade_finished() == TRUE)
{
UnfreezeMapObjects();
ScriptContext2_Disable();
@@ -191,7 +191,7 @@ void sub_80A1208(void)
struct MailStruct mail;
mail.itemId = gSpecialVar_ItemId;
- sub_80BEBEC(&mail, ReturnToBagFromKeyItem, 0);
+ sub_80BEBEC(&mail, CB2_BagMenuFromStartMenu, 0);
}
void FieldUseFunc_MachBike(u8 taskId)
@@ -404,7 +404,7 @@ void FieldUseFunc_TmCase(u8 taskId)
void InitTMCaseFromBag(void)
{
- InitTMCase(0, ReturnToBagFromKeyItem, 0);
+ InitTMCase(0, CB2_BagMenuFromStartMenu, 0);
}
void Task_InitTMCaseFromField(u8 taskId)
@@ -435,7 +435,7 @@ void FieldUseFunc_BerryPouch(u8 taskId)
void InitBerryPouchFromBag(void)
{
- InitBerryPouch(BERRYPOUCH_FROMFIELD, ReturnToBagFromKeyItem, 0);
+ InitBerryPouch(BERRYPOUCH_FROMFIELD, CB2_BagMenuFromStartMenu, 0);
}
void Task_InitBerryPouchFromField(u8 taskId)
@@ -478,7 +478,7 @@ void FieldUseFunc_TeachyTv(u8 taskId)
void InitTeachyTvFromBag(void)
{
- InitTeachyTvController(0, ReturnToBagFromKeyItem);
+ InitTeachyTvController(0, CB2_BagMenuFromStartMenu);
}
void Task_InitTeachyTvFromField(u8 taskId)
@@ -608,7 +608,7 @@ void FieldUseFunc_TownMap(u8 taskId)
void sub_80A1CAC(void)
{
- sub_80BFF50(0, ReturnToBagFromKeyItem);
+ sub_80BFF50(0, CB2_BagMenuFromStartMenu);
}
void sub_80A1CC0(u8 taskId)
@@ -640,7 +640,7 @@ void FieldUseFunc_FameChecker(u8 taskId)
void sub_80A1D58(void)
{
- UseFameChecker(ReturnToBagFromKeyItem);
+ UseFameChecker(CB2_BagMenuFromStartMenu);
}
void sub_80A1D68(u8 taskId)
diff --git a/src/mailbox_pc.c b/src/mailbox_pc.c
index 0ebffc67e..0a4535271 100644
--- a/src/mailbox_pc.c
+++ b/src/mailbox_pc.c
@@ -94,10 +94,10 @@ static void ItemPrintFunc(u8 windowId, s32 itemId, u8 y)
}
}
-u8 MailboxPC_InitListMenu(struct PlayerPC_Unk_203AAC4 * playerPcStruct)
+u8 MailboxPC_InitListMenu(struct PlayerPCItemPageStruct * playerPcStruct)
{
u16 i;
- for (i = 0; i < playerPcStruct->unk_5; i++)
+ for (i = 0; i < playerPcStruct->count; i++)
{
sListMenuItems[i].label = sString_Dummy;
sListMenuItems[i].index = i;
@@ -106,7 +106,7 @@ u8 MailboxPC_InitListMenu(struct PlayerPC_Unk_203AAC4 * playerPcStruct)
sListMenuItems[i].index = -2;
gMultiuseListMenuTemplate.items = sListMenuItems;
- gMultiuseListMenuTemplate.totalItems = playerPcStruct->unk_5 + 1;
+ gMultiuseListMenuTemplate.totalItems = playerPcStruct->count + 1;
gMultiuseListMenuTemplate.windowId = sWindowIds[1];
gMultiuseListMenuTemplate.header_X = 0;
gMultiuseListMenuTemplate.item_X = GetMenuCursorDimensionByFont(2, 0);
@@ -132,9 +132,9 @@ static void MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu * list)
PlaySE(SE_SELECT);
}
-void MailboxPC_AddScrollIndicatorArrows(struct PlayerPC_Unk_203AAC4 * playerPcStruct)
+void MailboxPC_AddScrollIndicatorArrows(struct PlayerPCItemPageStruct * playerPcStruct)
{
- playerPcStruct->unk_A = AddScrollIndicatorArrowPairParameterized(2, 0xC2, 0xC, 0x94, playerPcStruct->unk_5 - playerPcStruct->unk_4 + 1, 110, 110, &playerPcStruct->scrollOffset);
+ playerPcStruct->scrollIndicatorId = AddScrollIndicatorArrowPairParameterized(2, 0xC2, 0xC, 0x94, playerPcStruct->count - playerPcStruct->pageItems + 1, 110, 110, &playerPcStruct->scrollOffset);
}
void MailboxPC_DestroyListMenuBuffer(void)
diff --git a/src/map_preview_screen.c b/src/map_preview_screen.c
index 7d9fa935e..c465a5683 100644
--- a/src/map_preview_screen.c
+++ b/src/map_preview_screen.c
@@ -495,7 +495,7 @@ static void sub_80F83D0(u8 taskId)
}
break;
case 2:
- if (sub_807AA70())
+ if (field_weather_is_fade_finished())
{
Overworld_PlaySpecialMapMusic();
data[0]++;
diff --git a/src/menu2.c b/src/menu2.c
index c6d5ab094..221f84318 100644
--- a/src/menu2.c
+++ b/src/menu2.c
@@ -485,7 +485,7 @@ void AddTextPrinterParameterized5(u8 windowId, u8 fontId, const u8 *str, u8 x, u
AddTextPrinter(&printer, speed, callback);
}
-void sub_812E6DC(u8 windowId, const u8 * src, u16 x, u16 y)
+void Menu_PrintFormatIntlPlayerName(u8 windowId, const u8 * src, u16 x, u16 y)
{
s32 i;
diff --git a/src/mystery_event_script.c b/src/mystery_event_script.c
index 89df1ee34..26cbdb145 100644
--- a/src/mystery_event_script.c
+++ b/src/mystery_event_script.c
@@ -247,7 +247,7 @@ bool8 MEScrCmd_givepokemon(struct ScriptContext *ctx)
if (species == SPECIES_EGG)
StringCopyN(gStringVar1, gText_EggNickname, POKEMON_NAME_LENGTH + 1);
else
- StringCopyN(gStringVar1, gText_Pokemon, POKEMON_NAME_LENGTH + 1);
+ StringCopyN(gStringVar1, gStartMenuText_Pokemon, POKEMON_NAME_LENGTH + 1);
if (gPlayerPartyCount == PARTY_SIZE)
{
diff --git a/src/new_menu_helpers.c b/src/new_menu_helpers.c
index 9d2a5c883..f82dbe9c6 100644
--- a/src/new_menu_helpers.c
+++ b/src/new_menu_helpers.c
@@ -395,7 +395,7 @@ void ResetBg0(void)
ChangeBgX(0, 0, 0);
ChangeBgY(0, 0, 0);
DeactivateAllTextPrinters();
- sub_80F6E9C();
+ LoadStdWindowFrameGfx();
}
u16 RunTextPrinters_CheckPrinter0Active(void)
@@ -452,7 +452,7 @@ void AddTextPrinterWithCustomSpeedForMessage(bool8 allowSkippingDelayWithButtonP
AddTextPrinterParameterized2(0, 2, gStringVar4, speed, NULL, 2, 1, 3);
}
-void sub_80F6E9C(void)
+void LoadStdWindowFrameGfx(void)
{
if (gUnknown_203ADFA == 2)
{
@@ -644,7 +644,7 @@ static u16 GetStdPalColor(u8 colorNum)
void DisplayItemMessageOnField(u8 taskId, u8 bgId, const u8 *string, TaskFunc callback)
{
- sub_80F6E9C();
+ LoadStdWindowFrameGfx();
DisplayMessageAndContinueTask(taskId, 0, DLG_WINDOW_BASE_TILE_NUM, DLG_WINDOW_PALETTE_NUM, bgId, GetTextSpeedSetting(), string, callback);
CopyWindowToVram(0, 3);
}
@@ -667,7 +667,7 @@ u8 GetTextSpeedSetting(void)
return gUnknown_841F428[gSaveBlock2Ptr->optionsTextSpeed];
}
-u8 sub_80F78E0(u8 height)
+u8 CreateStartMenuWindow(u8 height)
{
if (sStartMenuWindowId == 0xFF)
{
@@ -702,15 +702,15 @@ u16 GetStdWindowBaseTileNum(void)
return STD_WINDOW_BASE_TILE_NUM;
}
-void sub_80F7974(const u8 * text)
+void DrawHelpMessageWindowWithText(const u8 * text)
{
- sub_814FE6C(sub_8112EB4(), DLG_WINDOW_BASE_TILE_NUM, 0x10 * DLG_WINDOW_PALETTE_NUM);
- sub_8113018(text, 2);
+ sub_814FE6C(CreateHelpMessageWindow(), DLG_WINDOW_BASE_TILE_NUM, 0x10 * DLG_WINDOW_PALETTE_NUM);
+ PrintTextOnHelpMessageWindow(text, 2);
}
-void sub_80F7998(void)
+void DestroyHelpMessageWindow_(void)
{
- sub_8112EDC(2);
+ DestroyHelpMessageWindow(2);
}
void sub_80F79A4(void)
diff --git a/src/normal.c b/src/normal.c
new file mode 100644
index 000000000..4d86b55a6
--- /dev/null
+++ b/src/normal.c
@@ -0,0 +1,916 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "palette.h"
+#include "random.h"
+#include "task.h"
+#include "trig.h"
+
+static void AnimConfusionDuck(struct Sprite *sprite);
+static void AnimSimplePaletteBlend(struct Sprite *sprite);
+static void sub_80B9A7C(struct Sprite *sprite);
+static void sub_80B9B8C(struct Sprite *sprite);
+static void sub_80BA27C(struct Sprite *sprite);
+static void sub_80BA560(struct Sprite *sprite);
+static void sub_80BA5F8(struct Sprite *sprite);
+static void sub_80BA630(struct Sprite *sprite);
+static void sub_80BA6C8(struct Sprite *sprite);
+static void sub_80BA738(struct Sprite *sprite);
+static void sub_80BA780(struct Sprite *sprite);
+static void sub_80BA5A8(struct Sprite *sprite);
+static void AnimConfusionDuckStep(struct Sprite *sprite);
+static void AnimSimplePaletteBlendStep(struct Sprite *sprite);
+static void sub_80B9AD0(struct Sprite *sprite);
+static void sub_80B9B5C(struct Sprite *sprite);
+static void sub_80B9C2C(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount);
+static void sub_80B9C7C(u8 taskId);
+static void sub_80B9DA0(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount);
+static void sub_80B9DF0(u8 taskId);
+static void sub_80B9EA8(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount);
+static void sub_80B9F04(u8 taskId);
+static void sub_80B9FD8(u8 taskId);
+static void sub_80BA090(u8 taskId);
+static void sub_80BA3CC(void);
+static void sub_80BA320(struct Sprite *sprite);
+static void sub_80BA4D0(u8 taskId);
+static void sub_80BA7BC(struct Sprite *sprite);
+
+
+static const union AnimCmd gUnknown_83E7ADC[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(4, 8),
+ ANIMCMD_FRAME(0, 8, .hFlip = TRUE),
+ ANIMCMD_FRAME(8, 8),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd gUnknown_83E7AF0[] =
+{
+ ANIMCMD_FRAME(0, 8, .hFlip = TRUE),
+ ANIMCMD_FRAME(4, 8),
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(8, 8),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E7B04[] =
+{
+ gUnknown_83E7ADC,
+ gUnknown_83E7AF0,
+};
+
+const struct SpriteTemplate gConfusionDuckSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_DUCK,
+ .paletteTag = ANIM_TAG_DUCK,
+ .oam = &gOamData_83AC9D0,
+ .anims = gUnknown_83E7B04,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimConfusionDuck,
+};
+
+const struct SpriteTemplate gSimplePaletteBlendSpriteTemplate =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimSimplePaletteBlend,
+};
+
+const struct SpriteTemplate gComplexPaletteBlendSpriteTemplate =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B9A7C,
+};
+
+static const union AnimCmd gUnknown_83E7B54[] =
+{
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_FRAME(16, 3),
+ ANIMCMD_FRAME(32, 3),
+ ANIMCMD_FRAME(48, 3),
+ ANIMCMD_FRAME(64, 3),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E7B6C[] =
+{
+ gUnknown_83E7B54,
+};
+
+const struct SpriteTemplate gUnknown_83E7B70 =
+{
+ .tileTag = ANIM_TAG_SPARKLE_4,
+ .paletteTag = ANIM_TAG_SPARKLE_4,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E7B6C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B9B8C,
+};
+
+const struct SpriteTemplate gUnknown_83E7B88 =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BA27C,
+};
+
+static const union AffineAnimCmd gUnknown_83E7BA0[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E7BB0[] =
+{
+ AFFINEANIMCMD_FRAME(0xD8, 0xD8, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E7BC8[] =
+{
+ AFFINEANIMCMD_FRAME(0xB0, 0xB0, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E7BE0[] =
+{
+ AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7BF8[] =
+{
+ gUnknown_83E7BA0,
+ gUnknown_83E7BB0,
+ gUnknown_83E7BC8,
+ gUnknown_83E7BE0,
+};
+
+const struct SpriteTemplate gBasicHitSplatSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_IMPACT,
+ .paletteTag = ANIM_TAG_IMPACT,
+ .oam = &gOamData_83ACB58,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7BF8,
+ .callback = sub_80BA560,
+};
+
+const struct SpriteTemplate gUnknown_83E7C20 =
+{
+ .tileTag = ANIM_TAG_IMPACT,
+ .paletteTag = ANIM_TAG_IMPACT,
+ .oam = &gOamData_83ACB58,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7BF8,
+ .callback = sub_80BA5F8,
+};
+
+const struct SpriteTemplate gUnknown_83E7C38 =
+{
+ .tileTag = ANIM_TAG_WATER_IMPACT,
+ .paletteTag = ANIM_TAG_WATER_IMPACT,
+ .oam = &gOamData_83ACB58,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7BF8,
+ .callback = sub_80BA560,
+};
+
+const struct SpriteTemplate gUnknown_83E7C50 =
+{
+ .tileTag = ANIM_TAG_IMPACT,
+ .paletteTag = ANIM_TAG_IMPACT,
+ .oam = &gOamData_83ACB58,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7BF8,
+ .callback = sub_80BA630,
+};
+
+const struct SpriteTemplate gUnknown_83E7C68 =
+{
+ .tileTag = ANIM_TAG_IMPACT,
+ .paletteTag = ANIM_TAG_IMPACT,
+ .oam = &gOamData_83ACB58,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7BF8,
+ .callback = sub_80BA6C8,
+};
+
+const struct SpriteTemplate gUnknown_83E7C80 =
+{
+ .tileTag = ANIM_TAG_CROSS_IMPACT,
+ .paletteTag = ANIM_TAG_CROSS_IMPACT,
+ .oam = &gOamData_83ACAF8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80BA738,
+};
+
+const struct SpriteTemplate gUnknown_83E7C98 =
+{
+ .tileTag = ANIM_TAG_IMPACT,
+ .paletteTag = ANIM_TAG_IMPACT,
+ .oam = &gOamData_83ACA38,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7BF8,
+ .callback = sub_80BA780,
+};
+
+const struct SpriteTemplate gUnknown_83E7CB0 =
+{
+ .tileTag = ANIM_TAG_IMPACT,
+ .paletteTag = ANIM_TAG_IMPACT,
+ .oam = &gOamData_83ACB58,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7BF8,
+ .callback = sub_80BA5A8,
+};
+
+// Moves a spinning duck around the mon's head.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: initial wave offset
+// arg 3: wave period (higher means faster wave)
+// arg 4: duration
+static void AnimConfusionDuck(struct Sprite *sprite)
+{
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[2];
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->data[1] = -gBattleAnimArgs[3];
+ sprite->data[4] = 1;
+ }
+ else
+ {
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->data[4] = 0;
+ StartSpriteAnim(sprite, 1);
+ }
+ sprite->data[3] = gBattleAnimArgs[4];
+ sprite->callback = AnimConfusionDuckStep;
+ sprite->callback(sprite);
+}
+
+static void AnimConfusionDuckStep(struct Sprite *sprite)
+{
+ sprite->pos2.x = Cos(sprite->data[0], 30);
+ sprite->pos2.y = Sin(sprite->data[0], 10);
+ if ((u16)sprite->data[0] < 128)
+ sprite->oam.priority = 1;
+ else
+ sprite->oam.priority = 3;
+ sprite->data[0] = (sprite->data[0] + sprite->data[1]) & 0xFF;
+ if (++sprite->data[2] == sprite->data[3])
+ DestroyAnimSprite(sprite);
+}
+
+// Performs a simple color blend on a specified sprite.
+// arg 0: palette selector
+// arg 1: delay
+// arg 2: start blend amount
+// arg 3: end blend amount
+// arg 4: blend color
+static void AnimSimplePaletteBlend(struct Sprite *sprite)
+{
+ u32 selectedPalettes = UnpackSelectedBattleAnimPalettes(gBattleAnimArgs[0]);
+
+ BeginNormalPaletteFade(selectedPalettes, gBattleAnimArgs[1], gBattleAnimArgs[2], gBattleAnimArgs[3], gBattleAnimArgs[4]);
+ sprite->invisible = TRUE;
+ sprite->callback = AnimSimplePaletteBlendStep;
+}
+
+// Unpacks a bitfield and returns a bitmask of its selected palettes.
+// Bits 0-6 of the selector parameter result in the following palettes being selected:
+// 0: battle background palettes (BG palettes 1, 2, and 3)
+// 1: gBattleAnimAttacker OBJ palette
+// 2: gBattleAnimTarget OBJ palette
+// 3: gBattleAnimAttacker partner OBJ palette
+// 4: gBattleAnimTarget partner OBJ palette
+// 5: BG palette 4
+// 6: BG palette 5
+u32 UnpackSelectedBattleAnimPalettes(s16 selector)
+{
+ u8 battleBackground = selector & 1;
+ u8 attacker = (selector >> 1) & 1;
+ u8 target = (selector >> 2) & 1;
+ u8 attackerPartner = (selector >> 3) & 1;
+ u8 targetPartner = (selector >> 4) & 1;
+ u8 arg5 = (selector >> 5) & 1;
+ u8 arg6 = (selector >> 6) & 1;
+
+ return sub_8075BE8(battleBackground, attacker, target, attackerPartner, targetPartner, arg5, arg6);
+}
+
+static void AnimSimplePaletteBlendStep(struct Sprite *sprite)
+{
+ if (!gPaletteFade.active)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B9A7C(struct Sprite *sprite)
+{
+ u32 selectedPalettes;
+
+ sprite->data[0] = gBattleAnimArgs[1];
+ sprite->data[1] = gBattleAnimArgs[1];
+ sprite->data[2] = gBattleAnimArgs[2];
+ sprite->data[3] = gBattleAnimArgs[3];
+ sprite->data[4] = gBattleAnimArgs[4];
+ sprite->data[5] = gBattleAnimArgs[5];
+ sprite->data[6] = gBattleAnimArgs[6];
+ sprite->data[7] = gBattleAnimArgs[0];
+ selectedPalettes = UnpackSelectedBattleAnimPalettes(sprite->data[7]);
+ BlendPalettes(selectedPalettes, gBattleAnimArgs[4], gBattleAnimArgs[3]);
+ sprite->invisible = TRUE;
+ sprite->callback = sub_80B9AD0;
+}
+
+static void sub_80B9AD0(struct Sprite *sprite)
+{
+ u32 selectedPalettes;
+
+ if (sprite->data[0] > 0)
+ {
+ --sprite->data[0];
+ return;
+ }
+ if (gPaletteFade.active)
+ return;
+ if (sprite->data[2] == 0)
+ {
+ sprite->callback = sub_80B9B5C;
+ return;
+ }
+ selectedPalettes = UnpackSelectedBattleAnimPalettes(sprite->data[7]);
+ if (sprite->data[1] & 0x100)
+ BlendPalettes(selectedPalettes, sprite->data[4], sprite->data[3]);
+ else
+ BlendPalettes(selectedPalettes, sprite->data[6], sprite->data[5]);
+ sprite->data[1] ^= 0x100;
+ sprite->data[0] = sprite->data[1] & 0xFF;
+ --sprite->data[2];
+}
+
+static void sub_80B9B5C(struct Sprite *sprite)
+{
+ u32 selectedPalettes;
+
+ if (!gPaletteFade.active)
+ {
+ selectedPalettes = UnpackSelectedBattleAnimPalettes(sprite->data[7]);
+ BlendPalettes(selectedPalettes, 0, 0);
+ DestroyAnimSprite(sprite);
+ }
+}
+
+static void sub_80B9B8C(struct Sprite *sprite)
+{
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = 0;
+ sprite->data[1] = 10;
+ sprite->data[2] = 8;
+ sprite->data[3] = 40;
+ sprite->data[4] = 112;
+ sprite->data[5] = 0;
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = TranslateSpriteInGrowingCircleOverDuration;
+ sprite->callback(sprite);
+}
+
+void sub_80B9BDC(u8 taskId)
+{
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = gBattleAnimArgs[1];
+ gTasks[taskId].data[2] = gBattleAnimArgs[2];
+ gTasks[taskId].data[3] = gBattleAnimArgs[3];
+ gTasks[taskId].data[4] = gBattleAnimArgs[4];
+ gTasks[taskId].data[5] = gBattleAnimArgs[5];
+ gTasks[taskId].data[8] = 0;
+ sub_80B9C2C(taskId, 0, gTasks[taskId].data[4]);
+ gTasks[taskId].func = sub_80B9C7C;
+}
+
+static void sub_80B9C2C(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount)
+{
+ u32 selectedPalettes = UnpackSelectedBattleAnimPalettes(gTasks[taskId].data[0]);
+
+ BeginNormalPaletteFade(selectedPalettes,
+ gTasks[taskId].data[1],
+ initialBlendAmount,
+ targetBlendAmount,
+ gTasks[taskId].data[5]);
+ --gTasks[taskId].data[2];
+ gTasks[taskId].data[8] ^= 1;
+}
+
+static void sub_80B9C7C(u8 taskId)
+{
+ u8 initialBlendAmount, targetBlendAmount;
+
+ if (!gPaletteFade.active)
+ {
+ if (gTasks[taskId].data[2] > 0)
+ {
+ if (gTasks[taskId].data[8] == 0)
+ {
+ initialBlendAmount = gTasks[taskId].data[3];
+ targetBlendAmount = gTasks[taskId].data[4];
+ }
+ else
+ {
+ initialBlendAmount = gTasks[taskId].data[4];
+ targetBlendAmount = gTasks[taskId].data[3];
+ }
+ if (gTasks[taskId].data[2] == 1)
+ targetBlendAmount = 0;
+ sub_80B9C2C(taskId, initialBlendAmount, targetBlendAmount);
+ }
+ else
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+}
+
+void sub_80B9CE4(u8 taskId)
+{
+ s32 battler;
+ u32 selectedPalettes = 0;
+
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = gBattleAnimArgs[1];
+ gTasks[taskId].data[2] = gBattleAnimArgs[2];
+ gTasks[taskId].data[3] = gBattleAnimArgs[3];
+ gTasks[taskId].data[4] = gBattleAnimArgs[4];
+ gTasks[taskId].data[5] = gBattleAnimArgs[5];
+ gTasks[taskId].data[8] = 0;
+ for (battler = 0; battler < gBattlersCount; ++battler)
+ if (battler != gBattleAnimAttacker && battler != gBattleAnimTarget)
+ selectedPalettes |= 1 << (battler + 16);
+ if (gBattleAnimArgs[0] == 1)
+ selectedPalettes |= 0xE;
+ gTasks[taskId].data[9] = selectedPalettes >> 16;
+ gTasks[taskId].data[10] = selectedPalettes & 0xFF;
+ sub_80B9DA0(taskId, 0, gTasks[taskId].data[4]);
+ gTasks[taskId].func = sub_80B9DF0;
+}
+
+static void sub_80B9DA0(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount)
+{
+ u32 selectedPalettes = ((u16)gTasks[taskId].data[9] << 16) | (u16)gTasks[taskId].data[10];
+
+ BeginNormalPaletteFade(selectedPalettes,
+ gTasks[taskId].data[1],
+ initialBlendAmount,
+ targetBlendAmount,
+ gTasks[taskId].data[5]);
+ --gTasks[taskId].data[2];
+ gTasks[taskId].data[8] ^= 1;
+}
+
+static void sub_80B9DF0(u8 taskId)
+{
+ u8 initialBlendAmount, targetBlendAmount;
+
+ if (!gPaletteFade.active)
+ {
+ if (gTasks[taskId].data[2] > 0)
+ {
+ if (gTasks[taskId].data[8] == 0)
+ {
+ initialBlendAmount = gTasks[taskId].data[3];
+ targetBlendAmount = gTasks[taskId].data[4];
+ }
+ else
+ {
+ initialBlendAmount = gTasks[taskId].data[4];
+ targetBlendAmount = gTasks[taskId].data[3];
+ }
+
+ if (gTasks[taskId].data[2] == 1)
+ targetBlendAmount = 0;
+ sub_80B9DA0(taskId, initialBlendAmount, targetBlendAmount);
+ }
+ else
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+}
+
+void sub_80B9E58(u8 taskId)
+{
+ u8 paletteIndex;
+
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = gBattleAnimArgs[1];
+ gTasks[taskId].data[2] = gBattleAnimArgs[2];
+ gTasks[taskId].data[3] = gBattleAnimArgs[3];
+ gTasks[taskId].data[4] = gBattleAnimArgs[4];
+ gTasks[taskId].data[5] = gBattleAnimArgs[5];
+ gTasks[taskId].data[8] = 0;
+ sub_80B9EA8(taskId, 0, gTasks[taskId].data[4]);
+ gTasks[taskId].func = sub_80B9F04;
+}
+
+static void sub_80B9EA8(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount)
+{
+ u8 paletteIndex = IndexOfSpritePaletteTag(gTasks[taskId].data[0]);
+
+ BeginNormalPaletteFade(1 << (paletteIndex + 16),
+ gTasks[taskId].data[1],
+ initialBlendAmount,
+ targetBlendAmount,
+ gTasks[taskId].data[5]);
+ --gTasks[taskId].data[2];
+ gTasks[taskId].data[8] ^= 1;
+}
+
+static void sub_80B9F04(u8 taskId)
+{
+ u8 initialBlendAmount, targetBlendAmount;
+
+ if (!gPaletteFade.active)
+ {
+ if (gTasks[taskId].data[2] > 0)
+ {
+ if (gTasks[taskId].data[8] == 0)
+ {
+ initialBlendAmount = gTasks[taskId].data[3];
+ targetBlendAmount = gTasks[taskId].data[4];
+ }
+ else
+ {
+ initialBlendAmount = gTasks[taskId].data[4];
+ targetBlendAmount = gTasks[taskId].data[3];
+ }
+
+ if (gTasks[taskId].data[2] == 1)
+ targetBlendAmount = 0;
+ sub_80B9EA8(taskId, initialBlendAmount, targetBlendAmount);
+ }
+ else
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+}
+
+void sub_80B9F6C(u8 taskId)
+{
+ u8 paletteIndex;
+
+ gTasks[taskId].data[0] = gBattleAnimArgs[1];
+ gTasks[taskId].data[1] = gBattleAnimArgs[1];
+ gTasks[taskId].data[2] = gBattleAnimArgs[2];
+ gTasks[taskId].data[3] = gBattleAnimArgs[3];
+ gTasks[taskId].data[4] = gBattleAnimArgs[4];
+ gTasks[taskId].data[5] = gBattleAnimArgs[5];
+ gTasks[taskId].data[6] = gBattleAnimArgs[6];
+ gTasks[taskId].data[7] = gBattleAnimArgs[0];
+ paletteIndex = IndexOfSpritePaletteTag(gBattleAnimArgs[0]);
+ BeginNormalPaletteFade(1 << (paletteIndex + 16),
+ 0,
+ gBattleAnimArgs[4],
+ gBattleAnimArgs[4],
+ gBattleAnimArgs[3]);
+ gTasks[taskId].func = sub_80B9FD8;
+}
+
+static void sub_80B9FD8(u8 taskId)
+{
+ u32 selectedPalettes;
+
+ if (gTasks[taskId].data[0] > 0)
+ {
+ --gTasks[taskId].data[0];
+ return;
+ }
+ if (gPaletteFade.active)
+ return;
+ if (gTasks[taskId].data[2] == 0)
+ {
+ gTasks[taskId].func = sub_80BA090;
+ return;
+ }
+ selectedPalettes = 1 << (IndexOfSpritePaletteTag(gTasks[taskId].data[7]) + 16);
+ if (gTasks[taskId].data[1] & 0x100)
+ BeginNormalPaletteFade(selectedPalettes,
+ 0,
+ gTasks[taskId].data[4],
+ gTasks[taskId].data[4],
+ gTasks[taskId].data[3]);
+ else
+ BeginNormalPaletteFade(selectedPalettes,
+ 0,
+ gTasks[taskId].data[6],
+ gTasks[taskId].data[6],
+ gTasks[taskId].data[5]);
+ gTasks[taskId].data[1] ^= 0x100;
+ gTasks[taskId].data[0] = gTasks[taskId].data[1] & 0xFF;
+ --gTasks[taskId].data[2];
+}
+
+static void sub_80BA090(u8 taskId)
+{
+ u32 selectedPalettes;
+
+ if (!gPaletteFade.active)
+ {
+ selectedPalettes = 1 << (IndexOfSpritePaletteTag(gTasks[taskId].data[7]) + 16);
+ BeginNormalPaletteFade(selectedPalettes, 0, 0, 0, RGB(0, 0, 0));
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+void sub_80BA0E8(u8 taskId)
+{
+ u32 selectedPalettes = 0;
+ u8 attackerBattler = gBattleAnimAttacker;
+ u8 targetBattler = gBattleAnimTarget;
+
+ if (gBattleAnimArgs[0] & 0x100)
+ selectedPalettes = sub_8075BE8(1, 0, 0, 0, 0, 0, 0);
+ if (gBattleAnimArgs[1] & 0x100)
+ selectedPalettes |= (0x10000 << attackerBattler);
+ if (gBattleAnimArgs[2] & 0x100)
+ selectedPalettes |= (0x10000 << targetBattler);
+ InvertPlttBuffer(selectedPalettes);
+ DestroyAnimVisualTask(taskId);
+}
+
+// not used
+static void sub_80BA16C(u8 taskId)
+{
+ u8 attackerBattler;
+ u8 targetBattler;
+ u8 paletteIndex;
+ u32 selectedPalettes = 0;
+
+ if (gTasks[taskId].data[0] == 0)
+ {
+ gTasks[taskId].data[2] = gBattleAnimArgs[0];
+ gTasks[taskId].data[3] = gBattleAnimArgs[1];
+ gTasks[taskId].data[4] = gBattleAnimArgs[2];
+ gTasks[taskId].data[1] = gBattleAnimArgs[3];
+ gTasks[taskId].data[5] = gBattleAnimArgs[4];
+ gTasks[taskId].data[6] = gBattleAnimArgs[5];
+ gTasks[taskId].data[7] = gBattleAnimArgs[6];
+ }
+ ++gTasks[taskId].data[0];
+ attackerBattler = gBattleAnimAttacker;
+ targetBattler = gBattleAnimTarget;
+ if (gTasks[taskId].data[2] & 0x100)
+ selectedPalettes = 0x0000FFFF;
+ if (gTasks[taskId].data[2] & 0x1)
+ {
+ paletteIndex = IndexOfSpritePaletteTag(gSprites[gHealthboxSpriteIds[attackerBattler]].template->paletteTag);
+ selectedPalettes |= (1 << paletteIndex) << 16;
+ }
+ if (gTasks[taskId].data[3] & 0x100)
+ selectedPalettes |= (1 << attackerBattler) << 16;
+ if (gTasks[taskId].data[4] & 0x100)
+ selectedPalettes |= (1 << targetBattler) << 16;
+ TintPlttBuffer(selectedPalettes, gTasks[taskId].data[5], gTasks[taskId].data[6], gTasks[taskId].data[7]);
+ if (gTasks[taskId].data[0] == gTasks[taskId].data[1])
+ {
+ UnfadePlttBuffer(selectedPalettes);
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+static void sub_80BA27C(struct Sprite *sprite)
+{
+ u16 var0;
+
+ sprite->invisible = TRUE;
+ sprite->data[0] = -gBattleAnimArgs[0];
+ sprite->data[1] = gBattleAnimArgs[1];
+ sprite->data[2] = gBattleAnimArgs[1];
+ sprite->data[3] = gBattleAnimArgs[2];
+
+ switch (gBattleAnimArgs[3])
+ {
+ case 0:
+ StoreSpriteCallbackInData6(sprite, (void *)&gBattle_BG3_X);
+ break;
+ case 1:
+ StoreSpriteCallbackInData6(sprite, (void *)&gBattle_BG3_Y);
+ break;
+ case 2:
+ StoreSpriteCallbackInData6(sprite, (void *)&gSpriteCoordOffsetX);
+ break;
+ default:
+ StoreSpriteCallbackInData6(sprite, (void *)&gSpriteCoordOffsetY);
+ break;
+ }
+ sprite->data[4] = *(u16 *)(sprite->data[6] | (sprite->data[7] << 16));
+ sprite->data[5] = gBattleAnimArgs[3];
+ var0 = sprite->data[5] - 2;
+ if (var0 < 2)
+ sub_80BA3CC();
+ sprite->callback = sub_80BA320;
+}
+
+static void sub_80BA320(struct Sprite *sprite)
+{
+ u8 i;
+ u16 var0;
+
+ if (sprite->data[3] > 0)
+ {
+ --sprite->data[3];
+ if (sprite->data[1] > 0)
+ {
+ --sprite->data[1];
+ }
+ else
+ {
+ sprite->data[1] = sprite->data[2];
+ *(u16 *)(sprite->data[6] | (sprite->data[7] << 16)) += sprite->data[0];
+ sprite->data[0] = -sprite->data[0];
+ }
+ }
+ else
+ {
+ *(u16 *)(sprite->data[6] | (sprite->data[7] << 16)) = sprite->data[4];
+ var0 = sprite->data[5] - 2;
+ if (var0 < 2)
+ for (i = 0; i < gBattlersCount; ++i)
+ gSprites[gBattlerSpriteIds[i]].coordOffsetEnabled = 0;
+ DestroyAnimSprite(sprite);
+ }
+}
+
+static void sub_80BA3CC(void)
+{
+ gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = 0;
+ gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = 0;
+ if (gBattleAnimArgs[4] == 2)
+ {
+ gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = 1;
+ gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = 1;
+ }
+ else
+ {
+ if (gBattleAnimArgs[4] == 0)
+ gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = 1;
+ else
+ gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = 1;
+ }
+}
+
+void sub_80BA47C(u8 taskId)
+{
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = gBattleAnimArgs[1];
+ gTasks[taskId].data[2] = gBattleAnimArgs[2];
+ gTasks[taskId].data[3] = gBattleAnimArgs[3];
+ gTasks[taskId].data[8] = gBattleAnimArgs[3];
+ gBattle_BG3_X = gBattleAnimArgs[0];
+ gBattle_BG3_Y = gBattleAnimArgs[1];
+ gTasks[taskId].func = sub_80BA4D0;
+ gTasks[taskId].func(taskId);
+}
+
+static void sub_80BA4D0(u8 taskId)
+{
+ if (gTasks[taskId].data[3] == 0)
+ {
+ if (gBattle_BG3_X == gTasks[taskId].data[0])
+ gBattle_BG3_X = -gTasks[taskId].data[0];
+ else
+ gBattle_BG3_X = gTasks[taskId].data[0];
+
+ if (gBattle_BG3_Y == -gTasks[taskId].data[1])
+ gBattle_BG3_Y = 0;
+ else
+ gBattle_BG3_Y = -gTasks[taskId].data[1];
+
+ gTasks[taskId].data[3] = gTasks[taskId].data[8];
+ if (--gTasks[taskId].data[2] == 0)
+ {
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ else
+ {
+ --gTasks[taskId].data[3];
+ }
+}
+
+static void sub_80BA560(struct Sprite *sprite)
+{
+ StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
+ if (gBattleAnimArgs[2] == 0)
+ InitSpritePosToAnimAttacker(sprite, 1);
+ else
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+static void sub_80BA5A8(struct Sprite *sprite)
+{
+ StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
+ if (gBattleAnimArgs[2] == 0)
+ InitSpritePosToAnimAttacker(sprite, 1);
+ else
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
+ StoreSpriteCallbackInData6(sprite, sub_80B1D3C);
+}
+
+static void sub_80BA5F8(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER && !IsContest())
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ sub_80BA560(sprite);
+}
+
+static void sub_80BA630(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[1] == -1)
+ gBattleAnimArgs[1] = Random() & 3;
+ StartSpriteAffineAnim(sprite, gBattleAnimArgs[1]);
+ if (gBattleAnimArgs[0] == 0)
+ InitSpritePosToAnimAttacker(sprite, 0);
+ else
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ sprite->pos2.x += (Random() % 48) - 24;
+ sprite->pos2.y += (Random() % 24) - 12;
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
+}
+
+static void sub_80BA6C8(struct Sprite *sprite)
+{
+ sprite->data[0] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
+ sprite->pos1.x = gSprites[sprite->data[0]].pos1.x + gSprites[sprite->data[0]].pos2.x;
+ sprite->pos1.y = gSprites[sprite->data[0]].pos1.y + gSprites[sprite->data[0]].pos2.y;
+ sprite->pos2.x = gBattleAnimArgs[1];
+ sprite->pos2.y = gBattleAnimArgs[2];
+ StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
+}
+
+static void sub_80BA738(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[2] == 0)
+ InitSpritePosToAnimAttacker(sprite, 1);
+ else
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->data[0] = gBattleAnimArgs[3];
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = WaitAnimForDuration;
+}
+
+static void sub_80BA780(struct Sprite *sprite)
+{
+ StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
+ if (gBattleAnimArgs[2] == 0)
+ InitSpritePosToAnimAttacker(sprite, 1);
+ else
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->callback = sub_80BA7BC;
+}
+
+static void sub_80BA7BC(struct Sprite *sprite)
+{
+ sprite->invisible ^= 1;
+ if (sprite->data[0]++ > 12)
+ DestroyAnimSprite(sprite);
+}
diff --git a/src/player_pc.c b/src/player_pc.c
new file mode 100644
index 000000000..b1929b9ed
--- /dev/null
+++ b/src/player_pc.c
@@ -0,0 +1,741 @@
+#include "global.h"
+#include "palette.h"
+#include "item.h"
+#include "task.h"
+#include "menu_indicators.h"
+#include "new_menu_helpers.h"
+#include "strings.h"
+#include "menu.h"
+#include "mail.h"
+#include "mail_data.h"
+#include "help_system.h"
+#include "sound.h"
+#include "overworld.h"
+#include "script.h"
+#include "mailbox_pc.h"
+#include "player_pc.h"
+#include "field_weather.h"
+#include "event_scripts.h"
+#include "field_fadetransition.h"
+#include "string_util.h"
+#include "item_menu.h"
+#include "item_pc.h"
+#include "party_menu.h"
+#include "constants/items.h"
+#include "constants/songs.h"
+
+#define PC_ITEM_ID 0
+#define PC_QUANTITY 1
+#define NEW_GAME_PC_ITEMS(i, type) (((u16 *)gNewGamePCItems + type)[i * 2])
+
+#define tCount data[2]
+#define tPageItems data[4]
+#define tItemPcParam data[6]
+#define tWindowId data[10]
+#define tListMenuTaskId data[11]
+
+static EWRAM_DATA const u8 *sItemOrder = NULL;
+static EWRAM_DATA u8 sTopMenuItemCount = 0;
+EWRAM_DATA struct PlayerPCItemPageStruct gPlayerPcMenuManager = {};
+
+#define SELECTED_MAIL (gSaveBlock1Ptr->mail[PC_MAIL_NUM(gPlayerPcMenuManager.scrollOffset) + gPlayerPcMenuManager.selectedRow])
+
+static void Task_DrawPlayerPcTopMenu(u8 taskId);
+static void Task_TopMenuHandleInput(u8 taskId);
+static void Task_PlayerPcItemStorage(u8 taskId);
+static void Task_PlayerPcMailbox(u8 taskId);
+static void Task_PlayerPcTurnOff(u8 taskId);
+static void Task_CreateItemStorageSubmenu(u8 taskId, u8 cursorPos);
+static void PrintStringOnWindow0WithDialogueFrame(const u8 *str);
+static void Task_TopMenu_ItemStorageSubmenu_HandleInput(u8 taskId);
+static void Task_PlayerPcDepositItem(u8 taskId);
+static void Task_DepositItem_WaitFadeAndGoToBag(u8 taskId);
+static void CB2_ReturnFromDepositMenu(void);
+static void Task_PlayerPcWithdrawItem(u8 taskId);
+static void CB2_ReturnFromWithdrawMenu(void);
+static void Task_WithdrawItemBeginFade(u8 taskId);
+static void Task_PlayerPcCancel(u8 taskId);
+static void Task_SetPageItemVars(u8 taskId);
+static u8 CountPCMail(void);
+static void PCMailCompaction(void);
+static void Task_DrawMailboxPcMenu(u8 taskId);
+static void Task_MailboxPcHandleInput(u8 taskId);
+static void Task_PrintWhatToDoWithSelectedMail(u8 taskId);
+static void Task_DestroyMailboxPcViewAndCancel(u8 taskId);
+static void Task_DrawMailSubmenu(u8 taskId);
+static void Task_MailSubmenuHandleInput(u8 taskId);
+static void Task_PlayerPcReadMail(u8 taskId);
+static void Task_WaitFadeAndReadSelectedMail(u8 taskId);
+static void CB2_SetCbToReturnToMailbox(void);
+static void Task_PlayerPcMoveMailToBag(u8 taskId);
+static void Task_DrawYesNoMenuToConfirmMoveToBag(u8 taskId);
+static void Task_MoveToBagYesNoMenuHandleInput(u8 taskId);
+static void Task_TryPutMailInBag_DestroyMsgIfSuccessful(u8 taskId);
+static void Task_DeclinedMoveMailToBag(u8 taskId);
+static void Task_PlayerPcGiveMailToMon(u8 taskId);
+static void Task_WaitFadeAndGoToPartyMenu(u8 taskId);
+static void Task_Error_NoPokemon(u8 taskId);
+static void Task_PlayerPcExitMailSubmenu(u8 taskId);
+
+static const u8 *const sItemStorageActionDescriptionPtrs[] = {
+ gText_TakeOutItemsFromThePC,
+ gText_StoreItemsInThePC,
+ gText_GoBackToThePreviousMenu
+};
+
+static const struct MenuAction sMenuActions_TopMenu[] = {
+ {gText_ItemStorage, Task_PlayerPcItemStorage},
+ {gText_Mailbox, Task_PlayerPcMailbox},
+ {gText_TurnOff, Task_PlayerPcTurnOff}
+};
+
+static const u8 gUnknown_8402200[] = { 0, 1, 2 };
+static const u8 gUnknown_8402203[] = { 0, 1, 2 };
+
+static const struct MenuAction sMenuActions_ItemPc[] = {
+ {gText_WithdrawItem2, Task_PlayerPcWithdrawItem},
+ {gText_DepositItem2, Task_PlayerPcDepositItem},
+ {gFameCheckerText_Cancel, Task_PlayerPcCancel}
+};
+
+static const struct ItemSlot gNewGamePCItems[] = {
+ { ITEM_POTION, 1 },
+ { ITEM_NONE, 0 }
+};
+
+static const struct MenuAction sMenuActions_MailSubmenu[] = {
+ {gOtherText_Read, Task_PlayerPcReadMail},
+ {gOtherText_MoveToBag, Task_PlayerPcMoveMailToBag},
+ {gOtherText_Give2, Task_PlayerPcGiveMailToMon},
+ {gOtherText_Exit, Task_PlayerPcExitMailSubmenu}
+};
+
+static const struct WindowTemplate sWindowTemplate_TopMenu_3Items = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 13,
+ .height = 6,
+ .paletteNum = 15,
+ .baseBlock = 0x008
+};
+
+static const struct WindowTemplate sWindowTemplate_TopMenu_4Items = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 13,
+ .height = 8,
+ .paletteNum = 15,
+ .baseBlock = 0x008
+};
+
+static const struct WindowTemplate sWindowTemplate_ItemStorageSubmenu = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 14,
+ .height = 6,
+ .paletteNum = 15,
+ .baseBlock = 0x008
+};
+
+void NewGameInitPCItems(void)
+{
+ u8 i;
+
+ for (i = 0, ClearPCItemSlots(); NEW_GAME_PC_ITEMS(i, PC_ITEM_ID) && NEW_GAME_PC_ITEMS(i, PC_QUANTITY) &&
+ AddPCItem(NEW_GAME_PC_ITEMS(i, PC_ITEM_ID), NEW_GAME_PC_ITEMS(i, PC_QUANTITY)) == TRUE; i++)
+ ;
+}
+
+void sub_80EB6AC(void)
+{
+ u8 taskId;
+
+ gPlayerPcMenuManager.unk_9 = 0;
+ HelpSystem_BackupSomeVariable();
+ sItemOrder = gUnknown_8402200;
+ sTopMenuItemCount = 3;
+ taskId = CreateTask(TaskDummy, 0);
+ DisplayItemMessageOnField(taskId, 2, gText_WhatWouldYouLikeToDo, Task_DrawPlayerPcTopMenu);
+}
+
+void sub_80EB6FC(void)
+{
+ u8 taskId;
+
+ gPlayerPcMenuManager.unk_9 = 1;
+ HelpSystem_BackupSomeVariable();
+ sItemOrder = gUnknown_8402203;
+ sTopMenuItemCount = 3;
+ taskId = CreateTask(TaskDummy, 0);
+ DisplayItemMessageOnField(taskId, 2, gText_WhatWouldYouLikeToDo, Task_DrawPlayerPcTopMenu);
+}
+
+static void Task_DrawPlayerPcTopMenu(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ if (sTopMenuItemCount == 3)
+ tWindowId = AddWindow(&sWindowTemplate_TopMenu_3Items);
+ else
+ tWindowId = AddWindow(&sWindowTemplate_TopMenu_4Items);
+ SetStdWindowBorderStyle(tWindowId, 0);
+ AddItemMenuActionTextPrinters(tWindowId, 2, GetMenuCursorDimensionByFont(2, 0), 2, GetFontAttribute(2, FONTATTR_LETTER_SPACING), 16, sTopMenuItemCount, sMenuActions_TopMenu, sItemOrder);
+ Menu_InitCursor(tWindowId, 2, 0, 2, 16, sTopMenuItemCount, 0);
+ ScheduleBgCopyTilemapToVram(0);
+ gTasks[taskId].func = Task_TopMenuHandleInput;
+}
+
+static void Task_TopMenuHandleInput(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ s8 input = Menu_ProcessInputNoWrapAround();
+ switch (input)
+ {
+ case -2:
+ break;
+ case -1:
+ PlaySE(SE_SELECT);
+ ClearStdWindowAndFrameToTransparent(tWindowId, FALSE);
+ ClearWindowTilemap(tWindowId);
+ RemoveWindow(tWindowId);
+ ScheduleBgCopyTilemapToVram(0);
+ gTasks[taskId].func = Task_PlayerPcTurnOff;
+ break;
+ default:
+ ClearStdWindowAndFrameToTransparent(tWindowId, FALSE);
+ ClearWindowTilemap(tWindowId);
+ RemoveWindow(tWindowId);
+ ScheduleBgCopyTilemapToVram(0);
+ gTasks[taskId].func = sMenuActions_TopMenu[sItemOrder[input]].func.void_u8;
+ break;
+ }
+}
+
+static void Task_ReturnToTopMenu(u8 taskId)
+{
+ HelpSystem_RestoreSomeVariable();
+ DisplayItemMessageOnField(taskId, 2, gText_WhatWouldYouLikeToDo, Task_DrawPlayerPcTopMenu);
+}
+
+static void Task_PlayerPcItemStorage(u8 taskId)
+{
+ Task_CreateItemStorageSubmenu(taskId, FALSE);
+ gTasks[taskId].func = Task_TopMenu_ItemStorageSubmenu_HandleInput;
+}
+
+static void Task_PlayerPcMailbox(u8 taskId)
+{
+ gPlayerPcMenuManager.count = CountPCMail();
+ if (gPlayerPcMenuManager.count == 0)
+ {
+ DisplayItemMessageOnField(taskId, 2, gText_TheresNoMailHere, Task_ReturnToTopMenu);
+ }
+ else
+ {
+ gPlayerPcMenuManager.selectedRow = 0;
+ gPlayerPcMenuManager.scrollOffset = 0;
+ PCMailCompaction();
+ Task_SetPageItemVars(taskId);
+ if (gPlayerPcMenuManager.unk_9 == 0)
+ HelpSystem_SetSomeVariable2(34);
+ else
+ HelpSystem_SetSomeVariable2(30);
+ if (MailboxPC_InitBuffers(gPlayerPcMenuManager.count) == TRUE)
+ {
+ ClearDialogWindowAndFrame(0, FALSE);
+ Task_DrawMailboxPcMenu(taskId);
+ gTasks[taskId].func = Task_MailboxPcHandleInput;
+ }
+ else
+ {
+ DisplayItemMessageOnField(taskId, 2, gText_TheresNoMailHere, Task_ReturnToTopMenu);
+ }
+ }
+}
+
+static void Task_PlayerPcTurnOff(u8 taskId)
+{
+ if (gPlayerPcMenuManager.unk_9 == 0)
+ ScriptContext1_SetupScript(EventScript_PalletTown_PlayersHouse_2F_ShutDownPC);
+ else
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+}
+
+static void Task_CreateItemStorageSubmenu(u8 taskId, u8 cursorPos)
+{
+ s16 *data = gTasks[taskId].data;
+ if (gPlayerPcMenuManager.unk_9 == 0)
+ HelpSystem_SetSomeVariable2(33);
+ else
+ HelpSystem_SetSomeVariable2(29);
+ tWindowId = AddWindow(&sWindowTemplate_ItemStorageSubmenu);
+ SetStdWindowBorderStyle(tWindowId, FALSE);
+ PrintTextArray(tWindowId, 2, GetMenuCursorDimensionByFont(2, 0), 2, 16, 3, sMenuActions_ItemPc);
+ Menu_InitCursor(tWindowId, 2, 0, 2, 16, 3, cursorPos);
+ ScheduleBgCopyTilemapToVram(0);
+ PrintStringOnWindow0WithDialogueFrame(sItemStorageActionDescriptionPtrs[cursorPos]);
+}
+
+static void PrintStringOnWindow0WithDialogueFrame(const u8 *str)
+{
+ DrawDialogueFrame(0, FALSE);
+ AddTextPrinterParameterized(0, 2, str, 0, 1, 0, NULL);
+}
+
+static void Task_TopMenu_ItemStorageSubmenu_HandleInput(u8 taskId)
+{
+ if (JOY_REPT(DPAD_UP))
+ {
+ if (Menu_GetCursorPos() != 0)
+ {
+ PlaySE(SE_SELECT);
+ Menu_MoveCursor(-1);
+ PrintStringOnWindow0WithDialogueFrame(sItemStorageActionDescriptionPtrs[Menu_GetCursorPos()]);
+ }
+ }
+ else if (JOY_REPT(DPAD_DOWN))
+ {
+ if (Menu_GetCursorPos() != 2)
+ {
+ PlaySE(SE_SELECT);
+ Menu_MoveCursor(+1);
+ PrintStringOnWindow0WithDialogueFrame(sItemStorageActionDescriptionPtrs[Menu_GetCursorPos()]);
+ }
+ }
+ else if (JOY_NEW(A_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ sMenuActions_ItemPc[Menu_GetCursorPos()].func.void_u8(taskId);
+ }
+ else if (JOY_NEW(B_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ sMenuActions_ItemPc[2].func.void_u8(taskId);
+ }
+}
+
+static void Task_DepositItem_WaitFadeAndGoToBag(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ CleanupOverworldWindowsAndTilemaps();
+ sub_8107DB4(3, POCKET_ITEMS - 1, CB2_ReturnToField);
+ gFieldCallback = CB2_ReturnFromDepositMenu;
+ DestroyTask(taskId);
+ }
+}
+
+static void Task_PlayerPcDepositItem(u8 taskId)
+{
+ gTasks[taskId].func = Task_DepositItem_WaitFadeAndGoToBag;
+ fade_screen(1, 0);
+}
+
+static void Task_ReturnToItemStorageSubmenu(u8 taskId)
+{
+ if (field_weather_is_fade_finished() == TRUE)
+ gTasks[taskId].func = Task_TopMenu_ItemStorageSubmenu_HandleInput;
+}
+
+static void CB2_ReturnFromDepositMenu(void)
+{
+ u8 taskId;
+ LoadStdWindowFrameGfx();
+ DrawDialogueFrame(0, TRUE);
+ taskId = CreateTask(Task_ReturnToItemStorageSubmenu, 0);
+ Task_CreateItemStorageSubmenu(taskId, 1);
+ sub_807DC00();
+}
+
+static void Task_PlayerPcWithdrawItem(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ tCount = CountItemsInPC();
+ if (tCount != 0)
+ {
+ tItemPcParam = 0;
+ gTasks[taskId].func = Task_WithdrawItemBeginFade;
+ gFieldCallback = CB2_ReturnFromWithdrawMenu;
+ }
+ else
+ {
+ ClearStdWindowAndFrameToTransparent(tWindowId, FALSE);
+ ClearWindowTilemap(tWindowId);
+ RemoveWindow(tWindowId);
+ DisplayItemMessageOnField(taskId, 2, gText_ThereAreNoItems, Task_PlayerPcItemStorage);
+ }
+}
+
+static void CB2_ReturnFromWithdrawMenu(void)
+{
+ u8 taskId;
+ LoadStdWindowFrameGfx();
+ DrawDialogueFrame(0, TRUE);
+ taskId = CreateTask(Task_ReturnToItemStorageSubmenu, 0);
+ Task_CreateItemStorageSubmenu(taskId, 0);
+ sub_807DC00();
+}
+
+static void Task_WithdrawItem_WaitFadeAndGoToItemStorage(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ if (!gPaletteFade.active)
+ {
+ CleanupOverworldWindowsAndTilemaps();
+ ItemPc_Init(tItemPcParam, CB2_ReturnToField);
+ DestroyTask(taskId);
+ }
+}
+
+static void Task_WithdrawItemBeginFade(u8 taskId)
+{
+ gTasks[taskId].func = Task_WithdrawItem_WaitFadeAndGoToItemStorage;
+ ItemPc_SetInitializedFlag(0);
+ fade_screen(1, 0);
+}
+
+static void Task_PlayerPcCancel(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ ClearStdWindowAndFrameToTransparent(tWindowId, FALSE);
+ ClearWindowTilemap(tWindowId);
+ CopyWindowToVram(tWindowId, 1);
+ RemoveWindow(tWindowId);
+ Task_ReturnToTopMenu(taskId);
+}
+
+static void Task_SetPageItemVars(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ if (tCount >= 8)
+ tPageItems = 8;
+ else
+ tPageItems = tCount + 1;
+ if (gPlayerPcMenuManager.count >= 8)
+ gPlayerPcMenuManager.pageItems = 8;
+ else
+ gPlayerPcMenuManager.pageItems = gPlayerPcMenuManager.count + 1;
+}
+
+static u8 CountPCMail(void)
+{
+ u8 count = 0;
+ u8 i;
+
+ for (i = PC_MAIL_NUM(0); i < MAIL_COUNT; i++)
+ {
+ if (gSaveBlock1Ptr->mail[i].itemId != ITEM_NONE)
+ count++;
+ }
+ return count;
+}
+
+static void PCMailCompaction(void)
+{
+ u8 i;
+ u8 j;
+ for (i = PC_MAIL_NUM(0); i < MAIL_COUNT - 1; i++)
+ {
+ for (j = i + 1; j < MAIL_COUNT; j++)
+ {
+ if (gSaveBlock1Ptr->mail[i].itemId == ITEM_NONE)
+ {
+ struct MailStruct mail = gSaveBlock1Ptr->mail[i];
+ gSaveBlock1Ptr->mail[i] = gSaveBlock1Ptr->mail[j];
+ gSaveBlock1Ptr->mail[j] = mail;
+ }
+ }
+ }
+}
+
+static void Task_DrawMailboxPcMenu(u8 taskId)
+{
+ u8 windowId = MailboxPC_GetAddWindow(0);
+ s32 width = GetStringWidth(2, gText_Mailbox, 0);
+ MailboxPC_GetAddWindow(1);
+ AddTextPrinterParameterized(windowId, 2, gText_Mailbox, (80 - width) / 2, 2, 0, NULL);
+ ScheduleBgCopyTilemapToVram(0);
+ gTasks[taskId].tListMenuTaskId = MailboxPC_InitListMenu(&gPlayerPcMenuManager);
+ MailboxPC_AddScrollIndicatorArrows(&gPlayerPcMenuManager);
+}
+
+static void Task_MailboxPcHandleInput(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ s32 input;
+ if (!gPaletteFade.active)
+ {
+ input = ListMenu_ProcessInput(tListMenuTaskId);
+ ListMenuGetScrollAndRow(tListMenuTaskId, &gPlayerPcMenuManager.scrollOffset, &gPlayerPcMenuManager.selectedRow);
+ switch (input)
+ {
+ case -1:
+ break;
+ case -2:
+ PlaySE(SE_SELECT);
+ RemoveScrollIndicatorArrowPair(gPlayerPcMenuManager.scrollIndicatorId);
+ Task_DestroyMailboxPcViewAndCancel(taskId);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ MailboxPC_RemoveWindow(0);
+ MailboxPC_RemoveWindow(1);
+ DestroyListMenuTask(tListMenuTaskId, &gPlayerPcMenuManager.scrollOffset, &gPlayerPcMenuManager.selectedRow);
+ ScheduleBgCopyTilemapToVram(0);
+ RemoveScrollIndicatorArrowPair(gPlayerPcMenuManager.scrollIndicatorId);
+ gTasks[taskId].func = Task_PrintWhatToDoWithSelectedMail;
+ break;
+ }
+ }
+}
+
+static void Task_PrintWhatToDoWithSelectedMail(u8 taskId)
+{
+ s32 length;
+ s32 i;
+ u8 *ptr;
+ StringCopy(gStringVar1, SELECTED_MAIL.playerName);
+ length = StringLength(gStringVar1);
+ if (length > 5)
+ {
+ for (ptr = gStringVar1 + length - 1; ptr >= gStringVar1; ptr--)
+ {
+ if (*ptr)
+ break;
+ *ptr = EOS;
+ }
+ }
+ else
+ {
+ ConvertInternationalString(gStringVar1, LANGUAGE_JAPANESE);
+ }
+ StringExpandPlaceholders(gStringVar4, gText_WhatWouldYouLikeToDoWithPlayersMail);
+ DisplayItemMessageOnField(taskId, 2, gStringVar4, Task_DrawMailSubmenu);
+}
+
+static void Task_DestroyMailboxPcViewAndCancel(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ MailboxPC_RemoveWindow(0);
+ MailboxPC_RemoveWindow(1);
+ DestroyListMenuTask(tListMenuTaskId, NULL, NULL);
+ ScheduleBgCopyTilemapToVram(0);
+ MailboxPC_DestroyListMenuBuffer();
+ Task_ReturnToTopMenu(taskId);
+}
+
+static void Task_DrawMailSubmenu(u8 taskId)
+{
+ u8 windowId = MailboxPC_GetAddWindow(2);
+ PrintTextArray(windowId, 2, GetMenuCursorDimensionByFont(2, 0), 2, 16, 4, sMenuActions_MailSubmenu);
+ Menu_InitCursor(windowId, 2, 0, 2, 16, 4, 0);
+ ScheduleBgCopyTilemapToVram(0);
+ gTasks[taskId].func = Task_MailSubmenuHandleInput;
+}
+
+static void Task_MailSubmenuHandleInput(u8 taskId)
+{
+ s8 input = Menu_ProcessInput_other();
+ switch (input)
+ {
+ case -1:
+ PlaySE(SE_SELECT);
+ Task_PlayerPcExitMailSubmenu(taskId);
+ break;
+ case -2:
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ sMenuActions_MailSubmenu[input].func.void_u8(taskId);
+ break;
+ }
+}
+
+static void Task_PlayerPcReadMail(u8 taskId)
+{
+ fade_screen(1, 0);
+ gTasks[taskId].func = Task_WaitFadeAndReadSelectedMail;
+}
+
+static void Task_WaitFadeAndReadSelectedMail(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ MailboxPC_DestroyListMenuBuffer();
+ CleanupOverworldWindowsAndTilemaps();
+ sub_80BEBEC(&SELECTED_MAIL, CB2_SetCbToReturnToMailbox, 1);
+ DestroyTask(taskId);
+ }
+}
+
+static void Task_WaitFadeAndReturnToMailboxPcInputHandler(u8 taskId)
+{
+ if (field_weather_is_fade_finished() == TRUE)
+ gTasks[taskId].func = Task_MailboxPcHandleInput;
+}
+
+static void CB2_ReturnToMailbox(void)
+{
+ u8 taskId;
+ if (gPlayerPcMenuManager.unk_9 == 0)
+ HelpSystem_SetSomeVariable2(34);
+ else
+ HelpSystem_SetSomeVariable2(30);
+ LoadStdWindowFrameGfx();
+ taskId = CreateTask(Task_WaitFadeAndReturnToMailboxPcInputHandler, 0);
+ if (MailboxPC_InitBuffers(gPlayerPcMenuManager.count) == TRUE)
+ Task_DrawMailboxPcMenu(taskId);
+ else
+ DestroyTask(taskId);
+ sub_807DC00();
+}
+
+static void CB2_SetCbToReturnToMailbox(void)
+{
+ gFieldCallback = CB2_ReturnToMailbox;
+ SetMainCallback2(CB2_ReturnToField);
+}
+
+static void Task_PlayerPcMoveMailToBag(u8 taskId)
+{
+ DisplayItemMessageOnField(taskId, 2, gText_MessageWillBeLost, Task_DrawYesNoMenuToConfirmMoveToBag);
+}
+
+static void Task_DrawYesNoMenuToConfirmMoveToBag(u8 taskId)
+{
+ DisplayYesNoMenuDefaultYes();
+ gTasks[taskId].func = Task_MoveToBagYesNoMenuHandleInput;
+}
+
+static void Task_MoveToBagYesNoMenuHandleInput(u8 taskId)
+{
+ switch (Menu_ProcessInputNoWrapClearOnChoose())
+ {
+ case -2:
+ break;
+ case 0:
+ Task_TryPutMailInBag_DestroyMsgIfSuccessful(taskId);
+ break;
+ case -1:
+ PlaySE(SE_SELECT);
+ // fallthrough
+ case 1:
+ Task_DeclinedMoveMailToBag(taskId);
+ break;
+ }
+}
+
+static void Task_TryPutMailInBag_DestroyMsgIfSuccessful(u8 taskId)
+{
+ struct MailStruct * mail = &SELECTED_MAIL;
+ if (!AddBagItem(mail->itemId, 1))
+ {
+ DisplayItemMessageOnField(taskId, 2, gText_BagIsFull, Task_PlayerPcExitMailSubmenu);
+ }
+ else
+ {
+ DisplayItemMessageOnField(taskId, 2, gText_MailReturnedToBagMessageErased, Task_PlayerPcExitMailSubmenu);
+ ClearMailStruct(mail);
+ PCMailCompaction();
+ gPlayerPcMenuManager.count--;
+ if (gPlayerPcMenuManager.count < gPlayerPcMenuManager.pageItems + gPlayerPcMenuManager.scrollOffset)
+ {
+ if (gPlayerPcMenuManager.scrollOffset != 0)
+ gPlayerPcMenuManager.scrollOffset--;
+ }
+ Task_SetPageItemVars(taskId);
+ }
+}
+
+static void Task_DeclinedMoveMailToBag(u8 taskId)
+{
+ Task_PlayerPcExitMailSubmenu(taskId);
+}
+
+static void Task_PlayerPcGiveMailToMon(u8 taskId)
+{
+ if (CalculatePlayerPartyCount() == 0)
+ {
+ Task_Error_NoPokemon(taskId);
+ }
+ else
+ {
+ fade_screen(1, 0);
+ gTasks[taskId].func = Task_WaitFadeAndGoToPartyMenu;
+ }
+}
+
+static void Task_WaitFadeAndGoToPartyMenu(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ MailboxPC_DestroyListMenuBuffer();
+ CleanupOverworldWindowsAndTilemaps();
+ PartyMenuInit_FromPlayerPc();
+ DestroyTask(taskId);
+ }
+}
+
+static void CB2_ReturnToMailboxPc_UpdateScrollVariables(void)
+{
+ u8 taskId;
+ u8 count;
+ if (gPlayerPcMenuManager.unk_9 == 0)
+ HelpSystem_SetSomeVariable2(34);
+ else
+ HelpSystem_SetSomeVariable2(30);
+ taskId = CreateTask(Task_WaitFadeAndReturnToMailboxPcInputHandler, 0);
+ count = gPlayerPcMenuManager.count;
+ gPlayerPcMenuManager.count = CountPCMail();
+ PCMailCompaction();
+ if (count != gPlayerPcMenuManager.count)
+ {
+ if (gPlayerPcMenuManager.count < gPlayerPcMenuManager.pageItems + gPlayerPcMenuManager.scrollOffset)
+ {
+ if (gPlayerPcMenuManager.scrollOffset != 0)
+ gPlayerPcMenuManager.scrollOffset--;
+ }
+ }
+ Task_SetPageItemVars(taskId);
+ LoadStdWindowFrameGfx();
+ if (MailboxPC_InitBuffers(gPlayerPcMenuManager.count) == TRUE)
+ Task_DrawMailboxPcMenu(taskId);
+ else
+ DestroyTask(taskId);
+ sub_807DC00();
+}
+
+void CB2_PlayerPC_ReturnFromPartyMenu(void)
+{
+ gFieldCallback = CB2_ReturnToMailboxPc_UpdateScrollVariables;
+ SetMainCallback2(CB2_ReturnToField);
+}
+
+static void Task_Error_NoPokemon(u8 taskId)
+{
+ DisplayItemMessageOnField(taskId, 2, gText_ThereIsNoPokemon, Task_PlayerPcExitMailSubmenu);
+}
+
+static void Task_RedrawPlayerPcMailboxAndSetUpInputHandler(u8 taskId)
+{
+ ClearDialogWindowAndFrame(0, FALSE);
+ Task_DrawMailboxPcMenu(taskId);
+ ScheduleBgCopyTilemapToVram(0);
+ gTasks[taskId].func = Task_MailboxPcHandleInput;
+}
+
+static void Task_PlayerPcExitMailSubmenu(u8 taskId)
+{
+ MailboxPC_RemoveWindow(2);
+ ScheduleBgCopyTilemapToVram(0);
+ gTasks[taskId].func = Task_RedrawPlayerPcMailboxAndSetUpInputHandler;
+}
+
+#undef tListMenuTaskId
+#undef tWindowId
+#undef tItemPcParam
+#undef tPageItems
+#undef tCount
diff --git a/src/pokemon.c b/src/pokemon.c
index 4685dcbcd..1159b1861 100644
--- a/src/pokemon.c
+++ b/src/pokemon.c
@@ -13,7 +13,6 @@
#include "event_data.h"
#include "util.h"
#include "pokemon_storage_system.h"
-#include "data.h"
#include "battle_gfx_sfx_util.h"
#include "battle_controllers.h"
#include "evolution_scene.h"
diff --git a/src/psychic.c b/src/psychic.c
new file mode 100644
index 000000000..662320a2b
--- /dev/null
+++ b/src/psychic.c
@@ -0,0 +1,1083 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "gpu_regs.h"
+#include "palette.h"
+#include "sound.h"
+#include "scanline_effect.h"
+#include "trig.h"
+#include "constants/songs.h"
+
+static void sub_80B2ECC(struct Sprite *sprite);
+static void sub_80B31D0(struct Sprite *sprite);
+static void sub_80B3278(struct Sprite *sprite);
+static void sub_80B32F4(struct Sprite *sprite);
+static void sub_80B37EC(struct Sprite *sprite);
+static void sub_80B3A34(struct Sprite *sprite);
+static void sub_80B3E84(struct Sprite *sprite);
+static void sub_80B300C(struct Sprite *sprite);
+static void sub_80B3044(struct Sprite *sprite);
+static void sub_80B30B0(struct Sprite *sprite);
+static void sub_80B3168(struct Sprite *sprite);
+static void sub_80B3384(struct Sprite *sprite);
+static void sub_80B33B8(struct Sprite *sprite);
+static void sub_80B3454(u8 taskId);
+static void sub_80B34DC(u8 taskId);
+static void sub_80B3618(u8 taskId);
+static void sub_80B3980(u8 taskId);
+static void sub_80B3B78(u8 taskId);
+static void sub_80B3D78(u8 taskId);
+
+static const union AffineAnimCmd gUnknown_83E6DDC[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0xFFFE, 0xFFFE, -10, 120),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6DF4[] =
+{
+ gUnknown_83E6DDC,
+};
+
+const struct SpriteTemplate gUnknown_83E6DF8 =
+{
+ .tileTag = ANIM_TAG_SPIRAL,
+ .paletteTag = ANIM_TAG_SPIRAL,
+ .oam = &gOamData_83ACB60,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6DF4,
+ .callback = sub_8075D9C,
+};
+
+const struct SpriteTemplate gUnknown_83E6E10 =
+{
+ .tileTag = ANIM_TAG_GREEN_LIGHT_WALL,
+ .paletteTag = ANIM_TAG_GREEN_LIGHT_WALL,
+ .oam = &gOamData_83ACB00,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2ECC,
+};
+
+const struct SpriteTemplate gUnknown_83E6E28 =
+{
+ .tileTag = ANIM_TAG_BLUE_LIGHT_WALL,
+ .paletteTag = ANIM_TAG_BLUE_LIGHT_WALL,
+ .oam = &gOamData_83ACB00,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2ECC,
+};
+
+const struct SpriteTemplate gUnknown_83E6E40 =
+{
+ .tileTag = ANIM_TAG_RED_LIGHT_WALL,
+ .paletteTag = ANIM_TAG_RED_LIGHT_WALL,
+ .oam = &gOamData_83ACB00,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2ECC,
+};
+
+const struct SpriteTemplate gUnknown_83E6E58 =
+{
+ .tileTag = ANIM_TAG_GRAY_LIGHT_WALL,
+ .paletteTag = ANIM_TAG_GRAY_LIGHT_WALL,
+ .oam = &gOamData_83ACB00,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2ECC,
+};
+
+const struct SpriteTemplate gUnknown_83E6E70 =
+{
+ .tileTag = ANIM_TAG_ORANGE_LIGHT_WALL,
+ .paletteTag = ANIM_TAG_ORANGE_LIGHT_WALL,
+ .oam = &gOamData_83ACB00,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B2ECC,
+};
+
+static const union AnimCmd gUnknown_83E6E88[] =
+{
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_FRAME(16, 3),
+ ANIMCMD_FRAME(32, 3),
+ ANIMCMD_FRAME(48, 3),
+ ANIMCMD_FRAME(64, 3),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6EA0[] =
+{
+ gUnknown_83E6E88,
+};
+
+const struct SpriteTemplate gUnknown_83E6EA4 =
+{
+ .tileTag = ANIM_TAG_SPARKLE_4,
+ .paletteTag = ANIM_TAG_SPARKLE_4,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E6EA0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B31D0,
+};
+
+static const union AnimCmd gUnknown_83E6EBC[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(4, 5),
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_FRAME(12, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6ED0[] =
+{
+ gUnknown_83E6EBC,
+};
+
+const struct SpriteTemplate gUnknown_83E6ED4 =
+{
+ .tileTag = ANIM_TAG_SPARKLE_3,
+ .paletteTag = ANIM_TAG_SPARKLE_3,
+ .oam = &gOamData_83AC9D0,
+ .anims = gUnknown_83E6ED0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B31D0,
+};
+
+const struct SpriteTemplate gUnknown_83E6EEC =
+{
+ .tileTag = ANIM_TAG_GOLD_RING,
+ .paletteTag = ANIM_TAG_GOLD_RING,
+ .oam = &gOamData_83ACA18,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = TranslateAnimSpriteToTargetMonLocation,
+};
+
+static const union AnimCmd gUnknown_83E6F04[] =
+{
+ ANIMCMD_FRAME(8, 60, .hFlip = TRUE),
+ ANIMCMD_FRAME(16, 5, .hFlip = TRUE),
+ ANIMCMD_FRAME(8, 5, .hFlip = TRUE),
+ ANIMCMD_FRAME(0, 5, .hFlip = TRUE),
+ ANIMCMD_FRAME(8, 22, .hFlip = TRUE),
+ ANIMCMD_LOOP(0),
+ ANIMCMD_FRAME(16, 5, .hFlip = TRUE),
+ ANIMCMD_FRAME(8, 5, .hFlip = TRUE),
+ ANIMCMD_FRAME(0, 5, .hFlip = TRUE),
+ ANIMCMD_FRAME(8, 5, .hFlip = TRUE),
+ ANIMCMD_LOOP(1),
+ ANIMCMD_FRAME(8, 22, .hFlip = TRUE),
+ ANIMCMD_FRAME(24, 3, .hFlip = TRUE),
+ ANIMCMD_FRAME(32, 3, .hFlip = TRUE),
+ ANIMCMD_FRAME(40, 22, .hFlip = TRUE),
+ ANIMCMD_END,
+};
+
+const union AnimCmd gUnknown_83E6F44[] =
+{
+ ANIMCMD_FRAME(8, 60),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(8, 22),
+ ANIMCMD_LOOP(0),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_LOOP(1),
+ ANIMCMD_FRAME(8, 22),
+ ANIMCMD_FRAME(24, 3),
+ ANIMCMD_FRAME(32, 3),
+ ANIMCMD_FRAME(40, 22),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6F84[] =
+{
+ gUnknown_83E6F04,
+ gUnknown_83E6F44,
+};
+
+const struct SpriteTemplate gUnknown_83E6F8C =
+{
+ .tileTag = ANIM_TAG_BENT_SPOON,
+ .paletteTag = ANIM_TAG_BENT_SPOON,
+ .oam = &gOamData_83ACA18,
+ .anims = gUnknown_83E6F84,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B3278,
+};
+
+static const union AnimCmd gUnknown_83E6FA4[] =
+{
+ ANIMCMD_FRAME(0, 6),
+ ANIMCMD_FRAME(16, 6),
+ ANIMCMD_FRAME(32, 6),
+ ANIMCMD_FRAME(48, 6),
+ ANIMCMD_FRAME(64, 6),
+ ANIMCMD_FRAME(80, 6),
+ ANIMCMD_FRAME(96, 18),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6FC4[] =
+{
+ gUnknown_83E6FA4,
+};
+
+static const union AffineAnimCmd gUnknown_83E6FC8[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, 4, 4),
+ AFFINEANIMCMD_FRAME(0, 0, -4, 8),
+ AFFINEANIMCMD_FRAME(0, 0, 4, 4),
+ AFFINEANIMCMD_LOOP(2),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6FF0[] =
+{
+ gUnknown_83E6FC8,
+};
+
+const struct SpriteTemplate gUnknown_83E6FF4 =
+{
+ .tileTag = ANIM_TAG_AMNESIA,
+ .paletteTag = ANIM_TAG_AMNESIA,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E6FC4,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B32F4,
+};
+
+static const union AffineAnimCmd gUnknown_83E700C[] =
+{
+ AFFINEANIMCMD_FRAME(-8, 10, 0, 16),
+ AFFINEANIMCMD_FRAME(18, -18, 0, 16),
+ AFFINEANIMCMD_FRAME(-20, 16, 0, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E702C[] =
+{
+ AFFINEANIMCMD_FRAME(64, -4, 0, 20),
+ AFFINEANIMCMD_FRAME(0, 0, 0, -56),
+ AFFINEANIMCMD_END,
+};
+
+static const struct SpriteTemplate gUnknown_83E7044 =
+{
+ .tileTag = ANIM_TAG_HOLLOW_ORB,
+ .paletteTag = ANIM_TAG_HOLLOW_ORB,
+ .oam = &gOamData_83ACAF0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct SpriteTemplate gUnknown_83E705C =
+{
+ .tileTag = 0x280A,
+ .paletteTag = 0x280A,
+ .oam = &gOamData_83AC9E0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B37EC,
+};
+
+static const union AffineAnimCmd gUnknown_83E7074[] =
+{
+ AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8),
+ AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd gUnknown_83E708C[] =
+{
+ AFFINEANIMCMD_FRAME(0xF0, 0xF0, 0, 0),
+ AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 6),
+ AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
+ AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 2),
+ AFFINEANIMCMD_JUMP(1),
+};
+
+static const union AffineAnimCmd gUnknown_83E70B4[] =
+{
+ AFFINEANIMCMD_FRAME(0xD0, 0xD0, 0, 0),
+ AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 4),
+ AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
+ AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 4),
+ AFFINEANIMCMD_JUMP(1),
+};
+
+static const union AffineAnimCmd gUnknown_83E70DC[] =
+{
+ AFFINEANIMCMD_FRAME(0xB0, 0xB0, 0, 0),
+ AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 2),
+ AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
+ AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 6),
+ AFFINEANIMCMD_JUMP(1),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7104[] =
+{
+ gUnknown_83E7074,
+ gUnknown_83E708C,
+ gUnknown_83E70B4,
+ gUnknown_83E70DC,
+};
+
+static const struct SpriteTemplate gUnknown_83E7114 =
+{
+ .tileTag = ANIM_TAG_BLUEGREEN_ORB,
+ .paletteTag = ANIM_TAG_BLUEGREEN_ORB,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7104,
+ .callback = sub_80B3A34,
+};
+
+static const union AffineAnimCmd gUnknown_83E712C[] =
+{
+ AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0),
+ AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 120),
+ AFFINEANIMCMD_END_ALT(1),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7144[] =
+{
+ gUnknown_83E712C,
+};
+
+const struct SpriteTemplate gUnknown_83E7148 =
+{
+ .tileTag = ANIM_TAG_WHITE_CIRCLE_OF_LIGHT,
+ .paletteTag = ANIM_TAG_WHITE_CIRCLE_OF_LIGHT,
+ .oam = &gOamData_83ACBC0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7144,
+ .callback = sub_8075D9C,
+};
+
+static const union AffineAnimCmd gUnknown_83E7160[] =
+{
+ AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0),
+ AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 17),
+ AFFINEANIMCMD_LOOP(0),
+ AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 10),
+ AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 10),
+ AFFINEANIMCMD_LOOP(4),
+ AFFINEANIMCMD_LOOP(0),
+ AFFINEANIMCMD_FRAME(0xFFF0, 0xFFF0, 0, 5),
+ AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 5),
+ AFFINEANIMCMD_LOOP(7),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E71B8[] =
+{
+ AFFINEANIMCMD_FRAME(0xFFEC, 0x18, 0, 15),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E71C8[] =
+{
+ gUnknown_83E7160,
+ gUnknown_83E71B8,
+};
+
+const struct SpriteTemplate gUnknown_83E71D0 =
+{
+ .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .oam = &gOamData_83ACBC0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E71C8,
+ .callback = sub_80B3E84,
+};
+
+static void sub_80B2ECC(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER || IsContest())
+ {
+ sprite->oam.priority = 2;
+ sprite->subpriority = 200;
+ }
+ if (!IsContest())
+ {
+ u8 battlerCopy;
+ u8 battler = battlerCopy = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
+ u8 rank = GetBattlerSpriteBGPriorityRank(battler);
+ s32 var0 = 1;
+ bool8 toBG2 = (rank ^ var0) != 0;
+
+ if (IsBattlerSpriteVisible(battler))
+ MoveBattlerSpriteToBG(battler, toBG2);
+ battler = BATTLE_PARTNER(battlerCopy);
+ if (IsBattlerSpriteVisible(battler))
+ MoveBattlerSpriteToBG(battler, toBG2 ^ var0);
+ }
+ if (!IsContest() && IsDoubleBattle())
+ {
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
+ {
+ sprite->pos1.x = 72;
+ sprite->pos1.y = 80;
+ }
+ else
+ {
+ sprite->pos1.x = 176;
+ sprite->pos1.y = 40;
+ }
+ }
+ else
+ {
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[0];
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[1];
+ }
+ if (IsContest())
+ sprite->pos1.y += 9;
+ sprite->data[0] = 256 + IndexOfSpritePaletteTag(gBattleAnimArgs[2]) * 16;
+ sprite->callback = sub_80B300C;
+ sub_80B300C(sprite);
+}
+
+static void sub_80B300C(struct Sprite *sprite)
+{
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[3], 16 - sprite->data[3]));
+ if (sprite->data[3] == 13)
+ sprite->callback = sub_80B3044;
+ else
+ ++sprite->data[3];
+}
+
+static void sub_80B3044(struct Sprite *sprite)
+{
+ u16 color;
+ u16 startOffset;
+ s32 i;
+
+ if (++sprite->data[1] == 2)
+ {
+ sprite->data[1] = 0;
+ startOffset = sprite->data[0];
+ color = gPlttBufferFaded[startOffset + 8];
+ for (i = 8; i > 0; --i)
+ gPlttBufferFaded[startOffset + i] = gPlttBufferFaded[startOffset + i - 1];
+ gPlttBufferFaded[startOffset + 1] = color;
+ if (++sprite->data[2] == 16)
+ sprite->callback = sub_80B30B0;
+ }
+}
+
+static void sub_80B30B0(struct Sprite *sprite)
+{
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[3], 16 - sprite->data[3]));
+ if (--sprite->data[3] == -1)
+ {
+ if (!IsContest())
+ {
+ u8 battlerCopy;
+ u8 battler = battlerCopy = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
+
+ if (IsBattlerSpriteVisible(battler))
+ gSprites[gBattlerSpriteIds[battler]].invisible = FALSE;
+ battler = BATTLE_PARTNER(battlerCopy);
+ if (IsBattlerSpriteVisible(battler))
+ gSprites[gBattlerSpriteIds[battler]].invisible = FALSE;
+ }
+ sprite->invisible = TRUE;
+ sprite->callback = sub_80B3168;
+ }
+}
+
+static void sub_80B3168(struct Sprite *sprite)
+{
+ if (!IsContest())
+ {
+ u8 battlerCopy;
+ u8 battler = battlerCopy = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
+ u8 rank = GetBattlerSpriteBGPriorityRank(battler);
+ s32 var0 = 1;
+ bool8 toBG2 = (rank ^ var0) != 0;
+
+ if (IsBattlerSpriteVisible(battler))
+ sub_8073128(toBG2);
+ battler = battlerCopy ^ 2;
+ if (IsBattlerSpriteVisible(battler))
+ sub_8073128(toBG2 ^ var0);
+ }
+ sprite->callback = DestroyAnimSprite;
+}
+
+static void sub_80B31D0(struct Sprite *sprite)
+{
+ if (sprite->data[0] == 0)
+ {
+ int arg3 = gBattleAnimArgs[3];
+ bool8 respectMonPicOffsets = FALSE;
+ if (arg3 == 0)
+ respectMonPicOffsets = TRUE;
+ if (!IsContest() && IsDoubleBattle())
+ {
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
+ {
+ sprite->pos1.x = 72 - gBattleAnimArgs[0];
+ sprite->pos1.y = gBattleAnimArgs[1] + 80;
+ }
+ else
+ {
+ sprite->pos1.x = gBattleAnimArgs[0] + 176;
+ sprite->pos1.y = gBattleAnimArgs[1] + 40;
+ }
+ }
+ else
+ {
+ if (gBattleAnimArgs[2] == 0)
+ InitSpritePosToAnimAttacker(sprite, respectMonPicOffsets);
+ else
+ InitSpritePosToAnimTarget(sprite, respectMonPicOffsets);
+ }
+
+ ++sprite->data[0];
+ }
+ else if (sprite->animEnded || sprite->affineAnimEnded)
+ {
+ DestroySpriteAndMatrix(sprite);
+ }
+}
+
+static void sub_80B3278(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ StartSpriteAnim(sprite, 1);
+ sprite->pos1.x -= 40;
+ sprite->pos1.y += 10;
+ sprite->data[1] = -1;
+ }
+ else
+ {
+ sprite->pos1.x += 40;
+ sprite->pos1.y -= 10;
+ sprite->data[1] = 1;
+ }
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+}
+
+static void sub_80B32F4(struct Sprite *sprite)
+{
+ s16 x = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_WIDTH) / 2;
+ s16 y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / -2;
+
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
+ x = -x;
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + x;
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + y;
+ if (sprite->pos1.y < 16)
+ sprite->pos1.y = 16;
+ StoreSpriteCallbackInData6(sprite, sub_80B3384);
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+}
+
+static void sub_80B3384(struct Sprite *sprite)
+{
+ sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
+ sprite->affineAnims = gUnknown_83E6FF0;
+ sprite->data[0] = 0;
+ InitSpriteAffineAnim(sprite);
+ sprite->callback = sub_80B33B8;
+}
+
+static void sub_80B33B8(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (sprite->affineAnimEnded)
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
+ sprite->data[1] = 18;
+ ++sprite->data[0];
+ }
+ break;
+ case 1:
+ if (--sprite->data[1] == -1)
+ DestroyAnimSprite(sprite);
+ break;
+ }
+}
+
+void sub_80B3418(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
+
+ task->data[0] = spriteId;
+ PrepareAffineAnimInTaskData(task, spriteId, gUnknown_83E700C);
+ task->func = sub_80B3454;
+}
+
+static void sub_80B3454(u8 taskId)
+{
+ if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80B3480(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
+
+ task->data[0] = spriteId;
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->data[3] = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? 4 : 8;
+ PrepareAffineAnimInTaskData(task, task->data[0], gUnknown_83E702C);
+ task->func = sub_80B34DC;
+}
+
+static void sub_80B34DC(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[1])
+ {
+ case 0:
+ RunAffineAnimFromTaskData(task);
+ if (++task->data[2] > 19)
+ ++task->data[1];
+ break;
+ case 1:
+ if (task->data[3] != 0)
+ {
+ gSprites[task->data[0]].pos2.y -= 8;
+ --task->data[3];
+ }
+ else
+ {
+ gSprites[task->data[0]].invisible = TRUE;
+ gSprites[task->data[0]].pos1.x = 272;
+ ResetSpriteRotScale(task->data[0]);
+ DestroyAnimVisualTask(taskId);
+ }
+ break;
+ }
+}
+
+void sub_80B3584(u8 taskId)
+{
+ u16 var0, var1;
+ struct Task *task = &gTasks[taskId];
+
+ task->data[3] = 16;
+ task->data[4] = 0;
+ task->data[13] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ task->data[14] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ var0 = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_WIDTH) / 3;
+ var1 = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / 3;
+ task->data[12] = var0 > var1 ? var0 : var1;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
+ task->func = sub_80B3618;
+}
+
+static void sub_80B3618(u8 taskId)
+{
+ u16 i;
+ u8 spriteId;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[1] > 8)
+ {
+ task->data[1] = 0;
+ spriteId = CreateSprite(&gUnknown_83E7044, task->data[13], task->data[14], 0);
+ task->data[task->data[2] + 8] = spriteId;
+ if (spriteId != MAX_SPRITES)
+ {
+ switch (task->data[2])
+ {
+ case 0:
+ gSprites[spriteId].pos2.x = task->data[12];
+ gSprites[spriteId].pos2.y = -task->data[12];
+ break;
+ case 1:
+ gSprites[spriteId].pos2.x = -task->data[12];
+ gSprites[spriteId].pos2.y = task->data[12];
+ break;
+ case 2:
+ gSprites[spriteId].pos2.x = task->data[12];
+ gSprites[spriteId].pos2.y = task->data[12];
+ break;
+ case 3:
+ gSprites[spriteId].pos2.x = -task->data[12];
+ gSprites[spriteId].pos2.y = -task->data[12];
+ break;
+ }
+ }
+
+ if (++task->data[2] == 5)
+ ++task->data[0];
+ }
+ break;
+ case 1:
+ if (task->data[1] & 1)
+ --task->data[3];
+ else
+ ++task->data[4];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
+ if (++task->data[1] == 32)
+ {
+ for (i = 8; i < 13; ++i)
+ if (task->data[i] != 64)
+ DestroySprite(&gSprites[task->data[i]]);
+ ++task->data[0];
+ }
+ break;
+ case 2:
+ ++task->data[0];
+ break;
+ case 3:
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B37A4(struct Sprite *sprite)
+{
+ if (sprite->data[1] > sprite->data[0] - 10)
+ sprite->invisible = sprite->data[1] & 1;
+ if (sprite->data[1] == sprite->data[0])
+ DestroyAnimSprite(sprite);
+ ++sprite->data[1];
+}
+
+static void sub_80B37EC(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ sprite->data[0] = gBattleAnimArgs[1];
+ sprite->callback = sub_80B37A4;
+}
+
+void sub_80B3834(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (IsContest())
+ {
+ if (gBattleAnimArgs[0] == 1)
+ {
+ task->data[10] = -10;
+ task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_RIGHT) - 8;
+ task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) + 8;
+ task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_RIGHT) - 8;
+ task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) + 8;
+ }
+ else
+ {
+ task->data[10] = 10;
+ task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_LEFT) + 8;
+ task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM) - 8;
+ task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_LEFT) + 8;
+ task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_BOTTOM) - 8;
+ }
+ }
+ else
+ {
+ if (gBattleAnimArgs[0] == 1)
+ {
+ task->data[10] = -10;
+ task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_LEFT) + 8;
+ task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) + 8;
+ task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_LEFT) + 8;
+ task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) + 8;
+ }
+ else
+ {
+ task->data[10] = 10;
+ task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_RIGHT) - 8;
+ task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM) - 8;
+ task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_RIGHT) - 8;
+ task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_BOTTOM) - 8;
+ }
+ }
+ task->data[1] = 6;
+ task->func = sub_80B3980;
+}
+
+static void sub_80B3980(u8 taskId)
+{
+ u8 spriteId;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[1] > 6)
+ {
+ task->data[1] = 0;
+ spriteId = CreateSprite(&gUnknown_83E7114, task->data[11], task->data[12], 0);
+ if (spriteId != 64)
+ {
+ gSprites[spriteId].data[0] = 16;
+ gSprites[spriteId].data[2] = task->data[13];
+ gSprites[spriteId].data[4] = task->data[14];
+ gSprites[spriteId].data[5] = task->data[10];
+ InitAnimArcTranslation(&gSprites[spriteId]);
+ StartSpriteAffineAnim(&gSprites[spriteId], task->data[2] & 3);
+ }
+
+ if (++task->data[2] == 12)
+ ++task->data[0];
+ }
+ break;
+ case 1:
+ if (++task->data[1] > 17)
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B3A34(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ DestroySprite(sprite);
+ }
+}
+
+void sub_80B3A58(u8 taskId)
+{
+ s16 i;
+ u8 yOffset;
+ struct ScanlineEffectParams scanlineParams;
+ struct Task *task = &gTasks[taskId];
+
+ yOffset = GetBattlerYCoordWithElevation(gBattleAnimTarget);
+ task->data[14] = yOffset - 32;
+ switch (gBattleAnimArgs[0])
+ {
+ case 0:
+ task->data[11] = 2;
+ task->data[12] = 5;
+ task->data[13] = 64;
+ task->data[15] = yOffset + 32;
+ break;
+ case 1:
+ task->data[11] = 2;
+ task->data[12] = 5;
+ task->data[13] = 192;
+ task->data[15] = yOffset + 32;
+ break;
+ case 2:
+ task->data[11] = 4;
+ task->data[12] = 4;
+ task->data[13] = 0;
+ task->data[15] = yOffset + 32;
+ break;
+ }
+ if (task->data[14] < 0)
+ task->data[14] = 0;
+ if (GetBattlerSpriteBGPriorityRank(gBattleAnimTarget) == 1)
+ {
+ task->data[10] = gBattle_BG1_X;
+ scanlineParams.dmaDest = &REG_BG1HOFS;
+ }
+ else
+ {
+ task->data[10] = gBattle_BG2_X;
+ scanlineParams.dmaDest = &REG_BG2HOFS;
+ }
+ for (i = task->data[14]; i <= task->data[14] + 64; ++i)
+ {
+ gScanlineEffectRegBuffers[0][i] = task->data[10];
+ gScanlineEffectRegBuffers[1][i] = task->data[10];
+ }
+ scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
+ scanlineParams.initState = 1;
+ scanlineParams.unused9 = 0;
+ ScanlineEffect_SetParams(scanlineParams);
+ task->func = sub_80B3B78;
+}
+
+static void sub_80B3B78(u8 taskId)
+{
+ s16 sineIndex, i;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ sineIndex = task->data[13];
+ for (i = task->data[14]; i <= task->data[15]; ++i)
+ {
+ s16 var2 = (gSineTable[sineIndex] >> task->data[12]);
+
+ if (var2 > 0)
+ var2 += (task->data[1] & 3);
+ else if (var2 < 0)
+ var2 -= (task->data[1] & 3);
+ gScanlineEffectRegBuffers[0][i] = task->data[10] + var2;
+ gScanlineEffectRegBuffers[1][i] = task->data[10] + var2;
+ sineIndex += task->data[11];
+ }
+ if (++task->data[1] > 23)
+ ++task->data[0];
+ break;
+ case 1:
+ gScanlineEffect.state = 3;
+ ++task->data[0];
+ break;
+ case 2:
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80B3C78(u8 taskId)
+{
+ s16 spriteId;
+ s16 matrixNum;
+ struct Task *task = &gTasks[taskId];
+
+ matrixNum = AllocOamMatrix();
+ if (matrixNum == 0xFF)
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ spriteId = CloneBattlerSpriteWithBlend(gBattleAnimArgs[0]);
+ if (spriteId < 0)
+ {
+ FreeOamMatrix(matrixNum);
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ gSprites[spriteId].callback = SpriteCallbackDummy;
+ gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_DOUBLE;
+ gSprites[spriteId].oam.matrixNum = matrixNum;
+ gSprites[spriteId].affineAnimPaused = TRUE;
+ ++gSprites[spriteId].subpriority;
+ SetSpriteRotScale(spriteId, 256, 256, 0);
+ CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
+ task->data[13] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
+ task->data[14] = matrixNum;
+ task->data[15] = spriteId;
+ task->func = sub_80B3D78;
+}
+
+static void sub_80B3D78(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[1] += 4;
+ task->data[2] = 256 - (gSineTable[task->data[1]] >> 1);
+ SetSpriteRotScale(task->data[15], task->data[2], task->data[2], 0);
+ SetBattlerSpriteYOffsetFromOtherYScale(task->data[15], task->data[13]);
+ if (task->data[1] == 48)
+ ++task->data[0];
+ break;
+ case 1:
+ task->data[1] -= 4;
+ task->data[2] = 256 - (gSineTable[task->data[1]] >> 1);;
+ SetSpriteRotScale(task->data[15], task->data[2], task->data[2], 0);
+ SetBattlerSpriteYOffsetFromOtherYScale(task->data[15], task->data[13]);
+ if (task->data[1] == 0)
+ ++task->data[0];
+ break;
+ case 2:
+ obj_delete_but_dont_free_vram(&gSprites[task->data[15]]);
+ ++task->data[0];
+ break;
+ case 3:
+ FreeOamMatrix(task->data[14]);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B3E84(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
+ if (IsContest())
+ sprite->pos1.y += 12;
+ sprite->data[1] = 8;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1]));
+ ++sprite->data[0];
+ break;
+ case 1:
+ if (sprite->affineAnimEnded)
+ {
+ PlaySE12WithPanning(SE_W100, BattleAnimAdjustPanning(-64));
+ ChangeSpriteAffineAnim(sprite, 1);
+ ++sprite->data[0];
+ }
+ break;
+ case 2:
+ if (sprite->data[2]++ > 1)
+ {
+ sprite->data[2] = 0;
+ --sprite->data[1];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1]));
+ if (sprite->data[1] == 0)
+ {
+ ++sprite->data[0];
+ sprite->invisible = TRUE;
+ }
+ }
+ sprite->data[3] += 0x380;
+ sprite->pos2.y -= sprite->data[3] >> 8;
+ sprite->data[3] &= 0xFF;
+ break;
+ case 3:
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyAnimSprite(sprite);
+ break;
+ }
+}
diff --git a/src/quest_log.c b/src/quest_log.c
index c8bd19174..ef8f56249 100644
--- a/src/quest_log.c
+++ b/src/quest_log.c
@@ -92,188 +92,185 @@ struct UnkStruct_203AE98 * gUnknown_3005E94;
static struct UnkStruct_300201C * gUnknown_300201C;
static u16 gUnknown_3002020;
-EWRAM_DATA u8 gUnknown_203ADF8 = 0;
+static EWRAM_DATA u8 gUnknown_203ADF8 = 0;
static EWRAM_DATA u8 sNumScenes = 0;
EWRAM_DATA u8 gUnknown_203ADFA = 0;
-EWRAM_DATA u16 gUnknown_203ADFC = 0;
-EWRAM_DATA u8 gUnknown_203ADFE[3] = {0};
-EWRAM_DATA u16 * gUnknown_203AE04 = NULL;
-EWRAM_DATA u16 * gUnknown_203AE08 = NULL;
-EWRAM_DATA u16 * gUnknown_203AE0C[32] = {NULL};
-EWRAM_DATA void (* gUnknown_203AE8C)(void) = NULL;
-EWRAM_DATA u16 *gUnknown_203AE90 = NULL;
-EWRAM_DATA struct UnkStruct_203AE94 gUnknown_203AE94 = {0};
-EWRAM_DATA struct UnkStruct_203AE98 gUnknown_203AE98[32] = {0};
-EWRAM_DATA u16 gUnknown_203AF98 = 0;
-EWRAM_DATA u8 gUnknown_203AF9A[64][2] = {{0}};
-EWRAM_DATA u16 gUnknown_203B01A = 0;
-EWRAM_DATA u16 gUnknown_203B01C = 0;
-EWRAM_DATA u16 gUnknown_203B01E = 0;
-EWRAM_DATA u8 gUnknown_203B020 = 0;
-EWRAM_DATA struct UnkStruct_203B024 gUnknown_203B024 = {0};
-EWRAM_DATA struct UnkStruct_203B044 gUnknown_203B044 = {0};
-EWRAM_DATA u8 gUnknown_203B048 = 0;
-EWRAM_DATA u8 gUnknown_203B049 = 0;
-EWRAM_DATA u8 gUnknown_203B04A = 0;
-EWRAM_DATA u8 gUnknown_203B04B = 0;
-
-void sub_8110A00(void);
-void sub_8110A3C(void);
-void sub_8110BB0(u8);
-void sub_8110BE8(u8);
-void sub_8110E3C(void);
-void sub_8110D94(void);
-void sub_8110E20(void);
-void sub_8110D48(u8);
-u8 sub_8110E68(struct UnkStruct_203AE98 *);
-void sub_8110F90(u8);
-void sub_8111150(u8);
-void sub_8111368(void);
-void sub_81115E8(void);
-u16 sub_8111618(void);
-u16 sub_811164C(void);
-void sub_8111688(void);
-void sub_811175C(u8, struct UnkStruct_203AE98 *);
-void sub_81118F4(s8);
-void sub_8111914(void);
-void sub_8111984(void);
-void sub_8111A34(u8);
-void sub_8111AD8(void);
-void sub_8111B80(void);
-u8 sub_8111BD4(void);
-void sub_8111D10(void);
-void sub_8111D90(u8);
-void sub_8111E20(void);
-void sub_8111E64(s8);
-void sub_8111E84(void);
-bool8 sub_8111F60(void);
-void sub_8111F8C(u8);
-void sub_8111FCC(u8);
-void sub_8112044(u8);
-void sub_81120AC(u8);
-bool8 sub_81121D8(u8);
-void sub_811229C(void);
-void sub_8112364(void);
-void sub_8112888(u8);
-void sub_8112940(u8, struct UnkStruct_203AE98 *, u16);
-u8 sub_8112CAC(void);
-bool8 sub_8112CEC(void);
-bool8 sub_8112D1C(void);
-void sub_8113078(struct Var4038Struct *);
-void sub_81130BC(struct Var4038Struct *);
-u8 sub_8113194(struct Var4038Struct *);
-u16 sub_81132A0(struct Var4038Struct *);
-void sub_81132E0(struct Var4038Struct *);
-bool16 sub_811337C(struct Var4038Struct *);
-void sub_8113390(struct Var4038Struct *);
-void sub_8113414(struct LinkBattleRecords *, u8, u8);
-void sub_81134CC(struct Var4038Struct *);
-bool8 sub_8113508(struct Var4038Struct * );
-void sub_8113524(struct Var4038Struct *);
-bool8 sub_81136D4(void);
-bool8 sub_8113778(u16, u16 *);
-bool8 sub_81137E4(u16, u16 *);
-u16 * sub_8113828(u16, u16 *);
-bool8 sub_81138A0(u16, u16 *);
-bool8 sub_8113954(u16, u16 *);
-void sub_8113A1C(u16);
-void sub_811381C(void);
-void sub_81138F8(void);
-bool8 sub_8113A44(u16, u16 *);
-u16 * sub_8113A78(u16 *, u16 **);
-void sub_8113ABC(u16 *);
-bool8 sub_8113AE8(u16 *);
-bool8 sub_8113B44(u16 *);
-void sub_8113B88(void);
-void sub_8113B94(u16);
-void sub_8113BD8(void);
-u16 * sub_8113BF4(u16 *);
-u16 * sub_8113C20(u16 *, struct UnkStruct_203AE98 *);
-u16 * sub_8113C5C(u16 *, u16);
-u16 * sub_8113C8C(u16 *, struct UnkStruct_203AE98 *);
-u16 * sub_8113CC8(u16 *, struct UnkStruct_203AE98 *);
-u16 * sub_8113D08(u16 *, struct UnkStruct_203AE98 *);
-u16 * sub_8113D48(u16 *, struct UnkStruct_203AE98 *);
-u16 * sub_8113D94(u16 *, struct UnkStruct_203AE98 *);
-u16 * sub_8113F14(u16 *, const u16 *);
-const u16 * sub_8113F3C(const u16 *);
-u16 * sub_8113F80(u16 *, const u16 *);
-const u16 * sub_8113FBC(const u16 *);
-u16 * sub_8114174(u16 *, const u16 *);
-const u16 * sub_8114188(const u16 *);
-u16 * sub_81141D0(u16 *, const u16 *);
-const u16 * sub_81141E4(const u16 *);
-u16 * sub_811422C(u16 *, const u16 *);
-const u16 * sub_8114240(const u16 *);
-u16 * sub_8114288(u16 *, const u16 *);
-const u16 * sub_811429C(const u16 *);
-u16 * sub_8114310(u16 *, const u16 *);
-const u16 * sub_8114324(const u16 *);
-u16 * sub_8114380(u16 *, const u16 *);
-const u16 * sub_8114394(const u16 *);
-u16 * sub_81143F0(u16 *, const u16 *);
-const u16 * sub_811443C(const u16 *);
-u16 * sub_811445C(u16 *, const u16 *);
-const u16 * sub_811448C(const u16 *);
-u16 * sub_81144EC(u16 *, const u16 *);
-const u16 * sub_8114518(const u16 *);
-u16 * sub_8114578(u16 *, const u16 *);
-const u16 * sub_81145A4(const u16 *);
-u16 * sub_8114604(u16 *, const u16 *);
-const u16 * sub_811464C(const u16 *);
-u16 * sub_8114710(u16 *, const u16 *);
-const u16 * sub_8114724(const u16 *);
-u16 * sub_8114744(u16 *, const u16 *);
-const u16 * sub_8114758(const u16 *);
-u16 * sub_8114778(u16 *, const u16 *);
-const u16 * sub_81147A8(const u16 *);
-u16 * sub_8114808(u16 *, const u16 *);
-const u16 * sub_8114834(const u16 *);
-u16 * sub_811488C(u16 *, const u16 *);
-const u16 * sub_81148BC(const u16 *);
-u16 * sub_8114918(u16 *, const u16 *);
-const u16 * sub_8114944(const u16 *);
-u16 * sub_8114990(u16 *, const u16 *);
-const u16 * sub_81149D0(const u16 *);
-u16 * sub_8114A1C(u16 *, const u16 *);
-const u16 * sub_8114A4C(const u16 *);
-u16 * sub_8114AA0(u16 *, const u16 *);
-const u16 * sub_8114AC8(const u16 *);
-u16 * sub_8114B0C(u16 *, const u16 *);
-const u16 * sub_8114B34(const u16 *);
-u16 * sub_8114B78(u16 *, const u16 *);
-const u16 * sub_8114BA0(const u16 *);
-u16 * sub_8114BE4(u16 *, const u16 *);
-const u16 * sub_8114C0C(const u16 *);
-u16 * sub_8114C68(u16 *, const u16 *);
-const u16 * sub_8114C8C(const u16 *);
-u16 * sub_8114CC0(u16 *, const u16 *);
-const u16 * sub_8114CE4(const u16 *);
-u16 * sub_8114D4C(u16 *, const u16 *);
-const u16 * sub_8114D68(const u16 *);
-u16 * sub_8114DE8(u16 *, const u16 *);
-const u16 * sub_8114E68(const u16 *);
-bool8 sub_8114FBC(u16);
-u16 * sub_8114FF0(u16 *, const u16 *);
-const u16 * sub_811500C(const u16 *);
-u16 * sub_8115078(u16 *, const u16 *);
-const u16 * sub_81150CC(const u16 *);
-u16 * sub_81151C0(u16 *, const u16 *);
-const u16 * sub_81151DC(const u16 *);
-u16 * sub_8115280(u16 *, const u16 *);
-const u16 * sub_81152BC(const u16 *);
-bool8 sub_81153A8(u16, u16 *);
-bool8 sub_81153E4(u16, u16 *);
-u16 * sub_8115410(u16 *, const u16 *);
-const u16 * sub_8115460(const u16 *);
-u16 * sub_81154DC(u16 *, const u16 *);
-const u16 * sub_8115518(const u16 *);
-u16 * sub_81155A4(u16 *, const u16 *);
-const u16 * sub_81155E0(const u16 *);
-u16 * sub_81156D8(u16 *, const u16 *);
-const u16 * sub_8115700(const u16 *);
-u16 * sub_81157DC(u16 *, const u16 *);
-const u16 * sub_8115800(const u16 *);
+static EWRAM_DATA u16 gUnknown_203ADFC = 0;
+static EWRAM_DATA u8 gUnknown_203ADFE[3] = {0};
+static EWRAM_DATA u16 * gUnknown_203AE04 = NULL;
+static EWRAM_DATA u16 * gUnknown_203AE08 = NULL;
+static EWRAM_DATA u16 * gUnknown_203AE0C[32] = {NULL};
+static EWRAM_DATA void (* gUnknown_203AE8C)(void) = NULL;
+static EWRAM_DATA u16 *gUnknown_203AE90 = NULL;
+static EWRAM_DATA struct UnkStruct_203AE94 gUnknown_203AE94 = {0};
+static EWRAM_DATA struct UnkStruct_203AE98 gUnknown_203AE98[32] = {0};
+static EWRAM_DATA u16 gUnknown_203AF98 = 0;
+static EWRAM_DATA u8 gUnknown_203AF9A[64][2] = {{0}};
+static EWRAM_DATA u16 gUnknown_203B01A = 0;
+static EWRAM_DATA u16 gUnknown_203B01C = 0;
+static EWRAM_DATA u16 gUnknown_203B01E = 0;
+static EWRAM_DATA u8 sHelpMessageWindowId = 0;
+static EWRAM_DATA struct UnkStruct_203B024 gUnknown_203B024 = {0};
+static EWRAM_DATA struct UnkStruct_203B044 gUnknown_203B044 = {0};
+static EWRAM_DATA u8 gUnknown_203B048 = 0;
+static EWRAM_DATA u8 gUnknown_203B049 = 0;
+static EWRAM_DATA u8 gUnknown_203B04A = 0;
+static EWRAM_DATA u8 gUnknown_203B04B = 0;
+
+static void sub_8110A00(void);
+static void sub_8110A3C(void);
+static void sub_8110BB0(u8);
+static void sub_8110BE8(u8);
+static void sub_8110E3C(void);
+static void sub_8110D94(void);
+static void sub_8110E20(void);
+static void sub_8110D48(u8);
+static u8 sub_8110E68(struct UnkStruct_203AE98 *);
+static void sub_8110F90(u8);
+static void sub_8111150(u8);
+static void sub_8111368(void);
+static void sub_81115E8(void);
+static u16 sub_8111618(void);
+static u16 sub_811164C(void);
+static void sub_8111688(void);
+static void sub_811175C(u8, struct UnkStruct_203AE98 *);
+static void sub_81118F4(s8);
+static void sub_8111914(void);
+static void sub_8111984(void);
+static void sub_8111A34(u8);
+static void sub_8111AD8(void);
+static void sub_8111B80(void);
+static u8 sub_8111BD4(void);
+static void sub_8111D10(void);
+static void sub_8111D90(u8);
+static void sub_8111E20(void);
+static void sub_8111E64(s8);
+static void sub_8111E84(void);
+static bool8 sub_8111F60(void);
+static void sub_8111F8C(u8);
+static void sub_8111FCC(u8);
+static void sub_8112044(u8);
+static void sub_81120AC(u8);
+static bool8 sub_81121D8(u8);
+static void sub_811229C(void);
+static void sub_8112888(u8);
+static void sub_8112940(u8, struct UnkStruct_203AE98 *, u16);
+static bool8 sub_8112CEC(void);
+static bool8 sub_8112D1C(void);
+static void sub_8113078(struct Var4038Struct *);
+static void sub_81130BC(struct Var4038Struct *);
+static u8 sub_8113194(struct Var4038Struct *);
+static u16 sub_81132A0(struct Var4038Struct *);
+static void sub_81132E0(struct Var4038Struct *);
+static bool16 sub_811337C(struct Var4038Struct *);
+static void sub_8113390(struct Var4038Struct *);
+static void sub_8113414(struct LinkBattleRecords *, u8, u8);
+static void sub_81134CC(struct Var4038Struct *);
+static bool8 sub_8113508(struct Var4038Struct * );
+static void sub_8113524(struct Var4038Struct *);
+static bool8 sub_81136D4(void);
+static bool8 sub_8113778(u16, u16 *);
+static bool8 sub_81137E4(u16, u16 *);
+static u16 * sub_8113828(u16, u16 *);
+static bool8 sub_81138A0(u16, u16 *);
+static bool8 sub_8113954(u16, u16 *);
+static void sub_8113A1C(u16);
+static void sub_811381C(void);
+static bool8 sub_8113A44(u16, u16 *);
+static u16 * sub_8113A78(u16 *, u16 **);
+static void sub_8113ABC(u16 *);
+static bool8 sub_8113AE8(u16 *);
+static bool8 sub_8113B44(u16 *);
+static void sub_8113B88(void);
+static void sub_8113B94(u16);
+static void sub_8113BD8(void);
+static u16 * sub_8113BF4(u16 *);
+static u16 * sub_8113C20(u16 *, struct UnkStruct_203AE98 *);
+static u16 * sub_8113C5C(u16 *, u16);
+static u16 * sub_8113C8C(u16 *, struct UnkStruct_203AE98 *);
+static u16 * sub_8113CC8(u16 *, struct UnkStruct_203AE98 *);
+static u16 * sub_8113D08(u16 *, struct UnkStruct_203AE98 *);
+static u16 * sub_8113D48(u16 *, struct UnkStruct_203AE98 *);
+static u16 * sub_8113D94(u16 *, struct UnkStruct_203AE98 *);
+static u16 * sub_8113F14(u16 *, const u16 *);
+static const u16 * sub_8113F3C(const u16 *);
+static u16 * sub_8113F80(u16 *, const u16 *);
+static const u16 * sub_8113FBC(const u16 *);
+static u16 * sub_8114174(u16 *, const u16 *);
+static const u16 * sub_8114188(const u16 *);
+static u16 * sub_81141D0(u16 *, const u16 *);
+static const u16 * sub_81141E4(const u16 *);
+static u16 * sub_811422C(u16 *, const u16 *);
+static const u16 * sub_8114240(const u16 *);
+static u16 * sub_8114288(u16 *, const u16 *);
+static const u16 * sub_811429C(const u16 *);
+static u16 * sub_8114310(u16 *, const u16 *);
+static const u16 * sub_8114324(const u16 *);
+static u16 * sub_8114380(u16 *, const u16 *);
+static const u16 * sub_8114394(const u16 *);
+static u16 * sub_81143F0(u16 *, const u16 *);
+static const u16 * sub_811443C(const u16 *);
+static u16 * sub_811445C(u16 *, const u16 *);
+static const u16 * sub_811448C(const u16 *);
+static u16 * sub_81144EC(u16 *, const u16 *);
+static const u16 * sub_8114518(const u16 *);
+static u16 * sub_8114578(u16 *, const u16 *);
+static const u16 * sub_81145A4(const u16 *);
+static u16 * sub_8114604(u16 *, const u16 *);
+static const u16 * sub_811464C(const u16 *);
+static u16 * sub_8114710(u16 *, const u16 *);
+static const u16 * sub_8114724(const u16 *);
+static u16 * sub_8114744(u16 *, const u16 *);
+static const u16 * sub_8114758(const u16 *);
+static u16 * sub_8114778(u16 *, const u16 *);
+static const u16 * sub_81147A8(const u16 *);
+static u16 * sub_8114808(u16 *, const u16 *);
+static const u16 * sub_8114834(const u16 *);
+static u16 * sub_811488C(u16 *, const u16 *);
+static const u16 * sub_81148BC(const u16 *);
+static u16 * sub_8114918(u16 *, const u16 *);
+static const u16 * sub_8114944(const u16 *);
+static u16 * sub_8114990(u16 *, const u16 *);
+static const u16 * sub_81149D0(const u16 *);
+static u16 * sub_8114A1C(u16 *, const u16 *);
+static const u16 * sub_8114A4C(const u16 *);
+static u16 * sub_8114AA0(u16 *, const u16 *);
+static const u16 * sub_8114AC8(const u16 *);
+static u16 * sub_8114B0C(u16 *, const u16 *);
+static const u16 * sub_8114B34(const u16 *);
+static u16 * sub_8114B78(u16 *, const u16 *);
+static const u16 * sub_8114BA0(const u16 *);
+static u16 * sub_8114BE4(u16 *, const u16 *);
+static const u16 * sub_8114C0C(const u16 *);
+static u16 * sub_8114C68(u16 *, const u16 *);
+static const u16 * sub_8114C8C(const u16 *);
+static u16 * sub_8114CC0(u16 *, const u16 *);
+static const u16 * sub_8114CE4(const u16 *);
+static u16 * sub_8114D4C(u16 *, const u16 *);
+static const u16 * sub_8114D68(const u16 *);
+static u16 * sub_8114DE8(u16 *, const u16 *);
+static const u16 * sub_8114E68(const u16 *);
+static bool8 sub_8114FBC(u16);
+static u16 * sub_8114FF0(u16 *, const u16 *);
+static const u16 * sub_811500C(const u16 *);
+static u16 * sub_8115078(u16 *, const u16 *);
+static const u16 * sub_81150CC(const u16 *);
+static u16 * sub_81151C0(u16 *, const u16 *);
+static const u16 * sub_81151DC(const u16 *);
+static u16 * sub_8115280(u16 *, const u16 *);
+static const u16 * sub_81152BC(const u16 *);
+static bool8 sub_81153A8(u16, u16 *);
+static bool8 sub_81153E4(u16, u16 *);
+static u16 * sub_8115410(u16 *, const u16 *);
+static const u16 * sub_8115460(const u16 *);
+static u16 * sub_81154DC(u16 *, const u16 *);
+static const u16 * sub_8115518(const u16 *);
+static u16 * sub_81155A4(u16 *, const u16 *);
+static const u16 * sub_81155E0(const u16 *);
+static u16 * sub_81156D8(u16 *, const u16 *);
+static const u16 * sub_8115700(const u16 *);
+static u16 * sub_81157DC(u16 *, const u16 *);
+static const u16 * sub_8115800(const u16 *);
void sub_8115834(u8 *);
extern const u8 gUnknown_841A155[];
@@ -404,17 +401,17 @@ extern const u8 gUnknown_841B277[];
extern const u8 gUnknown_8418C1B[];
-const struct WindowTemplate gUnknown_845661C[3] = {
+static const struct WindowTemplate gUnknown_845661C[3] = {
{ 0, 0, 0, 30, 2, 15, 0x0e9 },
{ 0, 0, 18, 30, 2, 15, 0x0ad },
{ 0, 0, 14, 30, 6, 15, 0x14c }
};
-const u8 gUnknown_8456634[3] = {15, 1, 12};
+static const u8 gUnknown_8456634[3] = {15, 1, 12};
-const u16 gUnknown_8456638[] = INCBIN_U16("data/graphics/unknown_8456638.bin");
+static const u16 gUnknown_8456638[] = INCBIN_U16("data/graphics/unknown_8456638.bin");
-const u8 gUnknown_8456698[] = {17, 10, 3};
+static const u8 gUnknown_8456698[] = {17, 10, 3};
void sub_8110840(void * oldPointer)
{
@@ -493,7 +490,7 @@ void sub_81109CC(u8 a0)
gUnknown_203AE8C = sub_8110A3C;
}
-void sub_8110A00(void)
+static void sub_8110A00(void)
{
if (sub_8110E68(gUnknown_203AE98) != 1)
{
@@ -504,7 +501,7 @@ void sub_8110A00(void)
}
}
-void sub_8110A3C(void)
+static void sub_8110A3C(void)
{
if (gUnknown_203AE94.unk_0_0 == 2)
gUnknown_203AE94.unk_0_0 = 0;
@@ -556,7 +553,7 @@ void sub_8110AEC(u16 a0)
sub_81109CC(1);
}
-void sub_8110BB0(u8 a0)
+static void sub_8110BB0(u8 a0)
{
struct QuestLog * questLog = &gSaveBlock1Ptr->questLog[a0];
questLog->unk_001 = gSaveBlock1Ptr->location.mapGroup;
@@ -567,7 +564,7 @@ void sub_8110BB0(u8 a0)
}
#ifdef NONMATCHING
-void sub_8110BE8(u8 a0)
+static void sub_8110BE8(u8 a0)
{
struct QuestLog * questLog = &gSaveBlock1Ptr->questLog[a0];
u16 i; // r6
@@ -602,7 +599,7 @@ void sub_8110BE8(u8 a0)
}
#else
NAKED
-void sub_8110BE8(u8 a0)
+static void sub_8110BE8(u8 a0)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r10\n"
@@ -767,7 +764,7 @@ void sub_8110BE8(u8 a0)
}
#endif // NONMATCHING
-void sub_8110D48(u8 a0)
+static void sub_8110D48(u8 a0)
{
struct QuestLog * questLog = &gSaveBlock1Ptr->questLog[a0];
@@ -775,7 +772,7 @@ void sub_8110D48(u8 a0)
CpuCopy16(gSaveBlock1Ptr->vars, questLog->vars, VARS_COUNT * sizeof(u16));
}
-void sub_8110D94(void)
+static void sub_8110D94(void)
{
u16 i, j;
u16 sp0[4];
@@ -794,19 +791,19 @@ void sub_8110D94(void)
}
}
-void sub_8110E20(void)
+static void sub_8110E20(void)
{
VarSet(VAR_0x40AE, gSaveBlock1Ptr->mapDataId);
}
-void sub_8110E3C(void)
+static void sub_8110E3C(void)
{
sub_8113BF4(gUnknown_203AE08);
if (++gUnknown_203ADF8 > 3)
gUnknown_203ADF8 = 0;
}
-bool8 sub_8110E68(struct UnkStruct_203AE98 * a0)
+static bool8 sub_8110E68(struct UnkStruct_203AE98 * a0)
{
u16 i;
@@ -865,7 +862,7 @@ void TrySetUpQuestLogScenes_ElseContinueFromSave(u8 taskId)
}
}
-void sub_8110F90(u8 unused)
+static void sub_8110F90(u8 unused)
{
gSaveBlock1Ptr->location.mapGroup = 3;
gSaveBlock1Ptr->location.mapNum = 19;
@@ -937,7 +934,7 @@ void sub_8111134(void)
CopyWindowToVram(gUnknown_203ADFE[1], 1);
}
-void sub_8111150(u8 a0)
+static void sub_8111150(u8 a0)
{
struct QuestLog *questLog = &gSaveBlock1Ptr->questLog[a0];
u16 i;
@@ -982,7 +979,7 @@ void sub_8111274(u8 a0, u8 a1)
}
}
-void sub_8111368(void)
+static void sub_8111368(void)
{
gUnknown_203ADFA = 2;
sub_806E6FC();
@@ -1091,14 +1088,14 @@ void sub_8111438(void)
Free(r9);
}
-void sub_81115E8(void)
+static void sub_81115E8(void)
{
u16 r4 = sub_8111618();
u16 r1 = sub_811164C();
VarSet(VAR_0x4027, (r4 << 12) + r1);
}
-u16 sub_8111618(void)
+static u16 sub_8111618(void)
{
u16 count = 0;
u16 i;
@@ -1112,7 +1109,7 @@ u16 sub_8111618(void)
return count;
}
-u16 sub_811164C(void)
+static u16 sub_811164C(void)
{
u16 count = 0;
u16 i, j;
@@ -1129,7 +1126,7 @@ u16 sub_811164C(void)
return count;
}
-void sub_8111688(void)
+static void sub_8111688(void)
{
u16 i, j;
u16 sp0[4];
@@ -1161,7 +1158,7 @@ void sub_8111708(void)
}
}
-void sub_811175C(u8 a0, struct UnkStruct_203AE98 * a1)
+static void sub_811175C(u8 a0, struct UnkStruct_203AE98 * a1)
{
u16 i;
u16 *r4;
@@ -1208,13 +1205,13 @@ void sub_811175C(u8 a0, struct UnkStruct_203AE98 * a1)
}
}
-void sub_81118F4(s8 a0)
+static void sub_81118F4(s8 a0)
{
fade_screen(1, a0);
gUnknown_203AE8C = sub_8111914;
}
-void sub_8111914(void)
+static void sub_8111914(void)
{
if (!gPaletteFade.active)
{
@@ -1232,7 +1229,7 @@ void sub_8111914(void)
}
}
-void sub_8111984(void)
+static void sub_8111984(void)
{
sub_806E6FC();
Save_ResetSaveCounters();
@@ -1269,7 +1266,7 @@ bool8 sub_81119D4(void (*a0)(void))
return FALSE;
}
-void sub_8111A34(u8 taskId)
+static void sub_8111A34(u8 taskId)
{
void (*routine)(void);
s16 * data = gTasks[taskId].data;
@@ -1298,7 +1295,7 @@ void sub_8111A34(u8 taskId)
}
}
-void sub_8111AD8(void)
+static void sub_8111AD8(void)
{
if (gUnknown_203AE94.unk_0_0 == 1)
{
@@ -1327,7 +1324,7 @@ void sub_8111AD8(void)
}
}
-void sub_8111B80(void)
+static void sub_8111B80(void)
{
if (gUnknown_203AE94.unk_0_0 == 0)
{
@@ -1344,7 +1341,7 @@ void sub_8111B80(void)
sub_8112888(1);
}
-u8 sub_8111BD4(void)
+static u8 sub_8111BD4(void)
{
u16 i;
u16 count = 0;
@@ -1405,7 +1402,7 @@ void sub_8111CF0(void)
sub_8111070(sNumScenes);
}
-void sub_8111D10(void)
+static void sub_8111D10(void)
{
u16 i;
u8 count = 0;
@@ -1422,7 +1419,7 @@ void sub_8111D10(void)
ScheduleBgCopyTilemapToVram(0);
}
-void sub_8111D90(u8 a0)
+static void sub_8111D90(u8 a0)
{
const u16 * src = gUnknown_8456638;
u16 * buffer = Alloc(0x1680);
@@ -1459,7 +1456,7 @@ void sub_8111D90(u8 a0)
}
}
-void sub_8111E20(void)
+static void sub_8111E20(void)
{
ClearWindowTilemap(gUnknown_203ADFE[2]);
FillWindowPixelRect(gUnknown_203ADFE[2], 15, 0, 0, 0xf0, 0x30);
@@ -1468,13 +1465,13 @@ void sub_8111E20(void)
CopyWindowToVram(gUnknown_203ADFE[1], 1);
}
-void sub_8111E64(s8 a0)
+static void sub_8111E64(s8 a0)
{
fade_screen(1, a0);
gUnknown_203AE8C = sub_8111E84;
}
-void sub_8111E84(void)
+static void sub_8111E84(void)
{
if (!gPaletteFade.active)
{
@@ -1501,7 +1498,7 @@ void sub_8111F38(u16 a0, u16 a1)
CpuSet(gPlttBufferUnfaded + a0, gUnknown_203AE90 + a0, a1);
}
-bool8 sub_8111F60(void)
+static bool8 sub_8111F60(void)
{
LoadPalette(stdpal_get(4), 0xF0, 0x20);
sub_8111070(0);
@@ -1510,7 +1507,7 @@ bool8 sub_8111F60(void)
return TRUE;
}
-void sub_8111F8C(u8 taskId)
+static void sub_8111F8C(u8 taskId)
{
struct Task *task = &gTasks[taskId];
@@ -1524,7 +1521,7 @@ void sub_8111F8C(u8 taskId)
}
}
-void sub_8111FCC(u8 taskId)
+static void sub_8111FCC(u8 taskId)
{
struct Task *task = &gTasks[taskId];
@@ -1544,7 +1541,7 @@ void sub_8111FCC(u8 taskId)
}
}
-void sub_8112044(u8 taskId)
+static void sub_8112044(u8 taskId)
{
struct Task *task = &gTasks[taskId];
@@ -1559,7 +1556,7 @@ void sub_8112044(u8 taskId)
task->data[0]++;
}
-void sub_81120AC(u8 taskId)
+static void sub_81120AC(u8 taskId)
{
s16 * data = gTasks[taskId].data;
u8 i;
@@ -1609,7 +1606,7 @@ void sub_81120AC(u8 taskId)
}
}
-bool8 sub_81121D8(u8 taskId)
+static bool8 sub_81121D8(u8 taskId)
{
s16 * data = gTasks[taskId].data;
@@ -1626,7 +1623,7 @@ bool8 sub_81121D8(u8 taskId)
return FALSE;
}
-void sub_811229C(void)
+static void sub_811229C(void)
{
u16 * buffer = Alloc(0x400);
CpuCopy16(gUnknown_203AE90, buffer, 0x400);
@@ -1833,7 +1830,7 @@ void sub_81127F8(struct UnkStruct_3005E90 * a0)
}
}
-void sub_8112888(u8 a0)
+static void sub_8112888(u8 a0)
{
switch (a0)
{
@@ -1875,7 +1872,7 @@ void sub_81128BC(u8 a0)
}
}
-void sub_8112940(u8 a0, struct UnkStruct_203AE98 *a1, u16 a2)
+static void sub_8112940(u8 a0, struct UnkStruct_203AE98 *a1, u16 a2)
{
s32 i;
@@ -2218,21 +2215,21 @@ u8 sub_8112CAC(void)
}
}
-bool8 sub_8112CEC(void)
+static bool8 sub_8112CEC(void)
{
if (gUnknown_203AF98 >= gUnknown_3005E8C || ScriptContext2_IsEnabled() == TRUE)
return TRUE;
return FALSE;
}
-bool8 sub_8112D1C(void)
+static bool8 sub_8112D1C(void)
{
if (gUnknown_203AF98 >= gUnknown_3005E8C)
return TRUE;
return FALSE;
}
-const struct UnkStruct_300201C gUnknown_84566A4 = {
+static const struct UnkStruct_300201C gUnknown_84566A4 = {
0,
FALSE,
0x7FFF
@@ -2294,37 +2291,37 @@ void sub_8112E3C(u8 a0, struct UnkStruct_300201C * a1, u16 a2)
const u16 gUnknown_84566A8[] = INCBIN_U16("data/graphics/unknown_84566a8.bin");
-const struct WindowTemplate gUnknown_8456928 = {
+static const struct WindowTemplate sHelpMessageWindowTemplate = {
0x00, 0, 15, 30, 5, 15, 0x008F
};
void MapNamePopupWindowIdSetDummy(void)
{
- gUnknown_203B020 = 0xFF;
+ sHelpMessageWindowId = 0xFF;
}
-u8 sub_8112EB4(void)
+u8 CreateHelpMessageWindow(void)
{
- if (gUnknown_203B020 == 0xFF)
+ if (sHelpMessageWindowId == 0xFF)
{
- gUnknown_203B020 = AddWindow(&gUnknown_8456928);
- PutWindowTilemap(gUnknown_203B020);
+ sHelpMessageWindowId = AddWindow(&sHelpMessageWindowTemplate);
+ PutWindowTilemap(sHelpMessageWindowId);
}
- return gUnknown_203B020;
+ return sHelpMessageWindowId;
}
-void sub_8112EDC(u8 a0)
+void DestroyHelpMessageWindow(u8 a0)
{
- if (gUnknown_203B020 != 0xFF)
+ if (sHelpMessageWindowId != 0xFF)
{
- FillWindowPixelBuffer(gUnknown_203B020, 0x00);
- ClearWindowTilemap(gUnknown_203B020);
+ FillWindowPixelBuffer(sHelpMessageWindowId, PIXEL_FILL(0));
+ ClearWindowTilemap(sHelpMessageWindowId);
if (a0)
- CopyWindowToVram(gUnknown_203B020, a0);
+ CopyWindowToVram(sHelpMessageWindowId, a0);
- RemoveWindow(gUnknown_203B020);
- gUnknown_203B020 = 0xFF;
+ RemoveWindow(sHelpMessageWindowId);
+ sHelpMessageWindowId = 0xFF;
}
}
@@ -2460,24 +2457,24 @@ void sub_8112F18(u8 a0)
void sub_8112FD0(void)
{
- sub_8112F18(gUnknown_203B020);
+ sub_8112F18(sHelpMessageWindowId);
}
-const u8 gUnknown_8456930[3] = {
+static const u8 gUnknown_8456930[3] = {
0, 10, 2
};
void sub_8112FE4(const u8 * a0)
{
- AddTextPrinterParameterized4(gUnknown_203B020, 0x02, 2, 5, 1, 1, gUnknown_8456930, -1, a0);
+ AddTextPrinterParameterized4(sHelpMessageWindowId, 0x02, 2, 5, 1, 1, gUnknown_8456930, -1, a0);
}
-void sub_8113018(const u8 * text, u8 mode)
+void PrintTextOnHelpMessageWindow(const u8 * text, u8 mode)
{
sub_8112FD0();
sub_8112FE4(text);
if (mode)
- CopyWindowToVram(gUnknown_203B020, mode);
+ CopyWindowToVram(sHelpMessageWindowId, mode);
}
void sub_8113044(void)
@@ -2491,7 +2488,7 @@ void sub_8113064(void)
sub_8113078(VAR_0x4038_STRUCT);
}
-void sub_8113078(struct Var4038Struct * varPtr)
+static void sub_8113078(struct Var4038Struct * varPtr)
{
if (sub_8113508(varPtr))
{
@@ -2505,7 +2502,7 @@ void sub_81130A8(void)
sub_81130BC(VAR_0x4038_STRUCT);
}
-void sub_81130BC(struct Var4038Struct * varPtr)
+static void sub_81130BC(struct Var4038Struct * varPtr)
{
if (!varPtr->unk_0_7)
{
@@ -2543,11 +2540,11 @@ u8 sub_8113114(struct Var4038Struct * a0, u8 a1)
return a0->unk_0_0;
}
-const u8 gUnknown_8456938[] = {
+static const u8 gUnknown_8456938[] = {
1, 3, 5, 0, 7, 6, 4, 2
};
-u8 sub_8113194(struct Var4038Struct * a0)
+static u8 sub_8113194(struct Var4038Struct * a0)
{
u8 i;
u8 retval = 0;
@@ -2568,7 +2565,7 @@ u8 sub_8113194(struct Var4038Struct * a0)
return gUnknown_8456938[retval];
}
-const u8 gUnknown_8456940[] = {
+static const u8 gUnknown_8456940[] = {
5, 6, 3, 7, 4, 1, 0, 2
};
@@ -2602,7 +2599,7 @@ u16 sub_8113288(void)
return sub_81132A0(VAR_0x4038_STRUCT);
}
-u16 sub_81132A0(struct Var4038Struct * a0)
+static u16 sub_81132A0(struct Var4038Struct * a0)
{
u8 count = 0;
u8 i;
@@ -2621,7 +2618,7 @@ void sub_81132CC(void)
sub_81132E0(VAR_0x4038_STRUCT);
}
-void sub_81132E0(struct Var4038Struct * a0)
+static void sub_81132E0(struct Var4038Struct * a0)
{
u8 i = 0;
u16 var_4039;
@@ -2653,12 +2650,12 @@ bool16 sub_8113364(void)
return sub_811337C(VAR_0x4038_STRUCT);
}
-bool16 sub_811337C(struct Var4038Struct * a0)
+static bool16 sub_811337C(struct Var4038Struct * a0)
{
return (a0->unk_1 >> gSpecialVar_0x8004) & 1;
}
-void sub_8113390(struct Var4038Struct * a0)
+static void sub_8113390(struct Var4038Struct * a0)
{
a0->unk_1 |= 1;
a0->unk_1 |= 2;
@@ -2697,7 +2694,7 @@ void sub_81133A4(void)
sub_8113414(&gSaveBlock2Ptr->linkBattleRecords, r3, r2);
}
-void sub_8113414(struct LinkBattleRecords * a0, u8 a1, u8 a2)
+static void sub_8113414(struct LinkBattleRecords * a0, u8 a1, u8 a2)
{
u8 * str;
const u8 * src = a0->entries[a1].name;
@@ -2742,7 +2739,7 @@ void sub_81134B8(void)
sub_81134CC(VAR_0x4038_STRUCT);
}
-void sub_81134CC(struct Var4038Struct * a0)
+static void sub_81134CC(struct Var4038Struct * a0)
{
if (VarGet(VAR_MAP_SCENE_SAFFRON_CITY_POKEMON_TRAINER_FAN_CLUB) == 2)
{
@@ -2754,7 +2751,7 @@ void sub_81134CC(struct Var4038Struct * a0)
}
}
-bool8 sub_8113508(struct Var4038Struct * a0)
+static bool8 sub_8113508(struct Var4038Struct * a0)
{
return a0->unk_0_7;
}
@@ -2764,7 +2761,7 @@ void sub_8113510(void)
sub_8113524(VAR_0x4038_STRUCT);
}
-void sub_8113524(struct Var4038Struct * a0)
+static void sub_8113524(struct Var4038Struct * a0)
{
a0->unk_0_7 = TRUE;
}
@@ -3092,7 +3089,7 @@ void sub_8113550(u16 a0, const u16 * a1)
}
#endif // NONMATCHING
-bool8 sub_81136D4(void)
+static bool8 sub_81136D4(void)
{
if (gSaveBlock1Ptr->location.mapGroup == 2 && (gSaveBlock1Ptr->location.mapNum == 1 || gSaveBlock1Ptr->location.mapNum == 2 || gSaveBlock1Ptr->location.mapNum == 3 || gSaveBlock1Ptr->location.mapNum == 4 || gSaveBlock1Ptr->location.mapNum == 5 || gSaveBlock1Ptr->location.mapNum == 6 || gSaveBlock1Ptr->location.mapNum == 7 || gSaveBlock1Ptr->location.mapNum == 8 || gSaveBlock1Ptr->location.mapNum == 9 || gSaveBlock1Ptr->location.mapNum == 10 || gSaveBlock1Ptr->location.mapNum == 11))
return TRUE;
@@ -3123,7 +3120,7 @@ bool8 sub_8113748(void)
return FALSE;
}
-bool8 sub_8113778(u16 a0, u16 * a1)
+static bool8 sub_8113778(u16 a0, u16 * a1)
{
if (a0 == 36 || a0 == 11)
return TRUE;
@@ -3143,7 +3140,7 @@ bool8 sub_8113778(u16 a0, u16 * a1)
return FALSE;
}
-bool8 sub_81137E4(u16 a0, u16 * a1)
+static bool8 sub_81137E4(u16 a0, u16 * a1)
{
if (a0 == 34)
{
@@ -3158,12 +3155,12 @@ bool8 sub_81137E4(u16 a0, u16 * a1)
return FALSE;
}
-void sub_811381C(void)
+static void sub_811381C(void)
{
gUnknown_203B048 = 0;
}
-u16 * sub_8113828(u16 a0, u16 * a1)
+static u16 * sub_8113828(u16 a0, u16 * a1)
{
if (sub_8113778(a0, a1) == TRUE)
return NULL;
@@ -3182,7 +3179,7 @@ u16 * sub_8113828(u16 a0, u16 * a1)
return sQuestLogStorageCBs[a0](gUnknown_203AE08, a1);
}
-bool8 sub_81138A0(u16 a0, u16 * a1)
+static bool8 sub_81138A0(u16 a0, u16 * a1)
{
if (a0 < 12 || a0 > 19)
return FALSE;
@@ -3218,7 +3215,7 @@ void sub_811390C(void)
}
}
-bool8 sub_8113954(u16 a0, u16 * a1)
+static bool8 sub_8113954(u16 a0, u16 * a1)
{
if (a0 != 34 && a0 != 30 && a0 != 32 && a0 != 33)
return FALSE;
@@ -3250,13 +3247,13 @@ void sub_81139BC(void)
}
}
-void sub_8113A1C(u16 a0)
+static void sub_8113A1C(u16 a0)
{
gUnknown_203AE08 = sub_8113C5C(gUnknown_203AE08, a0);
gUnknown_203AF98++;
}
-bool8 sub_8113A44(u16 a0, u16 *a1)
+static bool8 sub_8113A44(u16 a0, u16 *a1)
{
if (a0 != 31)
return FALSE;
@@ -3316,7 +3313,7 @@ static const u16 * (*const sQuestLogScriptParsingCBs[])(const u16 *) = {
sub_8115800
};
-const u8 gUnknown_8456AA0[] = {
+static const u8 gUnknown_8456AA0[] = {
0x08,
0x08,
0x08,
@@ -3362,7 +3359,7 @@ const u8 gUnknown_8456AA0[] = {
0x06
};
-u16 * sub_8113A78(u16 * a0, u16 **a1)
+static u16 * sub_8113A78(u16 * a0, u16 **a1)
{
u16 r2 = a0[0] & 0xfff;
u16 r4 = a0[0] >> 12;
@@ -3374,7 +3371,7 @@ u16 * sub_8113A78(u16 * a0, u16 **a1)
return gUnknown_8456AA0[r2] + (gUnknown_8456AA0[r2] - 4) * r4 + (void *)a0;
}
-void sub_8113ABC(u16 * a0)
+static void sub_8113ABC(u16 * a0)
{
u8 * r2 = (u8 *)(a0 + 2);
if ((a0[0] & 0xFFF) != 35)
@@ -3384,7 +3381,7 @@ void sub_8113ABC(u16 * a0)
}
#ifdef NONMATCHING
-bool8 sub_8113AE8(u16 * a0)
+static bool8 sub_8113AE8(u16 * a0)
{
if (a0 == NULL || a0[1] > gUnknown_203AF98)
return FALSE;
@@ -3398,7 +3395,7 @@ bool8 sub_8113AE8(u16 * a0)
}
#else
NAKED
-bool8 sub_8113AE8(u16 * a0)
+static bool8 sub_8113AE8(u16 * a0)
{
asm_unified("\tpush {r4,lr}\n"
"\tadds r4, r0, 0\n"
@@ -3449,7 +3446,7 @@ bool8 sub_8113AE8(u16 * a0)
}
#endif
-bool8 sub_8113B44(u16 * a0)
+static bool8 sub_8113B44(u16 * a0)
{
if (gUnknown_203B044.unk_2 == 0)
return FALSE;
@@ -3461,12 +3458,12 @@ bool8 sub_8113B44(u16 * a0)
return TRUE;
}
-void sub_8113B88(void)
+static void sub_8113B88(void)
{
gUnknown_203B044 = (struct UnkStruct_203B044){};
}
-void sub_8113B94(u16 a0)
+static void sub_8113B94(u16 a0)
{
if (gUnknown_203B044.unk_0 != (u8)a0 || gUnknown_203B044.unk_2 != gUnknown_203AF98)
{
@@ -3478,14 +3475,14 @@ void sub_8113B94(u16 a0)
gUnknown_203B044.unk_1++;
}
-void sub_8113BD8(void)
+static void sub_8113BD8(void)
{
gUnknown_203B049 = 0;
gUnknown_203B04A = 0;
gUnknown_203B04B = 0;
}
-u16 * sub_8113BF4(u16 * a0)
+static u16 * sub_8113BF4(u16 * a0)
{
if (!sub_8110988(a0, gUnknown_8456AA0[39]))
return NULL;
@@ -3493,7 +3490,7 @@ u16 * sub_8113BF4(u16 * a0)
return a0 + 1;
}
-u16 * sub_8113C20(u16 * a0, struct UnkStruct_203AE98 * a1)
+static u16 * sub_8113C20(u16 * a0, struct UnkStruct_203AE98 * a1)
{
if (!sub_8110988(a0, gUnknown_8456AA0[39]))
return NULL;
@@ -3506,7 +3503,7 @@ u16 * sub_8113C20(u16 * a0, struct UnkStruct_203AE98 * a1)
return a0 + 1;
}
-u16 * sub_8113C5C(u16 * a0, u16 a1)
+static u16 * sub_8113C5C(u16 * a0, u16 a1)
{
if (!sub_8110988(a0, gUnknown_8456AA0[41]))
return NULL;
@@ -3515,7 +3512,7 @@ u16 * sub_8113C5C(u16 * a0, u16 a1)
return a0 + 2;
}
-u16 * sub_8113C8C(u16 * a0, struct UnkStruct_203AE98 * a1)
+static u16 * sub_8113C8C(u16 * a0, struct UnkStruct_203AE98 * a1)
{
if (!sub_8110988(a0, gUnknown_8456AA0[41]))
return NULL;
@@ -3528,7 +3525,7 @@ u16 * sub_8113C8C(u16 * a0, struct UnkStruct_203AE98 * a1)
return a0 + 2;
}
-u16 * sub_8113CC8(u16 * a0, struct UnkStruct_203AE98 * a1)
+static u16 * sub_8113CC8(u16 * a0, struct UnkStruct_203AE98 * a1)
{
u8 * r6 = (u8 *)a0 + 4;
@@ -3543,7 +3540,7 @@ u16 * sub_8113CC8(u16 * a0, struct UnkStruct_203AE98 * a1)
return (u16 *)(r6 + 4);
}
-u16 * sub_8113D08(u16 * a0, struct UnkStruct_203AE98 * a1)
+static u16 * sub_8113D08(u16 * a0, struct UnkStruct_203AE98 * a1)
{
u8 * r6 = (u8 *)a0 + 4;
@@ -3558,7 +3555,7 @@ u16 * sub_8113D08(u16 * a0, struct UnkStruct_203AE98 * a1)
return (u16 *)(r6 + 4);
}
-u16 * sub_8113D48(u16 * a0, struct UnkStruct_203AE98 * a1)
+static u16 * sub_8113D48(u16 * a0, struct UnkStruct_203AE98 * a1)
{
u16 * r4 = a0;
u8 * r6 = (u8 *)a0 + 4;
@@ -3577,7 +3574,7 @@ u16 * sub_8113D48(u16 * a0, struct UnkStruct_203AE98 * a1)
return (u16 *)(r6 + 4);
}
-u16 * sub_8113D94(u16 * a0, struct UnkStruct_203AE98 * a1)
+static u16 * sub_8113D94(u16 * a0, struct UnkStruct_203AE98 * a1)
{
u16 * r5 = a0;
u8 * r6 = (u8 *)a0 + 4;
@@ -3636,7 +3633,7 @@ u16 * sub_8113DE0(u16 a0, u16 * a1)
return r5;
}
-const u16 * sub_8113E88(u16 a0, const u16 * a1)
+static const u16 * sub_8113E88(u16 a0, const u16 * a1)
{
a1 = (const void *)a1 + (gUnknown_203B044.unk_2 * (gUnknown_8456AA0[a0] - 4) + 4);
return a1;
@@ -3663,7 +3660,7 @@ void QuestLog_AutoGetSpeciesName(u16 a0, u8 * a1, u8 a2)
}
}
-u16 * sub_8113F14(u16 * a0, const u16 * a1)
+static u16 * sub_8113F14(u16 * a0, const u16 * a1)
{
u16 * r2 = sub_8113DE0(3, a0);
if (r2 == NULL)
@@ -3674,7 +3671,7 @@ u16 * sub_8113F14(u16 * a0, const u16 * a1)
return r2 + 2;
}
-const u16 * sub_8113F3C(const u16 * a0)
+static const u16 * sub_8113F3C(const u16 * a0)
{
const u16 * r4 = sub_8113E88(3, a0);
QuestLog_AutoGetSpeciesName(r4[0], gStringVar1, 0);
@@ -3684,7 +3681,7 @@ const u16 * sub_8113F3C(const u16 * a0)
return r4;
}
-u16 * sub_8113F80(u16 * a0, const u16 * a1)
+static u16 * sub_8113F80(u16 * a0, const u16 * a1)
{
u16 * r2 = sub_8113DE0(4, a0);
if (r2 == NULL)
@@ -3700,7 +3697,7 @@ u16 * sub_8113F80(u16 * a0, const u16 * a1)
return r2 + 3;
}
-const u16 * sub_8113FBC(const u16 * a0)
+static const u16 * sub_8113FBC(const u16 * a0)
{
const u16 * r5 = sub_8113E88(4, a0);
@@ -3763,12 +3760,12 @@ u16 * sub_811414C(u16 a0, u16 * a1, const u16 * a2)
return r1 + 2;
}
-u16 * sub_8114174(u16 * a0, const u16 * a1)
+static u16 * sub_8114174(u16 * a0, const u16 * a1)
{
return sub_811414C(5, a0, a1);
}
-const u16 * sub_8114188(const u16 * a0)
+static const u16 * sub_8114188(const u16 * a0)
{
const u16 * r4 = sub_8113E88(5, a0);
QuestLog_AutoGetSpeciesName(r4[1], gStringVar1, 0);
@@ -3778,12 +3775,12 @@ const u16 * sub_8114188(const u16 * a0)
return r4;
}
-u16 * sub_81141D0(u16 * a0, const u16 * a1)
+static u16 * sub_81141D0(u16 * a0, const u16 * a1)
{
return sub_811414C(6, a0, a1);
}
-const u16 * sub_81141E4(const u16 * a0)
+static const u16 * sub_81141E4(const u16 * a0)
{
const u16 * r4 = sub_8113E88(6, a0);
@@ -3794,12 +3791,12 @@ const u16 * sub_81141E4(const u16 * a0)
return r4;
}
-u16 * sub_811422C(u16 * a0, const u16 * a1)
+static u16 * sub_811422C(u16 * a0, const u16 * a1)
{
return sub_811414C(7, a0, a1);
}
-const u16 * sub_8114240(const u16 * a0)
+static const u16 * sub_8114240(const u16 * a0)
{
const u16 * r4 = sub_8113E88(7, a0);
@@ -3810,12 +3807,12 @@ const u16 * sub_8114240(const u16 * a0)
return r4;
}
-u16 * sub_8114288(u16 * a0, const u16 * a1)
+static u16 * sub_8114288(u16 * a0, const u16 * a1)
{
return sub_811414C(8, a0, a1);
}
-const u16 * sub_811429C(const u16 * a0)
+static const u16 * sub_811429C(const u16 * a0)
{
const u16 * r4 = sub_8113E88(8, a0);
@@ -3838,12 +3835,12 @@ u16 * sub_81142E4(u16 a0, u16 * a1, const u16 * a2)
return r1 + 3;
}
-u16 * sub_8114310(u16 * a0, const u16 * a1)
+static u16 * sub_8114310(u16 * a0, const u16 * a1)
{
return sub_81142E4(9, a0, a1);
}
-const u16 * sub_8114324(const u16 * a0)
+static const u16 * sub_8114324(const u16 * a0)
{
const u16 * r4 = sub_8113E88(9, a0);
QuestLog_AutoGetSpeciesName(r4[2], gStringVar1, 0);
@@ -3854,12 +3851,12 @@ const u16 * sub_8114324(const u16 * a0)
return r4;
}
-u16 * sub_8114380(u16 * a0, const u16 * a1)
+static u16 * sub_8114380(u16 * a0, const u16 * a1)
{
return sub_81142E4(10, a0, a1);
}
-const u16 * sub_8114394(const u16 * a0)
+static const u16 * sub_8114394(const u16 * a0)
{
const u16 * r4 = sub_8113E88(10, a0);
QuestLog_AutoGetSpeciesName(r4[2], gStringVar2, 0);
@@ -3870,7 +3867,7 @@ const u16 * sub_8114394(const u16 * a0)
return r4;
}
-u16 * sub_81143F0(u16 * a0, const u16 * a1)
+static u16 * sub_81143F0(u16 * a0, const u16 * a1)
{
u16 * r4 = a0;
if (gUnknown_203B044.unk_0 == 11 && gUnknown_203B044.unk_1 != 0)
@@ -3884,14 +3881,14 @@ u16 * sub_81143F0(u16 * a0, const u16 * a1)
return r4 + 2;
}
-const u16 * sub_811443C(const u16 * a0)
+static const u16 * sub_811443C(const u16 * a0)
{
StringExpandPlaceholders(gStringVar4, gUnknown_841A2B0);
a0 += 2;
return a0;
}
-u16 * sub_811445C(u16 * a0, const u16 * a1)
+static u16 * sub_811445C(u16 * a0, const u16 * a1)
{
u16 * r4 = a0 + 4;
@@ -3905,7 +3902,7 @@ u16 * sub_811445C(u16 * a0, const u16 * a1)
return r4;
}
-const u16 * sub_811448C(const u16 * a0)
+static const u16 * sub_811448C(const u16 * a0)
{
const u16 * r6 = a0 + 4;
@@ -3920,25 +3917,25 @@ const u16 * sub_811448C(const u16 * a0)
return r6;
}
-const u8 *const gUnknown_8456ACC[] = {
+static const u8 *const gUnknown_8456ACC[] = {
gUnknown_841A74E,
gUnknown_841A756,
gUnknown_841A762
};
-const u8 *const gUnknown_8456AD8[] = {
+static const u8 *const gUnknown_8456AD8[] = {
gUnknown_841AF98,
gUnknown_841A762,
gUnknown_841AF9F
};
-const u8 *const gUnknown_8456AE4[] = {
+static const u8 *const gUnknown_8456AE4[] = {
gUnknown_841A502,
gUnknown_841A506,
gUnknown_841AFD1
};
-u16 * sub_81144EC(u16 * a0, const u16 * a1)
+static u16 * sub_81144EC(u16 * a0, const u16 * a1)
{
a0[0] = 13;
a0[1] = gUnknown_203AF98;
@@ -3948,7 +3945,7 @@ u16 * sub_81144EC(u16 * a0, const u16 * a1)
return a0;
}
-const u16 * sub_8114518(const u16 * a0)
+static const u16 * sub_8114518(const u16 * a0)
{
DynamicPlaceholderTextUtil_Reset();
@@ -3962,7 +3959,7 @@ const u16 * sub_8114518(const u16 * a0)
return a0;
}
-u16 * sub_8114578(u16 * a0, const u16 * a1)
+static u16 * sub_8114578(u16 * a0, const u16 * a1)
{
a0[0] = 14;
a0[1] = gUnknown_203AF98;
@@ -3972,7 +3969,7 @@ u16 * sub_8114578(u16 * a0, const u16 * a1)
return a0;
}
-const u16 * sub_81145A4(const u16 * a0)
+static const u16 * sub_81145A4(const u16 * a0)
{
DynamicPlaceholderTextUtil_Reset();
@@ -3986,7 +3983,7 @@ const u16 * sub_81145A4(const u16 * a0)
return a0;
}
-u16 * sub_8114604(u16 * a0, const u16 * a1)
+static u16 * sub_8114604(u16 * a0, const u16 * a1)
{
a0[0] = 15;
a0[1] = gUnknown_203AF98;
@@ -3998,7 +3995,7 @@ u16 * sub_8114604(u16 * a0, const u16 * a1)
return a0;
}
-const u16 * sub_811464C(const u16 * a0)
+static const u16 * sub_811464C(const u16 * a0)
{
DynamicPlaceholderTextUtil_Reset();
@@ -4021,35 +4018,35 @@ const u16 * sub_811464C(const u16 * a0)
return a0;
}
-u16 * sub_8114710(u16 * a0, const u16 * a1)
+static u16 * sub_8114710(u16 * a0, const u16 * a1)
{
a0[0] = 16;
a0[1] = gUnknown_203AF98;
return a0 + 2;
}
-const u16 * sub_8114724(const u16 * a0)
+static const u16 * sub_8114724(const u16 * a0)
{
StringExpandPlaceholders(gStringVar4, gUnknown_841A50B);
a0 += 2;
return a0;
}
-u16 * sub_8114744(u16 * a0, const u16 * a1)
+static u16 * sub_8114744(u16 * a0, const u16 * a1)
{
a0[0] = 17;
a0[1] = gUnknown_203AF98;
return a0 + 2;
}
-const u16 * sub_8114758(const u16 * a0)
+static const u16 * sub_8114758(const u16 * a0)
{
StringExpandPlaceholders(gStringVar4, gUnknown_841A732);
a0 += 2;
return a0;
}
-u16 * sub_8114778(u16 * a0, const u16 * a1)
+static u16 * sub_8114778(u16 * a0, const u16 * a1)
{
u8 * r4 = (u8 *)(a0 + 4);
a0[0] = 18;
@@ -4061,7 +4058,7 @@ u16 * sub_8114778(u16 * a0, const u16 * a1)
return (u16 *)r4;
}
-const u16 * sub_81147A8(const u16 * a0)
+static const u16 * sub_81147A8(const u16 * a0)
{
const u8 * r6 = (const u8 *)(a0 + 4);
memset(gStringVar1, EOS, 8);
@@ -4074,7 +4071,7 @@ const u16 * sub_81147A8(const u16 * a0)
return (const u16 *)r6;
}
-u16 * sub_8114808(u16 * a0, const u16 * a1)
+static u16 * sub_8114808(u16 * a0, const u16 * a1)
{
a0[0] = 19;
a0[1] = gUnknown_203AF98;
@@ -4084,7 +4081,7 @@ u16 * sub_8114808(u16 * a0, const u16 * a1)
return a0;
}
-const u16 * sub_8114834(const u16 * a0)
+static const u16 * sub_8114834(const u16 * a0)
{
memset(gStringVar1, EOS, 8);
memcpy(gStringVar1, (const u8 *)a0 + 5, 7);
@@ -4095,7 +4092,7 @@ const u16 * sub_8114834(const u16 * a0)
return a0;
}
-u16 * sub_811488C(u16 * a0, const u16 * a1)
+static u16 * sub_811488C(u16 * a0, const u16 * a1)
{
a0 = sub_8113DE0(20, a0);
if (a0 == NULL)
@@ -4107,7 +4104,7 @@ u16 * sub_811488C(u16 * a0, const u16 * a1)
return a0 + 3;
}
-const u16 * sub_81148BC(const u16 * a0)
+static const u16 * sub_81148BC(const u16 * a0)
{
const u8 * boxIdxs;
a0 = sub_8113E88(20, a0);
@@ -4121,7 +4118,7 @@ const u16 * sub_81148BC(const u16 * a0)
return a0 + 3;
}
-u16 * sub_8114918(u16 * a0, const u16 * a1)
+static u16 * sub_8114918(u16 * a0, const u16 * a1)
{
a0 = sub_8113DE0(21, a0);
if (a0 == NULL)
@@ -4132,7 +4129,7 @@ u16 * sub_8114918(u16 * a0, const u16 * a1)
return a0 + 3;
}
-const u16 * sub_8114944(const u16 * a0)
+static const u16 * sub_8114944(const u16 * a0)
{
const u8 * boxIdxs;
a0 = sub_8113E88(21, a0);
@@ -4145,7 +4142,7 @@ const u16 * sub_8114944(const u16 * a0)
return a0 + 3;
}
-u16 * sub_8114990(u16 * a0, const u16 * a1)
+static u16 * sub_8114990(u16 * a0, const u16 * a1)
{
u16 * r2;
u16 * ret;
@@ -4168,7 +4165,7 @@ u16 * sub_8114990(u16 * a0, const u16 * a1)
return ret + 1;
}
-const u16 * sub_81149D0(const u16 * a0)
+static const u16 * sub_81149D0(const u16 * a0)
{
const u8 * boxIdxs;
a0 = sub_8113E88(22, a0);
@@ -4181,7 +4178,7 @@ const u16 * sub_81149D0(const u16 * a0)
return a0 + 3;
}
-u16 * sub_8114A1C(u16 * a0, const u16 * a1)
+static u16 * sub_8114A1C(u16 * a0, const u16 * a1)
{
u16 * r2;
u16 * ret;
@@ -4195,7 +4192,7 @@ u16 * sub_8114A1C(u16 * a0, const u16 * a1)
return ret + 1;
}
-const u16 * sub_8114A4C(const u16 * a0)
+static const u16 * sub_8114A4C(const u16 * a0)
{
const u8 * boxIdxs;
a0 = sub_8113E88(23, a0);
@@ -4208,7 +4205,7 @@ const u16 * sub_8114A4C(const u16 * a0)
return (const u16 *)boxIdxs + 1;
}
-u16 * sub_8114AA0(u16 * a0, const u16 * a1)
+static u16 * sub_8114AA0(u16 * a0, const u16 * a1)
{
u16 * r2;
r2 = sub_8113DE0(24, a0);
@@ -4219,7 +4216,7 @@ u16 * sub_8114AA0(u16 * a0, const u16 * a1)
return r2 + 2;
}
-const u16 * sub_8114AC8(const u16 * a0)
+static const u16 * sub_8114AC8(const u16 * a0)
{
const u8 * boxIdxs;
a0 = sub_8113E88(24, a0);
@@ -4231,7 +4228,7 @@ const u16 * sub_8114AC8(const u16 * a0)
return (const u16 *)boxIdxs + 1;
}
-u16 * sub_8114B0C(u16 * a0, const u16 * a1)
+static u16 * sub_8114B0C(u16 * a0, const u16 * a1)
{
u16 * r2;
r2 = sub_8113DE0(25, a0);
@@ -4242,7 +4239,7 @@ u16 * sub_8114B0C(u16 * a0, const u16 * a1)
return r2 + 2;
}
-const u16 * sub_8114B34(const u16 * a0)
+static const u16 * sub_8114B34(const u16 * a0)
{
const u8 * boxIdxs;
a0 = sub_8113E88(25, a0);
@@ -4254,7 +4251,7 @@ const u16 * sub_8114B34(const u16 * a0)
return (const u16 *)boxIdxs + 1;
}
-u16 * sub_8114B78(u16 * a0, const u16 * a1)
+static u16 * sub_8114B78(u16 * a0, const u16 * a1)
{
u16 * r2;
r2 = sub_8113DE0(26, a0);
@@ -4265,7 +4262,7 @@ u16 * sub_8114B78(u16 * a0, const u16 * a1)
return r2 + 2;
}
-const u16 * sub_8114BA0(const u16 * a0)
+static const u16 * sub_8114BA0(const u16 * a0)
{
const u8 * boxIdxs;
a0 = sub_8113E88(26, a0);
@@ -4277,7 +4274,7 @@ const u16 * sub_8114BA0(const u16 * a0)
return (const u16 *)boxIdxs + 1;
}
-u16 * sub_8114BE4(u16 * a0, const u16 * a1)
+static u16 * sub_8114BE4(u16 * a0, const u16 * a1)
{
u16 * r2;
r2 = sub_8113DE0(27, a0);
@@ -4288,7 +4285,7 @@ u16 * sub_8114BE4(u16 * a0, const u16 * a1)
return r2 + 1;
}
-const u16 * sub_8114C0C(const u16 * a0)
+static const u16 * sub_8114C0C(const u16 * a0)
{
const u16 *r4 = sub_8113E88(27, a0);
DynamicPlaceholderTextUtil_Reset();
@@ -4301,7 +4298,7 @@ const u16 * sub_8114C0C(const u16 * a0)
return r4 + 1;
}
-u16 * sub_8114C68(u16 * a0, const u16 * a1)
+static u16 * sub_8114C68(u16 * a0, const u16 * a1)
{
a0 = sub_8113DE0(28, a0);
if (a0 == NULL)
@@ -4310,7 +4307,7 @@ u16 * sub_8114C68(u16 * a0, const u16 * a1)
return a0 + 1;
}
-const u16 * sub_8114C8C(const u16 * a0)
+static const u16 * sub_8114C8C(const u16 * a0)
{
const u16 *r4 = sub_8113E88(28, a0);
CopyItemName(r4[0], gStringVar1);
@@ -4318,7 +4315,7 @@ const u16 * sub_8114C8C(const u16 * a0)
return r4 + 1;
}
-u16 * sub_8114CC0(u16 * a0, const u16 * a1)
+static u16 * sub_8114CC0(u16 * a0, const u16 * a1)
{
a0 = sub_8113DE0(29, a0);
if (a0 == NULL)
@@ -4327,7 +4324,7 @@ u16 * sub_8114CC0(u16 * a0, const u16 * a1)
return a0 + 1;
}
-const u16 * sub_8114CE4(const u16 * a0)
+static const u16 * sub_8114CE4(const u16 * a0)
{
const u16 *r4 = sub_8113E88(29, a0);
CopyItemName(r4[0], gStringVar1);
@@ -4348,13 +4345,13 @@ u16 * sub_8114D18(u16 a0, u16 * a1, const u16 * a2)
return a1 + 4;
}
-u16 * sub_8114D4C(u16 * a0, const u16 * a1)
+static u16 * sub_8114D4C(u16 * a0, const u16 * a1)
{
gUnknown_203B048 = TRUE;
return sub_8114D18(30, a0, a1);
}
-const u16 * sub_8114D68(const u16 * a0)
+static const u16 * sub_8114D68(const u16 * a0)
{
const u8 * r6;
a0 = sub_8113E88(30, a0);
@@ -4370,7 +4367,7 @@ const u16 * sub_8114D68(const u16 * a0)
return a0 + 4;
}
-u16 * sub_8114DE8(u16 * a0, const u16 * a1)
+static u16 * sub_8114DE8(u16 * a0, const u16 * a1)
{
u16 * r4 = a0;
u8 * r5 = (u8 *)a0 + 8;
@@ -4393,7 +4390,7 @@ u16 * sub_8114DE8(u16 * a0, const u16 * a1)
return (u16 *)(r5 + 4);
}
-const u16 * sub_8114E68(const u16 * a0)
+static const u16 * sub_8114E68(const u16 * a0)
{
const u8 * r6;
if (!sub_8110944(a0, gUnknown_8456AA0[31]))
@@ -4441,7 +4438,7 @@ const u16 * sub_8114E68(const u16 * a0)
return (const u16 *)(r6 + 4);
}
-bool8 sub_8114FBC(u16 a0)
+static bool8 sub_8114FBC(u16 a0)
{
switch (a0)
{
@@ -4454,13 +4451,13 @@ bool8 sub_8114FBC(u16 a0)
return FALSE;
}
-u16 * sub_8114FF0(u16 * a0, const u16 * a1)
+static u16 * sub_8114FF0(u16 * a0, const u16 * a1)
{
gUnknown_203B048 = TRUE;
return sub_8114D18(32, a0, a1);
}
-const u16 * sub_811500C(const u16 * a0)
+static const u16 * sub_811500C(const u16 * a0)
{
const u8 * r5;
a0 = sub_8113E88(32, a0);
@@ -4474,7 +4471,7 @@ const u16 * sub_811500C(const u16 * a0)
return a0 + 4;
}
-u16 * sub_8115078(u16 * a0, const u16 * a1)
+static u16 * sub_8115078(u16 * a0, const u16 * a1)
{
if (!sub_8110944(a0, gUnknown_8456AA0[33]))
return NULL;
@@ -4487,7 +4484,7 @@ u16 * sub_8115078(u16 * a0, const u16 * a1)
return a0 + 5;
}
-const u16 * sub_81150CC(const u16 * a0)
+static const u16 * sub_81150CC(const u16 * a0)
{
const u8 * r5;
if (!sub_8110944(a0, gUnknown_8456AA0[33]))
@@ -4518,13 +4515,13 @@ const u16 * sub_81150CC(const u16 * a0)
return (const u16 *)(r5 + 2);
}
-u16 * sub_81151C0(u16 * a0, const u16 * a1)
+static u16 * sub_81151C0(u16 * a0, const u16 * a1)
{
gUnknown_203B048 = TRUE;
return sub_8114D18(34, a0, a1);
}
-const u16 * sub_81151DC(const u16 * a0)
+static const u16 * sub_81151DC(const u16 * a0)
{
const u16 * r5 = sub_8113E88(34, a0);
const u8 * r6 = (const u8 *)r5 + 6;
@@ -4546,7 +4543,7 @@ const u16 * sub_81151DC(const u16 * a0)
return (const u16 *)(r6 + 2);
}
-const u8 *const gUnknown_8456AF0[] = {
+static const u8 *const gUnknown_8456AF0[] = {
gUnknown_841B09F,
gUnknown_841B0A4,
gUnknown_841B0B5,
@@ -4600,7 +4597,7 @@ const u8 *const gUnknown_8456AF0[] = {
gUnknown_841B277
};
-const u8 *const gUnknown_8456BBC[] = {
+static const u8 *const gUnknown_8456BBC[] = {
gUnknown_841A53A,
gUnknown_841AD9E,
gUnknown_841ADC8,
@@ -4613,7 +4610,7 @@ const u8 *const gUnknown_8456BBC[] = {
gUnknown_841B005
};
-const u8 gUnknown_8456BE4[] = {
+static const u8 gUnknown_8456BE4[] = {
0x03,
0x04,
0x05,
@@ -4667,7 +4664,7 @@ const u8 gUnknown_8456BE4[] = {
0x07
};
-const u8 gUnknown_8456C17[] = {
+static const u8 gUnknown_8456C17[] = {
0x5a,
0x5b,
0x5d,
@@ -4678,7 +4675,7 @@ const u8 gUnknown_8456C17[] = {
0x59
};
-const u8 *const gUnknown_8456C20[] = {
+static const u8 *const gUnknown_8456C20[] = {
gUnknown_841AC51,
gUnknown_841ABAB,
gUnknown_841ABCD,
@@ -4693,7 +4690,7 @@ const u8 *const gUnknown_8456C20[] = {
gUnknown_841AD3C
};
-u16 * sub_8115280(u16 * a0, const u16 * a1)
+static u16 * sub_8115280(u16 * a0, const u16 * a1)
{
u16 * r2 = sub_8113DE0(35, a0);
if (r2 == NULL)
@@ -4704,7 +4701,7 @@ u16 * sub_8115280(u16 * a0, const u16 * a1)
return r2 + 1;
}
-const u16 * sub_81152BC(const u16 * a0)
+static const u16 * sub_81152BC(const u16 * a0)
{
u8 r4, r6;
const u16 * r5 = sub_8113E88(35, a0);
@@ -4738,7 +4735,7 @@ void sub_811539C(void)
gUnknown_203B04B = TRUE;
}
-bool8 sub_81153A8(u16 a0, u16 * a1)
+static bool8 sub_81153A8(u16 a0, u16 * a1)
{
if (a0 != 35)
{
@@ -4751,7 +4748,7 @@ bool8 sub_81153A8(u16 a0, u16 * a1)
return TRUE;
}
-bool8 sub_81153E4(u16 a0, u16 * a1)
+static bool8 sub_81153E4(u16 a0, u16 * a1)
{
if (a0 != 35)
return TRUE;
@@ -4761,7 +4758,7 @@ bool8 sub_81153E4(u16 a0, u16 * a1)
return TRUE;
}
-u16 * sub_8115410(u16 * a0, const u16 * a1)
+static u16 * sub_8115410(u16 * a0, const u16 * a1)
{
u8 * r3;
a0 = sub_8113DE0(36, a0);
@@ -4778,7 +4775,7 @@ u16 * sub_8115410(u16 * a0, const u16 * a1)
return (u16 *)(r3 + 2);
}
-const u16 * sub_8115460(const u16 * a0)
+static const u16 * sub_8115460(const u16 * a0)
{
const u16 * r4 = sub_8113E88(36, a0);
const u8 * r5 = (const u8 *)r4 + 2;
@@ -4796,7 +4793,7 @@ const u16 * sub_8115460(const u16 * a0)
return (const u16 *)(r5 + 2);
}
-u16 * sub_81154DC(u16 * a0, const u16 * a1)
+static u16 * sub_81154DC(u16 * a0, const u16 * a1)
{
a0 = sub_8113DE0(37, a0);
if (a0 == NULL)
@@ -4810,7 +4807,7 @@ u16 * sub_81154DC(u16 * a0, const u16 * a1)
return a0 + 5;
}
-const u16 * sub_8115518(const u16 * a0)
+static const u16 * sub_8115518(const u16 * a0)
{
const u16 * r4 = sub_8113E88(37, a0);
const u8 * r7 = (const u8 *)r4 + 8;
@@ -4830,7 +4827,7 @@ const u16 * sub_8115518(const u16 * a0)
return (const u16 *)(r7 + 2);
}
-u16 * sub_81155A4(u16 * a0, const u16 * a1)
+static u16 * sub_81155A4(u16 * a0, const u16 * a1)
{
a0 = sub_8113DE0(38, a0);
if (a0 == NULL)
@@ -4844,7 +4841,7 @@ u16 * sub_81155A4(u16 * a0, const u16 * a1)
return a0 + 5;
}
-const u16 * sub_81155E0(const u16 * a0) {
+static const u16 * sub_81155E0(const u16 * a0) {
const u16 *r5 = sub_8113E88(38, a0);
const u8 *r7 = (const u8 *) r5 + 8;
u32 r6 = (r5[2] << 16) + r5[3];
@@ -4876,7 +4873,7 @@ const u16 * sub_81155E0(const u16 * a0) {
return (const u16 *)(r7 + 2);
}
-u16 * sub_81156D8(u16 * a0, const u16 * a1)
+static u16 * sub_81156D8(u16 * a0, const u16 * a1)
{
a0 = sub_8113DE0(40, a0);
if (a0 == NULL)
@@ -4886,7 +4883,7 @@ u16 * sub_81156D8(u16 * a0, const u16 * a1)
return a0 + 2;
}
-const u16 * sub_8115700(const u16 * a0)
+static const u16 * sub_8115700(const u16 * a0)
{
const u16 * r4 = sub_8113E88(40, a0);
const u8 * r5 = (const u8 *)r4 + 2;
@@ -4896,7 +4893,7 @@ const u16 * sub_8115700(const u16 * a0)
return (const u16 *)(r5 + 2);
}
-const u16 gUnknown_8456C50[] = {
+static const u16 gUnknown_8456C50[] = {
0x0891,
0x0892,
0x0893,
@@ -4993,7 +4990,7 @@ void sub_8115798(void)
}
}
-u16 * sub_81157DC(u16 * a0, const u16 * a1)
+static u16 * sub_81157DC(u16 * a0, const u16 * a1)
{
a0 = sub_8113DE0(42, a0);
if (a0 == NULL)
@@ -5002,7 +4999,7 @@ u16 * sub_81157DC(u16 * a0, const u16 * a1)
return a0 + 1;
}
-const u16 * sub_8115800(const u16 * a0)
+static const u16 * sub_8115800(const u16 * a0)
{
const u16 * r4 = sub_8113E88(42, a0);
sub_80C4DF8(gStringVar1, r4[0]);
diff --git a/src/rock.c b/src/rock.c
new file mode 100644
index 000000000..4db903344
--- /dev/null
+++ b/src/rock.c
@@ -0,0 +1,830 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "gpu_regs.h"
+#include "graphics.h"
+#include "palette.h"
+#include "sound.h"
+#include "task.h"
+#include "trig.h"
+#include "constants/songs.h"
+
+static void sub_80B4634(struct Sprite *sprite);
+static void sub_80B46F8(struct Sprite *sprite);
+static void AnimDirtParticleAcrossScreen(struct Sprite *sprite);
+static void AnimRaiseSprite(struct Sprite *sprite);
+static void sub_80B4D00(u8 taskId);
+static void sub_80B4F78(struct Sprite *sprite);
+static void sub_80B4FE4(struct Sprite *sprite);
+static void sub_80B5074(struct Sprite *sprite);
+static void sub_80B50A0(struct Sprite *sprite);
+static void sub_80B477C(struct Sprite *sprite);
+static void sub_80B46B4(struct Sprite *sprite);
+static void sub_80B47C4(struct Sprite *sprite);
+static void sub_80B490C(u8 taskId);
+static void sub_80B4E70(struct Task *task);
+static u8 sub_80B4FB8(void);
+static void sub_80B5024(struct Sprite *sprite);
+static void sub_80B50F8(struct Sprite *sprite);
+
+static const union AnimCmd gUnknown_83E7390[] =
+{
+ ANIMCMD_FRAME(32, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E7398[] =
+{
+ ANIMCMD_FRAME(48, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E73A0[] =
+{
+ ANIMCMD_FRAME(64, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E73A8[] =
+{
+ gUnknown_83E7390,
+ gUnknown_83E7398,
+ gUnknown_83E73A0,
+};
+
+const struct SpriteTemplate gUnknown_83E73B4 =
+{
+ .tileTag = ANIM_TAG_ROCKS,
+ .paletteTag = ANIM_TAG_ROCKS,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E73A8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B4634,
+};
+
+const struct SpriteTemplate gUnknown_83E73CC =
+{
+ .tileTag = ANIM_TAG_ROCKS,
+ .paletteTag = ANIM_TAG_ROCKS,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E73A8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B46F8,
+};
+
+const struct SpriteTemplate gUnknown_83E73E4 =
+{
+ .tileTag = ANIM_TAG_MUD_SAND,
+ .paletteTag = ANIM_TAG_MUD_SAND,
+ .oam = &gOamData_83AC9C8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B477C,
+};
+
+static const union AffineAnimCmd gUnknown_83E73FC[] =
+{
+ AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0),
+ AFFINEANIMCMD_FRAME(0x2, 0xFFFD, 0, 5),
+ AFFINEANIMCMD_FRAME(0xFFFE, 0x3, 0, 5),
+ AFFINEANIMCMD_JUMP(1),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E741C[] =
+{
+ gUnknown_83E73FC,
+};
+
+const struct SpriteTemplate gUnknown_83E7420 =
+{
+ .tileTag = ANIM_TAG_WATER_ORB,
+ .paletteTag = ANIM_TAG_WATER_ORB,
+ .oam = &gOamData_83ACB50,
+ .anims = gUnknown_83E5958,
+ .images = NULL,
+ .affineAnims = gUnknown_83E741C,
+ .callback = sub_80B477C,
+};
+
+const struct SpriteTemplate gUnknown_83E7438 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5D48,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B477C,
+};
+
+const struct SpriteTemplate gUnknown_83E7450 =
+{
+ .tileTag = ANIM_TAG_FLYING_DIRT,
+ .paletteTag = ANIM_TAG_FLYING_DIRT,
+ .oam = &gOamData_83AC9F8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimDirtParticleAcrossScreen,
+};
+
+static const struct Subsprite gUnknown_83E7468[] =
+{
+ {
+ .x = -16,
+ .y = 0,
+ .shape = ST_OAM_H_RECTANGLE,
+ .size = 2,
+ .tileOffset = 0,
+ .priority = 1,
+ },
+ {
+ .x = 16,
+ .y = 0,
+ .shape = ST_OAM_H_RECTANGLE,
+ .size = 2,
+ .tileOffset = 8,
+ .priority = 1,
+ },
+};
+
+static const struct SubspriteTable gUnknown_83E7470[] =
+{
+ { ARRAY_COUNT(gUnknown_83E7468), gUnknown_83E7468 },
+};
+
+static const union AnimCmd gUnknown_83E7478[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E7480[] =
+{
+ ANIMCMD_FRAME(16, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E7488[] =
+{
+ ANIMCMD_FRAME(32, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E7490[] =
+{
+ ANIMCMD_FRAME(48, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E7498[] =
+{
+ ANIMCMD_FRAME(64, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E74A0[] =
+{
+ ANIMCMD_FRAME(80, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E74A8[] =
+{
+ gUnknown_83E7478,
+ gUnknown_83E7480,
+};
+
+static const union AnimCmd *const gUnknown_83E74B0[] =
+{
+ gUnknown_83E7488,
+ gUnknown_83E7490,
+};
+
+static const union AnimCmd *const gUnknown_83E74B8[] =
+{
+ gUnknown_83E7498,
+ gUnknown_83E74A0,
+};
+
+const struct SpriteTemplate gUnknown_83E74C0 =
+{
+ .tileTag = ANIM_TAG_ROCKS,
+ .paletteTag = ANIM_TAG_ROCKS,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E74A8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimRaiseSprite,
+};
+
+const struct SpriteTemplate gUnknown_83E74D8 =
+{
+ .tileTag = ANIM_TAG_MUD_SAND,
+ .paletteTag = ANIM_TAG_MUD_SAND,
+ .oam = &gOamData_83AC9C8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B4F78,
+};
+
+const struct SpriteTemplate gUnknown_83E74F0 =
+{
+ .tileTag = ANIM_TAG_ROCKS,
+ .paletteTag = ANIM_TAG_ROCKS,
+ .oam = &gOamData_83AC9D8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B4F78,
+};
+
+const struct SpriteTemplate gUnknown_83E7508 =
+{
+ .tileTag = ANIM_TAG_ROCKS,
+ .paletteTag = ANIM_TAG_ROCKS,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E74A8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B4FE4,
+};
+
+static const union AffineAnimCmd gUnknown_83E7520[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -5, 5),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd gUnknown_83E7530[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 5, 5),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E7540[] =
+{
+ gUnknown_83E7520,
+ gUnknown_83E7530,
+};
+
+const struct SpriteTemplate gUnknown_83E7548 =
+{
+ .tileTag = ANIM_TAG_ROCKS,
+ .paletteTag = ANIM_TAG_ROCKS,
+ .oam = &gOamData_83ACA38,
+ .anims = gUnknown_83E74A8,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7540,
+ .callback = sub_80B5074,
+};
+
+const struct SpriteTemplate gUnknown_83E7560 =
+{
+ .tileTag = ANIM_TAG_ROCKS,
+ .paletteTag = ANIM_TAG_ROCKS,
+ .oam = &gOamData_83ACA38,
+ .anims = gUnknown_83E74A8,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7540,
+ .callback = sub_80B50A0,
+};
+
+const struct SpriteTemplate gUnknown_83E7578 =
+{
+ .tileTag = ANIM_TAG_ROCKS,
+ .paletteTag = ANIM_TAG_ROCKS,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E74B8,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7540,
+ .callback = AnimMoveTwisterParticle,
+};
+
+const struct SpriteTemplate gUnknown_83E7590 =
+{
+ .tileTag = ANIM_TAG_ROCKS,
+ .paletteTag = ANIM_TAG_ROCKS,
+ .oam = &gOamData_83ACA38,
+ .anims = gUnknown_83E74B0,
+ .images = NULL,
+ .affineAnims = gUnknown_83E7540,
+ .callback = sub_8077350,
+};
+
+static void sub_80B4634(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[3] != 0)
+ SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y);
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += 14;
+ StartSpriteAnim(sprite, gBattleAnimArgs[1]);
+ AnimateSprite(sprite);
+ sprite->data[0] = 0;
+ sprite->data[1] = 0;
+ sprite->data[2] = 4;
+ sprite->data[3] = 16;
+ sprite->data[4] = -70;
+ sprite->data[5] = gBattleAnimArgs[2];
+ StoreSpriteCallbackInData6(sprite, sub_80B46B4);
+ sprite->callback = TranslateSpriteInEllipseOverDuration;
+ sprite->callback(sprite);
+}
+
+static void sub_80B46B4(struct Sprite *sprite)
+{
+ sprite->pos1.x += sprite->data[5];
+ sprite->data[0] = 192;
+ sprite->data[1] = sprite->data[5];
+ sprite->data[2] = 4;
+ sprite->data[3] = 32;
+ sprite->data[4] = -24;
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = TranslateSpriteInEllipseOverDuration;
+ sprite->callback(sprite);
+}
+
+static void sub_80B46F8(struct Sprite *sprite)
+{
+ StartSpriteAnim(sprite, gBattleAnimArgs[5]);
+ AnimateSprite(sprite);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2];
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[3];
+ InitSpriteDataForLinearTranslation(sprite);
+ sprite->data[3] = 0;
+ sprite->data[4] = 0;
+ sprite->callback = TranslateSpriteLinearFixedPoint;
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+}
+
+static void sub_80B477C(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[6] == 0)
+ InitSpritePosToAnimAttacker(sprite, 0);
+ else
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->data[1] = gBattleAnimArgs[2];
+ sprite->data[2] = gBattleAnimArgs[4];
+ sprite->data[3] = gBattleAnimArgs[5];
+ sprite->callback = sub_80B47C4;
+}
+
+static void sub_80B47C4(struct Sprite *sprite)
+{
+ sprite->data[4] += sprite->data[1];
+ sprite->pos2.y = -(sprite->data[4] >> 8);
+ sprite->pos2.x = Sin(sprite->data[5], sprite->data[3]);
+ sprite->data[5] = (sprite->data[5] + sprite->data[2]) & 0xFF;
+ if (--sprite->data[0] == -1)
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+void AnimTask_LoadSandstormBackground(u8 taskId)
+{
+ s32 var0;
+ struct BattleAnimBgData animBg;
+
+ var0 = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
+ SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
+ sub_80752A0(&animBg);
+ AnimLoadCompressedBgTilemap(animBg.bgId, gFile_graphics_battle_anims_backgrounds_sandstorm_brew_tilemap);
+ AnimLoadCompressedBgGfx(animBg.bgId, gFile_graphics_battle_anims_backgrounds_sandstorm_brew_sheet, animBg.tilesOffset);
+ LoadCompressedPalette(gBattleAnimSpritePal_FlyingDirt, animBg.paletteId * 16, 32);
+ if (IsContest())
+ sub_80730C0(animBg.paletteId, animBg.bgTilemap, 0, 0);
+ if (gBattleAnimArgs[0] && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ var0 = 1;
+ gTasks[taskId].data[0] = var0;
+ gTasks[taskId].func = sub_80B490C;
+}
+
+static void sub_80B490C(u8 taskId)
+{
+ struct BattleAnimBgData animBg;
+
+ if (gTasks[taskId].data[0] == 0)
+ gBattle_BG1_X += -6;
+ else
+ gBattle_BG1_X += 6;
+ gBattle_BG1_Y += -1;
+ switch (gTasks[taskId].data[12])
+ {
+ case 0:
+ if (++gTasks[taskId].data[10] == 4)
+ {
+ gTasks[taskId].data[10] = 0;
+ ++gTasks[taskId].data[11];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
+ if (gTasks[taskId].data[11] == 7)
+ {
+ ++gTasks[taskId].data[12];
+ gTasks[taskId].data[11] = 0;
+ }
+ }
+ break;
+ case 1:
+ if (++gTasks[taskId].data[11] == 101)
+ {
+ gTasks[taskId].data[11] = 7;
+ ++gTasks[taskId].data[12];
+ }
+ break;
+ case 2:
+ if (++gTasks[taskId].data[10] == 4)
+ {
+ gTasks[taskId].data[10] = 0;
+ --gTasks[taskId].data[11];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
+ if (gTasks[taskId].data[11] == 0)
+ {
+ ++gTasks[taskId].data[12];
+ gTasks[taskId].data[11] = 0;
+ }
+ }
+ break;
+ case 3:
+ sub_80752A0(&animBg);
+ sub_8075358(animBg.bgId);
+ ++gTasks[taskId].data[12];
+ break;
+ case 4:
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+// Animates the sprites that fly diagonally across the screen
+// in Sandstorm and Heat Wave.
+// arg 0: initial y pixel offset
+// arg 1: projectile speed
+// arg 2: y pixel drop
+// arg 3: ??? unknown (possibly a color bit)
+static void AnimDirtParticleAcrossScreen(struct Sprite *sprite)
+{
+ if (sprite->data[0] == 0)
+ {
+ if (gBattleAnimArgs[3] != 0 && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->pos1.x = 304;
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ sprite->data[5] = 1;
+ sprite->oam.matrixNum = ST_OAM_HFLIP;
+ }
+ else
+ {
+ sprite->pos1.x = -64;
+ }
+ sprite->pos1.y = gBattleAnimArgs[0];
+ SetSubspriteTables(sprite, gUnknown_83E7470);
+ sprite->data[1] = gBattleAnimArgs[1];
+ sprite->data[2] = gBattleAnimArgs[2];
+ ++sprite->data[0];
+ }
+ else
+ {
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ sprite->pos2.x += (sprite->data[3] >> 8);
+ sprite->pos2.y += (sprite->data[4] >> 8);
+ sprite->data[3] &= 0xFF;
+ sprite->data[4] &= 0xFF;
+ if (sprite->data[5] == 0)
+ {
+ if (sprite->pos1.x + sprite->pos2.x > 272)
+ {
+ sprite->callback = DestroyAnimSprite;
+ }
+ }
+ else if (sprite->pos1.x + sprite->pos2.x < -32)
+ {
+ sprite->callback = DestroyAnimSprite;
+ }
+ }
+}
+
+// Animates the rising rocks in Ancient Power.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: terminal y offset
+// arg 3: duration
+// arg 4: sprite size [1,5]
+static void AnimRaiseSprite(struct Sprite *sprite)
+{
+ StartSpriteAnim(sprite, gBattleAnimArgs[4]);
+ InitSpritePosToAnimAttacker(sprite, 0);
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->data[2] = sprite->pos1.x;
+ sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[2];
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+void sub_80B4BD0(u8 taskId)
+{
+ u16 var0, var1, var2, var3;
+ u8 var4;
+ s32 var5;
+ s16 pan1, pan2;
+ struct Task *task;
+
+ task = &gTasks[taskId];
+ var0 = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ var1 = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 24;
+ var2 = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ var3 = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + 24;
+ if (BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget)
+ var3 = var1;
+ var4 = sub_80B4FB8();
+ if (var4 == 1)
+ task->data[8] = 32;
+ else
+ task->data[8] = 48 - (var4 * 8);
+ task->data[0] = 0;
+ task->data[11] = 0;
+ task->data[9] = 0;
+ task->data[12] = 1;
+ var5 = task->data[8];
+ if (var5 < 0)
+ var5 += 7;
+ task->data[10] = (var5 >> 3) - 1;
+ task->data[2] = var0 * 8;
+ task->data[3] = var1 * 8;
+ task->data[4] = ((var2 - var0) * 8) / task->data[8];
+ task->data[5] = ((var3 - var1) * 8) / task->data[8];
+ task->data[6] = 0;
+ task->data[7] = 0;
+ pan1 = BattleAnimAdjustPanning(PAN_SIDE_PLAYER);
+ pan2 = BattleAnimAdjustPanning(PAN_SIDE_OPPONENT);
+ task->data[13] = pan1;
+ task->data[14] = (pan2 - pan1) / task->data[8];
+ task->data[1] = var4;
+ task->data[15] = GetAnimBattlerSpriteId(0);
+ task->func = sub_80B4D00;
+}
+
+static void sub_80B4D00(u8 taskId)
+{
+ struct Task *task;
+
+ task = &gTasks[taskId];
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[6] -= task->data[4];
+ task->data[7] -= task->data[5];
+ gSprites[task->data[15]].pos2.x = task->data[6] >> 3;
+ gSprites[task->data[15]].pos2.y = task->data[7] >> 3;
+ if (++task->data[9] == 10)
+ {
+ task->data[11] = 20;
+ ++task->data[0];
+ }
+ PlaySE12WithPanning(SE_W029, task->data[13]);
+ break;
+ case 1:
+ if (--task->data[11] == 0)
+ ++task->data[0];
+ break;
+ case 2:
+ if (--task->data[9] != 0)
+ {
+ task->data[6] += task->data[4];
+ task->data[7] += task->data[5];
+ }
+ else
+ {
+ task->data[6] = 0;
+ task->data[7] = 0;
+ ++task->data[0];
+ }
+ gSprites[task->data[15]].pos2.x = task->data[6] >> 3;
+ gSprites[task->data[15]].pos2.y = task->data[7] >> 3;
+ break;
+ case 3:
+ task->data[2] += task->data[4];
+ task->data[3] += task->data[5];
+ if (++task->data[9] >= task->data[10])
+ {
+ task->data[9] = 0;
+ sub_80B4E70(task);
+ task->data[13] += task->data[14];
+ PlaySE12WithPanning(SE_W091, task->data[13]);
+ }
+ if (--task->data[8] == 0)
+ {
+ ++task->data[0];
+ }
+ break;
+ case 4:
+ if (task->data[11] == 0)
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80B4E70(struct Task *task)
+{
+ const struct SpriteTemplate *spriteTemplate;
+ s32 var0;
+ u16 x, y;
+ u8 spriteId;
+
+ switch (task->data[1])
+ {
+ case 1:
+ spriteTemplate = &gUnknown_83E74D8;
+ var0 = 0;
+ break;
+ case 2:
+ case 3:
+ spriteTemplate = &gUnknown_83E74F0;
+ var0 = 80;
+ break;
+ case 4:
+ spriteTemplate = &gUnknown_83E74F0;
+ var0 = 64;
+ break;
+ case 5:
+ spriteTemplate = &gUnknown_83E74F0;
+ var0 = 48;
+ break;
+ default:
+ return;
+ }
+ x = task->data[2] >> 3;
+ y = task->data[3] >> 3;
+ x += (task->data[12] * 4);
+ spriteId = CreateSprite(spriteTemplate, x, y, 35);
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].data[0] = 18;
+ gSprites[spriteId].data[2] = ((task->data[12] * 20) + x) + (task->data[1] * 3);
+ gSprites[spriteId].data[4] = y;
+ gSprites[spriteId].data[5] = -16 - (task->data[1] * 2);
+ gSprites[spriteId].oam.tileNum += var0;
+ InitAnimArcTranslation(&gSprites[spriteId]);
+ ++task->data[11];
+ }
+ task->data[12] *= -1;
+}
+
+static void sub_80B4F78(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ {
+ u8 taskId = FindTaskIdByFunc(sub_80B4D00);
+
+ if (taskId != TASK_NONE)
+ --gTasks[taskId].data[11];
+ DestroySprite(sprite);
+ }
+}
+
+static u8 sub_80B4FB8(void)
+{
+ u8 retVal = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer;
+ u8 var0 = retVal - 1;
+
+ if (var0 > 4)
+ retVal = 1;
+ return retVal;
+}
+
+static void sub_80B4FE4(struct Sprite *sprite)
+{
+ StartSpriteAnim(sprite, gBattleAnimArgs[4]);
+ sprite->pos2.x = gBattleAnimArgs[0];
+ sprite->data[2] = gBattleAnimArgs[1];
+ sprite->data[3] -= gBattleAnimArgs[2];
+ sprite->data[0] = 3;
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->callback = sub_80B5024;
+ sprite->invisible = TRUE;
+}
+
+static void sub_80B5024(struct Sprite *sprite)
+{
+ sprite->invisible = FALSE;
+ if (sprite->data[3] != 0)
+ {
+ sprite->pos2.y = sprite->data[2] + sprite->data[3];
+ sprite->data[3] += sprite->data[0];
+ ++sprite->data[0];
+ if (sprite->data[3] > 0)
+ {
+ sprite->data[3] = 0;
+ }
+ }
+ else if (--sprite->data[1] == 0)
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+static void sub_80B5074(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
+ StartSpriteAffineAnim(sprite, 1);
+ TranslateAnimSpriteToTargetMonLocation(sprite);
+}
+
+static void sub_80B50A0(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1);
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[1] = gBattleAnimArgs[0];
+ sprite->data[2] = gBattleAnimArgs[1];
+ sprite->data[5] = gBattleAnimArgs[2];
+ StartSpriteAnim(sprite, gBattleAnimArgs[3]);
+ sprite->callback = sub_80B50F8;
+}
+
+static void sub_80B50F8(struct Sprite *sprite)
+{
+ sprite->data[0] += 8;
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ sprite->pos2.x += sprite->data[3] / 40;
+ sprite->pos2.y -= Sin(sprite->data[0], sprite->data[5]);
+ if (sprite->data[0] > 140)
+ DestroyAnimSprite(sprite);
+}
+
+void AnimTask_GetSeismicTossDamageLevel(u8 taskId)
+{
+ if (gAnimMoveDmg < 33)
+ gBattleAnimArgs[7] = 0;
+ if ((u32)gAnimMoveDmg - 33 < 33)
+ gBattleAnimArgs[7] = 1;
+ if (gAnimMoveDmg > 65)
+ gBattleAnimArgs[7] = 2;
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80B5188(u8 taskId)
+{
+ if (gTasks[taskId].data[0] == 0)
+ {
+ sub_8075458(0);
+ gTasks[taskId].data[1] = 200;
+ }
+ gBattle_BG3_Y += gTasks[taskId].data[1] / 10;
+ gTasks[taskId].data[1] -= 3;
+ if (gTasks[taskId].data[0] == 120)
+ {
+ sub_8075458(1);
+ DestroyAnimVisualTask(taskId);
+ }
+ ++gTasks[taskId].data[0];
+}
+
+void sub_80B51EC(u8 taskId)
+{
+ if (gTasks[taskId].data[0] == 0)
+ {
+ sub_8075458(0);
+ ++gTasks[taskId].data[0];
+ gTasks[taskId].data[2] = gBattle_BG3_Y;
+ }
+ gTasks[taskId].data[1] += 80;
+ gTasks[taskId].data[1] &= 0xFF;
+ gBattle_BG3_Y = gTasks[taskId].data[2] + Cos(4, gTasks[taskId].data[1]);
+ if (gBattleAnimArgs[7] == 0xFFF)
+ {
+ gBattle_BG3_Y = 0;
+ sub_8075458(1);
+ DestroyAnimVisualTask(taskId);
+ }
+}
diff --git a/src/save.c b/src/save.c
index 9f580477b..45f5fc6f0 100644
--- a/src/save.c
+++ b/src/save.c
@@ -85,7 +85,7 @@ u16 gSaveUnusedVar;
u16 gSaveFileStatus;
void (*gGameContinueCallback)(void);
struct SaveBlockChunk gRamSaveSectionLocations[0xE];
-u16 gUnknown_3005420;
+u16 gSaveSucceeded;
EWRAM_DATA struct SaveSection gSaveDataBuffer = {0};
EWRAM_DATA u32 gSaveUnusedVar2 = 0;
@@ -702,11 +702,11 @@ u8 TrySavingData(u8 saveType)
else
goto OK; // really?
}
- gUnknown_3005420 = 0xFF;
+ gSaveSucceeded = 0xFF;
return 0xFF;
OK:
- gUnknown_3005420 = 1;
+ gSaveSucceeded = 1;
return 1;
}
diff --git a/src/scrcmd.c b/src/scrcmd.c
index 85059691f..ae994fceb 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -1284,14 +1284,14 @@ bool8 ScrCmd_loadhelp(struct ScriptContext *ctx)
if (msg == NULL)
msg = (const u8 *)ctx->data[0];
- sub_80F7974(msg);
+ DrawHelpMessageWindowWithText(msg);
CopyWindowToVram(GetStartMenuWindowId(), 1);
return FALSE;
}
bool8 ScrCmd_unloadhelp(struct ScriptContext *ctx)
{
- sub_80F7998();
+ DestroyHelpMessageWindow_();
return FALSE;
}
@@ -1566,7 +1566,7 @@ bool8 ScrCmd_braillemessage(struct ScriptContext *ctx)
if (ptr == NULL)
ptr = (u8 *)ctx->data[0];
- sub_80F6E9C();
+ LoadStdWindowFrameGfx();
DrawDialogueFrame(0, 1);
AddTextPrinterParameterized(0, 6, ptr, 0, 1, 0, NULL);
return FALSE;
diff --git a/src/start_menu.c b/src/start_menu.c
new file mode 100644
index 000000000..e3854b803
--- /dev/null
+++ b/src/start_menu.c
@@ -0,0 +1,1008 @@
+#include "global.h"
+#include "palette.h"
+#include "bg.h"
+#include "gpu_regs.h"
+#include "scanline_effect.h"
+#include "overworld.h"
+#include "link.h"
+#include "pokedex.h"
+#include "item_menu.h"
+#include "party_menu.h"
+#include "save.h"
+#include "link_rfu.h"
+#include "event_data.h"
+#include "fieldmap.h"
+#include "safari_zone.h"
+#include "start_menu.h"
+#include "menu.h"
+#include "load_save.h"
+#include "strings.h"
+#include "string_util.h"
+#include "menu_helpers.h"
+#include "text_window.h"
+#include "field_fadetransition.h"
+#include "field_player_avatar.h"
+#include "new_menu_helpers.h"
+#include "map_obj_80688E4.h"
+#include "map_obj_lock.h"
+#include "script.h"
+#include "sound.h"
+#include "quest_log.h"
+#include "new_game.h"
+#include "event_scripts.h"
+#include "field_weather.h"
+#include "field_specials.h"
+#include "pokedex_screen.h"
+#include "trainer_card.h"
+#include "option_menu.h"
+#include "save_menu_util.h"
+#include "help_system.h"
+#include "constants/songs.h"
+#include "constants/flags.h"
+
+enum StartMenuOption
+{
+ STARTMENU_POKEDEX = 0,
+ STARTMENU_POKEMON,
+ STARTMENU_BAG,
+ STARTMENU_PLAYER,
+ STARTMENU_SAVE,
+ STARTMENU_OPTION,
+ STARTMENU_EXIT,
+ STARTMENU_RETIRE,
+ STARTMENU_PLAYER2,
+ MAX_STARTMENU_ITEMS
+};
+
+enum SaveCBReturn
+{
+ SAVECB_RETURN_CONTINUE = 0,
+ SAVECB_RETURN_OKAY,
+ SAVECB_RETURN_CANCEL,
+ SAVECB_RETURN_ERROR
+};
+
+static EWRAM_DATA bool8 (*sStartMenuCallback)(void) = NULL;
+static EWRAM_DATA u8 sStartMenuCursorPos = 0;
+static EWRAM_DATA u8 sNumStartMenuItems = 0;
+static EWRAM_DATA u8 sStartMenuOrder[MAX_STARTMENU_ITEMS] = {};
+static EWRAM_DATA s8 sDrawStartMenuState[2] = {};
+static EWRAM_DATA u8 sSafariZoneStatsWindowId = 0;
+static ALIGNED(4) EWRAM_DATA u8 sSaveStatsWindowId = 0;
+
+static u8 (*sSaveDialogCB)(void);
+static u8 sSaveDialogDelay;
+static bool8 sSaveDialogIsPrinting;
+
+static void SetUpStartMenu_Link(void);
+static void SetUpStartMenu_UnionRoom(void);
+static void SetUpStartMenu_SafariZone(void);
+static void SetUpStartMenu_NormalField(void);
+static bool8 StartCB_HandleInput(void);
+static void StartMenu_FadeScreenIfLeavingOverworld(void);
+static bool8 StartMenuPokedexSanityCheck(void);
+static bool8 StartMenuPokedexCallback(void);
+static bool8 StartMenuPokemonCallback(void);
+static bool8 StartMenuBagCallback(void);
+static bool8 StartMenuPlayerCallback(void);
+static bool8 StartMenuSaveCallback(void);
+static bool8 StartMenuOptionCallback(void);
+static bool8 StartMenuExitCallback(void);
+static bool8 StartMenuSafariZoneRetireCallback(void);
+static bool8 StartMenuLinkPlayerCallback(void);
+static bool8 StartCB_Save1(void);
+static bool8 StartCB_Save2(void);
+static void StartMenu_PrepareForSave(void);
+static u8 RunSaveDialogCB(void);
+static void task50_save_game(u8 taskId);
+static u8 SaveDialogCB_PrintAskSaveText(void);
+static u8 SaveDialogCB_AskSavePrintYesNoMenu(void);
+static u8 SaveDialogCB_AskSaveHandleInput(void);
+static u8 SaveDialogCB_PrintAskOverwriteText(void);
+static u8 SaveDialogCB_AskOverwritePrintYesNoMenu(void);
+static u8 SaveDialogCB_AskReplacePreviousFilePrintYesNoMenu(void);
+static u8 SaveDialogCB_AskOverwriteOrReplacePreviousFileHandleInput(void);
+static u8 SaveDialogCB_PrintSavingDontTurnOffPower(void);
+static u8 SaveDialogCB_DoSave(void);
+static u8 SaveDialogCB_PrintSaveResult(void);
+static u8 SaveDialogCB_WaitPrintSuccessAndPlaySE(void);
+static u8 SaveDialogCB_ReturnSuccess(void);
+static u8 SaveDialogCB_WaitPrintErrorAndPlaySE(void);
+static u8 SaveDialogCB_ReturnError(void);
+static void CB2_WhileSavingAfterLinkBattle(void);
+static void task50_after_link_battle_save(u8 taskId);
+static void PrintSaveStats(void);
+static void CloseSaveStatsWindow(void);
+static void CloseStartMenu(void);
+
+static const struct MenuAction sStartMenuActionTable[] = {
+ { gStartMenuText_Pokedex, {.u8_void = StartMenuPokedexCallback} },
+ { gStartMenuText_Pokemon, {.u8_void = StartMenuPokemonCallback} },
+ { gStartMenuText_Bag, {.u8_void = StartMenuBagCallback} },
+ { gStartMenuText_Player, {.u8_void = StartMenuPlayerCallback} },
+ { gStartMenuText_Save, {.u8_void = StartMenuSaveCallback} },
+ { gStartMenuText_Option, {.u8_void = StartMenuOptionCallback} },
+ { gStartMenuText_Exit, {.u8_void = StartMenuExitCallback} },
+ { gStartMenuText_Retire, {.u8_void = StartMenuSafariZoneRetireCallback} },
+ { gStartMenuText_Player, {.u8_void = StartMenuLinkPlayerCallback} }
+};
+
+static const struct WindowTemplate sSafariZoneStatsWindowTemplate = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 10,
+ .height = 4,
+ .paletteNum = 15,
+ .baseBlock = 0x008
+};
+
+static const u8 *const sStartMenuDescPointers[] = {
+ gStartMenuDesc_Pokedex,
+ gStartMenuDesc_Pokemon,
+ gStartMenuDesc_Bag,
+ gStartMenuDesc_Player,
+ gStartMenuDesc_Save,
+ gStartMenuDesc_Option,
+ gStartMenuDesc_Exit,
+ gStartMenuDesc_Retire,
+ gStartMenuDesc_Player
+};
+
+static const struct BgTemplate sBGTemplates_AfterLinkSaveMessage[] = {
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0x000
+ }
+};
+
+static const struct WindowTemplate sWindowTemplates_AfterLinkSaveMessage[] = {
+ {
+ .bg = 0,
+ .tilemapLeft = 2,
+ .tilemapTop = 15,
+ .width = 26,
+ .height = 4,
+ .paletteNum = 15,
+ .baseBlock = 0x198
+ }, DUMMY_WIN_TEMPLATE
+};
+
+static const struct WindowTemplate sSaveStatsWindowTemplate = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 14,
+ .height = 9,
+ .paletteNum = 13,
+ .baseBlock = 0x008
+};
+
+static ALIGNED(2) const u8 sTextColor_StatName[] = { 1, 2, 3 };
+static ALIGNED(2) const u8 sTextColor_StatValue[] = { 1, 4, 5 };
+static ALIGNED(2) const u8 sTextColor_LocationHeader[] = { 1, 6, 7 };
+
+static void SetUpStartMenu(void)
+{
+ sNumStartMenuItems = 0;
+ if (IsUpdateLinkStateCBActive() == TRUE)
+ SetUpStartMenu_Link();
+ else if (InUnionRoom() == TRUE)
+ SetUpStartMenu_UnionRoom();
+ else if (GetSafariZoneFlag() == TRUE)
+ SetUpStartMenu_SafariZone();
+ else
+ SetUpStartMenu_NormalField();
+}
+
+static void AppendToStartMenuItems(u8 newEntry)
+{
+ AppendToList(sStartMenuOrder, &sNumStartMenuItems, newEntry);
+}
+
+static void SetUpStartMenu_NormalField(void)
+{
+ if (FlagGet(FLAG_0x829) == TRUE)
+ AppendToStartMenuItems(STARTMENU_POKEDEX);
+ if (FlagGet(FLAG_0x828) == TRUE)
+ AppendToStartMenuItems(STARTMENU_POKEMON);
+ AppendToStartMenuItems(STARTMENU_BAG);
+ AppendToStartMenuItems(STARTMENU_PLAYER);
+ AppendToStartMenuItems(STARTMENU_SAVE);
+ AppendToStartMenuItems(STARTMENU_OPTION);
+ AppendToStartMenuItems(STARTMENU_EXIT);
+}
+
+static void SetUpStartMenu_SafariZone(void)
+{
+ AppendToStartMenuItems(STARTMENU_RETIRE);
+ AppendToStartMenuItems(STARTMENU_POKEDEX);
+ AppendToStartMenuItems(STARTMENU_POKEMON);
+ AppendToStartMenuItems(STARTMENU_BAG);
+ AppendToStartMenuItems(STARTMENU_PLAYER);
+ AppendToStartMenuItems(STARTMENU_OPTION);
+ AppendToStartMenuItems(STARTMENU_EXIT);
+}
+
+static void SetUpStartMenu_Link(void)
+{
+ AppendToStartMenuItems(STARTMENU_POKEMON);
+ AppendToStartMenuItems(STARTMENU_BAG);
+ AppendToStartMenuItems(STARTMENU_PLAYER2);
+ AppendToStartMenuItems(STARTMENU_OPTION);
+ AppendToStartMenuItems(STARTMENU_EXIT);
+}
+
+static void SetUpStartMenu_UnionRoom(void)
+{
+ AppendToStartMenuItems(STARTMENU_POKEMON);
+ AppendToStartMenuItems(STARTMENU_BAG);
+ AppendToStartMenuItems(STARTMENU_PLAYER);
+ AppendToStartMenuItems(STARTMENU_OPTION);
+ AppendToStartMenuItems(STARTMENU_EXIT);
+}
+
+static void DrawSafariZoneStatsWindow(void)
+{
+ sSafariZoneStatsWindowId = AddWindow(&sSafariZoneStatsWindowTemplate);
+ PutWindowTilemap(sSafariZoneStatsWindowId);
+ DrawStdWindowFrame(sSafariZoneStatsWindowId, FALSE);
+ ConvertIntToDecimalStringN(gStringVar1, gSafariZoneStepCounter, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ ConvertIntToDecimalStringN(gStringVar2, 600, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ ConvertIntToDecimalStringN(gStringVar3, gNumSafariBalls, STR_CONV_MODE_RIGHT_ALIGN, 2);
+ StringExpandPlaceholders(gStringVar4, gUnknown_84162A9);
+ AddTextPrinterParameterized(sSafariZoneStatsWindowId,2, gStringVar4, 4, 3, 0xFF, NULL);
+ CopyWindowToVram(sSafariZoneStatsWindowId, 2);
+}
+
+static void DestroySafariZoneStatsWindow(void)
+{
+ if (GetSafariZoneFlag())
+ {
+ ClearStdWindowAndFrameToTransparent(sSafariZoneStatsWindowId, FALSE);
+ CopyWindowToVram(sSafariZoneStatsWindowId, 2);
+ RemoveWindow(sSafariZoneStatsWindowId);
+ }
+}
+
+static s8 PrintStartMenuItems(s8 *cursor_p, u8 nitems)
+{
+ s16 i = *cursor_p;
+ do
+ {
+ if (sStartMenuOrder[i] == STARTMENU_PLAYER || sStartMenuOrder[i] == STARTMENU_PLAYER2)
+ {
+ Menu_PrintFormatIntlPlayerName(GetStartMenuWindowId(), sStartMenuActionTable[sStartMenuOrder[i]].text, 8, i * 15);
+ }
+ else
+ {
+ StringExpandPlaceholders(gStringVar4, sStartMenuActionTable[sStartMenuOrder[i]].text);
+ AddTextPrinterParameterized(GetStartMenuWindowId(), 2, gStringVar4, 8, i * 15, 0xFF, NULL);
+ }
+ i++;
+ if (i >= sNumStartMenuItems)
+ {
+ *cursor_p = i;
+ return TRUE;
+ }
+ } while (--nitems);
+ *cursor_p = i;
+ return FALSE;
+}
+
+static s8 DoDrawStartMenu(void)
+{
+ switch (sDrawStartMenuState[0])
+ {
+ case 0:
+ sDrawStartMenuState[0]++;
+ break;
+ case 1:
+ SetUpStartMenu();
+ sDrawStartMenuState[0]++;
+ break;
+ case 2:
+ LoadStdWindowFrameGfx();
+ DrawStdWindowFrame(CreateStartMenuWindow(sNumStartMenuItems), FALSE);
+ sDrawStartMenuState[0]++;
+ break;
+ case 3:
+ if (GetSafariZoneFlag())
+ DrawSafariZoneStatsWindow();
+ sDrawStartMenuState[0]++;
+ break;
+ case 4:
+ if (PrintStartMenuItems(&sDrawStartMenuState[1], 2) == TRUE)
+ sDrawStartMenuState[0]++;
+ break;
+ case 5:
+ sStartMenuCursorPos = Menu_InitCursor(GetStartMenuWindowId(), 2, 0, 0, 15, sNumStartMenuItems, sStartMenuCursorPos);
+ if (!MenuHelpers_LinkSomething() && InUnionRoom() != TRUE && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_HELP)
+ {
+ DrawHelpMessageWindowWithText(sStartMenuDescPointers[sStartMenuOrder[sStartMenuCursorPos]]);
+ }
+ CopyWindowToVram(GetStartMenuWindowId(), 1);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void DrawStartMenuInOneGo(void)
+{
+ sDrawStartMenuState[0] = 0;
+ sDrawStartMenuState[1] = 0;
+ while (!DoDrawStartMenu())
+ ;
+}
+
+static void task50_startmenu(u8 taskId)
+{
+ if (DoDrawStartMenu() == TRUE)
+ SwitchTaskToFollowupFunc(taskId);
+}
+
+static void OpenStartMenuWithFollowupFunc(TaskFunc func)
+{
+ u8 taskId;
+ sDrawStartMenuState[0] = 0;
+ sDrawStartMenuState[1] = 0;
+ taskId = CreateTask(task50_startmenu, 80);
+ SetTaskFuncWithFollowupFunc(taskId, task50_startmenu, func);
+}
+
+static bool8 FieldCB2_DrawStartMenu(void)
+{
+ if (!DoDrawStartMenu())
+ return FALSE;
+ FadeTransition_FadeInOnReturnToStartMenu();
+ return TRUE;
+}
+
+void SetUpReturnToStartMenu(void)
+{
+ sDrawStartMenuState[0] = 0;
+ sDrawStartMenuState[1] = 0;
+ gFieldCallback2 = FieldCB2_DrawStartMenu;
+}
+
+void Task_StartMenuHandleInput(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ switch (data[0])
+ {
+ case 0:
+ if (InUnionRoom() == TRUE)
+ var_800D_set_xB();
+ sStartMenuCallback = StartCB_HandleInput;
+ data[0]++;
+ break;
+ case 1:
+ if (sStartMenuCallback() == TRUE)
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void ShowStartMenu(void)
+{
+ if (!IsUpdateLinkStateCBActive())
+ {
+ player_bitmagic();
+ sub_805C270();
+ sub_805C780();
+ }
+ OpenStartMenuWithFollowupFunc(Task_StartMenuHandleInput);
+ ScriptContext2_Enable();
+}
+
+static bool8 StartCB_HandleInput(void)
+{
+ if (JOY_NEW(DPAD_UP))
+ {
+ PlaySE(SE_SELECT);
+ sStartMenuCursorPos = Menu_MoveCursor(-1);
+ if (!MenuHelpers_LinkSomething() && InUnionRoom() != TRUE && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_HELP)
+ {
+ PrintTextOnHelpMessageWindow(sStartMenuDescPointers[sStartMenuOrder[sStartMenuCursorPos]], 2);
+ }
+ }
+ if (JOY_NEW(DPAD_DOWN))
+ {
+ PlaySE(SE_SELECT);
+ sStartMenuCursorPos = Menu_MoveCursor(+1);
+ if (!MenuHelpers_LinkSomething() && InUnionRoom() != TRUE && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_HELP)
+ {
+ PrintTextOnHelpMessageWindow(sStartMenuDescPointers[sStartMenuOrder[sStartMenuCursorPos]], 2);
+ }
+ }
+ if (JOY_NEW(A_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ if (!StartMenuPokedexSanityCheck())
+ return FALSE;
+ sStartMenuCallback = sStartMenuActionTable[sStartMenuOrder[sStartMenuCursorPos]].func.u8_void;
+ StartMenu_FadeScreenIfLeavingOverworld();
+ return FALSE;
+ }
+ if (JOY_NEW(B_BUTTON | START_BUTTON))
+ {
+ DestroySafariZoneStatsWindow();
+ DestroyHelpMessageWindow_();
+ CloseStartMenu();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void StartMenu_FadeScreenIfLeavingOverworld(void)
+{
+ if (sStartMenuCallback != StartMenuSaveCallback
+ && sStartMenuCallback != StartMenuExitCallback
+ && sStartMenuCallback != StartMenuSafariZoneRetireCallback)
+ {
+ sub_80CCB68();
+ fade_screen(1, 0);
+ }
+}
+
+static bool8 StartMenuPokedexSanityCheck(void)
+{
+ if (sStartMenuActionTable[sStartMenuOrder[sStartMenuCursorPos]].func.u8_void == StartMenuPokedexCallback && GetNationalPokedexCount(0) == 0)
+ return FALSE;
+ return TRUE;
+}
+
+static bool8 StartMenuPokedexCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ IncrementGameStat(GAME_STAT_CHECKED_POKEDEX);
+ PlayRainStoppingSoundEffect();
+ DestroySafariZoneStatsWindow();
+ CleanupOverworldWindowsAndTilemaps();
+ SetMainCallback2(CB2_OpenPokedexFromStartMenu);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 StartMenuPokemonCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainStoppingSoundEffect();
+ DestroySafariZoneStatsWindow();
+ CleanupOverworldWindowsAndTilemaps();
+ SetMainCallback2(CB2_PartyMenuFromStartMenu);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 StartMenuBagCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainStoppingSoundEffect();
+ DestroySafariZoneStatsWindow();
+ CleanupOverworldWindowsAndTilemaps();
+ SetMainCallback2(CB2_BagMenuFromStartMenu);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 StartMenuPlayerCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainStoppingSoundEffect();
+ DestroySafariZoneStatsWindow();
+ CleanupOverworldWindowsAndTilemaps();
+ InitTrainerCard(CB2_ReturnToStartMenu);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 StartMenuSaveCallback(void)
+{
+ sStartMenuCallback = StartCB_Save1;
+ return FALSE;
+}
+
+static bool8 StartMenuOptionCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainStoppingSoundEffect();
+ DestroySafariZoneStatsWindow();
+ CleanupOverworldWindowsAndTilemaps();
+ SetMainCallback2(CB2_OptionsMenuFromStartMenu);
+ gMain.savedCallback = CB2_ReturnToStartMenu;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 StartMenuExitCallback(void)
+{
+ DestroySafariZoneStatsWindow();
+ DestroyHelpMessageWindow_();
+ CloseStartMenu();
+ return TRUE;
+}
+
+static bool8 StartMenuSafariZoneRetireCallback(void)
+{
+ DestroySafariZoneStatsWindow();
+ DestroyHelpMessageWindow_();
+ CloseStartMenu();
+ SafariZoneRetirePrompt();
+ return TRUE;
+}
+
+
+static bool8 StartMenuLinkPlayerCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainStoppingSoundEffect();
+ CleanupOverworldWindowsAndTilemaps();
+ InitLinkPartnerTrainerCard(gUnknown_300502C, CB2_ReturnToStartMenu);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 StartCB_Save1(void)
+{
+ HelpSystem_BackupSomeVariable();
+ HelpSystem_SetSomeVariable2(12);
+ StartMenu_PrepareForSave();
+ sStartMenuCallback = StartCB_Save2;
+ return FALSE;
+}
+
+static bool8 StartCB_Save2(void)
+{
+ switch (RunSaveDialogCB())
+ {
+ case SAVECB_RETURN_CONTINUE:
+ break;
+ case SAVECB_RETURN_OKAY:
+ ClearDialogWindowAndFrameToTransparent(0, TRUE);
+ sub_80696C0();
+ ScriptContext2_Disable();
+ HelpSystem_RestoreSomeVariable();
+ return TRUE;
+ case SAVECB_RETURN_CANCEL:
+ ClearDialogWindowAndFrameToTransparent(0, FALSE);
+ DrawStartMenuInOneGo();
+ HelpSystem_RestoreSomeVariable();
+ sStartMenuCallback = StartCB_HandleInput;
+ break;
+ case SAVECB_RETURN_ERROR:
+ ClearDialogWindowAndFrameToTransparent(0, TRUE);
+ sub_80696C0();
+ ScriptContext2_Disable();
+ HelpSystem_RestoreSomeVariable();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void StartMenu_PrepareForSave(void)
+{
+ save_serialize_map();
+ sSaveDialogCB = SaveDialogCB_PrintAskSaveText;
+ sSaveDialogIsPrinting = FALSE;
+}
+
+static u8 RunSaveDialogCB(void)
+{
+ if (RunTextPrinters_CheckPrinter0Active() == TRUE)
+ return 0;
+ sSaveDialogIsPrinting = FALSE;
+ return sSaveDialogCB();
+}
+
+void Field_AskSaveTheGame(void)
+{
+ HelpSystem_BackupSomeVariable();
+ HelpSystem_SetSomeVariable2(12);
+ StartMenu_PrepareForSave();
+ CreateTask(task50_save_game, 80);
+}
+
+static void PrintSaveTextWithFollowupFunc(const u8 *str, bool8 (*saveDialogCB)(void))
+{
+ StringExpandPlaceholders(gStringVar4, str);
+ sub_80F7768(0, TRUE);
+ AddTextPrinterForMessage(TRUE);
+ sSaveDialogIsPrinting = TRUE;
+ sSaveDialogCB = saveDialogCB;
+}
+
+static void task50_save_game(u8 taskId)
+{
+ switch (RunSaveDialogCB())
+ {
+ case 0:
+ return;
+ case 2:
+ case 3:
+ gSpecialVar_Result = FALSE;
+ break;
+ case 1:
+ gSpecialVar_Result = TRUE;
+ break;
+ }
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ HelpSystem_RestoreSomeVariable();
+}
+
+static void CloseSaveMessageWindow(void)
+{
+ ClearDialogWindowAndFrame(0, TRUE);
+}
+
+static void CloseSaveStatsWindow_(void)
+{
+ CloseSaveStatsWindow();
+}
+
+static void SetSaveDialogDelayTo60Frames(void)
+{
+ sSaveDialogDelay = 60;
+}
+
+static bool8 SaveDialog_Wait60FramesOrAButtonHeld(void)
+{
+ sSaveDialogDelay--;
+ if (JOY_HELD(A_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ else if (sSaveDialogDelay == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static bool8 SaveDialog_Wait60FramesThenCheckAButtonHeld(void)
+{
+ if (sSaveDialogDelay == 0)
+ {
+ if (JOY_HELD(A_BUTTON))
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ sSaveDialogDelay--;
+ return FALSE;
+ }
+}
+
+static u8 SaveDialogCB_PrintAskSaveText(void)
+{
+ ClearStdWindowAndFrame(GetStartMenuWindowId(), FALSE);
+ RemoveStartMenuWindow();
+ DestroyHelpMessageWindow(0);
+ PrintSaveStats();
+ PrintSaveTextWithFollowupFunc(gText_WouldYouLikeToSaveTheGame, SaveDialogCB_AskSavePrintYesNoMenu);
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_AskSavePrintYesNoMenu(void)
+{
+ DisplayYesNoMenuDefaultYes();
+ sSaveDialogCB = SaveDialogCB_AskSaveHandleInput;
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_AskSaveHandleInput(void)
+{
+ switch (Menu_ProcessInputNoWrapClearOnChoose())
+ {
+ case 0:
+ if ((gSaveFileStatus != SAVE_STATUS_EMPTY && gSaveFileStatus != SAVE_STATUS_INVALID) || !gDifferentSaveFile)
+ sSaveDialogCB = SaveDialogCB_PrintAskOverwriteText;
+ else
+ sSaveDialogCB = SaveDialogCB_PrintSavingDontTurnOffPower;
+ break;
+ case 1:
+ case -1:
+ CloseSaveStatsWindow_();
+ CloseSaveMessageWindow();
+ return SAVECB_RETURN_CANCEL;
+ }
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_PrintAskOverwriteText(void)
+{
+ if (gDifferentSaveFile == TRUE)
+ PrintSaveTextWithFollowupFunc(gText_DifferentGameFile, SaveDialogCB_AskReplacePreviousFilePrintYesNoMenu);
+ else
+ PrintSaveTextWithFollowupFunc(gText_AlreadySaveFile_WouldLikeToOverwrite, SaveDialogCB_AskOverwritePrintYesNoMenu);
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_AskOverwritePrintYesNoMenu(void)
+{
+ DisplayYesNoMenuDefaultYes();
+ sSaveDialogCB = SaveDialogCB_AskOverwriteOrReplacePreviousFileHandleInput;
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_AskReplacePreviousFilePrintYesNoMenu(void)
+{
+ DisplayYesNoMenuDefaultNo();
+ sSaveDialogCB = SaveDialogCB_AskOverwriteOrReplacePreviousFileHandleInput;
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_AskOverwriteOrReplacePreviousFileHandleInput(void)
+{
+ switch (Menu_ProcessInputNoWrapClearOnChoose())
+ {
+ case 0:
+ sSaveDialogCB = SaveDialogCB_PrintSavingDontTurnOffPower;
+ break;
+ case 1:
+ case -1:
+ CloseSaveStatsWindow_();
+ CloseSaveMessageWindow();
+ return SAVECB_RETURN_CANCEL;
+ }
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_PrintSavingDontTurnOffPower(void)
+{
+ sub_8112450();
+ PrintSaveTextWithFollowupFunc(gText_SavingDontTurnOffThePower, SaveDialogCB_DoSave);
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_DoSave(void)
+{
+ IncrementGameStat(GAME_STAT_SAVED_GAME);
+ if (gDifferentSaveFile == TRUE)
+ {
+ TrySavingData(SAVE_OVERWRITE_DIFFERENT_FILE);
+ gDifferentSaveFile = FALSE;
+ }
+ else
+ {
+ TrySavingData(SAVE_NORMAL);
+ }
+ sSaveDialogCB = SaveDialogCB_PrintSaveResult;
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_PrintSaveResult(void)
+{
+ if (gSaveSucceeded == TRUE)
+ PrintSaveTextWithFollowupFunc(gText_PlayerSavedTheGame, SaveDialogCB_WaitPrintSuccessAndPlaySE);
+ else
+ PrintSaveTextWithFollowupFunc(gText_SaveError_PleaseExchangeBackupMemory, SaveDialogCB_WaitPrintErrorAndPlaySE);
+ SetSaveDialogDelayTo60Frames();
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_WaitPrintSuccessAndPlaySE(void)
+{
+ if (!RunTextPrinters_CheckPrinter0Active())
+ {
+ PlaySE(SE_SAVE);
+ sSaveDialogCB = SaveDialogCB_ReturnSuccess;
+ }
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_ReturnSuccess(void)
+{
+ if (!IsSEPlaying() && SaveDialog_Wait60FramesOrAButtonHeld())
+ {
+ CloseSaveStatsWindow_();
+ return SAVECB_RETURN_OKAY;
+ }
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_WaitPrintErrorAndPlaySE(void)
+{
+ if (!RunTextPrinters_CheckPrinter0Active())
+ {
+ PlaySE(SE_BOO);
+ sSaveDialogCB = SaveDialogCB_ReturnError;
+ }
+ return SAVECB_RETURN_CONTINUE;
+}
+
+static u8 SaveDialogCB_ReturnError(void)
+{
+ if (!SaveDialog_Wait60FramesThenCheckAButtonHeld())
+ return SAVECB_RETURN_CONTINUE;
+ CloseSaveStatsWindow_();
+ return SAVECB_RETURN_ERROR;
+}
+
+static void VBlankCB_WhileSavingAfterLinkBattle(void)
+{
+ TransferPlttBuffer();
+}
+
+bool32 DoSetUpSaveAfterLinkBattle(u8 *state)
+{
+ switch (*state)
+ {
+ case 0:
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetVBlankCallback(NULL);
+ ScanlineEffect_Stop();
+ DmaFill16Defvars(3, 0, (void *)PLTT, PLTT_SIZE);
+ DmaFillLarge16(3, 0, (void *)VRAM, VRAM_SIZE, 0x1000);
+ break;
+ case 1:
+ ResetSpriteData();
+ ResetTasks();
+ ResetPaletteFade();
+ ScanlineEffect_Clear();
+ break;
+ case 2:
+ ResetBgsAndClearDma3BusyFlags(FALSE);
+ InitBgsFromTemplates(0, sBGTemplates_AfterLinkSaveMessage, NELEMS(sBGTemplates_AfterLinkSaveMessage));
+ InitWindows(sWindowTemplates_AfterLinkSaveMessage);
+ TextWindow_SetStdFrame0_WithPal(0, 0x008, 0xF0);
+ break;
+ case 3:
+ ShowBg(0);
+ BlendPalettes(0xFFFFFFFF, 16, RGB_BLACK);
+ SetVBlankCallback(VBlankCB_WhileSavingAfterLinkBattle);
+ EnableInterrupts(INTR_FLAG_VBLANK);
+ break;
+ case 4:
+ return TRUE;
+ }
+ (*state)++;
+ return FALSE;
+}
+
+void CB2_SetUpSaveAfterLinkBattle(void)
+{
+ if (DoSetUpSaveAfterLinkBattle(&gMain.state))
+ {
+ CreateTask(task50_after_link_battle_save, 80);
+ SetMainCallback2(CB2_WhileSavingAfterLinkBattle);
+ }
+}
+
+static void CB2_WhileSavingAfterLinkBattle(void)
+{
+ RunTasks();
+ UpdatePaletteFade();
+}
+
+static void task50_after_link_battle_save(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ if (!gPaletteFade.active)
+ {
+ switch (data[0])
+ {
+ case 0:
+ FillWindowPixelBuffer(0, PIXEL_FILL(1));
+ AddTextPrinterParameterized2(0, 2, gText_SavingDontTurnOffThePower2, 0xFF, NULL, 2, 1, 3);
+ DrawTextBorderOuter(0, 0x008, 0x0F);
+ PutWindowTilemap(0);
+ CopyWindowToVram(0, 3);
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ if (gWirelessCommType != 0 && InUnionRoom())
+ data[0] = 5;
+ else
+ data[0] = 1;
+ break;
+ case 1:
+ sub_804C1C0();
+ sub_80DA45C();
+ data[0] = 2;
+ break;
+ case 2:
+ if (sub_80DA4A0())
+ {
+ sav2_gender2_inplace_and_xFE();
+ data[0] = 3;
+ }
+ break;
+ case 3:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
+ data[0] = 4;
+ break;
+ case 4:
+ FreeAllWindowBuffers();
+ SetMainCallback2(gMain.savedCallback);
+ DestroyTask(taskId);
+ break;
+ case 5:
+ CreateTask(sub_80DA634, 5);
+ data[0] = 6;
+ break;
+ case 6:
+ if (!FuncIsActiveTask(sub_80DA634))
+ data[0] = 3;
+ break;
+ }
+ }
+}
+
+static void PrintSaveStats(void)
+{
+ u8 y;
+ u8 x;
+ sSaveStatsWindowId = AddWindow(&sSaveStatsWindowTemplate);
+ TextWindow_SetStdFrame0_WithPal(sSaveStatsWindowId, 0x21D, 0xD0);
+ DrawStdFrameWithCustomTileAndPalette(sSaveStatsWindowId, FALSE, 0x21D, 0x0D);
+ SaveStatToString(SAVE_STAT_LOCATION, gStringVar4, 8);
+ x = (u32)(112 - GetStringWidth(2, gStringVar4, -1)) / 2;
+ AddTextPrinterParameterized3(sSaveStatsWindowId, 2, x, 0, sTextColor_LocationHeader, -1, gStringVar4);
+ x = (u32)(112 - GetStringWidth(2, gStringVar4, -1)) / 2;
+ AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 2, 14, sTextColor_StatName, -1, gSaveStatName_Player);
+ SaveStatToString(SAVE_STAT_NAME, gStringVar4, 2);
+ Menu_PrintFormatIntlPlayerName(sSaveStatsWindowId, gStringVar4, 60, 14);
+ AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 2, 28, sTextColor_StatName, -1, gSaveStatName_Badges);
+ SaveStatToString(SAVE_STAT_BADGES, gStringVar4, 2);
+ AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 60, 28, sTextColor_StatValue, -1, gStringVar4);
+ y = 42;
+ if (FlagGet(FLAG_0x829) == TRUE)
+ {
+ AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 2, 42, sTextColor_StatName, -1, gSaveStatName_Pokedex);
+ SaveStatToString(SAVE_STAT_POKEDEX, gStringVar4, 2);
+ AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 60, 42, sTextColor_StatValue, -1, gStringVar4);
+ y = 56;
+ }
+ AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 2, y, sTextColor_StatName, -1, gSaveStatName_Time);
+ SaveStatToString(SAVE_STAT_TIME, gStringVar4, 2);
+ AddTextPrinterParameterized3(sSaveStatsWindowId, 0, 60, y, sTextColor_StatValue, -1, gStringVar4);
+ CopyWindowToVram(sSaveStatsWindowId, 2);
+}
+
+static void CloseSaveStatsWindow(void)
+{
+ ClearStdWindowAndFrame(sSaveStatsWindowId, FALSE);
+ RemoveWindow(sSaveStatsWindowId);
+}
+
+static void CloseStartMenu(void)
+{
+ PlaySE(SE_SELECT);
+ ClearStdWindowAndFrame(GetStartMenuWindowId(), TRUE);
+ RemoveStartMenuWindow();
+ sub_80696C0();
+ ScriptContext2_Disable();
+}
+
+void AppendToList(u8 *list, u8 *cursor, u8 newEntry)
+{
+ list[*cursor] = newEntry;
+ (*cursor)++;
+}
diff --git a/src/teachy_tv.c b/src/teachy_tv.c
index 18da0997c..aa273073b 100644
--- a/src/teachy_tv.c
+++ b/src/teachy_tv.c
@@ -510,7 +510,7 @@ static void TeachyTvMainCallback(void)
ScheduleBgCopyTilemapToVram(1);
ScheduleBgCopyTilemapToVram(2);
ScheduleBgCopyTilemapToVram(3);
- sub_812B1E0(9); // help system something
+ HelpSystem_SetSomeVariable(9); // help system something
BlendPalettes(0xFFFFFFFF, 0x10, 0);
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, 0);
SetVBlankCallback(TeachyTvVblankHandler);
@@ -736,7 +736,7 @@ static void TeachyTvOptionListController(u8 taskId)
{
input = ListMenu_ProcessInput(data[0]);
ListMenuGetScrollAndRow(data[0], &sStaticResources.scrollOffset, &sStaticResources.selectedRow);
- if ((JOY_NEW(SELECT_BUTTON) && sStaticResources.callback != ReturnToBagFromKeyItem))
+ if ((JOY_NEW(SELECT_BUTTON) && sStaticResources.callback != CB2_BagMenuFromStartMenu))
{
PlaySE(SE_SELECT);
TeachyTvQuitBeginFade(taskId);
diff --git a/src/trade.c b/src/trade.c
index 742650e4a..ee28ff224 100644
--- a/src/trade.c
+++ b/src/trade.c
@@ -137,6 +137,7 @@ void sub_804C718(void)
SetMainCallback2(sub_804C728);
}
+#ifdef NONMATCHING
void sub_804C728(void)
{
int i;
@@ -319,6 +320,10 @@ void sub_804C728(void)
CreateSprite(&temp, xPos + gTradeUnknownSpriteCoords[LANGUAGE_ENGLISH - 1][0] + (i * 32), gTradeUnknownSpriteCoords[LANGUAGE_ENGLISH - 1][1], 1);
}
+ /*
+ * These three lines are a pain to match due to register alloc and
+ * pointer arithmetic misbehavior.
+ */
id = GetMultiplayerId();
id ^= 1;
width = GetStringWidth(1, gLinkPlayers[id].name, 0);
@@ -406,3 +411,915 @@ void sub_804C728(void)
BuildOamBuffer();
UpdatePaletteFade();
}
+#else
+NAKED
+void sub_804C728(void)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r8\n"
+ "\tpush {r7}\n"
+ "\tsub sp, 0x28\n"
+ "\tldr r1, _0804C74C @ =gMain\n"
+ "\tmovs r2, 0x87\n"
+ "\tlsls r2, 3\n"
+ "\tadds r0, r1, r2\n"
+ "\tldrb r0, [r0]\n"
+ "\tadds r3, r1, 0\n"
+ "\tcmp r0, 0x16\n"
+ "\tbls _0804C742\n"
+ "\tb _0804CEE6\n"
+ "_0804C742:\n"
+ "\tlsls r0, 2\n"
+ "\tldr r1, _0804C750 @ =_0804C754\n"
+ "\tadds r0, r1\n"
+ "\tldr r0, [r0]\n"
+ "\tmov pc, r0\n"
+ "\t.align 2, 0\n"
+ "_0804C74C: .4byte gMain\n"
+ "_0804C750: .4byte _0804C754\n"
+ "\t.align 2, 0\n"
+ "_0804C754:\n"
+ "\t.4byte _0804C7B0\n"
+ "\t.4byte _0804C7FC\n"
+ "\t.4byte _0804C8C8\n"
+ "\t.4byte _0804C8F4\n"
+ "\t.4byte _0804C950\n"
+ "\t.4byte _0804C9B0\n"
+ "\t.4byte _0804C9F0\n"
+ "\t.4byte _0804CA10\n"
+ "\t.4byte _0804CB50\n"
+ "\t.4byte _0804CB78\n"
+ "\t.4byte _0804CB9C\n"
+ "\t.4byte _0804CC30\n"
+ "\t.4byte _0804CC3E\n"
+ "\t.4byte _0804CD10\n"
+ "\t.4byte _0804CDE0\n"
+ "\t.4byte _0804CE20\n"
+ "\t.4byte _0804CE3A\n"
+ "\t.4byte _0804CE48\n"
+ "\t.4byte _0804CE5C\n"
+ "\t.4byte _0804CE7C\n"
+ "\t.4byte _0804CE9C\n"
+ "\t.4byte _0804CEB0\n"
+ "\t.4byte _0804CED0\n"
+ "_0804C7B0:\n"
+ "\tldr r4, _0804C7E8 @ =gUnknown_2031DA8\n"
+ "\tldr r0, _0804C7EC @ =0x000010f0\n"
+ "\tbl AllocZeroed\n"
+ "\tstr r0, [r4]\n"
+ "\tbl sub_804C600\n"
+ "\tldr r4, _0804C7F0 @ =gUnknown_2031C90\n"
+ "\tmovs r0, 0xE0\n"
+ "\tlsls r0, 4\n"
+ "\tbl AllocZeroed\n"
+ "\tstr r0, [r4]\n"
+ "\tmovs r6, 0\n"
+ "\tldr r2, _0804C7F4 @ =gUnknown_2031C94\n"
+ "_0804C7CE:\n"
+ "\tlsls r1, r6, 8\n"
+ "\tldr r0, [r4]\n"
+ "\tadds r0, r1\n"
+ "\tstm r2!, {r0}\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0xD\n"
+ "\tble _0804C7CE\n"
+ "\tldr r1, _0804C7F8 @ =gMain\n"
+ "\tmovs r3, 0x87\n"
+ "\tlsls r3, 3\n"
+ "\tadds r1, r3\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804C7E8: .4byte gUnknown_2031DA8\n"
+ "_0804C7EC: .4byte 0x000010f0\n"
+ "_0804C7F0: .4byte gUnknown_2031C90\n"
+ "_0804C7F4: .4byte gUnknown_2031C94\n"
+ "_0804C7F8: .4byte gMain\n"
+ "_0804C7FC:\n"
+ "\tldr r2, _0804C864 @ =gPaletteFade\n"
+ "\tldrb r1, [r2, 0x8]\n"
+ "\tmovs r0, 0x7F\n"
+ "\tands r0, r1\n"
+ "\tstrb r0, [r2, 0x8]\n"
+ "\tmovs r6, 0\n"
+ "\tmovs r4, 0\n"
+ "_0804C80A:\n"
+ "\tmovs r0, 0x64\n"
+ "\tmuls r0, r6\n"
+ "\tldr r1, _0804C868 @ =gEnemyParty\n"
+ "\tadds r0, r1\n"
+ "\tstr r4, [sp]\n"
+ "\tstr r4, [sp, 0x4]\n"
+ "\tstr r4, [sp, 0x8]\n"
+ "\tstr r4, [sp, 0xC]\n"
+ "\tmovs r1, 0\n"
+ "\tmovs r2, 0\n"
+ "\tmovs r3, 0x20\n"
+ "\tbl CreateMon\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0x5\n"
+ "\tble _0804C80A\n"
+ "\tmovs r0, 0\n"
+ "\tbl sub_804F5BC\n"
+ "\tmovs r0, 0\n"
+ "\tbl ShowBg\n"
+ "\tldr r0, _0804C86C @ =gReceivedRemoteLinkPlayers\n"
+ "\tldrb r2, [r0]\n"
+ "\tcmp r2, 0\n"
+ "\tbne _0804C8B4\n"
+ "\tldr r1, _0804C870 @ =gLinkType\n"
+ "\tldr r5, _0804C874 @ =0x00001122\n"
+ "\tadds r0, r5, 0\n"
+ "\tstrh r0, [r1]\n"
+ "\tldr r0, _0804C878 @ =gUnknown_2031DA8\n"
+ "\tldr r0, [r0]\n"
+ "\tadds r0, 0xA8\n"
+ "\tstrb r2, [r0]\n"
+ "\tldr r0, _0804C87C @ =gWirelessCommType\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0804C880\n"
+ "\tbl sub_800B1F4\n"
+ "\tbl OpenLink\n"
+ "\tbl sub_80FBB20\n"
+ "\tb _0804C892\n"
+ "\t.align 2, 0\n"
+ "_0804C864: .4byte gPaletteFade\n"
+ "_0804C868: .4byte gEnemyParty\n"
+ "_0804C86C: .4byte gReceivedRemoteLinkPlayers\n"
+ "_0804C870: .4byte gLinkType\n"
+ "_0804C874: .4byte 0x00001122\n"
+ "_0804C878: .4byte gUnknown_2031DA8\n"
+ "_0804C87C: .4byte gWirelessCommType\n"
+ "_0804C880:\n"
+ "\tbl OpenLink\n"
+ "\tldr r1, _0804C8A8 @ =gMain\n"
+ "\tmovs r7, 0x87\n"
+ "\tlsls r7, 3\n"
+ "\tadds r1, r7\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "_0804C892:\n"
+ "\tldr r0, _0804C8AC @ =gWirelessCommType\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0804C89C\n"
+ "\tb _0804CEE6\n"
+ "_0804C89C:\n"
+ "\tldr r0, _0804C8B0 @ =sub_8081A90\n"
+ "\tmovs r1, 0x1\n"
+ "\tbl CreateTask\n"
+ "\tb _0804CEE6\n"
+ "\t.align 2, 0\n"
+ "_0804C8A8: .4byte gMain\n"
+ "_0804C8AC: .4byte gWirelessCommType\n"
+ "_0804C8B0: .4byte sub_8081A90\n"
+ "_0804C8B4:\n"
+ "\tldr r0, _0804C8C4 @ =gMain\n"
+ "\tmovs r1, 0x87\n"
+ "\tlsls r1, 3\n"
+ "\tadds r0, r1\n"
+ "\tmovs r1, 0x4\n"
+ "\tstrb r1, [r0]\n"
+ "\tb _0804CEE6\n"
+ "\t.align 2, 0\n"
+ "_0804C8C4: .4byte gMain\n"
+ "_0804C8C8:\n"
+ "\tldr r2, _0804C8F0 @ =gUnknown_2031DA8\n"
+ "\tldr r1, [r2]\n"
+ "\tadds r1, 0xA8\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "\tldr r0, [r2]\n"
+ "\tadds r1, r0, 0\n"
+ "\tadds r1, 0xA8\n"
+ "\tldrb r0, [r1]\n"
+ "\tcmp r0, 0xB\n"
+ "\tbhi _0804C8E2\n"
+ "\tb _0804CEE6\n"
+ "_0804C8E2:\n"
+ "\tmovs r0, 0\n"
+ "\tstrb r0, [r1]\n"
+ "\tmovs r2, 0x87\n"
+ "\tlsls r2, 3\n"
+ "\tadds r1, r3, r2\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804C8F0: .4byte gUnknown_2031DA8\n"
+ "_0804C8F4:\n"
+ "\tbl GetLinkPlayerCount_2\n"
+ "\tadds r4, r0, 0\n"
+ "\tbl GetSavedPlayerCount\n"
+ "\tlsls r4, 24\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r4, r0\n"
+ "\tbcs _0804C908\n"
+ "\tb _0804CEE6\n"
+ "_0804C908:\n"
+ "\tbl IsLinkMaster\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0804C940\n"
+ "\tldr r0, _0804C938 @ =gUnknown_2031DA8\n"
+ "\tldr r1, [r0]\n"
+ "\tadds r1, 0xA8\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r0, 0x1E\n"
+ "\tbhi _0804C928\n"
+ "\tb _0804CEE6\n"
+ "_0804C928:\n"
+ "\tbl CheckShouldAdvanceLinkState\n"
+ "\tldr r1, _0804C93C @ =gMain\n"
+ "\tmovs r3, 0x87\n"
+ "\tlsls r3, 3\n"
+ "\tadds r1, r3\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804C938: .4byte gUnknown_2031DA8\n"
+ "_0804C93C: .4byte gMain\n"
+ "_0804C940:\n"
+ "\tldr r1, _0804C94C @ =gMain\n"
+ "\tmovs r5, 0x87\n"
+ "\tlsls r5, 3\n"
+ "\tadds r1, r5\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804C94C: .4byte gMain\n"
+ "_0804C950:\n"
+ "\tldr r0, _0804C9A0 @ =gReceivedRemoteLinkPlayers\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x1\n"
+ "\tbeq _0804C95A\n"
+ "\tb _0804CEE6\n"
+ "_0804C95A:\n"
+ "\tbl IsLinkPlayerDataExchangeComplete\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r0, 0x1\n"
+ "\tbeq _0804C968\n"
+ "\tb _0804CEE6\n"
+ "_0804C968:\n"
+ "\tbl sub_80FBB4C\n"
+ "\tbl CalculatePlayerPartyCount\n"
+ "\tldr r1, _0804C9A4 @ =gMain\n"
+ "\tmovs r7, 0x87\n"
+ "\tlsls r7, 3\n"
+ "\tadds r1, r7\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tmovs r2, 0\n"
+ "\tstrb r0, [r1]\n"
+ "\tldr r0, _0804C9A8 @ =gUnknown_2031DA8\n"
+ "\tldr r0, [r0]\n"
+ "\tadds r0, 0xA8\n"
+ "\tstrb r2, [r0]\n"
+ "\tldr r0, _0804C9AC @ =gWirelessCommType\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804C992\n"
+ "\tb _0804CEE6\n"
+ "_0804C992:\n"
+ "\tmovs r0, 0x1\n"
+ "\tbl sub_80FA484\n"
+ "\tbl sub_800AB9C\n"
+ "\tb _0804CEE6\n"
+ "\t.align 2, 0\n"
+ "_0804C9A0: .4byte gReceivedRemoteLinkPlayers\n"
+ "_0804C9A4: .4byte gMain\n"
+ "_0804C9A8: .4byte gUnknown_2031DA8\n"
+ "_0804C9AC: .4byte gWirelessCommType\n"
+ "_0804C9B0:\n"
+ "\tldr r0, _0804C9E0 @ =gWirelessCommType\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0804C9E8\n"
+ "\tbl IsRfuTaskFinished\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804C9C4\n"
+ "\tb _0804CEE6\n"
+ "_0804C9C4:\n"
+ "\tldr r1, _0804C9E4 @ =gMain\n"
+ "\tmovs r0, 0x87\n"
+ "\tlsls r0, 3\n"
+ "\tadds r1, r0\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "\tbl LoadWirelessStatusIndicatorSpriteGfx\n"
+ "\tmovs r0, 0\n"
+ "\tmovs r1, 0\n"
+ "\tbl CreateWirelessStatusIndicatorSprite\n"
+ "\tb _0804CEE6\n"
+ "\t.align 2, 0\n"
+ "_0804C9E0: .4byte gWirelessCommType\n"
+ "_0804C9E4: .4byte gMain\n"
+ "_0804C9E8:\n"
+ "\tmovs r2, 0x87\n"
+ "\tlsls r2, 3\n"
+ "\tadds r1, r3, r2\n"
+ "\tb _0804CEC2\n"
+ "_0804C9F0:\n"
+ "\tbl shedinja_maker_maybe\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804C9FC\n"
+ "\tb _0804CEE6\n"
+ "_0804C9FC:\n"
+ "\tbl sub_804F9D8\n"
+ "\tldr r1, _0804CA0C @ =gMain\n"
+ "\tmovs r3, 0x87\n"
+ "\tlsls r3, 3\n"
+ "\tadds r1, r3\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804CA0C: .4byte gMain\n"
+ "_0804CA10:\n"
+ "\tbl CalculateEnemyPartyCount\n"
+ "\tmovs r0, 0\n"
+ "\tmovs r1, 0\n"
+ "\tbl SetGpuReg\n"
+ "\tmovs r0, 0x50\n"
+ "\tmovs r1, 0\n"
+ "\tbl SetGpuReg\n"
+ "\tldr r2, _0804CB2C @ =gUnknown_2031DA8\n"
+ "\tldr r0, [r2]\n"
+ "\tldr r1, _0804CB30 @ =gPlayerPartyCount\n"
+ "\tldrb r1, [r1]\n"
+ "\tadds r0, 0x36\n"
+ "\tstrb r1, [r0]\n"
+ "\tldr r0, [r2]\n"
+ "\tldr r1, _0804CB34 @ =gEnemyPartyCount\n"
+ "\tldrb r1, [r1]\n"
+ "\tadds r0, 0x37\n"
+ "\tstrb r1, [r0]\n"
+ "\tmovs r6, 0\n"
+ "\tldr r0, [r2]\n"
+ "\tadds r0, 0x36\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r6, r0\n"
+ "\tbge _0804CAA8\n"
+ "\tmov r8, r2\n"
+ "\tldr r7, _0804CB38 @ =gTradeMonSpriteCoords\n"
+ "_0804CA4A:\n"
+ "\tmovs r0, 0x64\n"
+ "\tadds r4, r6, 0\n"
+ "\tmuls r4, r0\n"
+ "\tldr r0, _0804CB3C @ =gPlayerParty\n"
+ "\tadds r4, r0\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0x41\n"
+ "\tbl GetMonData\n"
+ "\tadds r5, r0, 0\n"
+ "\tlsls r5, 16\n"
+ "\tlsrs r5, 16\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0\n"
+ "\tbl GetMonData\n"
+ "\tldrb r2, [r7]\n"
+ "\tlsls r2, 19\n"
+ "\tmovs r1, 0xE0\n"
+ "\tlsls r1, 12\n"
+ "\tadds r2, r1\n"
+ "\tasrs r2, 16\n"
+ "\tldrb r3, [r7, 0x1]\n"
+ "\tlsls r3, 19\n"
+ "\tldr r1, _0804CB40 @ =0xfff40000\n"
+ "\tadds r3, r1\n"
+ "\tasrs r3, 16\n"
+ "\tmovs r1, 0x1\n"
+ "\tstr r1, [sp]\n"
+ "\tstr r0, [sp, 0x4]\n"
+ "\tstr r1, [sp, 0x8]\n"
+ "\tadds r0, r5, 0\n"
+ "\tldr r1, _0804CB44 @ =sub_809718C\n"
+ "\tbl CreateMonIcon\n"
+ "\tmov r2, r8\n"
+ "\tldr r1, [r2]\n"
+ "\tadds r1, 0x28\n"
+ "\tadds r1, r6\n"
+ "\tstrb r0, [r1]\n"
+ "\tadds r7, 0x2\n"
+ "\tadds r6, 0x1\n"
+ "\tldr r0, [r2]\n"
+ "\tadds r0, 0x36\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r6, r0\n"
+ "\tblt _0804CA4A\n"
+ "_0804CAA8:\n"
+ "\tmovs r6, 0\n"
+ "\tldr r1, _0804CB2C @ =gUnknown_2031DA8\n"
+ "\tldr r0, [r1]\n"
+ "\tadds r0, 0x37\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r6, r0\n"
+ "\tbge _0804CB20\n"
+ "\tldr r0, _0804CB38 @ =gTradeMonSpriteCoords\n"
+ "\tmov r8, r1\n"
+ "\tadds r7, r0, 0\n"
+ "\tadds r7, 0xC\n"
+ "_0804CABE:\n"
+ "\tmovs r0, 0x64\n"
+ "\tadds r4, r6, 0\n"
+ "\tmuls r4, r0\n"
+ "\tldr r0, _0804CB48 @ =gEnemyParty\n"
+ "\tadds r4, r0\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0x41\n"
+ "\tmovs r2, 0\n"
+ "\tbl GetMonData\n"
+ "\tadds r5, r0, 0\n"
+ "\tlsls r5, 16\n"
+ "\tlsrs r5, 16\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0\n"
+ "\tbl GetMonData\n"
+ "\tldrb r2, [r7]\n"
+ "\tlsls r2, 19\n"
+ "\tmovs r3, 0xE0\n"
+ "\tlsls r3, 12\n"
+ "\tadds r2, r3\n"
+ "\tasrs r2, 16\n"
+ "\tldrb r3, [r7, 0x1]\n"
+ "\tlsls r3, 19\n"
+ "\tldr r1, _0804CB40 @ =0xfff40000\n"
+ "\tadds r3, r1\n"
+ "\tasrs r3, 16\n"
+ "\tmovs r1, 0x1\n"
+ "\tstr r1, [sp]\n"
+ "\tstr r0, [sp, 0x4]\n"
+ "\tmovs r0, 0\n"
+ "\tstr r0, [sp, 0x8]\n"
+ "\tadds r0, r5, 0\n"
+ "\tldr r1, _0804CB44 @ =sub_809718C\n"
+ "\tbl CreateMonIcon\n"
+ "\tmov r2, r8\n"
+ "\tldr r1, [r2]\n"
+ "\tadds r1, 0x2E\n"
+ "\tadds r1, r6\n"
+ "\tstrb r0, [r1]\n"
+ "\tadds r7, 0x2\n"
+ "\tadds r6, 0x1\n"
+ "\tldr r0, [r2]\n"
+ "\tadds r0, 0x37\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r6, r0\n"
+ "\tblt _0804CABE\n"
+ "_0804CB20:\n"
+ "\tldr r1, _0804CB4C @ =gMain\n"
+ "\tmovs r3, 0x87\n"
+ "\tlsls r3, 3\n"
+ "\tadds r1, r3\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804CB2C: .4byte gUnknown_2031DA8\n"
+ "_0804CB30: .4byte gPlayerPartyCount\n"
+ "_0804CB34: .4byte gEnemyPartyCount\n"
+ "_0804CB38: .4byte gTradeMonSpriteCoords\n"
+ "_0804CB3C: .4byte gPlayerParty\n"
+ "_0804CB40: .4byte 0xfff40000\n"
+ "_0804CB44: .4byte sub_809718C\n"
+ "_0804CB48: .4byte gEnemyParty\n"
+ "_0804CB4C: .4byte gMain\n"
+ "_0804CB50:\n"
+ "\tbl LoadHeldItemIcons\n"
+ "\tldr r0, _0804CB70 @ =gUnknown_2031DA8\n"
+ "\tldr r1, [r0]\n"
+ "\tadds r0, r1, 0\n"
+ "\tadds r0, 0x36\n"
+ "\tadds r1, 0x28\n"
+ "\tmovs r2, 0\n"
+ "\tbl sub_812256C\n"
+ "\tldr r1, _0804CB74 @ =gMain\n"
+ "\tmovs r5, 0x87\n"
+ "\tlsls r5, 3\n"
+ "\tadds r1, r5\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804CB70: .4byte gUnknown_2031DA8\n"
+ "_0804CB74: .4byte gMain\n"
+ "_0804CB78:\n"
+ "\tldr r0, _0804CB94 @ =gUnknown_2031DA8\n"
+ "\tldr r1, [r0]\n"
+ "\tadds r0, r1, 0\n"
+ "\tadds r0, 0x36\n"
+ "\tadds r1, 0x28\n"
+ "\tmovs r2, 0x1\n"
+ "\tbl sub_812256C\n"
+ "\tldr r1, _0804CB98 @ =gMain\n"
+ "\tmovs r7, 0x87\n"
+ "\tlsls r7, 3\n"
+ "\tadds r1, r7\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804CB94: .4byte gUnknown_2031DA8\n"
+ "_0804CB98: .4byte gMain\n"
+ "_0804CB9C:\n"
+ "\tldr r0, _0804CC14 @ =gSaveBlock2Ptr\n"
+ "\tldr r0, [r0]\n"
+ "\tldr r6, _0804CC18 @ =gUnknown_2031C94\n"
+ "\tldr r1, [r6]\n"
+ "\tldr r5, _0804CC1C @ =gDecompressionBuffer\n"
+ "\tstr r5, [sp]\n"
+ "\tmovs r4, 0x3\n"
+ "\tstr r4, [sp, 0x4]\n"
+ "\tmovs r2, 0\n"
+ "\tmovs r3, 0\n"
+ "\tbl sub_808BEB4\n"
+ "\tbl GetMultiplayerId\n"
+ "\tlsls r0, 24\n"
+ "\tmovs r1, 0x80\n"
+ "\tlsls r1, 17\n"
+ "\teors r1, r0\n"
+ "\tlsrs r1, 24\n"
+ "\tlsls r0, r1, 3\n"
+ "\tsubs r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tldr r1, _0804CC20 @ =gLinkPlayers + 8\n"
+ "\tadds r0, r1\n"
+ "\tldr r1, [r6, 0xC]\n"
+ "\tstr r5, [sp]\n"
+ "\tstr r4, [sp, 0x4]\n"
+ "\tmovs r2, 0\n"
+ "\tmovs r3, 0\n"
+ "\tbl sub_808BEB4\n"
+ "\tldr r4, _0804CC24 @ =gUnknown_8261ECC\n"
+ "\tldr r0, [r4]\n"
+ "\tldr r1, [r6, 0x18]\n"
+ "\tstr r5, [sp]\n"
+ "\tmovs r2, 0x2\n"
+ "\tstr r2, [sp, 0x4]\n"
+ "\tmovs r2, 0\n"
+ "\tmovs r3, 0\n"
+ "\tbl sub_808BEB4\n"
+ "\tldr r0, [r4, 0x4]\n"
+ "\tldr r1, [r6, 0x20]\n"
+ "\tmovs r2, 0x18\n"
+ "\tbl sub_804F728\n"
+ "\tldr r1, _0804CC28 @ =gMain\n"
+ "\tmovs r0, 0x87\n"
+ "\tlsls r0, 3\n"
+ "\tadds r1, r0\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tmovs r2, 0\n"
+ "\tstrb r0, [r1]\n"
+ "\tldr r0, _0804CC2C @ =gUnknown_2031DA8\n"
+ "\tldr r0, [r0]\n"
+ "\tadds r0, 0xA8\n"
+ "\tstrb r2, [r0]\n"
+ "\tb _0804CEE6\n"
+ "\t.align 2, 0\n"
+ "_0804CC14: .4byte gSaveBlock2Ptr\n"
+ "_0804CC18: .4byte gUnknown_2031C94\n"
+ "_0804CC1C: .4byte gDecompressionBuffer\n"
+ "_0804CC20: .4byte gLinkPlayers + 8\n"
+ "_0804CC24: .4byte gUnknown_8261ECC\n"
+ "_0804CC28: .4byte gMain\n"
+ "_0804CC2C: .4byte gUnknown_2031DA8\n"
+ "_0804CC30:\n"
+ "\tbl sub_804F610\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804CC3C\n"
+ "\tb _0804CEE6\n"
+ "_0804CC3C:\n"
+ "\tb _0804CEBA\n"
+ "_0804CC3E:\n"
+ "\tldr r0, _0804CCFC @ =gSaveBlock2Ptr\n"
+ "\tldr r1, [r0]\n"
+ "\tmovs r0, 0x1\n"
+ "\tmovs r2, 0\n"
+ "\tbl GetStringWidth\n"
+ "\tadds r1, r0, 0\n"
+ "\tmovs r0, 0x38\n"
+ "\tsubs r0, r1\n"
+ "\tlsrs r1, r0, 31\n"
+ "\tadds r0, r1\n"
+ "\tmovs r6, 0\n"
+ "\tadd r5, sp, 0x10\n"
+ "\tldr r3, _0804CD00 @ =gTradeUnknownSpriteCoords\n"
+ "\tmov r8, r3\n"
+ "\tasrs r0, 1\n"
+ "\tldrb r7, [r3, 0x4]\n"
+ "\tadds r4, r0, r7\n"
+ "_0804CC62:\n"
+ "\tadd r1, sp, 0x10\n"
+ "\tldr r0, _0804CD04 @ =gUnknown_8261CC8\n"
+ "\tldm r0!, {r2,r3,r7}\n"
+ "\tstm r1!, {r2,r3,r7}\n"
+ "\tldm r0!, {r2,r3,r7}\n"
+ "\tstm r1!, {r2,r3,r7}\n"
+ "\tldrh r0, [r5]\n"
+ "\tadds r0, r6\n"
+ "\tstrh r0, [r5]\n"
+ "\tlsls r1, r4, 16\n"
+ "\tasrs r1, 16\n"
+ "\tadd r0, sp, 0x10\n"
+ "\tmov r3, r8\n"
+ "\tldrb r2, [r3, 0x5]\n"
+ "\tmovs r3, 0x1\n"
+ "\tbl CreateSprite\n"
+ "\tadds r4, 0x20\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0x2\n"
+ "\tble _0804CC62\n"
+ "\tbl GetMultiplayerId\n"
+ "\tlsls r0, 24\n"
+ "\tmovs r1, 0x80\n"
+ "\tlsls r1, 17\n"
+ "\teors r1, r0\n"
+ "\tlsrs r1, 24\n"
+ "\tlsls r0, r1, 3\n"
+ "\tsubs r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tldr r1, _0804CD08 @ =gLinkPlayers + 8\n"
+ "\tadds r1, r0, r1\n"
+ "\tmovs r0, 0x1\n"
+ "\tmovs r2, 0\n"
+ "\tbl GetStringWidth\n"
+ "\tadds r1, r0, 0\n"
+ "\tmovs r0, 0x38\n"
+ "\tsubs r0, r1\n"
+ "\tlsrs r1, r0, 31\n"
+ "\tadds r0, r1\n"
+ "\tmovs r6, 0\n"
+ "\tadd r5, sp, 0x10\n"
+ "\tldr r7, _0804CD00 @ =gTradeUnknownSpriteCoords\n"
+ "\tmov r8, r7\n"
+ "\tasrs r0, 1\n"
+ "\tmov r1, r8\n"
+ "\tldrb r1, [r1, 0x6]\n"
+ "\tadds r4, r0, r1\n"
+ "_0804CCC6:\n"
+ "\tadd r1, sp, 0x10\n"
+ "\tldr r0, _0804CD04 @ =gUnknown_8261CC8\n"
+ "\tldm r0!, {r2,r3,r7}\n"
+ "\tstm r1!, {r2,r3,r7}\n"
+ "\tldm r0!, {r2,r3,r7}\n"
+ "\tstm r1!, {r2,r3,r7}\n"
+ "\tadds r0, r6, 0x3\n"
+ "\tldrh r1, [r5]\n"
+ "\tadds r0, r1\n"
+ "\tstrh r0, [r5]\n"
+ "\tlsls r1, r4, 16\n"
+ "\tasrs r1, 16\n"
+ "\tadd r0, sp, 0x10\n"
+ "\tmov r3, r8\n"
+ "\tldrb r2, [r3, 0x7]\n"
+ "\tmovs r3, 0x1\n"
+ "\tbl CreateSprite\n"
+ "\tadds r4, 0x20\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0x2\n"
+ "\tble _0804CCC6\n"
+ "\tldr r1, _0804CD0C @ =gMain\n"
+ "\tmovs r5, 0x87\n"
+ "\tlsls r5, 3\n"
+ "\tadds r1, r5\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804CCFC: .4byte gSaveBlock2Ptr\n"
+ "_0804CD00: .4byte gTradeUnknownSpriteCoords\n"
+ "_0804CD04: .4byte gUnknown_8261CC8\n"
+ "_0804CD08: .4byte gLinkPlayers + 8\n"
+ "_0804CD0C: .4byte gMain\n"
+ "_0804CD10:\n"
+ "\tldr r4, _0804CDCC @ =gUnknown_8261CC8\n"
+ "\tadd r1, sp, 0x10\n"
+ "\tadds r0, r4, 0\n"
+ "\tldm r0!, {r2,r3,r7}\n"
+ "\tstm r1!, {r2,r3,r7}\n"
+ "\tldm r0!, {r2,r5,r7}\n"
+ "\tstm r1!, {r2,r5,r7}\n"
+ "\tadd r1, sp, 0x10\n"
+ "\tadds r0, r1, 0\n"
+ "\tldrh r0, [r0]\n"
+ "\tadds r0, 0x6\n"
+ "\tstrh r0, [r1]\n"
+ "\tadds r0, r1, 0\n"
+ "\tmovs r1, 0xD7\n"
+ "\tmovs r2, 0x97\n"
+ "\tmovs r3, 0x1\n"
+ "\tbl CreateSprite\n"
+ "\tadd r0, sp, 0x10\n"
+ "\tldm r4!, {r3,r5,r7}\n"
+ "\tstm r0!, {r3,r5,r7}\n"
+ "\tldm r4!, {r1-r3}\n"
+ "\tstm r0!, {r1-r3}\n"
+ "\tadd r1, sp, 0x10\n"
+ "\tadds r0, r1, 0\n"
+ "\tldrh r0, [r0]\n"
+ "\tadds r0, 0x7\n"
+ "\tstrh r0, [r1]\n"
+ "\tadds r0, r1, 0\n"
+ "\tmovs r1, 0xF7\n"
+ "\tmovs r2, 0x97\n"
+ "\tmovs r3, 0x1\n"
+ "\tbl CreateSprite\n"
+ "\tmovs r6, 0\n"
+ "\tadd r4, sp, 0x10\n"
+ "\tmovs r5, 0xC0\n"
+ "\tlsls r5, 13\n"
+ "_0804CD5C:\n"
+ "\tadd r1, sp, 0x10\n"
+ "\tldr r0, _0804CDCC @ =gUnknown_8261CC8\n"
+ "\tldm r0!, {r2,r3,r7}\n"
+ "\tstm r1!, {r2,r3,r7}\n"
+ "\tldm r0!, {r2,r3,r7}\n"
+ "\tstm r1!, {r2,r3,r7}\n"
+ "\tadds r0, r6, 0\n"
+ "\tadds r0, 0x8\n"
+ "\tldrh r7, [r4]\n"
+ "\tadds r0, r7\n"
+ "\tstrh r0, [r4]\n"
+ "\tasrs r1, r5, 16\n"
+ "\tadd r0, sp, 0x10\n"
+ "\tmovs r2, 0x96\n"
+ "\tmovs r3, 0x1\n"
+ "\tbl CreateSprite\n"
+ "\tmovs r0, 0x80\n"
+ "\tlsls r0, 14\n"
+ "\tadds r5, r0\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0x5\n"
+ "\tble _0804CD5C\n"
+ "\tldr r0, _0804CDD0 @ =gUnknown_8261CB0\n"
+ "\tldr r2, _0804CDD4 @ =gTradeMonSpriteCoords\n"
+ "\tldrb r1, [r2]\n"
+ "\tlsls r1, 19\n"
+ "\tmovs r3, 0x80\n"
+ "\tlsls r3, 14\n"
+ "\tadds r1, r3\n"
+ "\tasrs r1, 16\n"
+ "\tldrb r2, [r2, 0x1]\n"
+ "\tlsls r2, 3\n"
+ "\tmovs r3, 0x2\n"
+ "\tbl CreateSprite\n"
+ "\tldr r2, _0804CDD8 @ =gUnknown_2031DA8\n"
+ "\tldr r1, [r2]\n"
+ "\tadds r1, 0x34\n"
+ "\tmovs r3, 0\n"
+ "\tstrb r0, [r1]\n"
+ "\tldr r0, [r2]\n"
+ "\tadds r0, 0x35\n"
+ "\tstrb r3, [r0]\n"
+ "\tldr r1, _0804CDDC @ =gMain\n"
+ "\tmovs r5, 0x87\n"
+ "\tlsls r5, 3\n"
+ "\tadds r1, r5\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "\tmovs r0, 0\n"
+ "\tbl rbox_fill_rectangle\n"
+ "\tb _0804CEE6\n"
+ "\t.align 2, 0\n"
+ "_0804CDCC: .4byte gUnknown_8261CC8\n"
+ "_0804CDD0: .4byte gUnknown_8261CB0\n"
+ "_0804CDD4: .4byte gTradeMonSpriteCoords\n"
+ "_0804CDD8: .4byte gUnknown_2031DA8\n"
+ "_0804CDDC: .4byte gMain\n"
+ "_0804CDE0:\n"
+ "\tmovs r0, 0\n"
+ "\tbl sub_804F748\n"
+ "\tmovs r0, 0\n"
+ "\tbl sub_804F020\n"
+ "\tldr r2, _0804CE14 @ =gUnknown_2031DA8\n"
+ "\tldr r0, [r2]\n"
+ "\tmovs r1, 0\n"
+ "\tstrb r1, [r0]\n"
+ "\tldr r0, [r2]\n"
+ "\tstrb r1, [r0, 0x1]\n"
+ "\tbl sub_804D764\n"
+ "\tldr r1, _0804CE18 @ =gMain\n"
+ "\tmovs r7, 0x87\n"
+ "\tlsls r7, 3\n"
+ "\tadds r1, r7\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "\tldr r0, _0804CE1C @ =0x00000111\n"
+ "\tbl PlayBGM\n"
+ "\tb _0804CEE6\n"
+ "\t.align 2, 0\n"
+ "_0804CE14: .4byte gUnknown_2031DA8\n"
+ "_0804CE18: .4byte gMain\n"
+ "_0804CE1C: .4byte 0x00000111\n"
+ "_0804CE20:\n"
+ "\tmovs r0, 0x1\n"
+ "\tbl sub_804F748\n"
+ "\tmovs r0, 0x1\n"
+ "\tbl sub_804F020\n"
+ "\tldr r1, _0804CE44 @ =gMain\n"
+ "\tmovs r0, 0x87\n"
+ "\tlsls r0, 3\n"
+ "\tadds r1, r0\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "_0804CE3A:\n"
+ "\tmovs r0, 0\n"
+ "\tbl sub_804D694\n"
+ "\tb _0804CEBA\n"
+ "\t.align 2, 0\n"
+ "_0804CE44: .4byte gMain\n"
+ "_0804CE48:\n"
+ "\tmovs r0, 0x1\n"
+ "\tbl sub_804D694\n"
+ "\tldr r1, _0804CE58 @ =gMain\n"
+ "\tmovs r3, 0x87\n"
+ "\tlsls r3, 3\n"
+ "\tadds r1, r3\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804CE58: .4byte gMain\n"
+ "_0804CE5C:\n"
+ "\tmovs r0, 0x1\n"
+ "\tnegs r0, r0\n"
+ "\tmovs r1, 0\n"
+ "\tstr r1, [sp]\n"
+ "\tmovs r2, 0x10\n"
+ "\tmovs r3, 0\n"
+ "\tbl BeginNormalPaletteFade\n"
+ "\tldr r1, _0804CE78 @ =gMain\n"
+ "\tmovs r5, 0x87\n"
+ "\tlsls r5, 3\n"
+ "\tadds r1, r5\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804CE78: .4byte gMain\n"
+ "_0804CE7C:\n"
+ "\tmovs r1, 0x82\n"
+ "\tlsls r1, 5\n"
+ "\tmovs r0, 0\n"
+ "\tbl SetGpuReg\n"
+ "\tmovs r0, 0x2\n"
+ "\tbl sub_804D694\n"
+ "\tldr r1, _0804CE98 @ =gMain\n"
+ "\tmovs r7, 0x87\n"
+ "\tlsls r7, 3\n"
+ "\tadds r1, r7\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804CE98: .4byte gMain\n"
+ "_0804CE9C:\n"
+ "\tmovs r0, 0\n"
+ "\tbl sub_804F890\n"
+ "\tldr r1, _0804CEAC @ =gMain\n"
+ "\tmovs r0, 0x87\n"
+ "\tlsls r0, 3\n"
+ "\tadds r1, r0\n"
+ "\tb _0804CEC2\n"
+ "\t.align 2, 0\n"
+ "_0804CEAC: .4byte gMain\n"
+ "_0804CEB0:\n"
+ "\tmovs r0, 0x1\n"
+ "\tbl sub_804F890\n"
+ "\tbl sub_804F964\n"
+ "_0804CEBA:\n"
+ "\tldr r1, _0804CECC @ =gMain\n"
+ "\tmovs r2, 0x87\n"
+ "\tlsls r2, 3\n"
+ "\tadds r1, r2\n"
+ "_0804CEC2:\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "\tb _0804CEE6\n"
+ "\t.align 2, 0\n"
+ "_0804CECC: .4byte gMain\n"
+ "_0804CED0:\n"
+ "\tldr r0, _0804CF08 @ =gPaletteFade\n"
+ "\tldrb r1, [r0, 0x7]\n"
+ "\tmovs r0, 0x80\n"
+ "\tands r0, r1\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804CEE6\n"
+ "\tldr r0, _0804CF0C @ =sub_804DFF0\n"
+ "\tstr r0, [r3]\n"
+ "\tldr r0, _0804CF10 @ =sub_804D638\n"
+ "\tbl SetMainCallback2\n"
+ "_0804CEE6:\n"
+ "\tbl RunTextPrinters\n"
+ "\tbl RunTasks\n"
+ "\tbl AnimateSprites\n"
+ "\tbl BuildOamBuffer\n"
+ "\tbl UpdatePaletteFade\n"
+ "\tadd sp, 0x28\n"
+ "\tpop {r3}\n"
+ "\tmov r8, r3\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.align 2, 0\n"
+ "_0804CF08: .4byte gPaletteFade\n"
+ "_0804CF0C: .4byte sub_804DFF0\n"
+ "_0804CF10: .4byte sub_804D638");
+}
+#endif //NONMATCHING
diff --git a/src/trainer_tower.c b/src/trainer_tower.c
index 17f6b9e09..9512e73d1 100644
--- a/src/trainer_tower.c
+++ b/src/trainer_tower.c
@@ -1278,7 +1278,7 @@ void sub_815E720(void)
sub_815EC0C();
windowId = AddWindow(gUnknown_847A218);
- sub_80F6E9C();
+ LoadStdWindowFrameGfx();
DrawStdWindowFrame(windowId, FALSE);
AddTextPrinterParameterized(windowId, 2, gUnknown_83FE982, 0x4A, 0, 0xFF, NULL);