summaryrefslogtreecommitdiff
path: root/src/battle/anim
diff options
context:
space:
mode:
Diffstat (limited to 'src/battle/anim')
-rw-r--r--[-rwxr-xr-x]src/battle/anim/alert.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/angel.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/angel_kiss.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/anger.c0
-rw-r--r--src/battle/anim/battle_intro.c499
-rw-r--r--[-rwxr-xr-x]src/battle/anim/blow_kiss.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/bottle.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/brace.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/breath.c0
-rw-r--r--src/battle/anim/bug.c302
-rw-r--r--[-rwxr-xr-x]src/battle/anim/bullet.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/copy_orb.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/cube.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/curtain.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/cutter.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/cyclone.c0
-rw-r--r--src/battle/anim/dark.c1008
-rw-r--r--src/battle/anim/dragon.c275
-rw-r--r--[-rwxr-xr-x]src/battle/anim/draw.c36
-rw-r--r--[-rwxr-xr-x]src/battle/anim/drum.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/egg.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/espeed.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/evasion.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/fang.c0
-rw-r--r--src/battle/anim/fire_2.c4
-rw-r--r--[-rwxr-xr-x]src/battle/anim/flash.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/flying_hearts.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/flying_path.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/flying_petals.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/glitter.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/glow.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/grip.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/grow.c0
-rw-r--r--src/battle/anim/guard.c3
-rw-r--r--[-rwxr-xr-x]src/battle/anim/guillotine.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/heal.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/heart_1.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/homing.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/hop.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/hop_2.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/kiss_fountain.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/leaf.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/love_bg.c23
-rw-r--r--[-rwxr-xr-x]src/battle/anim/lunge_1.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/lunge_2.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/money.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/moon.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/note_rain.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/note_scatter.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/note_scatter_2.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/note_wave.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/orbit.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/orbit_fast.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/orbit_scatter.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/orbs.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/osmose.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/perceive.c0
-rw-r--r--src/battle/anim/poison.c140
-rw-r--r--[-rwxr-xr-x]src/battle/anim/powder.c0
-rw-r--r--src/battle/anim/psychic.c900
-rw-r--r--[-rwxr-xr-x]src/battle/anim/ring.c0
-rw-r--r--src/battle/anim/rock.c602
-rw-r--r--[-rwxr-xr-x]src/battle/anim/roots.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/scan.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/scary_face.c21
-rw-r--r--[-rwxr-xr-x]src/battle/anim/seed.c0
-rw-r--r--src/battle/anim/sfx.c280
-rw-r--r--[-rwxr-xr-x]src/battle/anim/shadow_enlarge.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/shadow_minimize.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/shield.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/shimmer.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/silhouette.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/slash.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/sleep.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/slice.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/smoke.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/sonic.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/sonic_task.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/spin_finger.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/spit.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/splash.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/startle.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/strike.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/switch.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/sword.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/taunt_finger.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/tendrils.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/thought.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/thrashing.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/tile_in.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/tile_out.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/twinkle.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/unused_1.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/unused_2.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/unused_3.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/unused_4.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/unused_5.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/unused_6.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/unused_7.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/unused_8.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/unused_9.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/wave_finger.c0
-rw-r--r--[-rwxr-xr-x]src/battle/anim/whip.c0
-rw-r--r--src/battle/anim/wisp_fire.c196
-rw-r--r--[-rwxr-xr-x]src/battle/anim/withdraw.c0
105 files changed, 4232 insertions, 57 deletions
diff --git a/src/battle/anim/alert.c b/src/battle/anim/alert.c
index 7cd42c17b..7cd42c17b 100755..100644
--- a/src/battle/anim/alert.c
+++ b/src/battle/anim/alert.c
diff --git a/src/battle/anim/angel.c b/src/battle/anim/angel.c
index 5ec083887..5ec083887 100755..100644
--- a/src/battle/anim/angel.c
+++ b/src/battle/anim/angel.c
diff --git a/src/battle/anim/angel_kiss.c b/src/battle/anim/angel_kiss.c
index d5be6e2af..d5be6e2af 100755..100644
--- a/src/battle/anim/angel_kiss.c
+++ b/src/battle/anim/angel_kiss.c
diff --git a/src/battle/anim/anger.c b/src/battle/anim/anger.c
index 011aa68ce..011aa68ce 100755..100644
--- a/src/battle/anim/anger.c
+++ b/src/battle/anim/anger.c
diff --git a/src/battle/anim/battle_intro.c b/src/battle/anim/battle_intro.c
new file mode 100644
index 000000000..01f823fa7
--- /dev/null
+++ b/src/battle/anim/battle_intro.c
@@ -0,0 +1,499 @@
+#include "global.h"
+#include "constants/battle_constants.h"
+#include "battle.h"
+#include "battle_anim.h"
+#include "battle_anim_80CA710.h"
+#include "data2.h"
+#include "ewram.h"
+#include "main.h"
+#include "rom_8077ABC.h"
+#include "scanline_effect.h"
+#include "task.h"
+#include "trig.h"
+
+extern u16 gBattleTypeFlags;
+extern u16 gBattle_BG1_X;
+extern u16 gBattle_BG1_Y;
+extern u16 gBattle_BG2_X;
+extern u16 gBattle_BG2_Y;
+extern u16 gBattle_WIN0V;
+extern u16 gUnknown_02024DE8;
+extern u8 gBattleMonForms[];
+
+extern void sub_800FE20(struct Sprite *);
+
+static void BattleIntroTask_ScrollScenery(u8);
+static void BattleIntroTask_FadeScenery(u8);
+static void BattleIntroTask_ScrollAndFadeScenery(u8);
+static void BattleIntroTask_80E4C34(u8);
+
+static const TaskFunc sBattleIntroTaskFuncs[] =
+{
+ BattleIntroTask_ScrollScenery,
+ BattleIntroTask_ScrollScenery,
+ BattleIntroTask_FadeScenery,
+ BattleIntroTask_FadeScenery,
+ BattleIntroTask_FadeScenery,
+ BattleIntroTask_ScrollScenery,
+ BattleIntroTask_ScrollScenery,
+ BattleIntroTask_ScrollScenery,
+ BattleIntroTask_ScrollAndFadeScenery,
+ BattleIntroTask_ScrollAndFadeScenery,
+};
+
+#define tState data[0]
+#define tBgXOffset data[2]
+#define tFramesUntilBg1Slide data[3]
+
+void StartBattleIntroAnim(u8 a)
+{
+ u8 taskId;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ taskId = CreateTask(BattleIntroTask_80E4C34, 0);
+ }
+ else if ((gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) && gGameVersion != VERSION_RUBY)
+ {
+ a = 3;
+ taskId = CreateTask(BattleIntroTask_FadeScenery, 0);
+ }
+ else
+ {
+ taskId = CreateTask(sBattleIntroTaskFuncs[a], 0);
+ }
+
+ gTasks[taskId].tState = 0;
+ gTasks[taskId].data[1] = a;
+ gTasks[taskId].tBgXOffset = 0;
+ gTasks[taskId].tFramesUntilBg1Slide = 0;
+ gTasks[taskId].data[4] = 0;
+ gTasks[taskId].data[5] = 0;
+ gTasks[taskId].data[6] = 0;
+}
+
+static void EndBattleIntroTask(u8 taskId)
+{
+ DestroyTask(taskId);
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ gBattle_BG2_X = 0;
+ gBattle_BG2_Y = 0;
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ REG_BLDY = 0;
+ REG_WININ = 0x3F3F;
+ REG_WINOUT = 0x3F3F;
+}
+
+static void BattleIntroTask_ScrollScenery(u8 taskId)
+{
+ s32 i;
+
+ gBattle_BG1_X += 6;
+
+ switch (gTasks[taskId].tState)
+ {
+ case 0:
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ gTasks[taskId].tBgXOffset = 16;
+ gTasks[taskId].tState++;
+ }
+ else
+ {
+ gTasks[taskId].tBgXOffset = 1;
+ gTasks[taskId].tState++;
+ }
+ break;
+ case 1:
+ gTasks[taskId].tBgXOffset--;
+ if (gTasks[taskId].tBgXOffset == 0)
+ {
+ gTasks[taskId].tState++;
+ REG_WININ = 0x3F;
+ }
+ break;
+ case 2:
+ // Open up the window
+ gBattle_WIN0V -= WIN_RANGE(1, 0); // decrement min Y
+ gBattle_WIN0V += WIN_RANGE(0, 1); // increment max Y
+ if ((gBattle_WIN0V & 0xFF00) == 0x3000)
+ {
+ gTasks[taskId].tState++;
+ gTasks[taskId].tBgXOffset = DISPLAY_WIDTH;
+ gTasks[taskId].tFramesUntilBg1Slide = 32;
+ gUnknown_02024DE8 &= ~1;
+ }
+ break;
+ case 3:
+ if (gTasks[taskId].tFramesUntilBg1Slide != 0)
+ {
+ gTasks[taskId].tFramesUntilBg1Slide--;
+ }
+ 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) != 0)
+ gBattle_WIN0V -= 1020;
+
+ if (gTasks[taskId].tBgXOffset != 0)
+ gTasks[taskId].tBgXOffset -= 2;
+
+ // Slide in the top half of the BG from the left
+ for (i = 0; i < DISPLAY_HEIGHT / 2; i++)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].tBgXOffset;
+ // Slide in the bottom half of the BG from the right
+ for (; i < DISPLAY_HEIGHT; i++)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = -gTasks[taskId].tBgXOffset;
+
+ if (gTasks[taskId].tBgXOffset == 0)
+ {
+ gScanlineEffect.state = 3;
+ gTasks[taskId].tState++;
+ CpuFill32(0, (void *)(VRAM + 0xE000), 0x800);
+ REG_BG1CNT = 0x9C00;
+ REG_BG2CNT = 0x5E00;
+ }
+ break;
+ case 4:
+ EndBattleIntroTask(taskId);
+ break;
+ }
+}
+
+static void BattleIntroTask_FadeScenery(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] < 0xB4)
+ gTasks[taskId].data[6] += 4;
+ else
+ gTasks[taskId].data[6] += 6;
+ if (gTasks[taskId].data[6] == 0x168)
+ gTasks[taskId].data[6] = 0;
+ }
+
+ switch (gTasks[taskId].tState)
+ {
+ case 0:
+ gTasks[taskId].data[4] = 16;
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ gTasks[taskId].tBgXOffset = 16;
+ gTasks[taskId].tState++;
+ }
+ else
+ {
+ gTasks[taskId].tBgXOffset = 1;
+ gTasks[taskId].tState++;
+ }
+ break;
+ case 1:
+ gTasks[taskId].tBgXOffset--;
+ if (gTasks[taskId].tBgXOffset == 0)
+ {
+ gTasks[taskId].tState++;
+ REG_WININ = 0x3F;
+ }
+ break;
+ case 2:
+ // Open up window
+ gBattle_WIN0V -= WIN_RANGE(1, 0); // decrement min Y
+ gBattle_WIN0V += WIN_RANGE(0, 1); // increment max Y
+ if ((gBattle_WIN0V & 0xFF00) == 0x3000)
+ {
+ gTasks[taskId].tState++;
+ gTasks[taskId].tBgXOffset = DISPLAY_WIDTH;
+ gTasks[taskId].tFramesUntilBg1Slide = 32;
+ gTasks[taskId].data[5] = 1;
+ gUnknown_02024DE8 &= ~1;
+ }
+ break;
+ case 3:
+ if (gTasks[taskId].tFramesUntilBg1Slide != 0)
+ {
+ gTasks[taskId].tFramesUntilBg1Slide--;
+ if (gTasks[taskId].tFramesUntilBg1Slide == 0)
+ {
+ REG_BLDCNT = 0x1842;
+ REG_BLDALPHA = 0xF;
+ REG_BLDY = 0;
+ }
+ }
+ else
+ {
+ if ((gTasks[taskId].data[4] & 0x1F) && --gTasks[taskId].data[5] == 0)
+ {
+ gTasks[taskId].data[4] += 255;
+ gTasks[taskId].data[5] = 4;
+ }
+ }
+
+ if ((gBattle_WIN0V & 0xFF00) != 0)
+ gBattle_WIN0V -= 1020;
+
+ if (gTasks[taskId].tBgXOffset != 0)
+ gTasks[taskId].tBgXOffset -= 2;
+
+ // Slide in the top half of the BG from the left
+ for (i = 0; i < DISPLAY_HEIGHT / 2; i++)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].tBgXOffset;
+ // Slide in the bottom half of the BG from the right
+ for (; i < DISPLAY_HEIGHT; i++)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = -gTasks[taskId].tBgXOffset;
+
+ if (gTasks[taskId].tBgXOffset == 0)
+ {
+ gScanlineEffect.state = 3;
+ gTasks[taskId].tState++;
+ CpuFill32(0, (void *)(VRAM + 0xE000), 0x800);
+ REG_BG1CNT = 0x9C00;
+ REG_BG2CNT = 0x5E00;
+ }
+ break;
+ case 4:
+ EndBattleIntroTask(taskId);
+ break;
+ }
+
+ if (gTasks[taskId].tState != 4)
+ REG_BLDALPHA = gTasks[taskId].data[4];
+}
+
+static void BattleIntroTask_ScrollAndFadeScenery(u8 taskId)
+{
+ s32 i;
+
+ gBattle_BG1_X += 8;
+
+ switch (gTasks[taskId].tState)
+ {
+ case 0:
+ REG_BLDCNT = 0x1842;
+ REG_BLDALPHA = 0x0808;
+ REG_BLDY = 0;
+ gTasks[taskId].data[4] = 0x0808;
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ gTasks[taskId].tBgXOffset = 16;
+ gTasks[taskId].tState++;
+ }
+ else
+ {
+ gTasks[taskId].tBgXOffset = 1;
+ gTasks[taskId].tState++;
+ }
+ break;
+ case 1:
+ gTasks[taskId].tBgXOffset--;
+ if (gTasks[taskId].tBgXOffset == 0)
+ {
+ gTasks[taskId].tState++;
+ REG_WININ = 0x3F;
+ }
+ break;
+ case 2:
+ // Open up window
+ gBattle_WIN0V -= WIN_RANGE(1, 0); // decrement min Y
+ gBattle_WIN0V += WIN_RANGE(0, 1); // increment max Y
+ if ((gBattle_WIN0V & 0xFF00) == 0x3000)
+ {
+ gTasks[taskId].tState++;
+ gTasks[taskId].tBgXOffset = DISPLAY_WIDTH;
+ gTasks[taskId].tFramesUntilBg1Slide = 32;
+ gTasks[taskId].data[5] = 1;
+ gUnknown_02024DE8 &= ~1;
+ }
+ break;
+ case 3:
+ if (gTasks[taskId].tFramesUntilBg1Slide != 0)
+ {
+ gTasks[taskId].tFramesUntilBg1Slide--;
+ }
+ else
+ {
+ if ((gTasks[taskId].data[4] & 0xF) && --gTasks[taskId].data[5] == 0)
+ {
+ gTasks[taskId].data[4] += 255;
+ gTasks[taskId].data[5] = 6;
+ }
+ }
+
+ if ((gBattle_WIN0V & 0xFF00) != 0)
+ gBattle_WIN0V -= 1020;
+
+ if (gTasks[taskId].tBgXOffset != 0)
+ gTasks[taskId].tBgXOffset -= 2;
+
+ // Slide in the top half of the BG from the left
+ for (i = 0; i < DISPLAY_HEIGHT / 2; i++)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].tBgXOffset;
+ // Slide in the bottom half of the BG from the right
+ for (; i < DISPLAY_HEIGHT; i++)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = -gTasks[taskId].tBgXOffset;
+
+ if (gTasks[taskId].tBgXOffset == 0)
+ {
+ gScanlineEffect.state = 3;
+ gTasks[taskId].tState++;
+ CpuFill32(0, (void *)(VRAM + 0xE000), 0x800);
+ REG_BG1CNT = 0x9C00;
+ REG_BG2CNT = 0x5E00;
+ }
+ break;
+ case 4:
+ EndBattleIntroTask(taskId);
+ break;
+ }
+
+ if (gTasks[taskId].tState != 4)
+ REG_BLDALPHA = gTasks[taskId].data[4];
+}
+
+// Seems to only be used for link battles.
+static void BattleIntroTask_80E4C34(u8 taskId)
+{
+ s32 i;
+
+ if (gTasks[taskId].tState > 1 && gTasks[taskId].data[4] == 0)
+ {
+ if ((gBattle_BG1_X & 0x8000) || gBattle_BG1_X < 80) // hmm...
+ {
+ gBattle_BG1_X += 3;
+ gBattle_BG2_X -= 3;
+ }
+ else
+ {
+ CpuFill32(0, (void *)(VRAM + 0xE000), 0x800);
+ CpuFill32(0, (void *)(VRAM + 0xF000), 0x800);
+ gTasks[taskId].data[4] = 1;
+ }
+ }
+
+ switch (gTasks[taskId].tState)
+ {
+ case 0:
+ gTasks[taskId].tBgXOffset = 16;
+ gTasks[taskId].tState++;
+ break;
+ case 1:
+ gTasks[taskId].tBgXOffset--;
+ if (gTasks[taskId].tBgXOffset == 0)
+ {
+ gTasks[taskId].tState++;
+ gSprites[ewram1608A].oam.objMode = 2;
+ gSprites[ewram1608A].callback = sub_800FE20;
+ gSprites[ewram1608B].oam.objMode = 2;
+ gSprites[ewram1608B].callback = sub_800FE20;
+ REG_WININ = 0x3F;
+ REG_WINOUT = 0x3F06;
+ }
+ break;
+ case 2:
+ // Open up window
+ gBattle_WIN0V -= WIN_RANGE(1, 0); // decrement min Y
+ gBattle_WIN0V += WIN_RANGE(0, 1); // increment max Y
+ if ((gBattle_WIN0V & 0xFF00) == 0x3000)
+ {
+ gTasks[taskId].tState++;
+ gTasks[taskId].tBgXOffset = DISPLAY_WIDTH;
+ gTasks[taskId].tFramesUntilBg1Slide = 32;
+ gUnknown_02024DE8 &= ~1;
+ }
+ break;
+ case 3:
+ if ((gBattle_WIN0V & 0xFF00) != 0)
+ gBattle_WIN0V -= 1020;
+
+ if (gTasks[taskId].tBgXOffset != 0)
+ gTasks[taskId].tBgXOffset -= 2;
+
+ // Slide in the top half of the BG from the left
+ for (i = 0; i < DISPLAY_HEIGHT / 2; i++)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].tBgXOffset;
+ // Slide in the bottom half of the BG from the right
+ for (; i < DISPLAY_HEIGHT; i++)
+ gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = -gTasks[taskId].tBgXOffset;
+
+ if (gTasks[taskId].tBgXOffset == 0)
+ {
+ gScanlineEffect.state = 3;
+ gTasks[taskId].tState++;
+ REG_BG1CNT = 0x9C00;
+ REG_BG2CNT = 0x5E00;
+ }
+ break;
+ case 4:
+ EndBattleIntroTask(taskId);
+ break;
+ }
+}
+
+void unref_sub_80E4EC8(u8 a, u8 b, u8 c, u8 d)
+{
+ sub_80E4EF8(a, b, c, d, 0x4000, 30, 1);
+}
+
+// draws some 8x8 tilemap
+void sub_80E4EF8(u8 left, u8 top, u8 c, u8 paletteNum, u16 e, u8 bgMap, u8 g)
+{
+ u32 tileNum;
+ s32 x;
+ s32 y;
+ u8 bank = GetBankByIdentity(c);
+
+ DmaCopy16(3, gUnknown_081FAF4C[c] + gBattleMonForms[bank] * 0x800, (void *)(VRAM + e), 0x800);
+ tileNum = e / 32 - g * 512;
+ for (y = top; y < top + 8; y++)
+ {
+ for (x = left; x < left + 8; x++)
+ {
+ *(u16 *)(VRAM + x * 2 + bgMap * 0x800 + y * 64) = tileNum | (paletteNum << 12);
+ tileNum++;
+ }
+ }
+}
+
+void unref_sub_80E4FDC(u8 left, u8 top, u8 c, u8 form, u8 paletteNum, u16 f, u8 bgMap, u8 h)
+{
+ u32 tileNum;
+ s32 x;
+ s32 y;
+
+ DmaCopy16(3, gUnknown_081FAF4C[c] + form * 0x800, (void *)(VRAM + f), 0x800);
+ tileNum = f / 32 - h * 512;
+ for (y = top; y < top + 8; y++)
+ {
+ for (x = left; x < left + 8; x++)
+ {
+ *(u16 *)(VRAM + x * 2 + bgMap * 0x800 + y * 64) = tileNum | (paletteNum << 12);
+ tileNum++;
+ }
+ }
+}
diff --git a/src/battle/anim/blow_kiss.c b/src/battle/anim/blow_kiss.c
index e7b49471d..e7b49471d 100755..100644
--- a/src/battle/anim/blow_kiss.c
+++ b/src/battle/anim/blow_kiss.c
diff --git a/src/battle/anim/bottle.c b/src/battle/anim/bottle.c
index 5485bcf5d..5485bcf5d 100755..100644
--- a/src/battle/anim/bottle.c
+++ b/src/battle/anim/bottle.c
diff --git a/src/battle/anim/brace.c b/src/battle/anim/brace.c
index 19ea4297b..19ea4297b 100755..100644
--- a/src/battle/anim/brace.c
+++ b/src/battle/anim/brace.c
diff --git a/src/battle/anim/breath.c b/src/battle/anim/breath.c
index 831b222ad..831b222ad 100755..100644
--- a/src/battle/anim/breath.c
+++ b/src/battle/anim/breath.c
diff --git a/src/battle/anim/bug.c b/src/battle/anim/bug.c
new file mode 100644
index 000000000..dbc0f75a5
--- /dev/null
+++ b/src/battle/anim/bug.c
@@ -0,0 +1,302 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "contest.h"
+#include "rom_8077ABC.h"
+#include "trig.h"
+// #include "util.h"
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankAttacker;
+extern u8 gAnimBankTarget;
+
+static void sub_80DCA38(struct Sprite *sprite);
+static void sub_80DCAEC(struct Sprite *sprite);
+static void sub_80DCB5C(struct Sprite *sprite);
+static void sub_80DCBB4(struct Sprite *sprite);
+void sub_80DCD78(struct Sprite *sprite);
+
+// used in Move_MEGAHORN
+void sub_80DC824(struct Sprite *sprite)
+{
+ if (IsContest())
+ {
+ StartSpriteAffineAnim(sprite, 2);
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ }
+ else if (!GetBankSide(gAnimBankTarget))
+ {
+ StartSpriteAffineAnim(sprite, 1);
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ }
+
+ sprite->pos1.x = sub_8077EE4(gAnimBankTarget, 2) + gBattleAnimArgs[0];
+ sprite->pos1.y = sub_8077EE4(gAnimBankTarget, 3) + gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[4];
+
+ sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3];
+
+ sprite->callback = sub_8078B34;
+ StoreSpriteCallbackInData(sprite, DestroyAnimSprite);
+}
+
+// used in Move_LEECH_LIFE
+void sub_80DC8F4(struct Sprite *sprite)
+{
+ if (IsContest())
+ {
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ StartSpriteAffineAnim(sprite, 2);
+ }
+ else if (!GetBankSide(gAnimBankTarget))
+ {
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ }
+
+ sprite->pos1.x = sub_8077EE4(gAnimBankTarget, 2) + gBattleAnimArgs[0];
+ sprite->pos1.y = sub_8077EE4(gAnimBankTarget, 3) + gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[2];
+
+ sprite->data[2] = GetBankPosition(gAnimBankTarget, 2);
+ sprite->data[4] = GetBankPosition(gAnimBankTarget, 3);
+
+ sprite->callback = sub_8078B34;
+ StoreSpriteCallbackInData(sprite, DestroyAnimSprite);
+}
+
+// used in 2 moves:
+// Move_STRING_SHOT, Move_SPIDER_WEB
+void sub_80DC9A0(struct Sprite *sprite)
+{
+ if (IsContest())
+ gBattleAnimArgs[2] /= 2;
+
+ sub_80787B0(sprite, 1);
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+
+ if (!gBattleAnimArgs[4])
+ {
+ sprite->data[2] = GetBankPosition(gAnimBankTarget, 2);
+ sprite->data[4] = GetBankPosition(gAnimBankTarget, 3);
+ }
+ else
+ {
+ sub_807A3FC(gAnimBankTarget, 1, &sprite->data[2], &sprite->data[4]);
+ }
+
+ sub_8078BD4(sprite);
+ sprite->data[5] = gBattleAnimArgs[3];
+ sprite->callback = sub_80DCA38;
+}
+
+static void sub_80DCA38(struct Sprite *sprite)
+{
+ if (sub_8078B5C(sprite))
+ {
+ DestroyAnimSprite(sprite);
+ return;
+ }
+
+ sprite->pos2.x += Sin(sprite->data[6], sprite->data[5]);
+ sprite->data[6] = (sprite->data[6] + 13) & 0xFF;
+}
+
+// used in Move_STRING_SHOT
+void sub_80DCA70(struct Sprite *sprite)
+{
+ sub_807A3FC(gAnimBankTarget, 0, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBankSide(gAnimBankAttacker))
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+
+ sprite->pos1.y += gBattleAnimArgs[1];
+ if (!GetBankSide(gAnimBankTarget))
+ sprite->pos1.y += 8;
+
+ sprite->callback = sub_80DCAEC;
+}
+
+static void sub_80DCAEC(struct Sprite *sprite)
+{
+ if (++sprite->data[0] == 3)
+ {
+ sprite->data[0] = 0;
+ sprite->invisible ^= 1;
+ }
+
+ if (++sprite->data[1] == 51)
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// used in Move_SPIDER_WEB
+void sub_80DCB38(struct Sprite *sprite)
+{
+ REG_BLDCNT = 0x3F40;
+ REG_BLDALPHA = 16;
+
+ sprite->data[0] = 16;
+ sprite->callback = sub_80DCB5C;
+}
+
+static void sub_80DCB5C(struct Sprite *sprite)
+{
+ if (sprite->data[2] < 20)
+ {
+ sprite->data[2]++;
+ }
+ else if (sprite->data[1]++ & 1)
+ {
+ sprite->data[0]--;
+ REG_BLDALPHA = sprite->data[0] | ((16 - sprite->data[0]) << 8);
+
+ if (sprite->data[0] == 0)
+ {
+ sprite->invisible = TRUE;
+ sprite->callback = sub_80DCBB4;
+ }
+ }
+}
+
+static void sub_80DCBB4(struct Sprite *sprite)
+{
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ DestroyAnimSprite(sprite);
+}
+
+// used in 3 moves:
+// Move_POISON_STING, Move_TWINEEDLE, Move_SPIKE_CANNON
+void sub_80DCBCC(struct Sprite *sprite)
+{
+ s16 lVarX, lVarY;
+ u16 rot;
+
+ if (IsContest())
+ {
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ }
+ else
+ {
+ if (GetBankSide(gAnimBankAttacker))
+ {
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ }
+ }
+
+ if (!IsContest())
+ {
+ if (GetBankSide(gAnimBankAttacker) == GetBankSide(gAnimBankTarget))
+ {
+ if (GetBankIdentity(gAnimBankTarget) == 0 || GetBankIdentity(gAnimBankTarget) == 1)
+ {
+ s16 temp1, temp2;
+
+ temp1 = gBattleAnimArgs[2];
+ gBattleAnimArgs[2] = -temp1;
+
+ temp2 = gBattleAnimArgs[0];
+ gBattleAnimArgs[0] = -temp2;
+ }
+ }
+ }
+
+ sub_80787B0(sprite, 1);
+
+ lVarX = GetBankPosition(gAnimBankTarget, 2) + gBattleAnimArgs[2];
+ lVarY = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3];
+ rot = sub_80790F0(lVarX - sprite->pos1.x, lVarY - sprite->pos1.y);
+ rot += 0xC000;
+ sub_8078FDC(sprite, FALSE, 0x100, 0x100, rot);
+
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = lVarX;
+ sprite->data[4] = lVarY;
+
+ sprite->callback = sub_8078B34;
+ StoreSpriteCallbackInData(sprite, DestroyAnimSprite);
+}
+
+// used in 2 moves:
+// Move_PIN_MISSILE, Move_ICICLE_SPEAR
+void sub_80DCCFC(struct Sprite *sprite)
+{
+ sub_80787B0(sprite, 1);
+
+ if (GetBankSide(gAnimBankAttacker))
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3];
+ sprite->data[5] = gBattleAnimArgs[5];
+ sub_80786EC(sprite);
+
+ sprite->callback = sub_80DCD78;
+ sprite->invisible = TRUE;
+}
+
+void sub_80DCD78(struct Sprite *sprite)
+{
+ sprite->invisible = FALSE;
+
+ if (sub_8078718(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;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ tempData[i] = data[i];
+
+ x2 += x1;
+ y2 += y1;
+
+ if (!sub_8078718(sprite))
+ {
+ u16 rot = sub_80790F0(sprite->pos1.x + sprite->pos2.x - x2,
+ sprite->pos1.y + sprite->pos2.y - y2);
+ rot += 0xC000;
+ sub_8078FDC(sprite, FALSE, 0x100, 0x100, rot);
+
+ for (i = 0; i < 8; i++)
+ data[i] = tempData[i];
+ }
+ }
+}
+
+void sub_80DCE40(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3) + 18;
+ }
+ else
+ {
+ sprite->pos1.x = GetBankPosition(gAnimBankTarget, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankTarget, 3) + 18;
+ }
+
+ StoreSpriteCallbackInData(sprite, move_anim_8074EE0);
+ sprite->callback = sub_80785E4;
+}
diff --git a/src/battle/anim/bullet.c b/src/battle/anim/bullet.c
index 90b2021f1..90b2021f1 100755..100644
--- a/src/battle/anim/bullet.c
+++ b/src/battle/anim/bullet.c
diff --git a/src/battle/anim/copy_orb.c b/src/battle/anim/copy_orb.c
index 4fa8ea163..4fa8ea163 100755..100644
--- a/src/battle/anim/copy_orb.c
+++ b/src/battle/anim/copy_orb.c
diff --git a/src/battle/anim/cube.c b/src/battle/anim/cube.c
index 9adf46e32..9adf46e32 100755..100644
--- a/src/battle/anim/cube.c
+++ b/src/battle/anim/cube.c
diff --git a/src/battle/anim/curtain.c b/src/battle/anim/curtain.c
index 3c9e4e84c..3c9e4e84c 100755..100644
--- a/src/battle/anim/curtain.c
+++ b/src/battle/anim/curtain.c
diff --git a/src/battle/anim/cutter.c b/src/battle/anim/cutter.c
index 2234ebacb..2234ebacb 100755..100644
--- a/src/battle/anim/cutter.c
+++ b/src/battle/anim/cutter.c
diff --git a/src/battle/anim/cyclone.c b/src/battle/anim/cyclone.c
index 0f83df211..0f83df211 100755..100644
--- a/src/battle/anim/cyclone.c
+++ b/src/battle/anim/cyclone.c
diff --git a/src/battle/anim/dark.c b/src/battle/anim/dark.c
new file mode 100644
index 000000000..1c88dc23e
--- /dev/null
+++ b/src/battle/anim/dark.c
@@ -0,0 +1,1008 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "blend_palette.h"
+#include "decompress.h"
+#include "ewram.h"
+#include "palette.h"
+#include "rom_8077ABC.h"
+#include "scanline_effect.h"
+#include "sound.h"
+#include "sprite.h"
+#include "trig.h"
+#include "constants/battle_constants.h"
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankAttacker;
+extern u8 gAnimBankTarget;
+extern u8 gObjectBankIDs[];
+extern u16 gBattle_BG1_X;
+extern u16 gBattle_BG1_Y;
+extern u16 gBattle_BG2_X;
+extern u16 gBattle_BG2_Y;
+extern u16 gBattle_WIN0H;
+extern u16 gBattle_WIN0V;
+extern u16 gBattlePartyID[];
+extern u8 gAnimMoveTurn;
+
+extern const u8 gUnknown_08D1D574[];
+extern const u8 gUnknown_08D1D410[];
+extern const u16 gUnknown_08D1D54C[];
+
+static void sub_80DFE90(struct Sprite *sprite);
+static void sub_80DFC9C(u8 taskId);
+static void sub_80DFD58(u8 taskId);
+static void sub_80DFF58(struct Sprite *sprite);
+static void sub_80DFF98(struct Sprite *sprite);
+static void sub_80E00D0(struct Sprite *sprite);
+static void sub_80E02A4(u8 taskId);
+static void sub_80E0620(u8 taskId);
+static void sub_80E08CC(u8 priority);
+static void sub_80E079C(struct Task *task);
+static void sub_80E0CD0(u8 taskId);
+
+
+// used in Smoke Ball escape, Sky Attack, Feint Attack and Camouflage
+void sub_80DFC24(u8 taskId)
+{
+ int bank;
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ bank = gAnimBankAttacker;
+ gTasks[taskId].data[1] = 16;
+ REG_BLDALPHA = 16;
+ if (GetBankIdentity_permutated(bank) == 1)
+ REG_BLDCNT = 0x3F42;
+ else
+ REG_BLDCNT = 0x3F44;
+ gTasks[taskId].func = sub_80DFC9C;
+}
+
+static void sub_80DFC9C(u8 taskId)
+{
+ u8 r2 = gTasks[taskId].data[1] >> 8;
+ u8 r1 = gTasks[taskId].data[1];
+ if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0])
+ {
+ r2++;
+ r1--;
+ gTasks[taskId].data[1] = (r2 << 8) | r1;
+ REG_BLDALPHA = (r2 << 8) | r1;
+ gTasks[taskId].data[2] = 0;
+ if (r2 == 16)
+ {
+ gSprites[gObjectBankIDs[gAnimBankAttacker]].invisible = 1;
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ else
+ gTasks[taskId].data[2]++;
+}
+
+void sub_80DFD24(u8 taskId)
+{
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = 0x1000;
+ gTasks[taskId].func = sub_80DFD58;
+ REG_BLDALPHA = 0x1000;
+}
+
+void sub_80DFD58(u8 taskId)
+{
+ u8 r1 = gTasks[taskId].data[1] >> 8;
+ u8 r5 = gTasks[taskId].data[1];
+ if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0])
+ {
+ r1--;
+ r5++;
+ gTasks[taskId].data[1] = (r1 << 8) | r5;
+ REG_BLDALPHA = (r1 << 8) | r5;
+ gTasks[taskId].data[2] = 0;
+ if (r1 == 0)
+ {
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ else
+ gTasks[taskId].data[2]++;
+}
+
+// unlike the above is only used in Feint Attack
+
+void sub_80DFDC0(u8 taskId)
+{
+ REG_BLDALPHA = 0x1000;
+ if (GetBankIdentity_permutated(gAnimBankAttacker) == 1)
+ REG_BLDCNT = 0x3F42;
+ else
+ REG_BLDCNT = 0x3F44;
+ DestroyAnimVisualTask(taskId);
+}
+
+// unused sprite template's callback
+
+void sub_80DFE14(struct Sprite *sprite)
+{
+ sprite->data[1] = GetBankPosition(gAnimBankTarget, 2);
+ sprite->data[2] = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->data[3] = GetBankPosition(gAnimBankTarget, 3);
+ sprite->data[4] = GetBankPosition(gAnimBankAttacker, 3);
+ sprite->data[0] = 0x7E;
+ sub_8078A5C(sprite);
+ sprite->data[3] = -sprite->data[1];
+ sprite->data[4] = -sprite->data[2];
+ sprite->data[6] = 0xFFD8;
+ sprite->callback = sub_80DFE90;
+ sub_80DFE90(sprite);
+}
+
+static void sub_80DFE90(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);
+}
+
+void sub_80DFF1C(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_80DFF58;
+}
+
+static void sub_80DFF58(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_80DFF98;
+}
+
+static void sub_80DFF98(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)
+ move_anim_8074EE0(sprite);
+}
+
+void sub_80DFFD0(struct Sprite *sprite)
+{
+ u8 bank;
+ s8 xOffset;
+
+ if (gBattleAnimArgs[0] == 0)
+ bank = gAnimBankAttacker;
+ else
+ bank = gAnimBankTarget;
+
+ xOffset = 20;
+ sprite->oam.tileNum += 4;
+
+ switch (gBattleAnimArgs[1])
+ {
+ case 0:
+ sprite->pos1.x = sub_807A100(bank, 5) - 8;
+ sprite->pos1.y = sub_807A100(bank, 2) + 8;
+ break;
+ case 1:
+ sprite->pos1.x = sub_807A100(bank, 5) - 14;
+ sprite->pos1.y = sub_807A100(bank, 2) + 16;
+ break;
+ case 2:
+ sprite->pos1.x = sub_807A100(bank, 4) + 8;
+ sprite->pos1.y = sub_807A100(bank, 2) + 8;
+ StartSpriteAffineAnim(sprite, 1);
+ xOffset = -20;
+ break;
+ case 3:
+ sprite->pos1.x = sub_807A100(bank, 4) + 14;
+ sprite->pos1.y = sub_807A100(bank, 2) + 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;
+
+ sub_80786EC(sprite);
+ sprite->callback = sub_80E00D0;
+}
+
+static void sub_80E00D0(struct Sprite *sprite)
+{
+ if (sub_8078718(sprite))
+ move_anim_8074EE0(sprite);
+}
+
+void sub_80E00EC(u8 taskId)
+{
+ struct ScanlineEffectParams scanlineParams;
+ struct Struct_sub_8078914 subStruct;
+ u16 i;
+ u8 pos;
+ int var0;
+ struct Task *task = &gTasks[taskId];
+
+ task->data[7] = GetBankPosition(gAnimBankAttacker, 1) + 31;
+ task->data[6] = sub_807A100(gAnimBankAttacker, 2) - 7;
+ task->data[5] = task->data[7];
+ task->data[4] = task->data[6];
+ task->data[13] = (task->data[7] - task->data[6]) << 8;
+
+ pos = GetBankPosition(gAnimBankAttacker, 0);
+ task->data[14] = pos - 32;
+ task->data[15] = pos + 32;
+
+ if (GetBankSide(gAnimBankAttacker) == SIDE_PLAYER)
+ task->data[8] = -12;
+ else
+ task->data[8] = -64;
+
+ task->data[3] = GetBankIdentity_permutated(gAnimBankAttacker);
+ if (task->data[3] == 1)
+ {
+ sub_8078914(&subStruct);
+ task->data[10] = gBattle_BG1_Y;
+ REG_BLDCNT = 0x3F42;
+ FillPalette(0, subStruct.field_8 << 4, 32);
+ scanlineParams.dmaDest = &REG_BG1VOFS;
+ var0 = 2;
+
+ if (!IsContest())
+ gBattle_BG2_X += 240;
+ }
+ else
+ {
+ task->data[10] = gBattle_BG2_Y;
+ REG_BLDCNT = 0x3F44;
+ FillPalette(0, 144, 32);
+ scanlineParams.dmaDest = &REG_BG2VOFS;
+ var0 = 4;
+
+ if (!IsContest())
+ gBattle_BG1_X += 240;
+ }
+
+ scanlineParams.dmaControl = 0xA2600001;
+ 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_80E08CC(3);
+
+ for (i = 0; i < 112; i++)
+ {
+ gScanlineEffectRegBuffers[0][i] = task->data[10];
+ gScanlineEffectRegBuffers[1][i] = task->data[10];
+ }
+
+ ScanlineEffect_SetParams(scanlineParams);
+
+ REG_WINOUT = 0x3F00 | (var0 ^ 0x3F);
+ REG_WININ = 0x3F3F;
+ gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
+ gBattle_WIN0V = 160;
+
+ task->func = sub_80E02A4;
+}
+
+static void sub_80E02A4(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]--;
+ }
+
+ REG_BLDALPHA = (task->data[12] << 8) | task->data[11];
+
+ if (task->data[11] == 12 && task->data[12] == 8)
+ task->data[0]++;
+ }
+ break;
+ case 1:
+ task->data[4] -= 8;
+ sub_80E079C(task);
+
+ if (task->data[4] < task->data[8])
+ task->data[0]++;
+ break;
+ case 2:
+ task->data[4] -= 8;
+ sub_80E079C(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_80E03BC(u8 taskId)
+{
+ struct Struct_sub_8078914 subStruct;
+ struct ScanlineEffectParams scanlineParams;
+ u8 pos;
+ u16 i;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (IsContest() == TRUE)
+ {
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ REG_WININ = 0x3F3F;
+ REG_WINOUT = 0x3F3F;
+ DestroyAnimVisualTask(taskId);
+ }
+ else
+ {
+ task->data[3] = GetBankIdentity_permutated(gAnimBankTarget);
+ if (task->data[3] == 1)
+ {
+ REG_BLDCNT = 0x3F42;
+ gBattle_BG2_X += 240;
+ }
+ else
+ {
+ REG_BLDCNT = 0x3F44;
+ gBattle_BG1_X += 240;
+ }
+
+ task->data[0]++;
+ }
+ break;
+ case 1:
+ if (task->data[3] == 1)
+ {
+ sub_8078914(&subStruct);
+ task->data[10] = gBattle_BG1_Y;
+ FillPalette(0, subStruct.field_8 << 4, 32);
+ }
+ else
+ {
+ task->data[10] = gBattle_BG2_Y;
+ FillPalette(0, 144, 32);
+ }
+
+ sub_80E08CC(3);
+ task->data[0]++;
+ break;
+ case 2:
+ task->data[7] = GetBankPosition(gAnimBankTarget, 1) + 31;
+ task->data[6] = sub_807A100(gAnimBankTarget, 2) - 7;
+ task->data[13] = (task->data[7] - task->data[6]) << 8;
+ pos = GetBankPosition(gAnimBankTarget, 0);
+ task->data[14] = pos - 4;
+ task->data[15] = pos + 4;
+
+ if (GetBankSide(gAnimBankTarget) == 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 = 0xA2600001;
+ scanlineParams.initState = 1;
+ scanlineParams.unused9 = 0;
+ ScanlineEffect_SetParams(scanlineParams);
+ task->data[0]++;
+ break;
+ case 4:
+ if (task->data[3] == 1)
+ REG_WINOUT = 0x3F3D;
+ else
+ REG_WINOUT = 0x3F3B;
+
+ REG_WININ = 0x3F3F;
+ gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
+ gBattle_WIN0V = 160;
+
+ task->data[0] = 0;
+ task->data[1] = 0;
+ task->data[2] = 0;
+ REG_BLDALPHA = 0x80C;
+ task->func = sub_80E0620;
+ break;
+ }
+}
+
+static void sub_80E0620(u8 taskId)
+{
+ 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_80E079C(task);
+
+ if (task->data[5] == task->data[7])
+ task->data[0]++;
+ break;
+ case 1:
+ if (task->data[15] - task->data[14] < 64)
+ {
+ 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_80E079C(task);
+
+ if (task->data[4] == task->data[6] && task->data[1] != 0)
+ {
+ task->data[1] = 0;
+ task->data[0]++;
+ }
+ break;
+ case 2:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ if ((++task->data[2] & 1) != 0)
+ {
+ if (task->data[11] != 0)
+ task->data[11]--;
+ }
+ else
+ {
+ if (task->data[12] < 16)
+ task->data[12]++;
+ }
+
+ REG_BLDALPHA = (task->data[12] << 8) | task->data[11];
+
+ 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;
+ REG_WININ = 0x3F3F;
+ REG_WINOUT = 0x3F3F;
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+// static void sub_80E079C(struct Task *task)
+// {
+// int var0, var1;
+// s16 var2;
+// s16 i, j;
+
+// var2 = task->data[5] - task->data[4];
+// if (var2 != 0)
+// {
+// var0 = task->data[13] / var2;
+// var1 = task->data[6];
+
+// 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)
+// {
+// gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = (var1 - i) + task->data[10];
+// }
+
+// var1 += var0;
+// }
+
+// for (j = i; j < task->data[7]; j++)
+// {
+// if (j >= 0)
+// {
+// gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][j] = (task->data[10] + 159) - j;
+// }
+// }
+// }
+// else
+// {
+// for (i = 0; i < 112; i++)
+// {
+// gScanlineEffectRegBuffers[0][i] = task->data[10] + 159 - i;
+// gScanlineEffectRegBuffers[1][i] = task->data[10] + 159 - i;
+// }
+// }
+// }
+
+__attribute__((naked))
+static void sub_80E079C(struct Task *task)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r8\n\
+ push {r7}\n\
+ adds r6, r0, 0\n\
+ ldrh r0, [r6, 0x12]\n\
+ ldrh r4, [r6, 0x10]\n\
+ subs r0, r4\n\
+ lsls r0, 16\n\
+ asrs r1, r0, 16\n\
+ cmp r1, 0\n\
+ beq _080E0890\n\
+ movs r2, 0x22\n\
+ ldrsh r0, [r6, r2]\n\
+ bl __divsi3\n\
+ mov r8, r0\n\
+ movs r3, 0x14\n\
+ ldrsh r0, [r6, r3]\n\
+ lsls r5, r0, 8\n\
+ lsls r0, r4, 16\n\
+ movs r4, 0\n\
+ cmp r0, 0\n\
+ ble _080E07FC\n\
+ ldr r0, _080E0888 @ =gScanlineEffectRegBuffers\n\
+ mov r12, r0\n\
+ ldr r7, _080E088C @ =gScanlineEffect\n\
+_080E07D0:\n\
+ lsls r2, r4, 16\n\
+ asrs r2, 16\n\
+ lsls r3, r2, 1\n\
+ ldrb r1, [r7, 0x14]\n\
+ lsls r0, r1, 4\n\
+ subs r0, r1\n\
+ lsls r0, 7\n\
+ adds r3, r0\n\
+ add r3, r12\n\
+ adds r1, r2, 0\n\
+ subs r1, 0x9F\n\
+ ldrh r0, [r6, 0x1C]\n\
+ subs r0, r1\n\
+ strh r0, [r3]\n\
+ adds r2, 0x1\n\
+ lsls r2, 16\n\
+ lsrs r4, r2, 16\n\
+ asrs r2, 16\n\
+ movs r1, 0x10\n\
+ ldrsh r0, [r6, r1]\n\
+ cmp r2, r0\n\
+ blt _080E07D0\n\
+_080E07FC:\n\
+ ldrh r4, [r6, 0x10]\n\
+ lsls r3, r4, 16\n\
+ asrs r1, r3, 16\n\
+ movs r2, 0x12\n\
+ ldrsh r0, [r6, r2]\n\
+ cmp r1, r0\n\
+ bgt _080E0846\n\
+ ldr r0, _080E0888 @ =gScanlineEffectRegBuffers\n\
+ mov r12, r0\n\
+ ldr r7, _080E088C @ =gScanlineEffect\n\
+_080E0810:\n\
+ asrs r4, r3, 16\n\
+ cmp r4, 0\n\
+ blt _080E0832\n\
+ asrs r1, r5, 8\n\
+ subs r1, r4\n\
+ lsls r3, r4, 1\n\
+ ldrb r2, [r7, 0x14]\n\
+ lsls r0, r2, 4\n\
+ subs r0, r2\n\
+ lsls r0, 7\n\
+ adds r3, r0\n\
+ add r3, r12\n\
+ lsls r1, 16\n\
+ asrs r1, 16\n\
+ ldrh r2, [r6, 0x1C]\n\
+ adds r1, r2\n\
+ strh r1, [r3]\n\
+_080E0832:\n\
+ add r5, r8\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ lsls r3, r4, 16\n\
+ asrs r1, r3, 16\n\
+ movs r2, 0x12\n\
+ ldrsh r0, [r6, r2]\n\
+ cmp r1, r0\n\
+ ble _080E0810\n\
+_080E0846:\n\
+ movs r3, 0x1C\n\
+ ldrsh r0, [r6, r3]\n\
+ adds r0, 0x9F\n\
+ lsls r2, r4, 16\n\
+ asrs r1, r2, 16\n\
+ subs r5, r0, r1\n\
+ movs r3, 0x16\n\
+ ldrsh r0, [r6, r3]\n\
+ cmp r1, r0\n\
+ bge _080E08BE\n\
+ ldr r7, _080E0888 @ =gScanlineEffectRegBuffers\n\
+ ldr r4, _080E088C @ =gScanlineEffect\n\
+_080E085E:\n\
+ asrs r3, r2, 16\n\
+ cmp r3, 0\n\
+ blt _080E0876\n\
+ lsls r2, r3, 1\n\
+ ldrb r1, [r4, 0x14]\n\
+ lsls r0, r1, 4\n\
+ subs r0, r1\n\
+ lsls r0, 7\n\
+ adds r2, r0\n\
+ adds r2, r7\n\
+ strh r5, [r2]\n\
+ subs r5, 0x1\n\
+_080E0876:\n\
+ adds r0, r3, 0x1\n\
+ lsls r2, r0, 16\n\
+ asrs r1, r2, 16\n\
+ movs r3, 0x16\n\
+ ldrsh r0, [r6, r3]\n\
+ cmp r1, r0\n\
+ blt _080E085E\n\
+ b _080E08BE\n\
+ .align 2, 0\n\
+_080E0888: .4byte gScanlineEffectRegBuffers\n\
+_080E088C: .4byte gScanlineEffect\n\
+_080E0890:\n\
+ movs r1, 0x1C\n\
+ ldrsh r0, [r6, r1]\n\
+ adds r5, r0, 0\n\
+ adds r5, 0x9F\n\
+ movs r4, 0\n\
+ ldr r3, _080E08C8 @ =gScanlineEffectRegBuffers\n\
+ movs r2, 0xF0\n\
+ lsls r2, 3\n\
+ adds r6, r3, r2\n\
+_080E08A2:\n\
+ lsls r0, r4, 16\n\
+ asrs r0, 16\n\
+ lsls r2, r0, 1\n\
+ adds r1, r2, r3\n\
+ strh r5, [r1]\n\
+ adds r2, r6\n\
+ strh r5, [r2]\n\
+ subs r5, 0x1\n\
+ adds r0, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ asrs r0, 16\n\
+ cmp r0, 0x6F\n\
+ ble _080E08A2\n\
+_080E08BE:\n\
+ pop {r3}\n\
+ mov r8, r3\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .align 2, 0\n\
+_080E08C8: .4byte gScanlineEffectRegBuffers\n\
+ .syntax divided\n");
+}
+
+static void sub_80E08CC(u8 priority)
+{
+ u16 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ u8 spriteId = GetAnimBankSpriteId(i);
+ if (spriteId != 0xFF)
+ gSprites[spriteId].oam.priority = priority;
+ }
+}
+
+void sub_80E0918(u8 taskId)
+{
+ u8 toBG2 = GetBankIdentity_permutated(gAnimBankAttacker) ^ 1 ? 1 : 0;
+ sub_8076034(gAnimBankAttacker, toBG2);
+ gSprites[gObjectBankIDs[gAnimBankAttacker]].invisible = 0;
+
+ if (IsAnimBankSpriteVisible(gAnimBankAttacker ^ 2))
+ {
+ sub_8076034(gAnimBankAttacker ^ 2, toBG2 ^ 1);
+ gSprites[gObjectBankIDs[gAnimBankAttacker ^ 2]].invisible = 0;
+ }
+
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80E09C4(u8 taskId)
+{
+ u8 toBG2 = GetBankIdentity_permutated(gAnimBankAttacker) ^ 1 ? 1 : 0;
+ sub_8076464(toBG2);
+
+ if (IsAnimBankSpriteVisible(gAnimBankAttacker ^ 2))
+ sub_8076464(toBG2 ^ 1);
+
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80E0A10(struct Sprite *sprite)
+{
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ StartSpriteAnim(sprite, gBattleAnimArgs[2]);
+ sprite->callback = sub_8078600;
+ StoreSpriteCallbackInData(sprite, DestroyAnimSprite);
+}
+
+void sub_80E0A4C(u8 taskId)
+{
+ u16 species;
+ u8 spriteId;
+ u8 newSpriteId;
+ u16 paletteNum;
+ struct Struct_sub_8078914 subStruct;
+ int var0 = 0;
+
+ gBattle_WIN0H = var0;
+ gBattle_WIN0V = var0;
+ REG_WININ = 0x3F3F;
+ REG_WINOUT = 0x3F3D;
+ REG_DISPCNT |= DISPCNT_OBJWIN_ON;
+ REG_BLDCNT = 0x3F42;
+ REG_BLDALPHA = 0xC08;
+ REG_BG1CNT_BITFIELD.priority = 0;
+ REG_BG1CNT_BITFIELD.screenSize = 0;
+ if (!IsContest())
+ REG_BG1CNT_BITFIELD.charBaseBlock = 1;
+
+ if (IsDoubleBattle() && !IsContest())
+ {
+ if (GetBankIdentity(gAnimBankAttacker) == 3 || GetBankIdentity(gAnimBankAttacker) == 0)
+ {
+ if (IsAnimBankSpriteVisible(gAnimBankAttacker ^ 2) == TRUE)
+ {
+ gSprites[gObjectBankIDs[gAnimBankAttacker ^ 2]].oam.priority--;
+ REG_BG1CNT_BITFIELD.priority = 1;
+ var0 = 1;
+ }
+ }
+ }
+
+ if (IsContest())
+ {
+ species = EWRAM_19348;
+ }
+ else
+ {
+ if (GetBankSide(gAnimBankAttacker) != SIDE_PLAYER)
+ species = GetMonData(&gEnemyParty[gBattlePartyID[gAnimBankAttacker]], MON_DATA_SPECIES);
+ else
+ species = GetMonData(&gPlayerParty[gBattlePartyID[gAnimBankAttacker]], MON_DATA_SPECIES);
+ }
+
+ spriteId = GetAnimBankSpriteId(0);
+ newSpriteId = sub_807A4A0(gAnimBankAttacker, spriteId, species);
+
+ sub_8078914(&subStruct);
+ DmaClear32(3, subStruct.field_4, 0x1000);
+ LZDecompressVram(&gUnknown_08D1D574, subStruct.field_4);
+ LZDecompressVram(&gUnknown_08D1D410, subStruct.field_0);
+ LoadCompressedPalette(&gUnknown_08D1D54C, subStruct.field_8 << 4, 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)
+ sub_8079108(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] = var0;
+ gTasks[taskId].func = sub_80E0CD0;
+}
+
+static void sub_80E0CD0(u8 taskId)
+{
+ struct Struct_sub_8078914 subStruct;
+ u16 paletteNum;
+ u8 spriteId;
+ u8 taskIdCopy = taskId;
+
+ gTasks[taskIdCopy].data[10] += 4;
+ gBattle_BG1_X -= 4;
+
+ if (gTasks[taskIdCopy].data[10] == 128)
+ {
+ gTasks[taskIdCopy].data[10] = 0;
+ gBattle_BG1_X += 128;
+
+ if (++gTasks[taskIdCopy].data[11] == 2)
+ {
+ sub_8076464(0);
+ gBattle_WIN0H = 0;
+ gBattle_WIN0V = 0;
+ REG_WININ = 0x3F3F;
+ REG_WINOUT = 0x3F3F;
+
+ if (!IsContest())
+ REG_BG1CNT_BITFIELD.charBaseBlock = 0;
+
+ REG_DISPCNT ^= DISPCNT_OBJWIN_ON;
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+
+ spriteId = GetAnimBankSpriteId(0);
+ paletteNum = 16 + gSprites[spriteId].oam.paletteNum;
+ if (gTasks[taskIdCopy].data[1] == 0)
+ sub_8079108(paletteNum, 1);
+
+ DestroySprite(&gSprites[gTasks[taskIdCopy].data[0]]);
+ sub_8078914(&subStruct);
+ DmaClear32(3, subStruct.field_4, 0x800);
+
+ if (gTasks[taskIdCopy].data[6] == 1)
+ {
+ gSprites[gObjectBankIDs[gAnimBankAttacker ^ 2]].oam.priority++;
+ }
+
+ DestroyAnimVisualTask(taskIdCopy);
+ }
+ }
+}
+
+void sub_80E0E24(u8 taskId)
+{
+ u8 spriteId;
+ u8 bank;
+ bool8 calcSpriteId = FALSE;
+ u8 identity = 0;
+
+ switch (gBattleAnimArgs[0])
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ spriteId = GetAnimBankSpriteId(gBattleAnimArgs[0]);
+ break;
+ case 4:
+ identity = IDENTITY_PLAYER_MON1;
+ calcSpriteId = TRUE;
+ break;
+ case 5:
+ identity = IDENTITY_PLAYER_MON2;
+ calcSpriteId = TRUE;
+ break;
+ case 6:
+ identity = IDENTITY_OPPONENT_MON1;
+ calcSpriteId = TRUE;
+ break;
+ case 7:
+ identity = IDENTITY_OPPONENT_MON2;
+ calcSpriteId = TRUE;
+ break;
+ default:
+ spriteId = 0xFF;
+ break;
+ }
+
+ if (calcSpriteId)
+ {
+ bank = GetBankByIdentity(identity);
+ if (IsAnimBankSpriteVisible(bank))
+ spriteId = gObjectBankIDs[bank];
+ else
+ spriteId = 0xFF;
+ }
+
+ if (spriteId != 0xFF)
+ sub_8079108(gSprites[spriteId].oam.paletteNum + 16, gBattleAnimArgs[1]);
+
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80E0EE8(u8 taskId)
+{
+ if (gAnimMoveTurn < 2)
+ gBattleAnimArgs[7] = 0;
+
+ if (gAnimMoveTurn == 2)
+ gBattleAnimArgs[7] = 1;
+
+ DestroyAnimVisualTask(taskId);
+}
diff --git a/src/battle/anim/dragon.c b/src/battle/anim/dragon.c
new file mode 100644
index 000000000..bf39e01c0
--- /dev/null
+++ b/src/battle/anim/dragon.c
@@ -0,0 +1,275 @@
+#include "global.h"
+#include "rom_8077ABC.h"
+#include "trig.h"
+#include "battle_anim.h"
+#include "sound.h"
+#include "scanline_effect.h"
+
+void sub_80DF81C(struct Sprite *sprite);
+void sub_80DFBD8(struct Sprite *sprite);
+
+void sub_80DF9F4(u8 taskId);
+
+void sub_80DFAB0(struct Task *task);
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankAttacker;
+extern u8 gAnimBankTarget;
+extern u8 gBankAttacker;
+extern u16 gBattle_BG1_X;
+extern u16 gBattle_BG2_X;
+extern u16 gUnknown_03000730[];
+extern u8 gObjectBankIDs[];
+
+// Outrage
+
+void sub_80DF5A0(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3);
+ if (GetBankSide(gAnimBankAttacker))
+ {
+ 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 = 1;
+ StoreSpriteCallbackInData(sprite, move_anim_8074EE0);
+ sprite->callback = sub_8078504;
+}
+
+// part of Dragon Breath
+
+void sub_80DF63C(struct Sprite *sprite)
+{
+ sub_8078650(sprite);
+ sprite->data[2] = GetBankPosition(gAnimBankTarget, 2);
+ sprite->data[4] = GetBankPosition(gAnimBankTarget, 3);
+ if (GetBankSide(gAnimBankAttacker))
+ {
+ 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 = sub_8078B34;
+ StoreSpriteCallbackInData(sprite, move_anim_8074EE0);
+}
+
+// Dragon Rage
+
+void sub_80DF6F0(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 0);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 1);
+ }
+ else
+ {
+ sprite->pos1.x = GetBankPosition(gAnimBankTarget, 0);
+ sprite->pos1.y = GetBankPosition(gAnimBankTarget, 1);
+ }
+ sub_807867C(sprite, gBattleAnimArgs[1]);
+ sprite->pos1.y += gBattleAnimArgs[2];
+ sprite->callback = sub_8078600;
+ StoreSpriteCallbackInData(sprite, move_anim_8074EE0);
+}
+
+// Dragon Breath init
+
+void sub_80DF760(struct Sprite *sprite)
+{
+ if (GetBankSide(gAnimBankAttacker))
+ StartSpriteAffineAnim(sprite, 1);
+ sub_80DF63C(sprite);
+}
+
+//next 2 tasks might be Dragon Dance orbs?
+
+void sub_80DF78C(struct Sprite *sprite)
+{
+ u16 r5;
+ u16 r0;
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3);
+ sprite->data[4] = 0;
+ sprite->data[5] = 1;
+ sprite->data[6] = gBattleAnimArgs[0];
+ r5 = sub_807A100(gBankAttacker, 0);
+ r0 = sub_807A100(gBankAttacker, 1);
+ 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_80DF81C;
+}
+
+void sub_80DF81C(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;
+ }
+}
+
+// Dragon Dance scanline eff
+
+void sub_80DF924(u8 taskId)
+{
+ struct ScanlineEffectParams sp;
+ struct Task *task = &gTasks[taskId];
+ u16 i;
+ u8 r1;
+ if (GetBankIdentity_permutated(gAnimBankAttacker) == 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 = sub_8077FC0(gAnimBankAttacker);
+ 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_80DF9F4;
+}
+
+void sub_80DF9F4(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_80DFAB0(task);
+ break;
+ case 1:
+ if (++task->data[1] > 0x3C)
+ task->data[0]++;
+ sub_80DFAB0(task);
+ break;
+ case 2:
+ if (++task->data[7] > 1)
+ {
+ task->data[7] = 0;
+ if (--task->data[6] == 0)
+ task->data[0]++;
+ }
+ sub_80DFAB0(task);
+ break;
+ case 3:
+ gScanlineEffect.state = 3;
+ task->data[0]++;
+ break;
+ case 4:
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80DFAB0(struct Task *task)
+{
+ u16 r3 = task->data[5];
+ u16 i;
+ 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;
+}
+
+// Overheat
+
+void sub_80DFB28(struct Sprite *sprite)
+{
+ int r6 = (gBattleAnimArgs[2] * 3) / 5;
+ int i;
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 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_80DFBD8;
+ for (i = 0; i <= 6; i++)
+ gUnknown_03000730[i] = sprite->data[i];
+}
+
+void sub_80DFBD8(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/battle/anim/draw.c b/src/battle/anim/draw.c
index 3adb62e06..f9e505bf2 100755..100644
--- a/src/battle/anim/draw.c
+++ b/src/battle/anim/draw.c
@@ -3,7 +3,7 @@
#include "trig.h"
#include "battle_anim.h"
#include "sound.h"
-#include "unknown_task.h"
+#include "scanline_effect.h"
extern s16 gBattleAnimArgs[];
extern u8 gAnimBankAttacker;
@@ -21,7 +21,8 @@ static void sub_80D0E8C(struct Sprite* sprite);
void sub_80D0C88(u8 taskId)
{
struct Task* task = &gTasks[taskId];
- struct UnknownTaskStruct sp;
+ struct ScanlineEffectParams params;
+
s16 i;
task->data[0] = sub_8077FC0(gAnimBankTarget) + 32;
task->data[1] = 4;
@@ -30,30 +31,31 @@ void sub_80D0C88(u8 taskId)
task->data[4] = 0;
task->data[5] = 0;
task->data[15] = sub_807A100(gAnimBankTarget, 0);
+
if (GetBankIdentity_permutated(gAnimBankTarget) == 1)
{
task->data[6] = gBattle_BG1_X;
- sp.dest = (u16 *)REG_ADDR_BG1HOFS;
+ params.dmaDest = (u16 *)REG_ADDR_BG1HOFS;
}
else
{
task->data[6] = gBattle_BG2_X;
- sp.dest = (u16 *)REG_ADDR_BG2HOFS;
+ params.dmaDest = (u16 *)REG_ADDR_BG2HOFS;
}
for (i = task->data[0] - 0x40; i <= task->data[0];i++)
{
if (i >= 0)
{
- gUnknown_03004DE0[0][i] = task->data[6] + 0xF0;
- gUnknown_03004DE0[1][i] = task->data[6] + 0xF0;
+ gScanlineEffectRegBuffers[0][i] = task->data[6] + 0xF0;
+ gScanlineEffectRegBuffers[1][i] = task->data[6] + 0xF0;
}
}
- sp.control = 0xa2600001;
- sp.unk8 = 1;
- sp.unk9 = 0;
- sub_80895F8(sp);
+ params.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
+ params.initState = 1;
+ params.unused9 = 0;
+ ScanlineEffect_SetParams(params);
task->func = sub_80D0D68;
}
@@ -91,13 +93,13 @@ void sub_80D0D68(u8 taskId)
if (task->data[5] >= 0)
{
- gUnknown_03004DE0[0][task->data[5]] = task->data[6];
- gUnknown_03004DE0[1][task->data[5]] = task->data[6];
+ gScanlineEffectRegBuffers[0][task->data[5]] = task->data[6];
+ gScanlineEffectRegBuffers[1][task->data[5]] = task->data[6];
}
if (++task->data[3] >= task->data[15])
{
- gUnknown_03004DC0.unk15 = 3;
+ gScanlineEffect.unk15 = 3;
DestroyAnimVisualTask(taskId);
}
}
@@ -178,7 +180,7 @@ _080D0DE0:\n\
ldrsh r0, [r3, r1]\n\
cmp r0, 0\n\
blt _080D0E04\n\
- ldr r2, _080D0E28 @ =gUnknown_03004DE0\n\
+ ldr r2, _080D0E28 @ =gScanlineEffectRegBuffers\n\
lsls r0, 1\n\
adds r0, r2\n\
ldrh r1, [r3, 0x14]\n\
@@ -202,7 +204,7 @@ _080D0E04:\n\
ldrsh r1, [r3, r2]\n\
cmp r0, r1\n\
blt _080D0E22\n\
- ldr r1, _080D0E2C @ =gUnknown_03004DC0\n\
+ ldr r1, _080D0E2C @ =gScanlineEffect\n\
movs r0, 0x3\n\
strb r0, [r1, 0x15]\n\
adds r0, r4, 0\n\
@@ -212,8 +214,8 @@ _080D0E22:\n\
pop {r0}\n\
bx r0\n\
.align 2, 0\n\
-_080D0E28: .4byte gUnknown_03004DE0\n\
-_080D0E2C: .4byte gUnknown_03004DC0\n\
+_080D0E28: .4byte gScanlineEffectRegBuffers\n\
+_080D0E2C: .4byte gScanlineEffect\n\
.syntax divided\n");
}
#endif
diff --git a/src/battle/anim/drum.c b/src/battle/anim/drum.c
index 6306778ae..6306778ae 100755..100644
--- a/src/battle/anim/drum.c
+++ b/src/battle/anim/drum.c
diff --git a/src/battle/anim/egg.c b/src/battle/anim/egg.c
index 8004b3bf5..8004b3bf5 100755..100644
--- a/src/battle/anim/egg.c
+++ b/src/battle/anim/egg.c
diff --git a/src/battle/anim/espeed.c b/src/battle/anim/espeed.c
index 469522092..469522092 100755..100644
--- a/src/battle/anim/espeed.c
+++ b/src/battle/anim/espeed.c
diff --git a/src/battle/anim/evasion.c b/src/battle/anim/evasion.c
index ded8428d4..ded8428d4 100755..100644
--- a/src/battle/anim/evasion.c
+++ b/src/battle/anim/evasion.c
diff --git a/src/battle/anim/fang.c b/src/battle/anim/fang.c
index 5ed7372a8..5ed7372a8 100755..100644
--- a/src/battle/anim/fang.c
+++ b/src/battle/anim/fang.c
diff --git a/src/battle/anim/fire_2.c b/src/battle/anim/fire_2.c
index 6dc304232..4d577a765 100644
--- a/src/battle/anim/fire_2.c
+++ b/src/battle/anim/fire_2.c
@@ -23,8 +23,8 @@ void sub_80D57C4(u8 spriteId, u8 taskId, u8 a3);
void sub_80D51A8(struct Sprite *sprite)
{
if (GetBankSide(gAnimBankAttacker) == GetBankSide(gAnimBankTarget)
- && (gAnimBankAttacker == GetBankByPlayerAI(2)
- || gAnimBankAttacker == GetBankByPlayerAI(3)))
+ && (gAnimBankAttacker == GetBankByIdentity(2)
+ || gAnimBankAttacker == GetBankByIdentity(3)))
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->callback = sub_8079534;
diff --git a/src/battle/anim/flash.c b/src/battle/anim/flash.c
index eaa38e5b7..eaa38e5b7 100755..100644
--- a/src/battle/anim/flash.c
+++ b/src/battle/anim/flash.c
diff --git a/src/battle/anim/flying_hearts.c b/src/battle/anim/flying_hearts.c
index d2d22602a..d2d22602a 100755..100644
--- a/src/battle/anim/flying_hearts.c
+++ b/src/battle/anim/flying_hearts.c
diff --git a/src/battle/anim/flying_path.c b/src/battle/anim/flying_path.c
index 441ac0e6d..441ac0e6d 100755..100644
--- a/src/battle/anim/flying_path.c
+++ b/src/battle/anim/flying_path.c
diff --git a/src/battle/anim/flying_petals.c b/src/battle/anim/flying_petals.c
index 4eeaa5215..4eeaa5215 100755..100644
--- a/src/battle/anim/flying_petals.c
+++ b/src/battle/anim/flying_petals.c
diff --git a/src/battle/anim/glitter.c b/src/battle/anim/glitter.c
index e4577f1e1..e4577f1e1 100755..100644
--- a/src/battle/anim/glitter.c
+++ b/src/battle/anim/glitter.c
diff --git a/src/battle/anim/glow.c b/src/battle/anim/glow.c
index 63466c0ff..63466c0ff 100755..100644
--- a/src/battle/anim/glow.c
+++ b/src/battle/anim/glow.c
diff --git a/src/battle/anim/grip.c b/src/battle/anim/grip.c
index c4d7b1cef..c4d7b1cef 100755..100644
--- a/src/battle/anim/grip.c
+++ b/src/battle/anim/grip.c
diff --git a/src/battle/anim/grow.c b/src/battle/anim/grow.c
index 8788b32fe..8788b32fe 100755..100644
--- a/src/battle/anim/grow.c
+++ b/src/battle/anim/grow.c
diff --git a/src/battle/anim/guard.c b/src/battle/anim/guard.c
index ab093eab1..254160109 100644
--- a/src/battle/anim/guard.c
+++ b/src/battle/anim/guard.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "battle.h"
#include "battle_anim.h"
#include "rom_8077ABC.h"
@@ -12,7 +13,7 @@ extern u16 gBattleTypeFlags;
void sub_80D3014(struct Sprite *sprite)
{
- if ((gBattleTypeFlags & 1) && IsAnimBankSpriteVisible(gAnimBankAttacker ^ 2))
+ if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsAnimBankSpriteVisible(gAnimBankAttacker ^ 2))
{
sub_807A3FC(gAnimBankAttacker, 0, &sprite->pos1.x, &sprite->pos1.y);
sprite->pos1.y += 40;
diff --git a/src/battle/anim/guillotine.c b/src/battle/anim/guillotine.c
index b3d842cdf..b3d842cdf 100755..100644
--- a/src/battle/anim/guillotine.c
+++ b/src/battle/anim/guillotine.c
diff --git a/src/battle/anim/heal.c b/src/battle/anim/heal.c
index a8c14ea1c..a8c14ea1c 100755..100644
--- a/src/battle/anim/heal.c
+++ b/src/battle/anim/heal.c
diff --git a/src/battle/anim/heart_1.c b/src/battle/anim/heart_1.c
index 5df89f929..5df89f929 100755..100644
--- a/src/battle/anim/heart_1.c
+++ b/src/battle/anim/heart_1.c
diff --git a/src/battle/anim/homing.c b/src/battle/anim/homing.c
index 6fb4a76d8..6fb4a76d8 100755..100644
--- a/src/battle/anim/homing.c
+++ b/src/battle/anim/homing.c
diff --git a/src/battle/anim/hop.c b/src/battle/anim/hop.c
index 4006e2d43..4006e2d43 100755..100644
--- a/src/battle/anim/hop.c
+++ b/src/battle/anim/hop.c
diff --git a/src/battle/anim/hop_2.c b/src/battle/anim/hop_2.c
index 1bc3f46af..1bc3f46af 100755..100644
--- a/src/battle/anim/hop_2.c
+++ b/src/battle/anim/hop_2.c
diff --git a/src/battle/anim/kiss_fountain.c b/src/battle/anim/kiss_fountain.c
index d3270ee65..d3270ee65 100755..100644
--- a/src/battle/anim/kiss_fountain.c
+++ b/src/battle/anim/kiss_fountain.c
diff --git a/src/battle/anim/leaf.c b/src/battle/anim/leaf.c
index 676734717..676734717 100755..100644
--- a/src/battle/anim/leaf.c
+++ b/src/battle/anim/leaf.c
diff --git a/src/battle/anim/love_bg.c b/src/battle/anim/love_bg.c
index bd3d22ca6..c3828c681 100755..100644
--- a/src/battle/anim/love_bg.c
+++ b/src/battle/anim/love_bg.c
@@ -25,7 +25,7 @@ static void sub_80D21F0(u8 taskId);
void sub_80D2100(u8 taskId)
{
struct Struct_sub_8078914 subStruct;
- u8* tempvar;
+
REG_BLDCNT = 0x3F42;
REG_BLDALPHA = 0x1000;
REG_BG1CNT_BITFIELD.priority = 3;
@@ -38,9 +38,8 @@ void sub_80D2100(u8 taskId)
REG_BG1HOFS = 0;
REG_BG1VOFS = 0;
sub_8078914(&subStruct);
- tempvar = subStruct.field_4;
- DmaFill32(3, 0x0, tempvar, 0x1000);
- LZDecompressVram(&gAttractTilemap, tempvar);
+ DmaFill32Defvars(3, 0, subStruct.field_4, 0x1000);
+ LZDecompressVram(&gAttractTilemap, subStruct.field_4);
LZDecompressVram(&gAttractGfx, subStruct.field_0);
LoadCompressedPalette(&gAttractPal, subStruct.field_8 << 4, 32);
if (IsContest())
@@ -90,21 +89,7 @@ void sub_80D21F0(u8 taskId)
break;
case 3:
sub_8078914(&subStruct);
- {
- u8 *addr = subStruct.field_0;
- u32 size = 0x2000;
- while (1)
- {
- DmaFill32(3, 0, addr, 0x1000);
- addr += 0x1000;
- size -= 0x1000;
- if (size <= 0x1000)
- {
- DmaFill32(3, 0, addr, size);
- break;
- }
- }
- }
+ DmaFill32Large(3, 0, subStruct.field_0, 0x2000, 0x1000);
DmaClear32(3, subStruct.field_4, 0x800);
if (!IsContest())
REG_BG1CNT_BITFIELD.charBaseBlock = 0;
diff --git a/src/battle/anim/lunge_1.c b/src/battle/anim/lunge_1.c
index d379c8f09..d379c8f09 100755..100644
--- a/src/battle/anim/lunge_1.c
+++ b/src/battle/anim/lunge_1.c
diff --git a/src/battle/anim/lunge_2.c b/src/battle/anim/lunge_2.c
index fe2470567..fe2470567 100755..100644
--- a/src/battle/anim/lunge_2.c
+++ b/src/battle/anim/lunge_2.c
diff --git a/src/battle/anim/money.c b/src/battle/anim/money.c
index 8358d23db..8358d23db 100755..100644
--- a/src/battle/anim/money.c
+++ b/src/battle/anim/money.c
diff --git a/src/battle/anim/moon.c b/src/battle/anim/moon.c
index c532e8057..c532e8057 100755..100644
--- a/src/battle/anim/moon.c
+++ b/src/battle/anim/moon.c
diff --git a/src/battle/anim/note_rain.c b/src/battle/anim/note_rain.c
index 715462d73..715462d73 100755..100644
--- a/src/battle/anim/note_rain.c
+++ b/src/battle/anim/note_rain.c
diff --git a/src/battle/anim/note_scatter.c b/src/battle/anim/note_scatter.c
index 8564c58fe..8564c58fe 100755..100644
--- a/src/battle/anim/note_scatter.c
+++ b/src/battle/anim/note_scatter.c
diff --git a/src/battle/anim/note_scatter_2.c b/src/battle/anim/note_scatter_2.c
index 524c51c08..524c51c08 100755..100644
--- a/src/battle/anim/note_scatter_2.c
+++ b/src/battle/anim/note_scatter_2.c
diff --git a/src/battle/anim/note_wave.c b/src/battle/anim/note_wave.c
index 80ed2256f..80ed2256f 100755..100644
--- a/src/battle/anim/note_wave.c
+++ b/src/battle/anim/note_wave.c
diff --git a/src/battle/anim/orbit.c b/src/battle/anim/orbit.c
index c8cf339d2..c8cf339d2 100755..100644
--- a/src/battle/anim/orbit.c
+++ b/src/battle/anim/orbit.c
diff --git a/src/battle/anim/orbit_fast.c b/src/battle/anim/orbit_fast.c
index 92b67672b..92b67672b 100755..100644
--- a/src/battle/anim/orbit_fast.c
+++ b/src/battle/anim/orbit_fast.c
diff --git a/src/battle/anim/orbit_scatter.c b/src/battle/anim/orbit_scatter.c
index 54c157839..54c157839 100755..100644
--- a/src/battle/anim/orbit_scatter.c
+++ b/src/battle/anim/orbit_scatter.c
diff --git a/src/battle/anim/orbs.c b/src/battle/anim/orbs.c
index 6ca2fa71c..6ca2fa71c 100755..100644
--- a/src/battle/anim/orbs.c
+++ b/src/battle/anim/orbs.c
diff --git a/src/battle/anim/osmose.c b/src/battle/anim/osmose.c
index 1140aa34a..1140aa34a 100755..100644
--- a/src/battle/anim/osmose.c
+++ b/src/battle/anim/osmose.c
diff --git a/src/battle/anim/perceive.c b/src/battle/anim/perceive.c
index 3b3153428..3b3153428 100755..100644
--- a/src/battle/anim/perceive.c
+++ b/src/battle/anim/perceive.c
diff --git a/src/battle/anim/poison.c b/src/battle/anim/poison.c
new file mode 100644
index 000000000..f31c441fb
--- /dev/null
+++ b/src/battle/anim/poison.c
@@ -0,0 +1,140 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "rom_8077ABC.h"
+#include "trig.h"
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankAttacker;
+extern u8 gAnimBankTarget;
+
+void sub_80D9DD4(struct Sprite *sprite);
+void sub_80D9E78(struct Sprite *sprite);
+void sub_80D9EE8(struct Sprite *sprite);
+void sub_80D9FF0(struct Sprite *sprite);
+
+void sub_80D9D70(struct Sprite *sprite)
+{
+ if (!gBattleAnimArgs[3])
+ StartSpriteAnim(sprite, 2);
+
+ sub_80787B0(sprite, 1);
+
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[2] = GetBankPosition(gAnimBankTarget, 2);
+ sprite->data[4] = GetBankPosition(gAnimBankTarget, 3);
+ sprite->data[5] = -30;
+
+ sub_80786EC(sprite);
+
+ sprite->callback = sub_80D9DD4;
+}
+
+void sub_80D9DD4(struct Sprite *sprite) // same as sub_80D9E78
+{
+ if (sub_8078718(sprite))
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80D9DF0(struct Sprite *sprite)
+{
+ s16 l1, l2;
+ if (!gBattleAnimArgs[3])
+ StartSpriteAnim(sprite, 2);
+
+ sub_80787B0(sprite, 1);
+ sub_807A3FC(gAnimBankTarget, 1, &l1, &l2);
+
+ if (GetBankSide(gAnimBankAttacker))
+ gBattleAnimArgs[4] = -gBattleAnimArgs[4];
+
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[2] = l1 + gBattleAnimArgs[4];
+ sprite->data[4] = l2 + gBattleAnimArgs[5];
+ sprite->data[5] = -30;
+
+ sub_80786EC(sprite);
+
+ sprite->callback = sub_80D9E78;
+}
+
+void sub_80D9E78(struct Sprite *sprite) // same as sub_80D9DD4
+{
+ if (sub_8078718(sprite))
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80D9E94(struct Sprite *sprite)
+{
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[0];
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[1];
+
+ sub_8078A5C(sprite);
+
+ sprite->data[5] = sprite->data[1] / gBattleAnimArgs[2];
+ sprite->data[6] = sprite->data[2] / gBattleAnimArgs[2];
+
+ sprite->callback = sub_80D9EE8;
+}
+
+void sub_80D9EE8(struct Sprite *sprite)
+{
+ sub_8078394(sprite);
+
+ sprite->data[1] -= sprite->data[5];
+ sprite->data[2] -= sprite->data[6];
+
+ if (!sprite->data[0])
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80D9F14(struct Sprite *sprite)
+{
+ sub_807A3FC(gAnimBankTarget, TRUE, &sprite->pos1.x, &sprite->pos1.y);
+
+ if (GetBankSide(gAnimBankAttacker))
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2];
+ sprite->data[4] = sprite->pos1.y + sprite->data[0];
+
+ sprite->callback = sub_8078B34;
+ StoreSpriteCallbackInData(sprite, DestroyAnimSprite);
+}
+
+void sub_80D9F88(struct Sprite *sprite)
+{
+ if (!gBattleAnimArgs[2])
+ {
+ sub_8078764(sprite, TRUE);
+ }
+ else
+ {
+ sub_807A3FC(gAnimBankTarget, TRUE, &sprite->pos1.x, &sprite->pos1.y);
+
+ if (GetBankSide(gAnimBankAttacker))
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+
+ sprite->callback = sub_80D9FF0;
+}
+
+void sub_80D9FF0(struct Sprite *sprite)
+{
+ sprite->data[0] = (sprite->data[0] + 0xB) & 0xFF;
+ sprite->pos2.x = Sin(sprite->data[0], 4);
+ sprite->data[1] += 0x30;
+ sprite->pos2.y = -(sprite->data[1] >> 8);
+
+ if (sprite->affineAnimEnded)
+ DestroyAnimSprite(sprite);
+} \ No newline at end of file
diff --git a/src/battle/anim/powder.c b/src/battle/anim/powder.c
index a0be20d6f..a0be20d6f 100755..100644
--- a/src/battle/anim/powder.c
+++ b/src/battle/anim/powder.c
diff --git a/src/battle/anim/psychic.c b/src/battle/anim/psychic.c
new file mode 100644
index 000000000..6617183cb
--- /dev/null
+++ b/src/battle/anim/psychic.c
@@ -0,0 +1,900 @@
+#include "global.h"
+#include "battle.h"
+#include "battle_anim.h"
+#include "palette.h"
+#include "rom_8077ABC.h"
+#include "scanline_effect.h"
+#include "sound.h"
+#include "task.h"
+#include "trig.h"
+#include "constants/songs.h"
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankAttacker;
+extern u8 gAnimBankTarget;
+extern u16 gBattle_BG1_X;
+extern u16 gBattle_BG2_X;
+extern u8 gObjectBankIDs[];
+
+extern const union AffineAnimCmd *const gUnknown_083DA888[];
+extern struct AffineAnimFrameCmd gUnknown_083DA8A4;
+extern struct AffineAnimFrameCmd gUnknown_083DA8C4;
+extern const struct SpriteTemplate gSpriteTemplate_83DA8DC;
+extern const struct SpriteTemplate gSpriteTemplate_83DA9AC;
+
+static void sub_80DB88C(struct Sprite *sprite);
+static void sub_80DB8C0(struct Sprite *sprite);
+static void sub_80DB92C(struct Sprite *sprite);
+static void sub_80DB9E4(struct Sprite *sprite);
+static void sub_80DBC00(struct Sprite *sprite);
+static void sub_80DBC34(struct Sprite *sprite);
+static void sub_80DBCD0(u8 taskId);
+static void sub_80DBD58(u8 taskId);
+static void sub_80DBE98(u8 taskId);
+static void sub_80DC1FC(u8 taskId);
+static void sub_80DC3F4(u8 taskId);
+void sub_80DC5F4(u8 taskId);
+
+
+void sub_80DB74C(struct Sprite *sprite)
+{
+ if (GetBankSide(gAnimBankAttacker) == SIDE_PLAYER || IsContest())
+ {
+ sprite->oam.priority = 2;
+ sprite->subpriority = 200;
+ }
+
+ if (!IsContest())
+ {
+ u8 bankCopy;
+ u8 bank = bankCopy = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
+ u8 identity = GetBankIdentity_permutated(bank);
+ int var0 = 1;
+ u8 toBG_2 = (identity ^ var0) != 0;
+
+ if (IsAnimBankSpriteVisible(bank))
+ sub_8076034(bank, toBG_2);
+
+ bank = bankCopy ^ 2;
+ if (IsAnimBankSpriteVisible(bank))
+ sub_8076034(bank, toBG_2 ^ var0);
+ }
+
+ if (!IsContest() && IsDoubleBattle())
+ {
+ if (GetBankSide(gAnimBankAttacker) == SIDE_PLAYER)
+ {
+ sprite->pos1.x = 72;
+ sprite->pos1.y = 80;
+ }
+ else
+ {
+ sprite->pos1.x = 176;
+ sprite->pos1.y = 40;
+ }
+ }
+ else
+ {
+ if (GetBankSide(gAnimBankAttacker) != SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 0) + gBattleAnimArgs[0];
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 1) + gBattleAnimArgs[1];
+ }
+
+ if (IsContest())
+ sprite->pos1.y += 9;
+
+ sprite->data[0] = 256 + IndexOfSpritePaletteTag(gBattleAnimArgs[2]) * 16;
+ sprite->callback = sub_80DB88C;
+ sprite->callback(sprite);
+}
+
+static void sub_80DB88C(struct Sprite *sprite)
+{
+ REG_BLDALPHA = ((16 - sprite->data[3]) << 8) | sprite->data[3];
+
+ if (sprite->data[3] == 13)
+ sprite->callback = sub_80DB8C0;
+ else
+ sprite->data[3]++;
+}
+
+static void sub_80DB8C0(struct Sprite *sprite)
+{
+ u16 color;
+ u16 startOffset;
+ int 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_80DB92C;
+ }
+}
+
+static void sub_80DB92C(struct Sprite *sprite)
+{
+ REG_BLDALPHA = ((16 - sprite->data[3]) << 8) | sprite->data[3];
+
+ if (--sprite->data[3] == -1)
+ {
+ if (!IsContest())
+ {
+ u8 bankCopy;
+ u8 bank = bankCopy = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
+
+ if (IsAnimBankSpriteVisible(bank))
+ gSprites[gObjectBankIDs[bank]].invisible = 0;
+
+ bank = bankCopy ^ 2;
+ if (IsAnimBankSpriteVisible(bank))
+ gSprites[gObjectBankIDs[bank]].invisible = 0;
+ }
+
+ sprite->invisible = 1;
+ sprite->callback = sub_80DB9E4;
+ }
+}
+
+static void sub_80DB9E4(struct Sprite *sprite)
+{
+ if (!IsContest())
+ {
+ u8 bankCopy;
+ u8 bank = bankCopy = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
+ u8 identity = GetBankIdentity_permutated(bank);
+ int var0 = 1;
+ u8 toBG_2 = (identity ^ var0) != 0;
+
+ if (IsAnimBankSpriteVisible(bank))
+ sub_8076464(toBG_2);
+
+ bank = bankCopy ^ 2;
+ if (IsAnimBankSpriteVisible(bank))
+ sub_8076464(toBG_2 ^ var0);
+ }
+
+ sprite->callback = DestroyAnimSprite;
+}
+
+void sub_80DBA4C(struct Sprite *sprite)
+{
+ if (sprite->data[0] == 0)
+ {
+ int arg3 = gBattleAnimArgs[3];
+ u8 var0 = 0;
+ if (arg3 == 0)
+ var0 = 1;
+
+ if (!IsContest() && IsDoubleBattle())
+ {
+ if (GetBankSide(gAnimBankAttacker) == 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)
+ sub_80787B0(sprite, var0);
+ else
+ sub_8078764(sprite, var0);
+ }
+
+ sprite->data[0]++;
+ }
+ else
+ {
+ if (sprite->animEnded || sprite->affineAnimEnded)
+ move_anim_8074EE0(sprite);
+ }
+}
+
+void sub_80DBAF4(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3);
+
+ if (GetBankSide(gAnimBankAttacker) != 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;
+ }
+
+ StoreSpriteCallbackInData(sprite, DestroyAnimSprite);
+ sprite->callback = sub_8078600;
+}
+
+void sub_80DBB70(struct Sprite *sprite)
+{
+ s16 x = sub_807A100(gAnimBankAttacker, 1) / 2;
+ s16 y = sub_807A100(gAnimBankAttacker, 0) / -2;
+
+ if (GetBankSide(gAnimBankAttacker) == SIDE_OPPONENT)
+ {
+ x = -x;
+ }
+
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2) + x;
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3) + y;
+
+ if (sprite->pos1.y < 16)
+ {
+ sprite->pos1.y = 16;
+ }
+
+ StoreSpriteCallbackInData(sprite, sub_80DBC00);
+ sprite->callback = sub_8078600;
+}
+
+static void sub_80DBC00(struct Sprite *sprite)
+{
+ sprite->oam.affineMode = 1;
+ sprite->affineAnims = gUnknown_083DA888;
+ sprite->data[0] = 0;
+ InitSpriteAffineAnim(sprite);
+ sprite->callback = sub_80DBC34;
+}
+
+static void sub_80DBC34(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (sprite->affineAnimEnded)
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->oam.affineMode = 0;
+ sprite->data[1] = 18;
+ sprite->data[0]++;
+ }
+ break;
+ case 1:
+ if (--sprite->data[1] == -1)
+ {
+ DestroyAnimSprite(sprite);
+ }
+ break;
+ }
+}
+
+void sub_80DBC94(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ u8 spriteId = GetAnimBankSpriteId(0);
+ task->data[0] = spriteId;
+ sub_80798F4(task, spriteId, &gUnknown_083DA8A4);
+ task->func = sub_80DBCD0;
+}
+
+static void sub_80DBCD0(u8 taskId)
+{
+ if (!sub_807992C(&gTasks[taskId]))
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+void sub_80DBCFC(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ u8 spriteId = GetAnimBankSpriteId(0);
+ task->data[0] = spriteId;
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->data[3] = GetBankSide(gAnimBankAttacker) != SIDE_PLAYER ? 4 : 8;
+
+ sub_80798F4(task, task->data[0], &gUnknown_083DA8C4);
+ task->func = sub_80DBD58;
+}
+
+static void sub_80DBD58(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[1])
+ {
+ case 0:
+ sub_807992C(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 = 1;
+ gSprites[task->data[0]].pos1.x = 272;
+ sub_8078F40(task->data[0]);
+ DestroyAnimVisualTask(taskId);
+ }
+ break;
+ }
+}
+
+void sub_80DBE00(u8 taskId)
+{
+ u16 var0, var1;
+
+ struct Task *task = &gTasks[taskId];
+
+ task->data[3] = 16;
+ task->data[4] = 0;
+ task->data[13] = GetBankPosition(gAnimBankAttacker, 2);
+ task->data[14] = GetBankPosition(gAnimBankAttacker, 3);
+
+ var0 = sub_807A100(gAnimBankAttacker, 1) / 3;
+ var1 = sub_807A100(gAnimBankAttacker, 0) / 3;
+ task->data[12] = var0 > var1 ? var0 : var1;
+
+ REG_BLDCNT = 0x3F40;
+ REG_BLDALPHA = 0x10;
+
+ task->func = sub_80DBE98;
+}
+
+static void sub_80DBE98(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(&gSpriteTemplate_83DA8DC, task->data[13], task->data[14], 0);
+ task->data[task->data[2] + 8] = spriteId;
+
+ if (spriteId != 64)
+ {
+ 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]++;
+
+ REG_BLDALPHA = (task->data[4] << 8) | task->data[3];
+
+ 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:
+ REG_BLDALPHA = 0;
+ REG_BLDCNT = 0;
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80DC020(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]++;
+}
+
+void sub_80DC068(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3);
+ }
+
+ sprite->data[0] = gBattleAnimArgs[1];
+ sprite->callback = sub_80DC020;
+}
+
+void sub_80DC0B0(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (IsContest())
+ {
+ if (gBattleAnimArgs[0] == 1)
+ {
+ task->data[10] = -10;
+ task->data[11] = sub_807A100(gAnimBankTarget, 5) - 8;
+ task->data[12] = sub_807A100(gAnimBankTarget, 2) + 8;
+ task->data[13] = sub_807A100(gAnimBankAttacker, 5) - 8;
+ task->data[14] = sub_807A100(gAnimBankAttacker, 2) + 8;
+ }
+ else
+ {
+ task->data[10] = 10;
+ task->data[11] = sub_807A100(gAnimBankAttacker, 4) + 8;
+ task->data[12] = sub_807A100(gAnimBankAttacker, 3) - 8;
+ task->data[13] = sub_807A100(gAnimBankTarget, 4) + 8;
+ task->data[14] = sub_807A100(gAnimBankTarget, 3) - 8;
+ }
+ }
+ else
+ {
+ if (gBattleAnimArgs[0] == 1)
+ {
+ task->data[10] = -10;
+ task->data[11] = sub_807A100(gAnimBankTarget, 4) + 8;
+ task->data[12] = sub_807A100(gAnimBankTarget, 2) + 8;
+ task->data[13] = sub_807A100(gAnimBankAttacker, 4) + 8;
+ task->data[14] = sub_807A100(gAnimBankAttacker, 2) + 8;
+ }
+ else
+ {
+ task->data[10] = 10;
+ task->data[11] = sub_807A100(gAnimBankAttacker, 5) - 8;
+ task->data[12] = sub_807A100(gAnimBankAttacker, 3) - 8;
+ task->data[13] = sub_807A100(gAnimBankTarget, 5) - 8;
+ task->data[14] = sub_807A100(gAnimBankTarget, 3) - 8;
+ }
+ }
+
+ task->data[1] = 6;
+ task->func = sub_80DC1FC;
+}
+
+static void sub_80DC1FC(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(&gSpriteTemplate_83DA9AC, 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];
+
+ sub_80786EC(&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;
+ }
+}
+
+void sub_80DC2B0(struct Sprite *sprite)
+{
+ if (sub_8078718(sprite))
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ DestroySprite(sprite);
+ }
+}
+
+void sub_80DC2D4(u8 taskId)
+{
+ s16 i;
+ u8 var1;
+ struct ScanlineEffectParams scanlineParams;
+ struct Task *task = &gTasks[taskId];
+
+ var1 = sub_8077FC0(gAnimBankTarget);
+ task->data[14] = var1 - 32;
+
+ switch (gBattleAnimArgs[0])
+ {
+ case 0:
+ task->data[11] = 2;
+ task->data[12] = 5;
+ task->data[13] = 64;
+ task->data[15] = var1 + 32;
+ break;
+ case 1:
+ task->data[11] = 2;
+ task->data[12] = 5;
+ task->data[13] = 192;
+ task->data[15] = var1 + 32;
+ break;
+ case 2:
+ task->data[11] = 4;
+ task->data[12] = 4;
+ task->data[13] = 0;
+ task->data[15] = var1 + 32;
+ break;
+ }
+
+ if (task->data[14] < 0)
+ task->data[14] = 0;
+
+ if (GetBankIdentity_permutated(gAnimBankTarget) == 1)
+ {
+ task->data[10] = gBattle_BG1_X;
+ scanlineParams.dmaDest = &REG_BG1HOFS;
+ }
+ else
+ {
+ task->data[10] = gBattle_BG2_X;
+ scanlineParams.dmaDest = &REG_BG2HOFS;
+ }
+
+ i = task->data[14];
+ while (i <= task->data[14] + 64)
+ {
+ gScanlineEffectRegBuffers[0][i] = task->data[10];
+ gScanlineEffectRegBuffers[1][i] = task->data[10];
+ i++;
+ }
+
+ scanlineParams.dmaControl = 0XA2600001;
+ scanlineParams.initState = 1;
+ scanlineParams.unused9 = 0;
+ ScanlineEffect_SetParams(scanlineParams);
+
+ task->func = sub_80DC3F4;
+}
+
+static void sub_80DC3F4(u8 taskId)
+{
+ s16 sineIndex, i;
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ sineIndex = task->data[13];
+ i = task->data[14];
+ while (i <= task->data[15])
+ {
+ 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];
+ i++;
+ }
+
+ if (++task->data[1] > 23)
+ {
+ task->data[0]++;
+ }
+ break;
+ case 1:
+ gScanlineEffect.state = 3;
+ task->data[0]++;
+ break;
+ case 2:
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+#ifdef NONMATCHING
+void sub_80DC4F4(u8 taskId)
+{
+ s16 spriteId;
+ u8 matrixNum;
+ register u8 matrixNum2 asm("r6");
+ struct Task *task = &gTasks[taskId];
+
+ matrixNum = AllocOamMatrix();
+ matrixNum2 = matrixNum;
+ if (matrixNum2 == 0xFF)
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+
+ spriteId = duplicate_obj_of_side_rel2move_in_transparent_mode(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 = matrixNum2;
+ gSprites[spriteId].affineAnimPaused = 1;
+ gSprites[spriteId].subpriority++;
+ obj_id_set_rotscale(spriteId, 256, 256, 0);
+ CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
+
+ task->data[13] = GetAnimBankSpriteId(gBattleAnimArgs[0]);
+ task->data[14] = matrixNum;
+ task->data[15] = spriteId;
+ task->func = sub_80DC5F4;
+}
+#else
+__attribute__((naked))
+void sub_80DC4F4(u8 taskId)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ mov r8, r4\n\
+ lsls r0, r4, 2\n\
+ adds r0, r4\n\
+ lsls r0, 3\n\
+ ldr r1, _080DC528 @ =gTasks\n\
+ adds r7, r0, r1\n\
+ bl AllocOamMatrix\n\
+ lsls r0, 24\n\
+ lsrs r5, r0, 24\n\
+ mov r10, r5\n\
+ adds r6, r5, 0\n\
+ cmp r6, 0xFF\n\
+ bne _080DC52C\n\
+ adds r0, r4, 0\n\
+ bl DestroyAnimVisualTask\n\
+ b _080DC5D6\n\
+ .align 2, 0\n\
+_080DC528: .4byte gTasks\n\
+_080DC52C:\n\
+ ldr r1, _080DC550 @ =gBattleAnimArgs\n\
+ ldrb r0, [r1]\n\
+ bl duplicate_obj_of_side_rel2move_in_transparent_mode\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ mov r9, r1\n\
+ asrs r0, 16\n\
+ cmp r0, 0\n\
+ bge _080DC554\n\
+ adds r0, r5, 0\n\
+ bl FreeOamMatrix\n\
+ mov r0, r8\n\
+ bl DestroyAnimVisualTask\n\
+ b _080DC5D6\n\
+ .align 2, 0\n\
+_080DC550: .4byte gBattleAnimArgs\n\
+_080DC554:\n\
+ ldr r2, _080DC5E4 @ =gSprites\n\
+ lsls r4, r0, 4\n\
+ adds r4, r0\n\
+ lsls r4, 2\n\
+ adds r0, r2, 0\n\
+ adds r0, 0x1C\n\
+ adds r0, r4, r0\n\
+ ldr r1, _080DC5E8 @ =SpriteCallbackDummy\n\
+ str r1, [r0]\n\
+ adds r4, r2\n\
+ ldrb r0, [r4, 0x1]\n\
+ movs r1, 0x3\n\
+ orrs r0, r1\n\
+ strb r0, [r4, 0x1]\n\
+ movs r0, 0x1F\n\
+ ands r6, r0\n\
+ lsls r2, r6, 1\n\
+ ldrb r1, [r4, 0x3]\n\
+ movs r0, 0x3F\n\
+ negs r0, r0\n\
+ ands r0, r1\n\
+ orrs r0, r2\n\
+ strb r0, [r4, 0x3]\n\
+ adds r2, r4, 0\n\
+ adds r2, 0x2C\n\
+ ldrb r0, [r2]\n\
+ movs r1, 0x80\n\
+ orrs r0, r1\n\
+ strb r0, [r2]\n\
+ adds r1, r4, 0\n\
+ adds r1, 0x43\n\
+ ldrb r0, [r1]\n\
+ adds r0, 0x1\n\
+ strb r0, [r1]\n\
+ mov r1, r9\n\
+ lsls r0, r1, 24\n\
+ lsrs r0, 24\n\
+ movs r2, 0x80\n\
+ lsls r2, 1\n\
+ adds r1, r2, 0\n\
+ movs r3, 0\n\
+ bl obj_id_set_rotscale\n\
+ ldrb r3, [r4, 0x1]\n\
+ lsrs r1, r3, 6\n\
+ ldrb r2, [r4, 0x3]\n\
+ lsrs r2, 6\n\
+ lsls r3, 30\n\
+ lsrs r3, 30\n\
+ adds r0, r4, 0\n\
+ bl CalcCenterToCornerVec\n\
+ ldr r1, _080DC5EC @ =gBattleAnimArgs\n\
+ ldrb r0, [r1]\n\
+ bl GetAnimBankSpriteId\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ strh r0, [r7, 0x22]\n\
+ mov r0, r10\n\
+ strh r0, [r7, 0x24]\n\
+ mov r1, r9\n\
+ strh r1, [r7, 0x26]\n\
+ ldr r0, _080DC5F0 @ =sub_80DC5F4\n\
+ str r0, [r7]\n\
+_080DC5D6:\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\
+_080DC5E4: .4byte gSprites\n\
+_080DC5E8: .4byte SpriteCallbackDummy\n\
+_080DC5EC: .4byte gBattleAnimArgs\n\
+_080DC5F0: .4byte sub_80DC5F4\n\
+ .syntax divided\n");
+}
+#endif // NONMATCHING
+
+void sub_80DC5F4(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);
+ obj_id_set_rotscale(task->data[15], task->data[2], task->data[2], 0);
+ sub_8079AB8(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);;
+ obj_id_set_rotscale(task->data[15], task->data[2], task->data[2], 0);
+ sub_8079AB8(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;
+ }
+}
+
+void sub_80DC700(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 0);
+ sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 1);
+
+ if (IsContest())
+ sprite->pos1.y += 12;
+
+ sprite->data[1] = 8;
+ REG_BLDCNT = 0x3F40;
+ REG_BLDALPHA = ((16 - sprite->data[1]) << 8) | 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]--;
+ REG_BLDALPHA = ((16 - sprite->data[1]) << 8) | sprite->data[1];
+
+ if (sprite->data[1] == 0)
+ {
+ sprite->data[0]++;
+ sprite->invisible = 1;
+ }
+ }
+
+ sprite->data[3] += 896;
+ sprite->pos2.y -= sprite->data[3] >> 8;
+ sprite->data[3] &= 0xFF;
+ break;
+ case 3:
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ DestroyAnimSprite(sprite);
+ break;
+ }
+}
diff --git a/src/battle/anim/ring.c b/src/battle/anim/ring.c
index 915cadcbc..915cadcbc 100755..100644
--- a/src/battle/anim/ring.c
+++ b/src/battle/anim/ring.c
diff --git a/src/battle/anim/rock.c b/src/battle/anim/rock.c
new file mode 100644
index 000000000..b113ce040
--- /dev/null
+++ b/src/battle/anim/rock.c
@@ -0,0 +1,602 @@
+#include "global.h"
+#include "battle.h"
+#include "battle_anim.h"
+#include "decompress.h"
+#include "palette.h"
+#include "rom_8077ABC.h"
+#include "sound.h"
+#include "task.h"
+#include "trig.h"
+#include "constants/songs.h"
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankAttacker;
+extern u8 gAnimBankTarget;
+extern u32 gAnimMoveDmg;
+extern u16 gBattle_BG1_X;
+extern u16 gBattle_BG1_Y;
+extern u16 gBattle_BG3_Y;
+
+extern const u8 gBattleAnimBackgroundTilemap_SandstormBrew[];
+extern const u8 gBattleAnimBackgroundImage_SandstormBrew[];
+extern const u16 gBattleAnimSpritePalette_261[];
+extern const struct SpriteTemplate gSpriteTemplate_83DAD78;
+extern const struct SpriteTemplate gSpriteTemplate_83DAD90;
+
+extern const struct SubspriteTable gUnknown_083DAD10;
+
+static void sub_80DCF1C(struct Sprite *sprite);
+static void sub_80DD02C(struct Sprite *sprite);
+static void sub_80DD190(u8 taskId);
+static void sub_80DD604(u8 taskId);
+static void sub_80DD774(struct Task *task);
+static u8 sub_80DD8BC(void);
+static void sub_80DD928(struct Sprite *sprite);
+static void sub_80DD9FC(struct Sprite *sprite);
+
+
+void sub_80DCE9C(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[3] != 0)
+ sub_807A3FC(gAnimBankTarget, 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];
+
+ StoreSpriteCallbackInData(sprite, sub_80DCF1C);
+ sprite->callback = sub_8078278;
+ sprite->callback(sprite);
+}
+
+static void sub_80DCF1C(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;
+
+ StoreSpriteCallbackInData(sprite, move_anim_8074EE0);
+ sprite->callback = sub_8078278;
+ sprite->callback(sprite);
+}
+
+void sub_80DCF60(struct Sprite *sprite)
+{
+ StartSpriteAnim(sprite, gBattleAnimArgs[5]);
+ AnimateSprite(sprite);
+
+ if (GetBankSide(gAnimBankAttacker) != 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];
+
+ sub_8078A5C(sprite);
+ sprite->data[3] = 0;
+ sprite->data[4] = 0;
+
+ sprite->callback = sub_8078394;
+ StoreSpriteCallbackInData(sprite, move_anim_8074EE0);
+}
+
+void sub_80DCFE4(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[6] == 0)
+ sub_80787B0(sprite, 0);
+ else
+ sub_8078764(sprite, 0);
+
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->data[1] = gBattleAnimArgs[2];
+ sprite->data[2] = gBattleAnimArgs[4];
+ sprite->data[3] = gBattleAnimArgs[5];
+
+ sprite->callback = sub_80DD02C;
+}
+
+static void sub_80DD02C(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 do_boulder_dust(u8 taskId)
+{
+ struct Struct_sub_8078914 subStruct;
+ int var0 = 0;
+
+ REG_BLDCNT = 0x3F42;
+ REG_BLDALPHA = 0x1000;
+ REG_BG1CNT_BITFIELD.priority = 1;
+ REG_BG1CNT_BITFIELD.screenSize = 0;
+
+ if (!IsContest())
+ REG_BG1CNT_BITFIELD.charBaseBlock = 1;
+
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1VOFS = 0;
+
+ sub_8078914(&subStruct);
+ DmaFill32Defvars(3, 0, subStruct.field_4, 0x1000);
+ LZDecompressVram(&gBattleAnimBackgroundTilemap_SandstormBrew, subStruct.field_4);
+ LZDecompressVram(&gBattleAnimBackgroundImage_SandstormBrew, subStruct.field_0);
+ LoadCompressedPalette(&gBattleAnimSpritePalette_261, subStruct.field_8 << 4, 32);
+
+ if (IsContest())
+ sub_80763FC(subStruct.field_8, (u16 *)subStruct.field_4, 0, 0);
+
+ if (gBattleAnimArgs[0] != 0 && GetBankSide(gAnimBankAttacker) != SIDE_PLAYER)
+ var0 = 1;
+
+ gTasks[taskId].data[0] = var0;
+ gTasks[taskId].func = sub_80DD190;
+}
+
+static void sub_80DD190(u8 taskId)
+{
+ struct Struct_sub_8078914 subStruct;
+
+ if (gTasks[taskId].data[0] == 0)
+ gBattle_BG1_X += 0xFFFA;
+ 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]++;
+ REG_BLDALPHA = gTasks[taskId].data[11] | ((16 - gTasks[taskId].data[11]) << 8);
+ 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]--;
+ REG_BLDALPHA = gTasks[taskId].data[11] | ((16 - gTasks[taskId].data[11]) << 8);
+ if (gTasks[taskId].data[11] == 0)
+ {
+ gTasks[taskId].data[12]++;
+ gTasks[taskId].data[11] = 0;
+ }
+ }
+ break;
+ case 3:
+ sub_8078914(&subStruct);
+ DmaFill32Large(3, 0, subStruct.field_0, 0x2000, 0x1000);
+ DmaClear32(3, subStruct.field_4, 0x800);
+ if (!IsContest())
+ REG_BG1CNT_BITFIELD.charBaseBlock = 0;
+
+ gTasks[taskId].data[12]++;
+ // fall through
+ case 4:
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ REG_BG1CNT_BITFIELD.priority = 1;
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80DD3AC(struct Sprite *sprite)
+{
+ if (sprite->data[0] == 0)
+ {
+ if (gBattleAnimArgs[3] != 0 && GetBankSide(gAnimBankAttacker) != SIDE_PLAYER)
+ {
+ sprite->pos1.x = 304;
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ sprite->data[5] = 1;
+ sprite->oam.matrixNum = 8;
+ }
+ else
+ {
+ sprite->pos1.x = -64;
+ }
+
+ sprite->pos1.y = gBattleAnimArgs[0];
+ SetSubspriteTables(sprite, &gUnknown_083DAD10);
+ 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;
+ }
+ }
+}
+
+void sub_80DD490(struct Sprite *sprite)
+{
+ StartSpriteAnim(sprite, gBattleAnimArgs[4]);
+ sub_80787B0(sprite, 0);
+
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->data[2] = sprite->pos1.x;
+ sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[2];
+
+ sprite->callback = sub_8078B34;
+ StoreSpriteCallbackInData(sprite, DestroyAnimSprite);
+}
+
+void sub_80DD4D4(u8 taskId)
+{
+ u16 var0, var1, var2, var3;
+ u8 var4;
+ int var5;
+ s16 pan1, pan2;
+ struct Task *task;
+
+ task = &gTasks[taskId];
+
+ var0 = GetBankPosition(gAnimBankAttacker, 2);
+ var1 = GetBankPosition(gAnimBankAttacker, 1) + 24;
+ var2 = GetBankPosition(gAnimBankTarget, 2);
+ var3 = GetBankPosition(gAnimBankTarget, 1) + 24;
+
+ if ((gAnimBankAttacker ^ 2) == gAnimBankTarget)
+ var3 = var1;
+
+ var4 = sub_80DD8BC();
+ 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(-64);
+ pan2 = BattleAnimAdjustPanning(63);
+
+ task->data[13] = pan1;
+ task->data[14] = (pan2 - pan1) / task->data[8];
+ task->data[1] = var4;
+ task->data[15] = GetAnimBankSpriteId(0);
+
+ task->func = sub_80DD604;
+}
+
+static void sub_80DD604(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_80DD774(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_80DD774(struct Task *task)
+{
+ const struct SpriteTemplate *spriteTemplate;
+ int var0;
+ u16 x, y;
+ u8 spriteId;
+
+ switch (task->data[1])
+ {
+ case 1:
+ spriteTemplate = &gSpriteTemplate_83DAD78;
+ var0 = 0;
+ break;
+ case 2:
+ case 3:
+ spriteTemplate = &gSpriteTemplate_83DAD90;
+ var0 = 80;
+ break;
+ case 4:
+ spriteTemplate = &gSpriteTemplate_83DAD90;
+ var0 = 64;
+ break;
+ case 5:
+ spriteTemplate = &gSpriteTemplate_83DAD90;
+ 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 != 64)
+ {
+ 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;
+
+ sub_80786EC(&gSprites[spriteId]);
+ task->data[11]++;
+ }
+
+ task->data[12] *= -1;
+}
+
+void sub_80DD87C(struct Sprite *sprite)
+{
+ if (sub_8078718(sprite))
+ {
+ u8 taskId = FindTaskIdByFunc(sub_80DD604);
+ if (taskId != 0xFF)
+ gTasks[taskId].data[11]--;
+
+ DestroySprite(sprite);
+ }
+}
+
+u8 sub_80DD8BC(void)
+{
+ u8 retVal = gAnimDisableStructPtr->rolloutTimer2 - gAnimDisableStructPtr->rolloutTimer1;
+ u8 var0 = retVal - 1;
+ if (var0 > 4)
+ {
+ retVal = 1;
+ }
+
+ return retVal;
+}
+
+void sub_80DD8E8(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_80DD928;
+ sprite->invisible = 1;
+}
+
+static void sub_80DD928(struct Sprite *sprite)
+{
+ sprite->invisible = 0;
+ 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);
+ }
+ }
+}
+
+void sub_80DD978(struct Sprite *sprite)
+{
+ if (GetBankSide(gAnimBankAttacker) == SIDE_OPPONENT)
+ StartSpriteAffineAnim(sprite, 1);
+
+ sub_807941C(sprite);
+}
+
+void sub_80DD9A4(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBankPosition(gAnimBankTarget, 0);
+ sprite->pos1.y = GetBankPosition(gAnimBankTarget, 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_80DD9FC;
+}
+
+static void sub_80DD9FC(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 sub_80DDA4C(u8 taskId)
+{
+ if ((s32)gAnimMoveDmg < 33)
+ gBattleAnimArgs[7] = 0;
+ if (gAnimMoveDmg - 33 < 33)
+ gBattleAnimArgs[7] = 1;
+ if ((s32)gAnimMoveDmg > 65)
+ gBattleAnimArgs[7] = 2;
+
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80DDA8C(u8 taskId)
+{
+ if (gTasks[taskId].data[0] == 0)
+ {
+ sub_80789D4(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_80789D4(1);
+ DestroyAnimVisualTask(taskId);
+ }
+
+ gTasks[taskId].data[0]++;
+}
+
+void sub_80DDAF0(u8 taskId)
+{
+ if (gTasks[taskId].data[0] == 0)
+ {
+ sub_80789D4(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_80789D4(1);
+ DestroyAnimVisualTask(taskId);
+ }
+}
diff --git a/src/battle/anim/roots.c b/src/battle/anim/roots.c
index 68f8a3e2f..68f8a3e2f 100755..100644
--- a/src/battle/anim/roots.c
+++ b/src/battle/anim/roots.c
diff --git a/src/battle/anim/scan.c b/src/battle/anim/scan.c
index 22bb26973..22bb26973 100755..100644
--- a/src/battle/anim/scan.c
+++ b/src/battle/anim/scan.c
diff --git a/src/battle/anim/scary_face.c b/src/battle/anim/scary_face.c
index 47776a3cb..8d51521ee 100755..100644
--- a/src/battle/anim/scary_face.c
+++ b/src/battle/anim/scary_face.c
@@ -27,7 +27,7 @@ static void sub_80D24E0(u8 taskId);
void sub_80D23B4(u8 taskId)
{
struct Struct_sub_8078914 subStruct;
- u8* tempvar;
+
REG_BLDCNT = 0x3F42;
REG_BLDALPHA = 0x1000;
REG_BG1CNT_BITFIELD.priority = 1;
@@ -40,8 +40,7 @@ void sub_80D23B4(u8 taskId)
REG_BG1HOFS = 0;
REG_BG1VOFS = 0;
sub_8078914(&subStruct);
- tempvar = subStruct.field_4;
- DmaFill32(3, 0x0, tempvar, 0x1000);
+ DmaFill32Defvars(3, 0, subStruct.field_4, 0x1000);
if (IsContest())
LZDecompressVram(&gBattleAnimBackgroundTilemap_ScaryFaceContest, subStruct.field_4);
else if (GetBankSide(gAnimBankTarget) == 1)
@@ -98,21 +97,7 @@ void sub_80D24E0(u8 taskId)
break;
case 3:
sub_8078914(&subStruct);
- {
- u8 *addr = subStruct.field_0;
- u32 size = 0x2000;
- while (1)
- {
- DmaFill32(3, 0, addr, 0x1000);
- addr += 0x1000;
- size -= 0x1000;
- if (size <= 0x1000)
- {
- DmaFill32(3, 0, addr, size);
- break;
- }
- }
- }
+ DmaFill32Large(3, 0, subStruct.field_0, 0x2000, 0x1000);
DmaClear32(3, subStruct.field_4, 0x800);
if (!IsContest())
REG_BG1CNT_BITFIELD.charBaseBlock = 0;
diff --git a/src/battle/anim/seed.c b/src/battle/anim/seed.c
index be8613a74..be8613a74 100755..100644
--- a/src/battle/anim/seed.c
+++ b/src/battle/anim/seed.c
diff --git a/src/battle/anim/sfx.c b/src/battle/anim/sfx.c
new file mode 100644
index 000000000..10ef1681e
--- /dev/null
+++ b/src/battle/anim/sfx.c
@@ -0,0 +1,280 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "contest.h"
+#include "ewram.h"
+#include "rom_8077ABC.h"
+#include "sound.h"
+#include "task.h"
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankAttacker;
+extern u8 gAnimBankTarget;
+extern u16 gBattlePartyID[];
+extern u16 gAnimSpeciesByBanks[];
+extern u8 gUnknown_0202F7D2;
+
+static void sub_812AF98(u8 taskId);
+static void sub_812B004(u8 taskId);
+static void sub_812B108(u8 taskId);
+static void sub_812B404(u8 taskId);
+
+// used in 1 move:
+// Move_FIRE_BLAST
+void sub_812AF30(u8 taskId)
+{
+ s8 sourcePan, targetPan, panIncrement;
+
+ TASK.data[0] = gBattleAnimArgs[0];
+ TASK.data[1] = gBattleAnimArgs[1];
+
+ sourcePan = BattleAnimAdjustPanning(-64);
+ targetPan = BattleAnimAdjustPanning(63);
+ panIncrement = CalculatePanIncrement(sourcePan, targetPan, 2);
+
+ TASK.data[2] = sourcePan;
+ TASK.data[3] = targetPan;
+ TASK.data[4] = panIncrement;
+ TASK.data[10] = 10;
+
+ TASK.func = sub_812AF98;
+}
+
+static void sub_812AF98(u8 taskId)
+{
+ s16 pan = TASK.data[2];
+ s8 dPan = TASK.data[4];
+
+ if (++TASK.data[11] == 111)
+ {
+ TASK.data[10] = 5;
+ TASK.data[11] = 0;
+ TASK.func = sub_812B004;
+ }
+ else
+ {
+ if (++TASK.data[10] == 11)
+ {
+ TASK.data[10] = 0;
+ PlaySE12WithPanning(TASK.data[0], pan);
+ }
+ pan += dPan;
+ TASK.data[2] = sub_8077104(pan, dPan);
+ }
+}
+
+static void sub_812B004(u8 taskId)
+{
+ s8 pan;
+
+ if (++TASK.data[10] == 6)
+ {
+ TASK.data[10] = 0;
+
+ pan = BattleAnimAdjustPanning(63);
+ PlaySE12WithPanning(TASK.data[1], pan);
+
+ if (++TASK.data[11] == 2)
+ {
+ DestroyAnimSoundTask(taskId);
+ }
+ }
+}
+
+// used in 7 moves:
+// Move_ICE_BEAM, Move_AURORA_BEAM, Move_PSYBEAM,
+// Move_PSYWAVE, Move_SHADOW_BALL, Move_TRI_ATTACK,
+// Move_HYPER_BEAM
+void sub_812B058(u8 taskId)
+{
+ s16 sp = gBattleAnimArgs[0];
+ s8 r5 = gBattleAnimArgs[2];
+ s8 panIncrement = gBattleAnimArgs[3];
+ u8 r10 = gBattleAnimArgs[4]; // number of times the sound must be played
+ u8 r7 = gBattleAnimArgs[5];
+ u8 r9 = gBattleAnimArgs[6];
+
+ s8 pan1 = BattleAnimAdjustPanning(gBattleAnimArgs[1]);
+ s8 pan2 = BattleAnimAdjustPanning(r5);
+ panIncrement = CalculatePanIncrement(pan1, pan2, panIncrement);
+
+ TASK.data[0] = sp;
+ TASK.data[1] = pan1;
+ TASK.data[2] = pan2;
+ TASK.data[3] = panIncrement;
+ TASK.data[4] = r10;
+ TASK.data[5] = r7;
+ TASK.data[6] = r9;
+ TASK.data[10] = 0;
+ TASK.data[11] = pan1;
+ TASK.data[12] = r9;
+
+ TASK.func = sub_812B108;
+ TASK.func(taskId);
+}
+
+static void sub_812B108(u8 taskId)
+{
+ if (TASK.data[12]++ == TASK.data[6])
+ {
+ TASK.data[12] = 0;
+ PlaySE12WithPanning(TASK.data[0], TASK.data[11]);
+
+ if (--TASK.data[4] == 0)
+ {
+ DestroyAnimSoundTask(taskId);
+ return;
+ }
+ }
+
+ if (TASK.data[10]++ == TASK.data[5])
+ {
+ u16 dPan, oldPan;
+ TASK.data[10] = 0;
+ dPan = TASK.data[3];
+ oldPan = TASK.data[11];
+ TASK.data[11] = dPan + oldPan;
+ TASK.data[11] = sub_8077104(TASK.data[11], oldPan);
+ }
+}
+
+// #define shared19348 (*(struct UnknownContestStruct8 *)(gSharedMem + 0x19348))
+// #define EWRAM_19348 (*(u16 *)(gSharedMem + 0x19348))
+
+// used in 3 moves:
+// Move_HOWL, Move_ROAR, Move_GROWL
+void sub_812B18C(u8 taskId)
+{
+ u16 species = 0;
+ s8 pan = BattleAnimAdjustPanning(-64);
+
+ if (IsContest())
+ {
+ if (!gBattleAnimArgs[0])
+ species = shared19348.unk0;
+ else
+ DestroyAnimVisualTask(taskId);
+ }
+ else
+ {
+ u8 bank;
+ if (gBattleAnimArgs[0] == 0)
+ bank = gAnimBankAttacker;
+ else if (gBattleAnimArgs[0] == 1)
+ bank = gAnimBankTarget;
+ else if (gBattleAnimArgs[0] == 2)
+ bank = gAnimBankAttacker ^ 0x2;
+ else
+ bank = gAnimBankTarget ^ 0x2;
+
+ if (gBattleAnimArgs[0] == 1 || gBattleAnimArgs[0] == 3)
+ {
+ if (!IsAnimBankSpriteVisible(bank))
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ }
+
+ if (GetBankSide(bank))
+ species = GetMonData(&gEnemyParty[gBattlePartyID[bank]], 0xB);
+ else
+ species = GetMonData(&gPlayerParty[gBattlePartyID[bank]], 0xB);
+ }
+
+ if (species != 0)
+ {
+ s16 mode = gBattleAnimArgs[1];
+ if (mode == 0xFF)
+ PlayCry1(species, pan);
+ else
+ PlayCry3(species, pan, mode);
+ }
+
+ DestroyAnimVisualTask(taskId);
+}
+
+// used in Move_HYPER_VOICE
+void sub_812B2B8(u8 taskId)
+{
+ u16 species;
+ s8 pan = BattleAnimAdjustPanning(-64);
+
+ if (IsContest())
+ species = shared19348.unk0;
+ else
+ species = gAnimSpeciesByBanks[gAnimBankAttacker];
+
+ if (species != 0)
+ PlayCry3(species, pan, 4);
+
+ DestroyAnimVisualTask(taskId);
+}
+
+// used in 6 moves:
+// Move_SKY_ATTACK, Move_LUSTER_PURGE, Move_FLATTER,
+// Move_DRAGON_CLAW, Move_RETURN, Move_COSMIC_POWER,
+void sub_812B30C(u8 taskId)
+{
+ u16 songNum = gBattleAnimArgs[0];
+ s8 pan = BattleAnimAdjustPanning(gBattleAnimArgs[1]);
+ PlaySE1WithPanning(songNum, pan);
+
+ DestroyAnimVisualTask(taskId);
+}
+
+// used in 6 moves:
+// Move_SKY_ATTACK, Move_SUPERPOWER, Move_ENCORE,
+// Move_FLATTER, Move_RETURN, Move_COSMIC_POWER
+void sub_812B340(u8 taskId)
+{
+ u16 songNum = gBattleAnimArgs[0];
+ s8 pan = BattleAnimAdjustPanning(gBattleAnimArgs[1]);
+ PlaySE2WithPanning(songNum, pan);
+
+ DestroyAnimVisualTask(taskId);
+}
+
+// used in 2 moves:
+// Move_CONFUSE_RAY, Move_WILL_O_WISP
+void sub_812B374(u8 taskId)
+{
+ u8 r5 = gBattleAnimArgs[1];
+ s8 panIncrement = gBattleAnimArgs[2];
+ s16 r9 = gBattleAnimArgs[3];
+ s8 r1 = gBattleAnimArgs[0];
+
+ s8 sourcePan = BattleAnimAdjustPanning(r1);
+ s8 targetPan = BattleAnimAdjustPanning(r5);
+ panIncrement = CalculatePanIncrement(sourcePan, targetPan, panIncrement);
+
+ TASK.data[1] = sourcePan;
+ TASK.data[2] = targetPan;
+ TASK.data[3] = panIncrement;
+ TASK.data[5] = r9;
+ TASK.data[10] = 0;
+ TASK.data[11] = sourcePan;
+
+ TASK.func = sub_812B404;
+ TASK.func(taskId);
+}
+
+static void sub_812B404(u8 taskId)
+{
+ u16 dPan = TASK.data[3];
+
+ if (TASK.data[10]++ == TASK.data[5])
+ {
+ u16 oldPan;
+ TASK.data[10] = 0;
+ oldPan = TASK.data[11];
+ TASK.data[11] = dPan + oldPan;
+ TASK.data[11] = sub_8077104(TASK.data[11], oldPan);
+ }
+
+ gUnknown_0202F7D2 = TASK.data[11];
+
+ if (TASK.data[11] == TASK.data[2])
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+} \ No newline at end of file
diff --git a/src/battle/anim/shadow_enlarge.c b/src/battle/anim/shadow_enlarge.c
index 399cf1ba4..399cf1ba4 100755..100644
--- a/src/battle/anim/shadow_enlarge.c
+++ b/src/battle/anim/shadow_enlarge.c
diff --git a/src/battle/anim/shadow_minimize.c b/src/battle/anim/shadow_minimize.c
index 94069374f..94069374f 100755..100644
--- a/src/battle/anim/shadow_minimize.c
+++ b/src/battle/anim/shadow_minimize.c
diff --git a/src/battle/anim/shield.c b/src/battle/anim/shield.c
index 676318545..676318545 100755..100644
--- a/src/battle/anim/shield.c
+++ b/src/battle/anim/shield.c
diff --git a/src/battle/anim/shimmer.c b/src/battle/anim/shimmer.c
index 9e7bea1e4..9e7bea1e4 100755..100644
--- a/src/battle/anim/shimmer.c
+++ b/src/battle/anim/shimmer.c
diff --git a/src/battle/anim/silhouette.c b/src/battle/anim/silhouette.c
index a3147f598..a3147f598 100755..100644
--- a/src/battle/anim/silhouette.c
+++ b/src/battle/anim/silhouette.c
diff --git a/src/battle/anim/slash.c b/src/battle/anim/slash.c
index 6adcaf098..6adcaf098 100755..100644
--- a/src/battle/anim/slash.c
+++ b/src/battle/anim/slash.c
diff --git a/src/battle/anim/sleep.c b/src/battle/anim/sleep.c
index 0f0e54f80..0f0e54f80 100755..100644
--- a/src/battle/anim/sleep.c
+++ b/src/battle/anim/sleep.c
diff --git a/src/battle/anim/slice.c b/src/battle/anim/slice.c
index fe8745483..fe8745483 100755..100644
--- a/src/battle/anim/slice.c
+++ b/src/battle/anim/slice.c
diff --git a/src/battle/anim/smoke.c b/src/battle/anim/smoke.c
index 7ab873e63..7ab873e63 100755..100644
--- a/src/battle/anim/smoke.c
+++ b/src/battle/anim/smoke.c
diff --git a/src/battle/anim/sonic.c b/src/battle/anim/sonic.c
index 0897ec6e3..0897ec6e3 100755..100644
--- a/src/battle/anim/sonic.c
+++ b/src/battle/anim/sonic.c
diff --git a/src/battle/anim/sonic_task.c b/src/battle/anim/sonic_task.c
index 924b1b568..924b1b568 100755..100644
--- a/src/battle/anim/sonic_task.c
+++ b/src/battle/anim/sonic_task.c
diff --git a/src/battle/anim/spin_finger.c b/src/battle/anim/spin_finger.c
index 8eb060358..8eb060358 100755..100644
--- a/src/battle/anim/spin_finger.c
+++ b/src/battle/anim/spin_finger.c
diff --git a/src/battle/anim/spit.c b/src/battle/anim/spit.c
index 1e65ba53e..1e65ba53e 100755..100644
--- a/src/battle/anim/spit.c
+++ b/src/battle/anim/spit.c
diff --git a/src/battle/anim/splash.c b/src/battle/anim/splash.c
index 570ef0dca..570ef0dca 100755..100644
--- a/src/battle/anim/splash.c
+++ b/src/battle/anim/splash.c
diff --git a/src/battle/anim/startle.c b/src/battle/anim/startle.c
index 50e78af37..50e78af37 100755..100644
--- a/src/battle/anim/startle.c
+++ b/src/battle/anim/startle.c
diff --git a/src/battle/anim/strike.c b/src/battle/anim/strike.c
index bfa1dc4f7..bfa1dc4f7 100755..100644
--- a/src/battle/anim/strike.c
+++ b/src/battle/anim/strike.c
diff --git a/src/battle/anim/switch.c b/src/battle/anim/switch.c
index c4082b6aa..c4082b6aa 100755..100644
--- a/src/battle/anim/switch.c
+++ b/src/battle/anim/switch.c
diff --git a/src/battle/anim/sword.c b/src/battle/anim/sword.c
index b46fe6759..b46fe6759 100755..100644
--- a/src/battle/anim/sword.c
+++ b/src/battle/anim/sword.c
diff --git a/src/battle/anim/taunt_finger.c b/src/battle/anim/taunt_finger.c
index 023e14e45..023e14e45 100755..100644
--- a/src/battle/anim/taunt_finger.c
+++ b/src/battle/anim/taunt_finger.c
diff --git a/src/battle/anim/tendrils.c b/src/battle/anim/tendrils.c
index 9f57ffd45..9f57ffd45 100755..100644
--- a/src/battle/anim/tendrils.c
+++ b/src/battle/anim/tendrils.c
diff --git a/src/battle/anim/thought.c b/src/battle/anim/thought.c
index c3ab6f82c..c3ab6f82c 100755..100644
--- a/src/battle/anim/thought.c
+++ b/src/battle/anim/thought.c
diff --git a/src/battle/anim/thrashing.c b/src/battle/anim/thrashing.c
index 3fde815ae..3fde815ae 100755..100644
--- a/src/battle/anim/thrashing.c
+++ b/src/battle/anim/thrashing.c
diff --git a/src/battle/anim/tile_in.c b/src/battle/anim/tile_in.c
index a4a544a0c..a4a544a0c 100755..100644
--- a/src/battle/anim/tile_in.c
+++ b/src/battle/anim/tile_in.c
diff --git a/src/battle/anim/tile_out.c b/src/battle/anim/tile_out.c
index 50468a440..50468a440 100755..100644
--- a/src/battle/anim/tile_out.c
+++ b/src/battle/anim/tile_out.c
diff --git a/src/battle/anim/twinkle.c b/src/battle/anim/twinkle.c
index e26669f63..e26669f63 100755..100644
--- a/src/battle/anim/twinkle.c
+++ b/src/battle/anim/twinkle.c
diff --git a/src/battle/anim/unused_1.c b/src/battle/anim/unused_1.c
index d7e5fbfe4..d7e5fbfe4 100755..100644
--- a/src/battle/anim/unused_1.c
+++ b/src/battle/anim/unused_1.c
diff --git a/src/battle/anim/unused_2.c b/src/battle/anim/unused_2.c
index 122f39e02..122f39e02 100755..100644
--- a/src/battle/anim/unused_2.c
+++ b/src/battle/anim/unused_2.c
diff --git a/src/battle/anim/unused_3.c b/src/battle/anim/unused_3.c
index 6dbcbfefe..6dbcbfefe 100755..100644
--- a/src/battle/anim/unused_3.c
+++ b/src/battle/anim/unused_3.c
diff --git a/src/battle/anim/unused_4.c b/src/battle/anim/unused_4.c
index bda476a0a..bda476a0a 100755..100644
--- a/src/battle/anim/unused_4.c
+++ b/src/battle/anim/unused_4.c
diff --git a/src/battle/anim/unused_5.c b/src/battle/anim/unused_5.c
index 421cdd6bf..421cdd6bf 100755..100644
--- a/src/battle/anim/unused_5.c
+++ b/src/battle/anim/unused_5.c
diff --git a/src/battle/anim/unused_6.c b/src/battle/anim/unused_6.c
index 37e2031b0..37e2031b0 100755..100644
--- a/src/battle/anim/unused_6.c
+++ b/src/battle/anim/unused_6.c
diff --git a/src/battle/anim/unused_7.c b/src/battle/anim/unused_7.c
index 2be6e7633..2be6e7633 100755..100644
--- a/src/battle/anim/unused_7.c
+++ b/src/battle/anim/unused_7.c
diff --git a/src/battle/anim/unused_8.c b/src/battle/anim/unused_8.c
index 03772f951..03772f951 100755..100644
--- a/src/battle/anim/unused_8.c
+++ b/src/battle/anim/unused_8.c
diff --git a/src/battle/anim/unused_9.c b/src/battle/anim/unused_9.c
index cf3ccb0d4..cf3ccb0d4 100755..100644
--- a/src/battle/anim/unused_9.c
+++ b/src/battle/anim/unused_9.c
diff --git a/src/battle/anim/wave_finger.c b/src/battle/anim/wave_finger.c
index 2cf68c34c..2cf68c34c 100755..100644
--- a/src/battle/anim/wave_finger.c
+++ b/src/battle/anim/wave_finger.c
diff --git a/src/battle/anim/whip.c b/src/battle/anim/whip.c
index cb3ce327e..cb3ce327e 100755..100644
--- a/src/battle/anim/whip.c
+++ b/src/battle/anim/whip.c
diff --git a/src/battle/anim/wisp_fire.c b/src/battle/anim/wisp_fire.c
new file mode 100644
index 000000000..348ce6426
--- /dev/null
+++ b/src/battle/anim/wisp_fire.c
@@ -0,0 +1,196 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "blend_palette.h"
+#include "main.h"
+#include "rom_8077ABC.h"
+#include "task.h"
+#include "trig.h"
+
+extern s16 gBattleAnimArgs[];
+extern u8 gAnimBankTarget;
+extern u8 gAnimBankAttacker;
+
+extern u8 gObjectBankIDs[];
+extern s8 gUnknown_083D9794[16];
+extern s8 gUnknown_083D97A4[16];
+
+void sub_80D5E4C(u8 taskId);
+
+void sub_80D5CC0(struct Sprite *sprite)
+{
+ if (!sprite->data[0])
+ {
+ sprite->data[1] = gBattleAnimArgs[0];
+ sprite->data[0] += 1;
+ }
+
+ sprite->data[3] += 0xC0 * 2;
+ sprite->data[4] += 0xA0;
+
+ sprite->pos2.x = Sin(sprite->data[1], sprite->data[3] >> 8);
+ sprite->pos2.y = Cos(sprite->data[1], sprite->data[4] >> 8);
+
+ sprite->data[1] = (sprite->data[1] + 7) & 0xFF;
+
+ if (gMain.inBattle)
+ {
+ if (sprite->data[1] < 64 || sprite->data[1] > 195)
+ sprite->oam.priority = sub_8079ED4(gAnimBankTarget);
+ else
+ sprite->oam.priority = sub_8079ED4(gAnimBankTarget) + 1;
+ }
+ else
+ {
+ if (sprite->data[1] < 64 || sprite->data[1] > 195)
+ sprite->subpriority = 0x1D;
+ else
+ sprite->subpriority = 0x1F;
+ }
+
+ if (++sprite->data[2] > 0x14)
+ sprite->invisible ^= 1;
+
+ if (sprite->data[2] == 0x1E)
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80D5DDC(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->data[12] = !GetBankSide(gAnimBankAttacker) ? 1 : -1;
+ task->data[13] = IsAnimBankSpriteVisible(gAnimBankTarget ^ 2) + 1;
+ task->data[14] = GetAnimBankSpriteId(1);
+ task->data[15] = GetAnimBankSpriteId(3);
+
+ task->func = sub_80D5E4C;
+}
+
+void sub_80D5E4C(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[10] += task->data[12] * 2;
+ if (++task->data[1] >= 2)
+ {
+ task->data[1] = 0;
+ task->data[2]++;
+ if (task->data[2] & 1)
+ task->data[11] = 2;
+ else
+ task->data[11] = -2;
+ }
+
+ for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
+ {
+ gSprites[task->data[task->data[3] + 14]].pos2.x = task->data[10] + task->data[11];
+ }
+
+ if (++task->data[9] == 16)
+ {
+ task->data[9] = 0;
+ task->data[0]++;
+ }
+ break;
+ case 1:
+ if (++task->data[1] >= 5)
+ {
+ task->data[1] = 0;
+ task->data[2]++;
+
+ if (task->data[2] & 1)
+ task->data[11] = 2;
+ else
+ task->data[11] = -2;
+ }
+
+ for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
+ {
+ gSprites[task->data[task->data[3] + 14]].pos2.x = task->data[10] + task->data[11];
+ }
+
+ if (++task->data[9] == 96)
+ {
+ task->data[9] = 0;
+ task->data[0]++;
+ }
+ break;
+ case 2:
+ task->data[10] -= task->data[12] * 2;
+
+ if (++task->data[1] >= 2)
+ {
+ task->data[1] = 0;
+ task->data[2]++;
+
+ if (task->data[2] & 1)
+ task->data[11] = 2;
+ else
+ task->data[11] = -2;
+ }
+
+ for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
+ {
+ gSprites[task->data[task->data[3] + 14]].pos2.x = task->data[10] + task->data[11];
+ }
+
+ if (++task->data[9] == 16)
+ {
+ task->data[0]++;
+ }
+ break;
+ case 3:
+ for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
+ {
+ gSprites[task->data[task->data[3] + 14]].pos2.x = 0;
+ }
+
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80D6080(u8 taskId)
+{
+ struct Struct_sub_8078914 unk;
+ sub_8078914(&unk);
+ BlendPalette(unk.field_8 << 4, 16, gBattleAnimArgs[0], gBattleAnimArgs[1]); // u16 palOffset, u16 numEntries, u8 coeff, u16 blendColor
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80D60B4(u8 taskId)
+{
+ s8 unk;
+ u8 spriteId;
+
+ if (gTasks[taskId].data[0] == 0)
+ {
+ gTasks[taskId].data[1] = gBattleAnimArgs[0];
+ gTasks[taskId].data[2] = gBattleAnimArgs[1];
+ gTasks[taskId].data[3] = gBattleAnimArgs[2];
+ gTasks[taskId].data[4] = gBattleAnimArgs[3];
+ }
+ gTasks[taskId].data[0]++;
+
+ spriteId = gObjectBankIDs[gAnimBankTarget];
+
+ if (!gTasks[taskId].data[4])
+ unk = gUnknown_083D9794[gTasks[taskId].data[0] % 10];
+ else
+ unk = gUnknown_083D97A4[gTasks[taskId].data[0] % 10];
+
+ if (gTasks[taskId].data[3] == 1)
+ gSprites[spriteId].pos2.y = gBattleAnimArgs[1] * unk < 0 ? -(gBattleAnimArgs[1] * unk) : gBattleAnimArgs[1] * unk;
+ else
+ gSprites[spriteId].pos2.x = gBattleAnimArgs[1] * unk;
+
+ if (gTasks[taskId].data[0] == gTasks[taskId].data[1])
+ {
+ gSprites[spriteId].pos2.x = 0;
+ gSprites[spriteId].pos2.y = 0;
+ DestroyAnimVisualTask(taskId);
+ }
+} \ No newline at end of file
diff --git a/src/battle/anim/withdraw.c b/src/battle/anim/withdraw.c
index e67248b9f..e67248b9f 100755..100644
--- a/src/battle/anim/withdraw.c
+++ b/src/battle/anim/withdraw.c