diff options
Diffstat (limited to 'src/battle/anim')
58 files changed, 3410 insertions, 493 deletions
diff --git a/src/battle/anim/aurora.c b/src/battle/anim/aurora.c index 90fa5c879..b24809264 100644 --- a/src/battle/anim/aurora.c +++ b/src/battle/anim/aurora.c @@ -16,7 +16,7 @@ void sub_80D33B4(struct Sprite *sprite) { s16 r6; - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); if (GetBankSide(gAnimBankAttacker) != 0) r6 = -gBattleAnimArgs[2]; else @@ -26,7 +26,7 @@ void sub_80D33B4(struct Sprite *sprite) sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + r6; sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3]; - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); sprite->callback = sub_80D344C; sprite->affineAnimPaused = TRUE; sprite->callback(sprite); @@ -39,7 +39,7 @@ static void sub_80D344C(struct Sprite *sprite) StartSpriteAnim(sprite, 1); sprite->affineAnimPaused = FALSE; } - if (sub_8078B5C(sprite) != 0) + if (TranslateAnimSpriteByDeltas(sprite) != 0) DestroyAnimSprite(sprite); } diff --git a/src/battle/anim/blow_kiss.c b/src/battle/anim/blow_kiss.c index e7b49471d..f585b74bc 100644 --- a/src/battle/anim/blow_kiss.c +++ b/src/battle/anim/blow_kiss.c @@ -15,19 +15,19 @@ static void sub_80D1FA4(struct Sprite* sprite); void sub_80D1F58(struct Sprite* sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[0] = 0x5F; sprite->data[1] = sprite->pos1.x; sprite->data[2] = GetBankPosition(gAnimBankTarget, 2); sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3); - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); sprite->callback = sub_80D1FA4; } void sub_80D1FA4(struct Sprite* sprite) { - if (sub_8078B5C(sprite) == 0) + if (TranslateAnimSpriteByDeltas(sprite) == 0) { sprite->pos2.y += Sin(sprite->data[5], 14); sprite->data[5] = (sprite->data[5] + 4) & 0xFF; diff --git a/src/battle/anim/bubble.c b/src/battle/anim/bubble.c index 403003ce3..d6ec06be9 100644 --- a/src/battle/anim/bubble.c +++ b/src/battle/anim/bubble.c @@ -43,7 +43,7 @@ void sub_80D31C8(struct Sprite* sprite) sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3); - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); newSpriteId = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); sprite->data[5] = newSpriteId; @@ -69,7 +69,7 @@ static void sub_80D32E8(struct Sprite *sprite) u16 index = gSprites[spriteId].data[3]; sprite->data[0] = 1; - sub_8078B5C(sprite); + TranslateAnimSpriteByDeltas(sprite); sprite->pos2.x += Sin(index / 256, gSprites[spriteId].data[0]); sprite->pos2.y += Cos(index / 256, gSprites[spriteId].data[1]); @@ -97,6 +97,6 @@ static void sub_80D3370(struct Sprite *sprite) static void sub_80D3398(struct Sprite *sprite) { sprite->data[0] = 10; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, move_anim_8074EE0); } diff --git a/src/battle/anim/bug.c b/src/battle/anim/bug.c index dbc0f75a5..d57a1046e 100644 --- a/src/battle/anim/bug.c +++ b/src/battle/anim/bug.c @@ -13,7 +13,7 @@ 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); +static void AnimMissileArcStep(struct Sprite *sprite); // used in Move_MEGAHORN void sub_80DC824(struct Sprite *sprite) @@ -40,7 +40,7 @@ void sub_80DC824(struct Sprite *sprite) sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + gBattleAnimArgs[2]; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3]; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } @@ -65,7 +65,7 @@ void sub_80DC8F4(struct Sprite *sprite) sprite->data[2] = GetBankPosition(gAnimBankTarget, 2); sprite->data[4] = GetBankPosition(gAnimBankTarget, 3); - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } @@ -76,7 +76,7 @@ void sub_80DC9A0(struct Sprite *sprite) if (IsContest()) gBattleAnimArgs[2] /= 2; - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[0] = gBattleAnimArgs[2]; sprite->data[1] = sprite->pos1.x; sprite->data[3] = sprite->pos1.y; @@ -88,7 +88,7 @@ void sub_80DC9A0(struct Sprite *sprite) } else { - sub_807A3FC(gAnimBankTarget, 1, &sprite->data[2], &sprite->data[4]); + SetAverageBattlerPositions(gAnimBankTarget, 1, &sprite->data[2], &sprite->data[4]); } sub_8078BD4(sprite); @@ -98,7 +98,7 @@ void sub_80DC9A0(struct Sprite *sprite) static void sub_80DCA38(struct Sprite *sprite) { - if (sub_8078B5C(sprite)) + if (TranslateAnimSpriteByDeltas(sprite)) { DestroyAnimSprite(sprite); return; @@ -111,7 +111,7 @@ static void sub_80DCA38(struct Sprite *sprite) // used in Move_STRING_SHOT void sub_80DCA70(struct Sprite *sprite) { - sub_807A3FC(gAnimBankTarget, 0, &sprite->pos1.x, &sprite->pos1.y); + SetAverageBattlerPositions(gAnimBankTarget, 0, &sprite->pos1.x, &sprite->pos1.y); if (GetBankSide(gAnimBankAttacker)) sprite->pos1.x -= gBattleAnimArgs[0]; else @@ -174,9 +174,15 @@ static void sub_80DCBB4(struct Sprite *sprite) DestroyAnimSprite(sprite); } -// used in 3 moves: -// Move_POISON_STING, Move_TWINEEDLE, Move_SPIKE_CANNON -void sub_80DCBCC(struct Sprite *sprite) +// Translates a stinger sprite linearly to a destination location. The sprite is +// initially rotated so that it appears to be traveling in a straight line. +// Used by Move_POISON_STING, Move_TWINEEDLE, Move_SPIKE_CANNON +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: target x pixel offset +// arg 3: target y pixel offset +// arg 4: duration +void AnimTranslateStinger(struct Sprite *sprite) { s16 lVarX, lVarY; u16 rot; @@ -212,11 +218,11 @@ void sub_80DCBCC(struct Sprite *sprite) } } - sub_80787B0(sprite, 1); + InitAnimSpritePos(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 = ArcTan2Neg(lVarX - sprite->pos1.x, lVarY - sprite->pos1.y); rot += 0xC000; sub_8078FDC(sprite, FALSE, 0x100, 0x100, rot); @@ -224,15 +230,22 @@ void sub_80DCBCC(struct Sprite *sprite) sprite->data[2] = lVarX; sprite->data[4] = lVarY; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } // used in 2 moves: // Move_PIN_MISSILE, Move_ICICLE_SPEAR -void sub_80DCCFC(struct Sprite *sprite) +// Rotates sprite and moves it in an arc, so that it appears like a missle or arrow traveling. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: target x pixel offset +// arg 3: target y pixel offset +// arg 4: duration +// arg 5: wave amplitude +void AnimMissileArc(struct Sprite *sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); if (GetBankSide(gAnimBankAttacker)) gBattleAnimArgs[2] = -gBattleAnimArgs[2]; @@ -241,17 +254,17 @@ void sub_80DCCFC(struct Sprite *sprite) sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + gBattleAnimArgs[2]; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3]; sprite->data[5] = gBattleAnimArgs[5]; - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); - sprite->callback = sub_80DCD78; + sprite->callback = AnimMissileArcStep; sprite->invisible = TRUE; } -void sub_80DCD78(struct Sprite *sprite) +static void AnimMissileArcStep(struct Sprite *sprite) { sprite->invisible = FALSE; - if (sub_8078718(sprite)) + if (TranslateAnimSpriteLinearAndSine(sprite)) { DestroyAnimSprite(sprite); } @@ -271,12 +284,12 @@ void sub_80DCD78(struct Sprite *sprite) x2 += x1; y2 += y1; - if (!sub_8078718(sprite)) + if (!TranslateAnimSpriteLinearAndSine(sprite)) { - u16 rot = sub_80790F0(sprite->pos1.x + sprite->pos2.x - x2, + u16 rotation = ArcTan2Neg(sprite->pos1.x + sprite->pos2.x - x2, sprite->pos1.y + sprite->pos2.y - y2); - rot += 0xC000; - sub_8078FDC(sprite, FALSE, 0x100, 0x100, rot); + rotation += 0xC000; + sub_8078FDC(sprite, FALSE, 0x100, 0x100, rotation); for (i = 0; i < 8; i++) data[i] = tempData[i]; diff --git a/src/battle/anim/bullet.c b/src/battle/anim/bullet.c index 90b2021f1..1dca0b886 100644 --- a/src/battle/anim/bullet.c +++ b/src/battle/anim/bullet.c @@ -17,11 +17,11 @@ static void sub_80D00B4(struct Sprite* sprite); void sub_80CFFD8(struct Sprite* sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[0] = 20; sprite->data[2] = GetBankPosition(gAnimBankTarget, 2); sprite->data[4] = GetBankPosition(gAnimBankTarget, 3); - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; sprite->affineAnimPaused = 1; StoreSpriteCallbackInData(sprite, sub_80D0030); } diff --git a/src/battle/anim/cutter.c b/src/battle/anim/cutter.c index 2234ebacb..fed3598fc 100644 --- a/src/battle/anim/cutter.c +++ b/src/battle/anim/cutter.c @@ -1,4 +1,5 @@ #include "global.h" +#include "battle.h" #include "rom_8077ABC.h" #include "trig.h" #include "battle_anim.h" @@ -7,35 +8,42 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -static void sub_80CB09C(struct Sprite* sprite); -static void sub_80CB1A4(struct Sprite* sprite); +static void AnimTranslateLinearSingleSineWaveStep(struct Sprite* sprite); +static void AnimMoveTwisterParticleStep(struct Sprite* sprite); -// cutter (the cresent shaped leaf used in throwing projectiles for the listed moves.) +// Animates a sprite that moves linearly from one location to another, with a +// single-cycle sine wave added to the y position along the way. // Used by Razor Leaf and Magical Leaf. - -void sub_80CAFD0(struct Sprite* sprite) +// arg 0: initial x offset +// arg 1: initial y offset +// arg 2: target x offset +// arg 3: target y offset +// arg 4: translation duration +// arg 5: wave amplitude +// arg 6: target between double battle opponents (boolean) +void AnimTranslateLinearSingleSineWave(struct Sprite* sprite) { - sub_80787B0(sprite, 1); - if (GetBankSide(gAnimBankAttacker)) + InitAnimSpritePos(sprite, 1); + if (GetBankSide(gAnimBankAttacker) != SIDE_PLAYER) { gBattleAnimArgs[2] = -gBattleAnimArgs[2]; } sprite->data[0] = gBattleAnimArgs[4]; - if (!(gBattleAnimArgs[6])) + if (!gBattleAnimArgs[6]) { sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + gBattleAnimArgs[2]; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3]; } else { - sub_807A3FC(gAnimBankTarget, 1, &sprite->data[2], &sprite->data[4]); + SetAverageBattlerPositions(gAnimBankTarget, 1, &sprite->data[2], &sprite->data[4]); sprite->data[2] += gBattleAnimArgs[2]; sprite->data[4] += gBattleAnimArgs[3]; } sprite->data[5] = gBattleAnimArgs[5]; - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); if (GetBankSide(gAnimBankAttacker) == GetBankSide(gAnimBankTarget)) { sprite->data[0] = 1; @@ -45,18 +53,18 @@ void sub_80CAFD0(struct Sprite* sprite) sprite->data[0] = 0; } - sprite->callback = sub_80CB09C; + sprite->callback = AnimTranslateLinearSingleSineWaveStep; } -void sub_80CB09C(struct Sprite* sprite) +static void AnimTranslateLinearSingleSineWaveStep(struct Sprite* sprite) { - bool8 c = FALSE; + bool8 destroy = FALSE; s16 a = sprite->data[0]; s16 b = sprite->data[7]; s16 r0; sprite->data[0] = 1; - sub_8078718(sprite); + TranslateAnimSpriteLinearAndSine(sprite); r0 = sprite->data[7]; sprite->data[0] = a; if (b > 0xC8 && r0 <= 0x37 && sprite->oam.affineParam == 0) @@ -67,24 +75,30 @@ void sub_80CB09C(struct Sprite* sprite) sprite->invisible ^= 1; sprite->oam.affineParam++; if (sprite->oam.affineParam == 0x1E) - c = TRUE; + destroy = TRUE; } - if (sprite->pos1.x + sprite->pos2.x > 0x100 + if (sprite->pos1.x + sprite->pos2.x > 256 || sprite->pos1.x + sprite->pos2.x < -16 - || sprite->pos1.y + sprite->pos2.y > 0xA0 + || sprite->pos1.y + sprite->pos2.y > 160 || sprite->pos1.y + sprite->pos2.y < -16) - c = TRUE; + destroy = TRUE; - if (c) + if (destroy) DestroyAnimSprite(sprite); } -void sub_80CB144(struct Sprite* sprite) +// Animates particles in the Twister move animation. +// arg 0: duration +// arg 1: total y delta (the particles rise upward) +// arg 2: wave period (higher means faster wave) +// arg 3: wave amplitude +// arg 4: speedup frame (particles move faster at the end of the animation) +void AnimMoveTwisterParticle(struct Sprite* sprite) { if (!IsContest() && IsDoubleBattle() == TRUE) { - sub_807A3FC(gAnimBankTarget, 1, &sprite->pos1.x, &sprite->pos1.y); + SetAverageBattlerPositions(gAnimBankTarget, 1, &sprite->pos1.x, &sprite->pos1.y); } sprite->pos1.y += 32; @@ -93,10 +107,10 @@ void sub_80CB144(struct Sprite* sprite) sprite->data[2] = gBattleAnimArgs[2]; sprite->data[3] = gBattleAnimArgs[3]; sprite->data[4] = gBattleAnimArgs[4]; - sprite->callback = sub_80CB1A4; + sprite->callback = AnimMoveTwisterParticleStep; } -void sub_80CB1A4(struct Sprite* sprite) +static void AnimMoveTwisterParticleStep(struct Sprite* sprite) { if (sprite->data[1] == 0xFF) { diff --git a/src/battle/anim/cyclone.c b/src/battle/anim/cyclone.c index 0f83df211..b1210bc54 100644 --- a/src/battle/anim/cyclone.c +++ b/src/battle/anim/cyclone.c @@ -13,7 +13,7 @@ extern u8 gAnimBankTarget; void sub_80D0118(struct Sprite* sprite) { - sub_80787B0(sprite, 0); + InitAnimSpritePos(sprite, 0); if (GetBankSide(gAnimBankAttacker) == 0) sprite->pos1.y += 16; diff --git a/src/battle/anim/dark.c b/src/battle/anim/dark.c index 8ceb00298..055cf5802 100644 --- a/src/battle/anim/dark.c +++ b/src/battle/anim/dark.c @@ -1,22 +1,47 @@ #include "global.h" -#include "rom_8077ABC.h" -#include "trig.h" #include "battle_anim.h" -#include "sound.h" +#include "blend_palette.h" +#include "decompress.h" +#include "ewram.h" +#include "palette.h" +#include "rom_8077ABC.h" #include "scanline_effect.h" - -void sub_80DFE90(struct Sprite *sprite); - -void sub_80DFC9C(u8 taskId); -void sub_80DFD58(u8 taskId); +#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 u8 gBankSpriteIds[]; +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 +// used in Smoke Ball escape, Sky Attack, Feint Attack and Camouflage void sub_80DFC24(u8 taskId) { int bank; @@ -31,7 +56,7 @@ void sub_80DFC24(u8 taskId) gTasks[taskId].func = sub_80DFC9C; } -void sub_80DFC9C(u8 taskId) +static void sub_80DFC9C(u8 taskId) { u8 r2 = gTasks[taskId].data[1] >> 8; u8 r1 = gTasks[taskId].data[1]; @@ -44,7 +69,7 @@ void sub_80DFC9C(u8 taskId) gTasks[taskId].data[2] = 0; if (r2 == 16) { - gSprites[gObjectBankIDs[gAnimBankAttacker]].invisible = 1; + gSprites[gBankSpriteIds[gAnimBankAttacker]].invisible = 1; DestroyAnimVisualTask(taskId); } } @@ -103,7 +128,7 @@ void sub_80DFE14(struct Sprite *sprite) sprite->data[3] = GetBankPosition(gAnimBankTarget, 3); sprite->data[4] = GetBankPosition(gAnimBankAttacker, 3); sprite->data[0] = 0x7E; - sub_8078A5C(sprite); + InitSpriteDataForLinearTranslation(sprite); sprite->data[3] = -sprite->data[1]; sprite->data[4] = -sprite->data[2]; sprite->data[6] = 0xFFD8; @@ -111,7 +136,7 @@ void sub_80DFE14(struct Sprite *sprite) sub_80DFE90(sprite); } -void sub_80DFE90(struct Sprite *sprite) +static void sub_80DFE90(struct Sprite *sprite) { sprite->data[3] += sprite->data[1]; sprite->data[4] += sprite->data[2]; @@ -136,3 +161,848 @@ void sub_80DFE90(struct Sprite *sprite) 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; + + InitAnimSpriteTranslationOverDuration(sprite); + sprite->callback = sub_80E00D0; +} + +static void sub_80E00D0(struct Sprite *sprite) +{ + if (TranslateAnimSpriteLinearAndSine(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 = ®_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 = ®_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 = ®_BG1VOFS; + else + scanlineParams.dmaDest = ®_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; + MoveBattlerSpriteToBG(gAnimBankAttacker, toBG2); + gSprites[gBankSpriteIds[gAnimBankAttacker]].invisible = 0; + + if (IsAnimBankSpriteVisible(gAnimBankAttacker ^ 2)) + { + MoveBattlerSpriteToBG(gAnimBankAttacker ^ 2, toBG2 ^ 1); + gSprites[gBankSpriteIds[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[gBankSpriteIds[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[gBankSpriteIds[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 = gBankSpriteIds[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 index bf39e01c0..dc2c0bc50 100644 --- a/src/battle/anim/dragon.c +++ b/src/battle/anim/dragon.c @@ -19,7 +19,7 @@ extern u8 gBankAttacker; extern u16 gBattle_BG1_X; extern u16 gBattle_BG2_X; extern u16 gUnknown_03000730[]; -extern u8 gObjectBankIDs[]; +extern u8 gBankSpriteIds[]; // Outrage @@ -68,7 +68,7 @@ void sub_80DF63C(struct Sprite *sprite) StartSpriteAnim(sprite, 1); } sprite->data[0] = gBattleAnimArgs[4]; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, move_anim_8074EE0); } diff --git a/src/battle/anim/draw.c b/src/battle/anim/draw.c index f9e505bf2..be3a280af 100644 --- a/src/battle/anim/draw.c +++ b/src/battle/anim/draw.c @@ -59,7 +59,6 @@ void sub_80D0C88(u8 taskId) task->func = sub_80D0D68; } -#ifdef NONMATCHING void sub_80D0D68(u8 taskId) { struct Task* task = &gTasks[taskId]; @@ -99,126 +98,13 @@ void sub_80D0D68(u8 taskId) if (++task->data[3] >= task->data[15]) { - gScanlineEffect.unk15 = 3; + gScanlineEffect.state = 3; DestroyAnimVisualTask(taskId); } } break; } } -#else -__attribute__((naked)) -void sub_80D0D68(u8 taskId) -{ - asm(".syntax unified\n\ - push {r4,lr}\n\ - lsls r0, 24\n\ - lsrs r4, r0, 24\n\ - lsls r0, r4, 2\n\ - adds r0, r4\n\ - lsls r0, 3\n\ - ldr r1, _080D0D88 @ =gTasks\n\ - adds r3, r0, r1\n\ - movs r1, 0x10\n\ - ldrsh r0, [r3, r1]\n\ - cmp r0, 0\n\ - beq _080D0D8C\n\ - cmp r0, 0x1\n\ - beq _080D0DA2\n\ - b _080D0E22\n\ - .align 2, 0\n\ -_080D0D88: .4byte gTasks\n\ -_080D0D8C:\n\ - ldrh r0, [r3, 0x12]\n\ - adds r0, 0x1\n\ - strh r0, [r3, 0x12]\n\ - lsls r0, 16\n\ - asrs r0, 16\n\ - cmp r0, 0x14\n\ - ble _080D0E22\n\ - ldrh r0, [r3, 0x10]\n\ - adds r0, 0x1\n\ - strh r0, [r3, 0x10]\n\ - b _080D0E22\n\ -_080D0DA2:\n\ - ldrh r0, [r3, 0xA]\n\ - adds r0, 0x1\n\ - strh r0, [r3, 0xA]\n\ - lsls r0, 16\n\ - asrs r0, 16\n\ - cmp r0, 0x3\n\ - ble _080D0E22\n\ - movs r0, 0\n\ - strh r0, [r3, 0xA]\n\ - ldrh r1, [r3, 0xE]\n\ - movs r0, 0x3\n\ - ands r0, r1\n\ - strh r0, [r3, 0xC]\n\ - ldrh r0, [r3, 0x8]\n\ - subs r0, r1\n\ - strh r0, [r3, 0x12]\n\ - movs r2, 0xC\n\ - ldrsh r1, [r3, r2]\n\ - cmp r1, 0x1\n\ - beq _080D0DD8\n\ - cmp r1, 0x1\n\ - ble _080D0DE0\n\ - cmp r1, 0x2\n\ - beq _080D0DDC\n\ - cmp r1, 0x3\n\ - beq _080D0DDC\n\ - b _080D0DE0\n\ -_080D0DD8:\n\ - subs r0, 0x2\n\ - b _080D0DDE\n\ -_080D0DDC:\n\ - adds r0, 0x1\n\ -_080D0DDE:\n\ - strh r0, [r3, 0x12]\n\ -_080D0DE0:\n\ - movs r1, 0x12\n\ - ldrsh r0, [r3, r1]\n\ - cmp r0, 0\n\ - blt _080D0E04\n\ - ldr r2, _080D0E28 @ =gScanlineEffectRegBuffers\n\ - lsls r0, 1\n\ - adds r0, r2\n\ - ldrh r1, [r3, 0x14]\n\ - strh r1, [r0]\n\ - movs r1, 0x12\n\ - ldrsh r0, [r3, r1]\n\ - lsls r0, 1\n\ - movs r1, 0xF0\n\ - lsls r1, 3\n\ - adds r2, r1\n\ - adds r0, r2\n\ - ldrh r1, [r3, 0x14]\n\ - strh r1, [r0]\n\ -_080D0E04:\n\ - ldrh r0, [r3, 0xE]\n\ - adds r0, 0x1\n\ - strh r0, [r3, 0xE]\n\ - lsls r0, 16\n\ - asrs r0, 16\n\ - movs r2, 0x26\n\ - ldrsh r1, [r3, r2]\n\ - cmp r0, r1\n\ - blt _080D0E22\n\ - ldr r1, _080D0E2C @ =gScanlineEffect\n\ - movs r0, 0x3\n\ - strb r0, [r1, 0x15]\n\ - adds r0, r4, 0\n\ - bl DestroyAnimVisualTask\n\ -_080D0E22:\n\ - pop {r4}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_080D0E28: .4byte gScanlineEffectRegBuffers\n\ -_080D0E2C: .4byte gScanlineEffect\n\ -.syntax divided\n"); -} -#endif void sub_80D0E30(struct Sprite* sprite) { diff --git a/src/battle/anim/drum.c b/src/battle/anim/drum.c index 6306778ae..7937d040a 100644 --- a/src/battle/anim/drum.c +++ b/src/battle/anim/drum.c @@ -27,6 +27,6 @@ void sub_80CEDF0(struct Sprite* sprite) sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2) + a; sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3) + 8; sprite->data[0] = 8; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } diff --git a/src/battle/anim/egg.c b/src/battle/anim/egg.c index 8004b3bf5..b3de1dbb1 100644 --- a/src/battle/anim/egg.c +++ b/src/battle/anim/egg.c @@ -22,7 +22,7 @@ static void sub_80D158C(struct Sprite* sprite); void sub_80D1368(struct Sprite* sprite) { s16 r1; - sub_80787B0(sprite, 0); + InitAnimSpritePos(sprite, 0); r1 = (GetBankSide(gAnimBankAttacker)) ? -0xA0 : 0xA0; sprite->data[0] = 0x380; sprite->data[1] = r1; diff --git a/src/battle/anim/energy_wave.c b/src/battle/anim/energy_wave.c index 15045f5bd..8111f70a3 100644 --- a/src/battle/anim/energy_wave.c +++ b/src/battle/anim/energy_wave.c @@ -20,7 +20,7 @@ static void sub_80D370C(struct Sprite *); void sub_80D3554(struct Sprite *sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[0] = 30; sprite->data[1] = sprite->pos1.x; @@ -28,7 +28,7 @@ void sub_80D3554(struct Sprite *sprite) sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3); - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); sprite->data[5] = 0xD200 / sprite->data[0]; sprite->data[7] = gBattleAnimArgs[3]; @@ -49,7 +49,7 @@ void sub_80D3554(struct Sprite *sprite) static void sub_80D35DC(struct Sprite *sprite) { - if (sub_8078B5C(sprite)) + if (TranslateAnimSpriteByDeltas(sprite)) { DestroyAnimSprite(sprite); } @@ -147,7 +147,7 @@ void sub_80D3728(struct Sprite *sprite) else var2 = 1; - sub_80787B0(sprite, var1); + InitAnimSpritePos(sprite, var1); if (GetBankSide(gAnimBankAttacker) != 0) { @@ -157,6 +157,6 @@ void sub_80D3728(struct Sprite *sprite) sprite->data[0] = gBattleAnimArgs[4]; sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + gBattleAnimArgs[2]; sprite->data[4] = GetBankPosition(gAnimBankTarget, var2) + gBattleAnimArgs[3]; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } diff --git a/src/battle/anim/fight.c b/src/battle/anim/fight.c new file mode 100644 index 000000000..0f46187f2 --- /dev/null +++ b/src/battle/anim/fight.c @@ -0,0 +1,664 @@ +#include "global.h" +#include "battle_anim.h" +#include "random.h" +#include "rom_8077ABC.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" +#include "constants/battle_constants.h" + +extern s16 gBattleAnimArgs[]; +extern u8 gBankAttacker; +extern u8 gAnimBankAttacker; +extern u8 gAnimBankTarget; +extern u8 gBankSpriteIds[]; +extern u8 gBanksBySide[]; +extern u16 gBattle_BG1_X; +extern u16 gBattle_BG1_Y; +extern u16 gBattle_BG2_X; +extern u16 gBattle_BG2_Y; +extern u16 gBattle_BG3_X; +extern u16 gBattle_BG3_Y; +extern u16 gBattle_WIN0H; +extern u16 gBattle_WIN0V; +extern u16 gBattlePartyID[]; +extern u8 gAnimMoveTurn; + +extern struct SpriteTemplate gBasicHitSplatSpriteTemplate; + +static void sub_80D927C(struct Sprite *sprite); +static void sub_80D9328(struct Sprite *sprite); +static void sub_80D9404(struct Sprite *sprite); +static void AnimSpinningKickOrPunchFinish(struct Sprite *sprite); +static void AnimStompFootStep(struct Sprite *sprite); +static void AnimStompFootEnd(struct Sprite *sprite); +static void sub_80D9640(struct Sprite *sprite); +static void sub_80D97A0(struct Sprite *sprite); +static void sub_80D986C(struct Sprite *sprite); +static void sub_80D9934(struct Sprite *sprite); +static void sub_80D99F4(struct Sprite *sprite); + + +void sub_080B08A0(struct Sprite *sprite) +{ + sub_807867C(sprite, gBattleAnimArgs[0]); + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = 15; + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); +} + +void sub_80D902C(struct Sprite *sprite) +{ + if (gBattleAnimArgs[7] == 1 && GetBankSide(gAnimBankAttacker) != SIDE_PLAYER) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + } + + StartSpriteAnim(sprite, gBattleAnimArgs[6]); + gBattleAnimArgs[6] = 0; + sub_8079534(sprite); +} + +void sub_80D9078(struct Sprite *sprite) +{ + if (IsContest()) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + } + + sub_80D902C(sprite); +} + +// Displays a basic fist or foot sprite for a given duration. +// Used by many fighting moves (and elemental "punch" moves). +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: duration +// arg 3: ? (todo: related to initial pixel offsets) +// arg 4: anim num +void AnimBasicFistOrFoot(struct Sprite *sprite) +{ + StartSpriteAnim(sprite, gBattleAnimArgs[4]); + + if (gBattleAnimArgs[3] == 0) + InitAnimSpritePos(sprite, 1); + else + sub_8078764(sprite, 1); + + sprite->data[0] = gBattleAnimArgs[2]; + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); +} + +void sub_80D90F4(struct Sprite *sprite) +{ + u8 bank; + s16 xMod, yMod; + s16 x, y; + + if (gBattleAnimArgs[0] == 0) + bank = gAnimBankAttacker; + else + bank = gAnimBankTarget; + + if (gBattleAnimArgs[2] < 0) + gBattleAnimArgs[2] = Random() % 5; + + StartSpriteAnim(sprite, gBattleAnimArgs[2]); + sprite->pos1.x = GetBankPosition(bank, 2); + sprite->pos1.y = GetBankPosition(bank, 3); + + xMod = sub_807A100(bank, 1) / 2; + yMod = sub_807A100(bank, 0) / 4; + + x = Random() % xMod; + y = Random() % yMod; + + if (Random() & 1) + x *= -1; + if (Random() & 1) + y *= -1; + + if ((gBanksBySide[bank] & 1) == 0) + y += 0xFFF0; + + sprite->pos1.x += x; + sprite->pos1.y += y; + + sprite->data[0] = gBattleAnimArgs[1]; + sprite->data[7] = CreateSprite(&gBasicHitSplatSpriteTemplate, sprite->pos1.x, sprite->pos1.y, sprite->subpriority + 1); + if (sprite->data[7] != 64) + { + StartSpriteAffineAnim(&gSprites[sprite->data[7]], 0); + gSprites[sprite->data[7]].callback = SpriteCallbackDummy; + } + + sprite->callback = sub_80D927C; +} + +static void sub_80D927C(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + if (sprite->data[7] != 64) + { + FreeOamMatrix(gSprites[sprite->data[7]].oam.matrixNum); + DestroySprite(&gSprites[sprite->data[7]]); + } + + DestroyAnimSprite(sprite); + } + else + { + sprite->data[0]--; + } +} + +void sub_80D92D0(struct Sprite *sprite) +{ + sub_8078764(sprite, 1); + sprite->data[0] = 30; + + if (gBattleAnimArgs[2] == 0) + { + sprite->data[2] = sprite->pos1.x - 20; + } + else + { + sprite->data[2] = sprite->pos1.x + 20; + sprite->hFlip = 1; + } + + sprite->data[4] = sprite->pos1.y - 20; + sprite->callback = StartTranslateAnimSpriteByDeltas; + StoreSpriteCallbackInData(sprite, sub_80D9328); +} + +static void sub_80D9328(struct Sprite *sprite) +{ + if (++sprite->data[5] == 11) + { + sprite->data[2] = sprite->pos1.x - sprite->pos2.x; + sprite->data[4] = sprite->pos1.y - sprite->pos2.y; + sprite->data[0] = 8; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + + sprite->callback = StartTranslateAnimSpriteByDeltas; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); + } +} + +void sub_80D9378(struct Sprite *sprite) +{ + if ((gAnimBankAttacker ^ 2) == gAnimBankTarget && GetBankIdentity(gAnimBankTarget) < 2) + gBattleAnimArgs[0] *= -1; + + sub_8078764(sprite, 1); + + if (GetBankSide(gAnimBankAttacker) != SIDE_PLAYER) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + + sprite->data[0] = gBattleAnimArgs[3]; + 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; + + InitAnimSpriteTranslationDeltas(sprite); + + sprite->data[5] = gBattleAnimArgs[5]; + sprite->data[6] = gBattleAnimArgs[4]; + sprite->data[7] = 0; + + sprite->callback = sub_80D9404; +} + +static void sub_80D9404(struct Sprite *sprite) +{ + if (!TranslateAnimSpriteByDeltas(sprite)) + { + sprite->pos2.y += Sin(sprite->data[7] >> 8, sprite->data[5]); + sprite->data[7] += sprite->data[6]; + } + else + { + DestroyAnimSprite(sprite); + } +} + +// Animates the spinning, shrinking kick or punch, which then +// reappears at full size. Used by moves such as MOVE_MEGA_PUNCH and MOVE_MEGA_KICK. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: anim num +// arg 3: spin duration +void AnimSpinningKickOrPunch(struct Sprite *sprite) +{ + sub_8078764(sprite, 1); + StartSpriteAnim(sprite, gBattleAnimArgs[2]); + sprite->data[0] = gBattleAnimArgs[3]; + + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData(sprite, AnimSpinningKickOrPunchFinish); +} + +static void AnimSpinningKickOrPunchFinish(struct Sprite *sprite) +{ + StartSpriteAffineAnim(sprite, 0); + sprite->affineAnimPaused = 1; + sprite->data[0] = 20; + + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); +} + +// Animates MOVE_STOMP's foot that slides downward. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: initial wait duration +void AnimStompFoot(struct Sprite *sprite) +{ + sub_8078764(sprite, 1); + sprite->data[0] = gBattleAnimArgs[2]; + + sprite->callback = AnimStompFootStep; +} + +static void AnimStompFootStep(struct Sprite *sprite) +{ + if (--sprite->data[0] == -1) + { + sprite->data[0] = 6; + sprite->data[2] = GetBankPosition(gAnimBankTarget, 2); + sprite->data[4] = GetBankPosition(gAnimBankTarget, 3); + + sprite->callback = StartTranslateAnimSpriteByDeltas; + StoreSpriteCallbackInData(sprite, AnimStompFootEnd); + } +} + +static void AnimStompFootEnd(struct Sprite *sprite) +{ + sprite->data[0] = 15; + + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); +} + +void sub_80D9540(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + sub_8078764(sprite, 1); + sprite->data[1] = gBattleAnimArgs[2]; + sprite->data[2] = gBattleAnimArgs[3]; + sprite->data[0]++; + } + else + { + sprite->data[4] += sprite->data[1]; + sprite->pos2.x = sprite->data[4] >> 8; + sprite->pos2.y = Sin(sprite->data[3], sprite->data[2]); + sprite->data[3] = (sprite->data[3] + 3) & 0xFF; + + if (sprite->data[3] > 100) + sprite->invisible = sprite->data[3] % 2; + + if (sprite->data[3] > 120) + DestroyAnimSprite(sprite); + } +} + +void sub_80D95D0(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); + } + + sprite->pos1.x += gBattleAnimArgs[1]; + sprite->pos1.y += gBattleAnimArgs[2]; + + sprite->data[0] = 0; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[2] = gBattleAnimArgs[4]; + sprite->data[3] = 0; + sprite->callback = sub_80D9640; +} + +static void sub_80D9640(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + if (--sprite->data[1] == 0) + { + if (sprite->data[2] == 0) + DestroyAnimSprite(sprite); + else + sprite->data[0]++; + } + break; + case 1: + if (++sprite->data[1] > 1) + { + sprite->data[1] = 0; + sprite->data[3]++; + if (sprite->data[3] & 1) + sprite->pos2.x = 2; + else + sprite->pos2.x = -2; + } + + if (--sprite->data[2] == 0) + DestroyAnimSprite(sprite); + break; + } +} + +void sub_80D96B8(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 0) + gBattleAnimArgs[2]; + sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 1) + gBattleAnimArgs[3]; + } + else + { + sprite->pos1.x = GetBankPosition(gAnimBankTarget, 0) + gBattleAnimArgs[2]; + sprite->pos1.y = GetBankPosition(gAnimBankTarget, 1) + gBattleAnimArgs[3]; + } + + sprite->oam.tileNum += gBattleAnimArgs[1] * 16; + sprite->data[0] = 0; + + switch (gBattleAnimArgs[1]) + { + case 0: + sprite->data[6] = -3; + sprite->data[7] = -3; + break; + case 1: + sprite->data[6] = 3; + sprite->data[7] = -3; + break; + case 2: + sprite->data[6] = -3; + sprite->data[7] = 3; + break; + case 3: + sprite->data[6] = 3; + sprite->data[7] = 3; + break; + default: + DestroyAnimSprite(sprite); + return; + } + + sprite->callback = sub_80D97A0; +} + +static void sub_80D97A0(struct Sprite *sprite) +{ + sprite->pos1.x += sprite->data[6]; + sprite->pos1.y += sprite->data[7]; + + if (++sprite->data[0] > 40) + DestroyAnimSprite(sprite); +} + +void sub_80D97CC(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBankPosition(gBankAttacker, 2); + sprite->pos1.y = GetBankPosition(gBankAttacker, 3); + sprite->oam.priority = sub_8079ED4(gAnimBankAttacker); + sprite->data[7] = gAnimBankTarget; + } + else + { + sprite->oam.priority = sub_8079ED4(gAnimBankTarget); + sprite->data[7] = gAnimBankAttacker; + } + + sprite->data[0] = 0; + sprite->data[1] = 12; + sprite->data[2] = 8; + sprite->callback = sub_80D986C; +} + +static void sub_80D986C(struct Sprite *sprite) +{ + if (++sprite->data[0] == 180) + { + REG_BLDCNT = 0; + + sprite->data[0] = 16; + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = GetBankPosition(sprite->data[7], 2); + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = GetBankPosition(sprite->data[7], 3); + + InitAnimSpriteTranslationDeltas(sprite); + StoreSpriteCallbackInData(sprite, move_anim_8074EE0); + sprite->callback = TranslateAnimSpriteByDeltasUntil; + } +} + +void sub_80D98D8(struct Sprite *sprite) +{ + sprite->pos1.x = gBattleAnimArgs[0]; + sprite->pos1.y = 120; + + sprite->data[0] = gBattleAnimArgs[3]; + sub_8079BF4(&sprite->data[4], &sprite->data[5], (void *)(sprite->pos1.y << 8)); + + sprite->data[6] = gBattleAnimArgs[1]; + sprite->oam.tileNum += gBattleAnimArgs[2] * 4; + + sprite->callback = sub_80D9934; +} + +static void sub_80D9934(struct Sprite *sprite) +{ + void *var0; + + if (sprite->data[0] != 0) + { + var0 = sub_8079BFC(sprite->data[4], sprite->data[5]); + var0 -= sprite->data[6]; + sub_8079BF4(&sprite->data[4], &sprite->data[5], var0); + + var0 = (void *)(((intptr_t)var0) >> 8); + sprite->pos1.y = (intptr_t)var0; + if (sprite->pos1.y < -8) + DestroyAnimSprite(sprite); + else + sprite->data[0]--; + } + else + { + s16 pos0 = GetBankPosition(gAnimBankAttacker, 2); + s16 pos1 = GetBankPosition(gAnimBankAttacker, 3); + s16 pos2 = GetBankPosition(gAnimBankTarget, 2); + s16 pos3 = GetBankPosition(gAnimBankTarget, 3); + + sprite->data[0] = pos2 - pos0; + sprite->data[1] = pos3 - pos1; + sprite->data[2] = sprite->pos1.x << 4; + sprite->data[3] = sprite->pos1.y << 4; + + sprite->callback = sub_80D99F4; + } +} + +static void sub_80D99F4(struct Sprite *sprite) +{ + u16 edgeX; + + sprite->data[2] += sprite->data[0]; + sprite->data[3] += sprite->data[1]; + sprite->pos1.x = sprite->data[2] >> 4; + sprite->pos1.y = sprite->data[3] >> 4; + + edgeX = sprite->pos1.x + 8; + if (edgeX > 256 || sprite->pos1.y < -8 || sprite->pos1.y > 120) + DestroyAnimSprite(sprite); +} + +void sub_80D9A38(struct Sprite *sprite) +{ + u8 bank; + + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBankPosition(gBankAttacker, 2); + sprite->pos1.y = GetBankPosition(gBankAttacker, 3); + bank = gAnimBankTarget; + sprite->oam.priority = sub_8079ED4(gAnimBankAttacker); + } + else + { + bank = gAnimBankAttacker; + sprite->oam.priority = sub_8079ED4(gAnimBankTarget); + } + + if (IsContest()) + sprite->oam.matrixNum |= 0x8; + else if (GetBankSide(bank) == SIDE_PLAYER) + sprite->oam.matrixNum |= 0x18; + + sprite->data[0] = 16; + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = GetBankPosition(bank, 2); + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = GetBankPosition(bank, 3); + + InitAnimSpriteTranslationDeltas(sprite); + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); + sprite->callback = TranslateAnimSpriteByDeltasUntil; +} + +static void sub_80D9B24(struct Sprite *sprite) +{ + if (sprite->data[0] == sprite->data[4]) + DestroyAnimSprite(sprite); + + sprite->data[0]++; +} + +void sub_80D9B48(struct Sprite *sprite) +{ + u8 turn; + + sprite->pos1.x = GetBankPosition(gAnimBankTarget, 2); + sprite->pos1.y = GetBankPosition(gAnimBankTarget, 3); + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[2] = gBattleAnimArgs[0]; + sprite->data[3] = gBattleAnimArgs[1]; + sprite->data[4] = gBattleAnimArgs[2]; + + turn = gAnimMoveTurn; + if (GetBankSide(gAnimBankTarget) == SIDE_PLAYER) + turn++; + + if (turn & 1) + { + sprite->data[2] = -sprite->data[2]; + sprite->data[1]++; + } + + StartSpriteAnim(sprite, sprite->data[1]); + sprite->pos2.x = sprite->data[2]; + sprite->pos2.y = sprite->data[3]; + sprite->callback = sub_80D9B24; +} + +void sub_80D9BD4(struct Sprite *sprite) +{ + if (gBattleAnimArgs[2] == 0) + InitAnimSpritePos(sprite, 0); + else + sub_8078764(sprite, 0); + + if (IsContest()) + { + StartSpriteAnim(sprite, 2); + } + else if (GetBankSide(gAnimBankAttacker) != SIDE_PLAYER) + { + StartSpriteAnim(sprite, 1); + } + + sprite->callback = sub_8078600; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); +} + +void sub_80D9C40(struct Sprite *sprite) +{ + if (sprite->affineAnimEnded) + { + sprite->data[1] = (sprite->data[1] + 40) & 0xFF; + sprite->pos2.x = Sin(sprite->data[1], 2); + + if (++sprite->data[0] > 40) + { + DestroyAnimSprite(sprite); + } + } +} + +void sub_80D9C80(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + sub_80789D4(0); + task->data[8] = gBattleAnimArgs[0]; + task->data[0]++; + break; + case 1: + if (--task->data[8] == -1) + task->data[0]++; + break; + case 2: + default: + task->data[9] += 1280; + break; + } + + task->data[10] += 2816; + + if (GetBankSide(gAnimBankTarget) == SIDE_PLAYER) + gBattle_BG3_X += task->data[9] >> 8; + else + gBattle_BG3_X -= task->data[9] >> 8; + + gBattle_BG3_Y += task->data[10] >> 8; + + task->data[9] &= 0xFF; + task->data[10] &= 0xFF; + + if (gBattleAnimArgs[7] == -1) + { + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + sub_80789D4(1); + DestroyAnimVisualTask(taskId); + } +} diff --git a/src/battle/anim/fire_2.c b/src/battle/anim/fire_2.c index 4d577a765..f9c9b6d3b 100644 --- a/src/battle/anim/fire_2.c +++ b/src/battle/anim/fire_2.c @@ -1,4 +1,5 @@ #include "global.h" +#include "battle.h" #include "battle_anim.h" #include "heated_rock.h" #include "rom_8077ABC.h" @@ -11,24 +12,34 @@ extern u8 gAnimBankTarget; extern struct SpriteTemplate gSpriteTemplate_83D96C4; extern s16 gHeatedRockCoords[7][2]; -void sub_80D5254(struct Sprite *); -void sub_80D5348(struct Sprite *); -void sub_80D52AC(struct Sprite *); -void sub_80D5324(struct Sprite *); +static void AnimFireRingStep1(struct Sprite *); +static void UpdateFireRingCircleOffset(struct Sprite *); +static void AnimFireRingStep2(struct Sprite *); +static void AnimFireRingStep3(struct Sprite *); void sub_80D53F4(struct Sprite *); void sub_80D541C(struct Sprite *); void sub_80D54E0(u8 taskId); void sub_80D57C4(u8 spriteId, u8 taskId, u8 a3); -void sub_80D51A8(struct Sprite *sprite) + +// Animates the secondary effect of MOVE_EMBER, where the flames grow and slide +// horizontally a bit. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: target x pixel offset +// arg 3: target y pixel offset +// arg 4: duration +// arg 5: ? (todo: something related to which mon the pixel offsets are based on) +// arg 6: ? (todo: something related to which mon the pixel offsets are based on) +void AnimEmberFlare(struct Sprite *sprite) { if (GetBankSide(gAnimBankAttacker) == GetBankSide(gAnimBankTarget) - && (gAnimBankAttacker == GetBankByIdentity(2) - || gAnimBankAttacker == GetBankByIdentity(3))) + && (gAnimBankAttacker == GetBankByIdentity(IDENTITY_PLAYER_MON2) + || gAnimBankAttacker == GetBankByIdentity(IDENTITY_OPPONENT_MON2))) gBattleAnimArgs[2] = -gBattleAnimArgs[2]; sprite->callback = sub_8079534; - sub_8079534(sprite); + sprite->callback(sprite); } struct Sprite *sub_80D5210(struct Sprite *sprite) @@ -40,19 +51,26 @@ struct Sprite *sub_80D5210(struct Sprite *sprite) return sprite; } -void sub_80D522C(struct Sprite *sprite) +// Animates the a fire sprite in the first-half of the MOVE_FIRE_BLAST +// animation. The fire sprite first moves in a circle around the mon, +// and then it is translated towards the target mon, while still rotating. +// Lastly, it moves in a circle around the target mon. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: initial wave offset +void AnimFireRing(struct Sprite *sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[7] = gBattleAnimArgs[2]; sprite->data[0] = 0; - sprite->callback = sub_80D5254; + sprite->callback = AnimFireRingStep1; } -void sub_80D5254(struct Sprite *sprite) +static void AnimFireRingStep1(struct Sprite *sprite) { - sub_80D5348(sprite); + UpdateFireRingCircleOffset(sprite); if (++sprite->data[0] == 0x12) { @@ -62,15 +80,15 @@ void sub_80D5254(struct Sprite *sprite) sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3); - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); - sprite->callback = sub_80D52AC; + sprite->callback = AnimFireRingStep2; } } -void sub_80D52AC(struct Sprite *sprite) +static void AnimFireRingStep2(struct Sprite *sprite) { - if (sub_8078B5C(sprite)) + if (TranslateAnimSpriteByDeltas(sprite)) { sprite->data[0] = 0; @@ -79,8 +97,8 @@ void sub_80D52AC(struct Sprite *sprite) sprite->pos2.y = 0; sprite->pos2.x = 0; - sprite->callback = sub_80D5324; - sub_80D5324(sprite); + sprite->callback = AnimFireRingStep3; + sprite->callback(sprite); } else { @@ -91,15 +109,15 @@ void sub_80D52AC(struct Sprite *sprite) } } -void sub_80D5324(struct Sprite *sprite) +static void AnimFireRingStep3(struct Sprite *sprite) { - sub_80D5348(sprite); + UpdateFireRingCircleOffset(sprite); if (++sprite->data[0] == 0x1F) DestroyAnimSprite(sprite); } -void sub_80D5348(struct Sprite *sprite) +static void UpdateFireRingCircleOffset(struct Sprite *sprite) { sprite->pos2.x = Sin(sprite->data[7], 28); sprite->pos2.y = Cos(sprite->data[7], 28); @@ -107,7 +125,12 @@ void sub_80D5348(struct Sprite *sprite) sprite->data[7] = (sprite->data[7] + 20) & 0xFF; } -void sub_80D5374(struct Sprite *sprite) +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: duration +// arg 3: x delta +// arg 4: y delta +void AnimFireCross(struct Sprite *sprite) { sprite->pos1.x += gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; @@ -118,18 +141,18 @@ void sub_80D5374(struct Sprite *sprite) StoreSpriteCallbackInData(sprite, DestroyAnimSprite); - sprite->callback = sub_8078364; + sprite->callback = TranslateSpriteOverDuration; } void sub_80D53B4(struct Sprite *sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[1] = gBattleAnimArgs[2]; sprite->data[0] = gBattleAnimArgs[3]; sprite->invisible = TRUE; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, sub_80D53F4); } diff --git a/src/battle/anim/flying_hearts.c b/src/battle/anim/flying_hearts.c index d2d22602a..f20416535 100644 --- a/src/battle/anim/flying_hearts.c +++ b/src/battle/anim/flying_hearts.c @@ -19,7 +19,7 @@ void sub_80D2064(struct Sprite* sprite) sprite->pos1.y = 0xA0; sprite->data[0] = gBattleAnimArgs[2]; sprite->data[1] = gBattleAnimArgs[1]; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, sub_80D2094); } diff --git a/src/battle/anim/flying_path.c b/src/battle/anim/flying_path.c index 441ac0e6d..70c418afc 100644 --- a/src/battle/anim/flying_path.c +++ b/src/battle/anim/flying_path.c @@ -40,7 +40,7 @@ void sub_80CBDF4(u8 taskId) gSprites[task->data[2]].data[3] = task->data[9]; gSprites[task->data[2]].data[4] = task->data[7] + (task->data[11] / 2 + 10) * task->data[5]; gSprites[task->data[2]].data[5] = sub_80CC338(&gSprites[task->data[2]]); - sub_80786EC(&gSprites[task->data[2]]); + InitAnimSpriteTranslationOverDuration(&gSprites[task->data[2]]); task->func = sub_80CBF5C; } @@ -53,7 +53,7 @@ void sub_80CBF5C(u8 taskId) { case 4: sub_80CC358(task, taskId); - if (sub_8078718(sprite) == 0) + if (TranslateAnimSpriteLinearAndSine(sprite) == 0) { break; } @@ -65,7 +65,7 @@ void sub_80CBF5C(u8 taskId) break; case 8: sub_80CC358(task, taskId); - if (sub_8078718(sprite) == 0) + if (TranslateAnimSpriteLinearAndSine(sprite) == 0) { break; } @@ -77,7 +77,7 @@ void sub_80CBF5C(u8 taskId) break; case 0: sub_80CC358(task, taskId); - if (sub_8078718(sprite) == 0) + if (TranslateAnimSpriteLinearAndSine(sprite) == 0) break; task->data[15] = 1; @@ -98,12 +98,12 @@ void sub_80CBF5C(u8 taskId) task->data[3] = a; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); task->data[0]++; break; case 2: sub_80CC358(task, taskId); - if (sub_8078718(sprite) == 0) + if (TranslateAnimSpriteLinearAndSine(sprite) == 0) break; task->data[15] = 3; @@ -123,7 +123,7 @@ void sub_80CBF5C(u8 taskId) task->data[3] = 2; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); task->data[0]++; break; case 5: @@ -141,12 +141,12 @@ void sub_80CBF5C(u8 taskId) task->data[3] = 3; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); task->data[0]++; break; case 6: sub_80CC358(task, taskId); - if (sub_8078718(sprite) == 0) + if (TranslateAnimSpriteLinearAndSine(sprite) == 0) break; task->data[15] = 7; @@ -167,7 +167,7 @@ void sub_80CBF5C(u8 taskId) task->data[3] = 4; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); task->data[0]++; break; case 9: @@ -184,12 +184,12 @@ void sub_80CBF5C(u8 taskId) task->data[3] = 5; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); task->data[0]++; break; case 10: sub_80CC358(task, taskId); - if (sub_8078718(sprite) == 0) + if (TranslateAnimSpriteLinearAndSine(sprite) == 0) { break; } @@ -215,13 +215,13 @@ void sub_80CBF5C(u8 taskId) task->data[3] = 6; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); task->data[0]++; break; } case 12: sub_80CC358(task, taskId); - if (sub_8078718(sprite) != 0) + if (TranslateAnimSpriteLinearAndSine(sprite) != 0) { DestroySprite(sprite); task->data[0]++; diff --git a/src/battle/anim/glitter.c b/src/battle/anim/glitter.c index e4577f1e1..e6c101de3 100644 --- a/src/battle/anim/glitter.c +++ b/src/battle/anim/glitter.c @@ -35,7 +35,7 @@ void sub_80CD190(struct Sprite* sprite) if (IsDoubleBattle() && IsAnimBankSpriteVisible(bank ^ 2)) { - sub_807A3FC(bank, gBattleAnimArgs[6], &sprite->pos1.x, &sprite->pos1.y); + SetAverageBattlerPositions(bank, gBattleAnimArgs[6], &sprite->pos1.x, &sprite->pos1.y); sub_807867C(sprite, gBattleAnimArgs[0]); sprite->pos1.y += gBattleAnimArgs[1]; } diff --git a/src/battle/anim/grip.c b/src/battle/anim/grip.c index c4d7b1cef..dbf7a1562 100644 --- a/src/battle/anim/grip.c +++ b/src/battle/anim/grip.c @@ -33,7 +33,7 @@ void sub_80D0178(struct Sprite* sprite) sprite->data[0] = 6; sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + r8; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3) + r6; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, sub_80D020C); } diff --git a/src/battle/anim/guard.c b/src/battle/anim/guard.c index 254160109..211e0e841 100644 --- a/src/battle/anim/guard.c +++ b/src/battle/anim/guard.c @@ -15,7 +15,7 @@ void sub_80D3014(struct Sprite *sprite) { if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsAnimBankSpriteVisible(gAnimBankAttacker ^ 2)) { - sub_807A3FC(gAnimBankAttacker, 0, &sprite->pos1.x, &sprite->pos1.y); + SetAverageBattlerPositions(gAnimBankAttacker, 0, &sprite->pos1.x, &sprite->pos1.y); sprite->pos1.y += 40; StartSpriteAffineAnim(sprite, 1); @@ -30,6 +30,6 @@ void sub_80D3014(struct Sprite *sprite) sprite->data[2] = sprite->pos1.x; sprite->data[4] = sprite->pos1.y - 72; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } diff --git a/src/battle/anim/guillotine.c b/src/battle/anim/guillotine.c index b3d842cdf..15279d5e2 100644 --- a/src/battle/anim/guillotine.c +++ b/src/battle/anim/guillotine.c @@ -37,7 +37,7 @@ void sub_80D0228(struct Sprite* sprite) sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + r9; sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3) + r6; - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); sprite->data[5] = gBattleAnimArgs[0]; sprite->data[6] = sprite->data[0]; sprite->callback = sub_80D02D0; @@ -45,7 +45,7 @@ void sub_80D0228(struct Sprite* sprite) void sub_80D02D0(struct Sprite* sprite) { - if (sub_8078B5C(sprite) && sprite->animEnded == 1) + if (TranslateAnimSpriteByDeltas(sprite) && sprite->animEnded == 1) { SeekSpriteAnim(sprite, 0); sprite->animPaused = 1; @@ -85,6 +85,6 @@ void sub_80D0344(struct Sprite* sprite) void sub_80D03A8(struct Sprite* sprite) { - if (sub_8078B5C(sprite) != 0) + if (TranslateAnimSpriteByDeltas(sprite) != 0) DestroyAnimSprite(sprite); } diff --git a/src/battle/anim/heart_1.c b/src/battle/anim/heart_1.c index 5df89f929..857169e62 100644 --- a/src/battle/anim/heart_1.c +++ b/src/battle/anim/heart_1.c @@ -14,7 +14,7 @@ extern u8 gAnimBankTarget; void sub_80D1C80(struct Sprite* sprite) { if (++sprite->data[0] == 1) - sub_80787B0(sprite, 0); + InitAnimSpritePos(sprite, 0); sprite->pos2.x = Sin(sprite->data[1], 8); sprite->pos2.y = sprite->data[2] >> 8; diff --git a/src/battle/anim/heated_rock.c b/src/battle/anim/heated_rock.c index 51cfbd007..055960f40 100644 --- a/src/battle/anim/heated_rock.c +++ b/src/battle/anim/heated_rock.c @@ -50,101 +50,25 @@ void sub_80D5994(struct Sprite *sprite, s16 x, s16 y) sprite->data[5] = y * 8; } -#ifdef NONMATCHING void sub_80D59B0(struct Sprite *sprite) { int var1; - int var2; - if (++sprite->data[0] > 2) { sprite->data[0] = 0; ++sprite->data[1]; - sprite->data[3] += ((u16)sprite->data[1] * (u16)sprite->data[1]); + var1 = (u16)sprite->data[1] * (u16)sprite->data[1]; + sprite->data[3] += var1; } - var1 = (u16)sprite->data[4] + (u16)sprite->data[2]; - sprite->data[2] = var1; - var1 = (s16)var1 >> 3; - sprite->pos1.x = var1; - - var2 = (u16)sprite->data[5] + (u16)sprite->data[3]; - sprite->data[3] = var2; - var2 = (s16)var2 >> 3; - sprite->pos1.y = var2; + sprite->data[2] += sprite->data[4]; + sprite->pos1.x = sprite->data[2] >> 3; + sprite->data[3] += sprite->data[5]; + sprite->pos1.y = sprite->data[3] >> 3; - if ((u32)((var1 + 8) << 16) > 0x1000000 || var2 < -8 || var2 > 120) - { - sprite->invisible = 1; - } -} -#else -__attribute__((naked)) -void sub_80D59B0(struct Sprite *sprite) -{ - asm(".syntax unified\n\ - push {lr}\n\ - adds r2, r0, 0\n\ - ldrh r0, [r2, 0x2E]\n\ - adds r0, 0x1\n\ - strh r0, [r2, 0x2E]\n\ - lsls r0, 16\n\ - asrs r0, 16\n\ - cmp r0, 0x2\n\ - ble _080D59DA\n\ - movs r0, 0\n\ - strh r0, [r2, 0x2E]\n\ - ldrh r0, [r2, 0x30]\n\ - adds r0, 0x1\n\ - strh r0, [r2, 0x30]\n\ - ldrh r0, [r2, 0x30]\n\ - adds r1, r0, 0\n\ - muls r1, r0\n\ - adds r0, r1, 0\n\ - ldrh r3, [r2, 0x34]\n\ - adds r0, r3\n\ - strh r0, [r2, 0x34]\n\ -_080D59DA:\n\ - ldrh r0, [r2, 0x36]\n\ - ldrh r1, [r2, 0x32]\n\ - adds r0, r1\n\ - strh r0, [r2, 0x32]\n\ - lsls r0, 16\n\ - asrs r0, 19\n\ - strh r0, [r2, 0x20]\n\ - ldrh r1, [r2, 0x38]\n\ - ldrh r3, [r2, 0x34]\n\ - adds r1, r3\n\ - strh r1, [r2, 0x34]\n\ - lsls r1, 16\n\ - asrs r3, r1, 19\n\ - strh r3, [r2, 0x22]\n\ - adds r0, 0x8\n\ - lsls r0, 16\n\ - movs r1, 0x80\n\ - lsls r1, 17\n\ - cmp r0, r1\n\ - bhi _080D5A10\n\ - adds r1, r3, 0\n\ - movs r0, 0x8\n\ - negs r0, r0\n\ - cmp r1, r0\n\ - blt _080D5A10\n\ - cmp r1, 0x78\n\ - ble _080D5A1C\n\ -_080D5A10:\n\ - adds r0, r2, 0\n\ - adds r0, 0x3E\n\ - ldrb r1, [r0]\n\ - movs r2, 0x4\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ -_080D5A1C:\n\ - pop {r0}\n\ - bx r0\n\ - .syntax divided\n"); + if (sprite->pos1.x < -8 || sprite->pos1.x > 0xf8 || sprite->pos1.y < -8 || sprite->pos1.y > 120) + sprite->invisible = TRUE; } -#endif // NONMATCHING void sub_80D5A20(struct Sprite *sprite) { diff --git a/src/battle/anim/homing.c b/src/battle/anim/homing.c index 6fb4a76d8..208d3b831 100644 --- a/src/battle/anim/homing.c +++ b/src/battle/anim/homing.c @@ -60,7 +60,7 @@ void sub_80CC6CC(struct Sprite* sprite) sprite->data[2] = y * 16; sprite->data[3] = (sprite->data[5] - sprite->pos1.x) * 16 / gBattleAnimArgs[4]; sprite->data[4] = (sprite->data[6] - sprite->pos1.y) * 16 / gBattleAnimArgs[4]; - c = sub_80790F0(sprite->data[5] - x, sprite->data[6] - y); + c = ArcTan2Neg(sprite->data[5] - x, sprite->data[6] - y); if (IsContest()) c -= 0x8000; diff --git a/src/battle/anim/hop.c b/src/battle/anim/hop.c index 4006e2d43..0697e83a0 100644 --- a/src/battle/anim/hop.c +++ b/src/battle/anim/hop.c @@ -91,7 +91,7 @@ void sub_80CB94C(struct Sprite* sprite) { s16 e1; s16 e2; - sub_80787B0(sprite, 0); + InitAnimSpritePos(sprite, 0); e1 = GetBankPosition(gAnimBankTarget, 0); e2 = GetBankPosition(gAnimBankTarget, 1); if ((gAnimBankAttacker ^ 2) == gAnimBankTarget) diff --git a/src/battle/anim/lunge_1.c b/src/battle/anim/lunge_1.c index d379c8f09..a3b5f19c5 100644 --- a/src/battle/anim/lunge_1.c +++ b/src/battle/anim/lunge_1.c @@ -8,7 +8,7 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -extern u8 gObjectBankIDs[]; +extern u8 gBankSpriteIds[]; static void sub_80CD7CC(struct Sprite* sprite); static void sub_80CD81C(struct Sprite* sprite); @@ -46,16 +46,16 @@ void sub_80CD7CC(struct Sprite* sprite) sprite->data[0] = 6; sprite->data[1] = (GetBankSide(gAnimBankAttacker)) ? 2 : -2; sprite->data[2] = 0; - sprite->data[3] = gObjectBankIDs[gAnimBankAttacker]; + sprite->data[3] = gBankSpriteIds[gAnimBankAttacker]; StoreSpriteCallbackInData(sprite, sub_80CD81C); - sprite->callback = sub_8078458; + sprite->callback = TranslateMonBGUntil; } void sub_80CD81C(struct Sprite* sprite) { if (sprite->data[0] == 0) { - sprite->data[3] = gObjectBankIDs[gAnimBankAttacker]; + sprite->data[3] = gBankSpriteIds[gAnimBankAttacker]; sub_8078E70(sprite->data[3], 0); sprite->data[4] = (sprite->data[6] = GetBankSide(gAnimBankAttacker)) ? 0x300 : 0xFFFFFD00; sprite->data[5] = 0; @@ -76,9 +76,9 @@ void sub_80CD8A8(struct Sprite* sprite) sprite->data[0] = 4; sprite->data[1] = (GetBankSide(gAnimBankAttacker)) ? -3 : 3; sprite->data[2] = 0; - sprite->data[3] = gObjectBankIDs[gAnimBankAttacker]; + sprite->data[3] = gBankSpriteIds[gAnimBankAttacker]; StoreSpriteCallbackInData(sprite, sub_80CD9B8); - sprite->callback = sub_8078458; + sprite->callback = TranslateMonBGUntil; } void sub_80CD8F8(struct Sprite* sprite) @@ -94,7 +94,7 @@ void sub_80CD91C(struct Sprite* sprite) { if (sprite->data[0] == 0) { - sprite->data[3] = gObjectBankIDs[gAnimBankAttacker]; + sprite->data[3] = gBankSpriteIds[gAnimBankAttacker]; sprite->data[6] = GetBankSide(gAnimBankAttacker); if (GetBankSide(gAnimBankAttacker)) { diff --git a/src/battle/anim/lunge_2.c b/src/battle/anim/lunge_2.c index fe2470567..f222b291d 100644 --- a/src/battle/anim/lunge_2.c +++ b/src/battle/anim/lunge_2.c @@ -8,7 +8,7 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -extern u8 gObjectBankIDs[]; +extern u8 gBankSpriteIds[]; static void sub_80CDB60(u8 taskId); static void sub_80CDD20(u8 taskId); @@ -20,7 +20,7 @@ void sub_80CDAC8(u8 taskId) { u8 a; - gTasks[taskId].data[0] = gObjectBankIDs[gAnimBankAttacker]; + gTasks[taskId].data[0] = gBankSpriteIds[gAnimBankAttacker]; a = GetBankSide(gAnimBankAttacker); gTasks[taskId].data[1] = a; gTasks[taskId].data[2] = 0; diff --git a/src/battle/anim/money.c b/src/battle/anim/money.c index 8358d23db..c3d130750 100644 --- a/src/battle/anim/money.c +++ b/src/battle/anim/money.c @@ -19,14 +19,14 @@ void sub_80CFE9C(struct Sprite* sprite) s16 r7; u16 var; - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); r6 = GetBankPosition(gAnimBankTarget, 2); r7 = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3]; if (GetBankSide(gAnimBankAttacker) != 0) gBattleAnimArgs[2] = -gBattleAnimArgs[2]; r6 += gBattleAnimArgs[2]; - var = sub_80790F0(r6 - sprite->pos1.x, r7 - sprite->pos1.y); + var = ArcTan2Neg(r6 - sprite->pos1.x, r7 - sprite->pos1.y); var += 0xC000; sub_8078FDC(sprite, 0, 0x100, 0x100, var); sprite->data[0] = gBattleAnimArgs[4]; diff --git a/src/battle/anim/note_rain.c b/src/battle/anim/note_rain.c index 715462d73..44817b0a0 100644 --- a/src/battle/anim/note_rain.c +++ b/src/battle/anim/note_rain.c @@ -24,14 +24,14 @@ void sub_80D1BA8(struct Sprite* sprite, u8 a, u8 b) void sub_80D1C08(struct Sprite* sprite) { - sub_80787B0(sprite, 0); + InitAnimSpritePos(sprite, 0); if (GetBankSide(gAnimBankAttacker) != 0) gBattleAnimArgs[2] = -gBattleAnimArgs[2]; sprite->data[0] = gBattleAnimArgs[4]; sprite->data[2] = GetBankPosition(gAnimBankAttacker, 0) + gBattleAnimArgs[2]; sprite->data[4] = GetBankPosition(gAnimBankAttacker, 1) + gBattleAnimArgs[3]; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); sub_80D1BA8(sprite, gBattleAnimArgs[5], gBattleAnimArgs[6]); } diff --git a/src/battle/anim/note_scatter_2.c b/src/battle/anim/note_scatter_2.c index 524c51c08..262afb8bf 100644 --- a/src/battle/anim/note_scatter_2.c +++ b/src/battle/anim/note_scatter_2.c @@ -32,14 +32,14 @@ void sub_80CEE60(struct Sprite* sprite) sprite->data[2] = a + sprite->data[1]; sprite->data[3] = sprite->pos1.y; sprite->data[4] = sprite->data[3] - 40; - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); sprite->data[5] = gBattleAnimArgs[3]; sprite->callback = sub_80CEEE8; } void sub_80CEEE8(struct Sprite* sprite) { - if (sub_8078B5C(sprite) == 0) + if (TranslateAnimSpriteByDeltas(sprite) == 0) { s16 a; a = Sin(sprite->data[5], 8); diff --git a/src/battle/anim/orbit.c b/src/battle/anim/orbit.c index c8cf339d2..e7dd0df49 100644 --- a/src/battle/anim/orbit.c +++ b/src/battle/anim/orbit.c @@ -79,13 +79,13 @@ void sub_80CACEC(u8 taskId) void sub_80CAD54(struct Sprite* sprite) { - sub_80787B0(sprite, 0); + InitAnimSpritePos(sprite, 0); sprite->data[0] = gBattleAnimArgs[3]; sprite->data[1] = sprite->pos1.x; sprite->data[2] = sprite->pos1.x; sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBankPosition(gAnimBankAttacker, 3) + gBattleAnimArgs[2]; - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); sprite->data[5] = 0x40; sprite->callback = sub_80CADA8; sub_80CADA8(sprite); @@ -93,7 +93,7 @@ void sub_80CAD54(struct Sprite* sprite) void sub_80CADA8(struct Sprite* sprite) { - if (!sub_8078B5C(sprite)) + if (!TranslateAnimSpriteByDeltas(sprite)) { sprite->pos2.x += Sin(sprite->data[5], 32); sprite->pos2.y += Cos(sprite->data[5], -5); @@ -116,13 +116,13 @@ void sub_80CADA8(struct Sprite* sprite) void sub_80CAE20(struct Sprite* sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[0] = gBattleAnimArgs[3]; sprite->data[1] = sprite->pos1.x; sprite->data[2] = sprite->pos1.x; sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBankPosition(gAnimBankAttacker, 3) + gBattleAnimArgs[2]; - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); sprite->data[5] = 0x40; sprite->callback = sub_80CAE74; sub_80CAE74(sprite); @@ -130,7 +130,7 @@ void sub_80CAE20(struct Sprite* sprite) void sub_80CAE74(struct Sprite* sprite) { - if (!sub_8078B5C(sprite)) + if (!TranslateAnimSpriteByDeltas(sprite)) { sprite->pos2.x += Sin(sprite->data[5], 8); if ((u16)(sprite->data[5] - 0x3B) < 5 || (u16)(sprite->data[5] - 0xBB) < 5) diff --git a/src/battle/anim/orbit_fast.c b/src/battle/anim/orbit_fast.c index 92b67672b..71303b03c 100644 --- a/src/battle/anim/orbit_fast.c +++ b/src/battle/anim/orbit_fast.c @@ -8,12 +8,13 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -static void sub_80D2704(struct Sprite* sprite); +static void AnimOrbitFastStep(struct Sprite* sprite); -// orbit_fast (a quickly moving fast circular motion of a sprite around an object.) -// Used by Hidden Power. - -void sub_80D26A4(struct Sprite* sprite) +// Orbits a sphere in an ellipse around the mon. +// Used by MOVE_HIDDEN_POWER +// arg 0: duration +// arg 1: initial wave offset +void AnimOrbitFast(struct Sprite* sprite) { sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2); sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3); @@ -21,11 +22,11 @@ void sub_80D26A4(struct Sprite* sprite) sprite->data[0] = gBattleAnimArgs[0]; sprite->data[1] = gBattleAnimArgs[1]; sprite->data[7] = sub_8079E90(gAnimBankAttacker); - sprite->callback = sub_80D2704; - sub_80D2704(sprite); + sprite->callback = AnimOrbitFastStep; + sprite->callback(sprite); } -void sub_80D2704(struct Sprite* sprite) +static void AnimOrbitFastStep(struct Sprite* sprite) { if ((u16)(sprite->data[1] - 0x40) <= 0x7F) sprite->subpriority = sprite->data[7] + 1; diff --git a/src/battle/anim/orbit_scatter.c b/src/battle/anim/orbit_scatter.c index 54c157839..cda09a729 100644 --- a/src/battle/anim/orbit_scatter.c +++ b/src/battle/anim/orbit_scatter.c @@ -8,21 +8,21 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -static void sub_80D2834(struct Sprite* sprite); +static void AnimOrbitScatterStep(struct Sprite* sprite); -// orbit_scatter (scatters the objects associated with the fast orbit from the last file.) -// Used in Hidden Power. - -void sub_80D27E0(struct Sprite* sprite) +// Moves orbs away from the mon, based on where they are in their orbit. +// Used in MOVE_HIDDEN_POWER. +// arg 0: initial wave offset +void AnimOrbitScatter(struct Sprite* sprite) { sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2); sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3); sprite->data[0] = Sin(gBattleAnimArgs[0], 10); sprite->data[1] = Cos(gBattleAnimArgs[0], 7); - sprite->callback = sub_80D2834; + sprite->callback = AnimOrbitScatterStep; } -void sub_80D2834(struct Sprite* sprite) +static void AnimOrbitScatterStep(struct Sprite* sprite) { sprite->pos2.x += sprite->data[0]; sprite->pos2.y += sprite->data[1]; diff --git a/src/battle/anim/orbs.c b/src/battle/anim/orbs.c index 6ca2fa71c..6f1bba9c3 100644 --- a/src/battle/anim/orbs.c +++ b/src/battle/anim/orbs.c @@ -19,34 +19,34 @@ extern struct SpriteTemplate gSpriteTemplate_83D631C; void sub_80CA7B0(struct Sprite* sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[0] = gBattleAnimArgs[2]; sprite->data[2] = GetBankPosition(gAnimBankAttacker, 2); sprite->data[4] = GetBankPosition(gAnimBankAttacker, 3); - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, move_anim_8074EE0); } void sub_80CA800(struct Sprite* sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); StartSpriteAnim(sprite, gBattleAnimArgs[3]); sprite->data[0] = gBattleAnimArgs[2]; sprite->data[2] = GetBankPosition(gAnimBankTarget, 2); sprite->data[4] = GetBankPosition(gAnimBankTarget, 3); - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } void sub_80CA858(struct Sprite* sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[0] = gBattleAnimArgs[2]; sprite->data[1] = sprite->pos1.x; sprite->data[2] = GetBankPosition(gAnimBankTarget, 2); sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3); - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); sprite->data[5] = gBattleAnimArgs[3]; sprite->callback = sub_80CA8B4; sub_80CA8B4(sprite); @@ -54,7 +54,7 @@ void sub_80CA858(struct Sprite* sprite) void sub_80CA8B4(struct Sprite* sprite) { - if (sub_8078B5C(sprite)) + if (TranslateAnimSpriteByDeltas(sprite)) { DestroySprite(sprite); } @@ -99,13 +99,13 @@ void sub_80CA9A8(struct Sprite* sprite) sprite->data[2] = GetBankPosition(gAnimBankAttacker, 2); sprite->data[4] = GetBankPosition(gAnimBankAttacker, 3); sprite->data[5] = gBattleAnimArgs[2]; - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); sprite->callback = sub_80CA9F8; } void sub_80CA9F8(struct Sprite* sprite) { - if (sub_8078718(sprite)) + if (TranslateAnimSpriteLinearAndSine(sprite)) DestroyAnimSprite(sprite); } diff --git a/src/battle/anim/perceive.c b/src/battle/anim/perceive.c index 3b3153428..14db096c6 100644 --- a/src/battle/anim/perceive.c +++ b/src/battle/anim/perceive.c @@ -19,6 +19,6 @@ void sub_80D2904(struct Sprite* sprite) void sub_80D2920(struct Sprite* sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->callback = sub_80D2904; } diff --git a/src/battle/anim/poison.c b/src/battle/anim/poison.c index f31c441fb..3a7477a57 100644 --- a/src/battle/anim/poison.c +++ b/src/battle/anim/poison.c @@ -10,28 +10,28 @@ 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); +static void AnimBubbleEffectStep(struct Sprite *sprite); void sub_80D9D70(struct Sprite *sprite) { if (!gBattleAnimArgs[3]) StartSpriteAnim(sprite, 2); - sub_80787B0(sprite, 1); + InitAnimSpritePos(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); + InitAnimSpriteTranslationOverDuration(sprite); sprite->callback = sub_80D9DD4; } void sub_80D9DD4(struct Sprite *sprite) // same as sub_80D9E78 { - if (sub_8078718(sprite)) + if (TranslateAnimSpriteLinearAndSine(sprite)) DestroyAnimSprite(sprite); } @@ -41,8 +41,8 @@ void sub_80D9DF0(struct Sprite *sprite) if (!gBattleAnimArgs[3]) StartSpriteAnim(sprite, 2); - sub_80787B0(sprite, 1); - sub_807A3FC(gAnimBankTarget, 1, &l1, &l2); + InitAnimSpritePos(sprite, 1); + SetAverageBattlerPositions(gAnimBankTarget, 1, &l1, &l2); if (GetBankSide(gAnimBankAttacker)) gBattleAnimArgs[4] = -gBattleAnimArgs[4]; @@ -52,14 +52,14 @@ void sub_80D9DF0(struct Sprite *sprite) sprite->data[4] = l2 + gBattleAnimArgs[5]; sprite->data[5] = -30; - sub_80786EC(sprite); + InitAnimSpriteTranslationOverDuration(sprite); sprite->callback = sub_80D9E78; } void sub_80D9E78(struct Sprite *sprite) // same as sub_80D9DD4 { - if (sub_8078718(sprite)) + if (TranslateAnimSpriteLinearAndSine(sprite)) DestroyAnimSprite(sprite); } @@ -71,7 +71,7 @@ void sub_80D9E94(struct Sprite *sprite) sprite->data[3] = sprite->pos1.y; sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[1]; - sub_8078A5C(sprite); + InitSpriteDataForLinearTranslation(sprite); sprite->data[5] = sprite->data[1] / gBattleAnimArgs[2]; sprite->data[6] = sprite->data[2] / gBattleAnimArgs[2]; @@ -92,7 +92,7 @@ void sub_80D9EE8(struct Sprite *sprite) void sub_80D9F14(struct Sprite *sprite) { - sub_807A3FC(gAnimBankTarget, TRUE, &sprite->pos1.x, &sprite->pos1.y); + SetAverageBattlerPositions(gAnimBankTarget, TRUE, &sprite->pos1.x, &sprite->pos1.y); if (GetBankSide(gAnimBankAttacker)) gBattleAnimArgs[0] = -gBattleAnimArgs[0]; @@ -104,11 +104,17 @@ void sub_80D9F14(struct Sprite *sprite) sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2]; sprite->data[4] = sprite->pos1.y + sprite->data[0]; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } -void sub_80D9F88(struct Sprite *sprite) +// Animates a bubble by rising upward, swaying side to side, and +// enlarging the sprite. This is used as an after-effect by poison-type +// moves, along with MOVE_BUBBLE, and MOVE_BUBBLEBEAM. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: 0 = single-target, 1 = multi-target +void AnimBubbleEffect(struct Sprite *sprite) { if (!gBattleAnimArgs[2]) { @@ -116,7 +122,7 @@ void sub_80D9F88(struct Sprite *sprite) } else { - sub_807A3FC(gAnimBankTarget, TRUE, &sprite->pos1.x, &sprite->pos1.y); + SetAverageBattlerPositions(gAnimBankTarget, TRUE, &sprite->pos1.x, &sprite->pos1.y); if (GetBankSide(gAnimBankAttacker)) gBattleAnimArgs[0] = -gBattleAnimArgs[0]; @@ -125,10 +131,10 @@ void sub_80D9F88(struct Sprite *sprite) sprite->pos1.y += gBattleAnimArgs[1]; } - sprite->callback = sub_80D9FF0; + sprite->callback = AnimBubbleEffectStep; } -void sub_80D9FF0(struct Sprite *sprite) +static void AnimBubbleEffectStep(struct Sprite *sprite) { sprite->data[0] = (sprite->data[0] + 0xB) & 0xFF; sprite->pos2.x = Sin(sprite->data[0], 4); diff --git a/src/battle/anim/powder.c b/src/battle/anim/powder.c index a0be20d6f..5d67311dc 100644 --- a/src/battle/anim/powder.c +++ b/src/battle/anim/powder.c @@ -6,12 +6,17 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; -static void sub_80CA768(struct Sprite* sprite); +static void AnimMovePowderParticleStep(struct Sprite* sprite); -// powder +// Animates the falling particles that horizontally wave back and forth. // Used by Sleep Powder, Stun Spore, and Poison Powder. - -void sub_80CA710(struct Sprite* sprite) +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: total duration in frames +// arg 3: vertical movement speed (sub-pixel value) +// arg 4: wave amplitude +// arg 5: wave speed +void AnimMovePowderParticle(struct Sprite* sprite) { sprite->pos1.x += gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; @@ -28,10 +33,10 @@ void sub_80CA710(struct Sprite* sprite) } sprite->data[4] = gBattleAnimArgs[5]; - sprite->callback = sub_80CA768; + sprite->callback = AnimMovePowderParticleStep; } -void sub_80CA768(struct Sprite* sprite) +static void AnimMovePowderParticleStep(struct Sprite* sprite) { if (sprite->data[0] > 0) { diff --git a/src/battle/anim/psychic.c b/src/battle/anim/psychic.c new file mode 100644 index 000000000..42f396870 --- /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 gBankSpriteIds[]; + +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)) + MoveBattlerSpriteToBG(bank, toBG_2); + + bank = bankCopy ^ 2; + if (IsAnimBankSpriteVisible(bank)) + MoveBattlerSpriteToBG(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[gBankSpriteIds[bank]].invisible = 0; + + bank = bankCopy ^ 2; + if (IsAnimBankSpriteVisible(bank)) + gSprites[gBankSpriteIds[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) + InitAnimSpritePos(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]; + + InitAnimSpriteTranslationOverDuration(&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 (TranslateAnimSpriteLinearAndSine(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 = ®_BG1HOFS; + } + else + { + task->data[10] = gBattle_BG2_X; + scanlineParams.dmaDest = ®_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..86b2c4659 100644 --- a/src/battle/anim/ring.c +++ b/src/battle/anim/ring.c @@ -10,7 +10,7 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -extern u8 gObjectBankIDs[]; +extern u8 gBankSpriteIds[]; static void sub_80D1098(struct Sprite* sprite); @@ -32,7 +32,7 @@ void sub_80D0FD8(struct Sprite* sprite) r4 = gBattleAnimArgs[3] ^ 1; if (IsDoubleBattle() && IsAnimBankSpriteVisible(bank ^ 2)) { - sub_807A3FC(bank, r4, &sp0, &sp1); + SetAverageBattlerPositions(bank, r4, &sp0, &sp1); if (r4 == 0) r4 = GetBankPosition(bank, 0); else @@ -50,7 +50,7 @@ void sub_80D0FD8(struct Sprite* sprite) void sub_80D1098(struct Sprite* sprite) { - if (sub_8078B5C(sprite)) + if (TranslateAnimSpriteByDeltas(sprite)) { FreeSpriteOamMatrix(sprite); DestroyAnimSprite(sprite); @@ -94,23 +94,23 @@ void sub_80D10B8(struct Sprite* sprite) { r9 = GetBankPosition(bankr7, r10) + gBattleAnimArgs[0]; if (IsAnimBankSpriteVisible(bankr8 ^ 2)) - sprite->subpriority = gSprites[gObjectBankIDs[bankr8 ^ 2]].subpriority - 1; + sprite->subpriority = gSprites[gBankSpriteIds[bankr8 ^ 2]].subpriority - 1; else - sprite->subpriority = gSprites[gObjectBankIDs[bankr8]].subpriority - 1; + sprite->subpriority = gSprites[gBankSpriteIds[bankr8]].subpriority - 1; } else { r9 = GetBankPosition(bankr7, r10) - gBattleAnimArgs[0]; if (gMain.inBattle && IsAnimBankSpriteVisible(bankr7 ^ 2)) { - if (gSprites[gObjectBankIDs[bankr7]].pos1.x < gSprites[gObjectBankIDs[bankr7 ^ 2]].pos1.x) - sprite->subpriority = gSprites[gObjectBankIDs[bankr7 ^ 2]].subpriority + 1; + if (gSprites[gBankSpriteIds[bankr7]].pos1.x < gSprites[gBankSpriteIds[bankr7 ^ 2]].pos1.x) + sprite->subpriority = gSprites[gBankSpriteIds[bankr7 ^ 2]].subpriority + 1; else - sprite->subpriority = gSprites[gObjectBankIDs[bankr7]].subpriority - 1; + sprite->subpriority = gSprites[gBankSpriteIds[bankr7]].subpriority - 1; } else { - sprite->subpriority = gSprites[gObjectBankIDs[bankr7]].subpriority - 1; + sprite->subpriority = gSprites[gBankSpriteIds[bankr7]].subpriority - 1; } } @@ -118,7 +118,7 @@ void sub_80D10B8(struct Sprite* sprite) r6 = GetBankPosition(bankr7, sp4) + gBattleAnimArgs[1]; if (gMain.inBattle && IsAnimBankSpriteVisible(bankr8 ^ 2)) { - sub_807A3FC(bankr8, gBattleAnimArgs[6], &sp0, &sp1); + SetAverageBattlerPositions(bankr8, gBattleAnimArgs[6], &sp0, &sp1); } else { @@ -137,7 +137,7 @@ void sub_80D10B8(struct Sprite* sprite) sprite->data[2] = sp0; sprite->data[4] = sp1; sprite->data[0] = gBattleAnimArgs[0]; - obj_translate_based_on_private_1_2_3_4(sprite); + InitAnimSpriteTranslationDeltas(sprite); sprite->callback = sub_80D1098; sub_80D1098(sprite); } diff --git a/src/battle/anim/rock.c b/src/battle/anim/rock.c new file mode 100644 index 000000000..6fbe065b8 --- /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) + SetAverageBattlerPositions(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]; + + InitSpriteDataForLinearTranslation(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) + InitAnimSpritePos(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]); + InitAnimSpritePos(sprite, 0); + + sprite->data[0] = gBattleAnimArgs[3]; + sprite->data[2] = sprite->pos1.x; + sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[2]; + + sprite->callback = StartTranslateAnimSpriteByDeltas; + 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; + + InitAnimSpriteTranslationOverDuration(&gSprites[spriteId]); + task->data[11]++; + } + + task->data[12] *= -1; +} + +void sub_80DD87C(struct Sprite *sprite) +{ + if (TranslateAnimSpriteLinearAndSine(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); + + TranslateAnimSpriteToTargetMonLocation(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/scan.c b/src/battle/anim/scan.c index 22bb26973..403894cc8 100644 --- a/src/battle/anim/scan.c +++ b/src/battle/anim/scan.c @@ -26,7 +26,7 @@ void sub_80CD3E0(struct Sprite* sprite) sprite->pos1.x -= 32; sprite->pos1.y -= 32; sprite->data[0] = 20; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, sub_80CD408); } @@ -36,7 +36,7 @@ void sub_80CD408(struct Sprite* sprite) { case 0: sprite->data[0] = 1; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, sub_80CD408); break; case 1: @@ -47,7 +47,7 @@ void sub_80CD408(struct Sprite* sprite) sprite->data[0] = 8; sprite->data[2] = sprite->pos1.x + gUnknown_083D6DDC[sprite->data[5] >> 8][0]; sprite->data[4] = sprite->pos1.y + gUnknown_083D6DDC[sprite->data[5] >> 8][1]; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, sub_80CD4B8); sprite->data[5] += 0x100; PlaySE12WithPanning(0xD2, BattleAnimAdjustPanning(0x3F)); @@ -62,7 +62,7 @@ void sub_80CD4B8(struct Sprite* sprite) if ((sprite->data[5] >> 8) == 4) { sprite->data[0] = 10; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, sub_80CD4EC); } else @@ -80,7 +80,7 @@ void sub_80CD4EC(struct Sprite* sprite) sprite->data[0] = 3; sprite->data[1] = 0; sprite->data[2] = 0; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, sub_80CD5A8); } else @@ -112,7 +112,7 @@ void sub_80CD4EC(struct Sprite* sprite) sprite->data[0] = 6; sprite->data[2] = GetBankPosition(gAnimBankTarget, 2) + a; sprite->data[4] = GetBankPosition(gAnimBankTarget, 3) + b; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, sub_80CD654); } } diff --git a/src/battle/anim/seed.c b/src/battle/anim/seed.c index be8613a74..7f8154504 100644 --- a/src/battle/anim/seed.c +++ b/src/battle/anim/seed.c @@ -7,15 +7,20 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -static void sub_80CAB88(struct Sprite* sprite); -static void sub_80CABC0(struct Sprite* sprite); +static void AnimLeechSeedStep(struct Sprite* sprite); +static void AnimLeechSeedSprouts(struct Sprite* sprite); // seed (sprouts a sapling from a seed.) // Used by Leech Seed. - -void sub_80CAB18(struct Sprite* sprite) +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: target x pixel offset +// arg 3: target y pixel offset +// arg 4: duration +// arg 5: wave amplitude +void AnimLeechSeed(struct Sprite* sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); if (GetBankSide(gAnimBankAttacker)) { gBattleAnimArgs[2] = -gBattleAnimArgs[2]; @@ -25,26 +30,26 @@ void sub_80CAB18(struct Sprite* sprite) sprite->data[2] = GetBankPosition(gAnimBankTarget, 0) + gBattleAnimArgs[2]; sprite->data[4] = GetBankPosition(gAnimBankTarget, 1) + gBattleAnimArgs[3]; sprite->data[5] = gBattleAnimArgs[5]; - sub_80786EC(sprite); - sprite->callback = sub_80CAB88; + InitAnimSpriteTranslationOverDuration(sprite); + sprite->callback = AnimLeechSeedStep; } -void sub_80CAB88(struct Sprite* sprite) +static void AnimLeechSeedStep(struct Sprite* sprite) { - if (sub_8078718(sprite)) + if (TranslateAnimSpriteLinearAndSine(sprite)) { sprite->invisible = 1; sprite->data[0] = 10; - sprite->callback = sub_80782D8; - StoreSpriteCallbackInData(sprite, sub_80CABC0); + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData(sprite, AnimLeechSeedSprouts); } } -void sub_80CABC0(struct Sprite* sprite) +static void AnimLeechSeedSprouts(struct Sprite* sprite) { sprite->invisible = 0; StartSpriteAnim(sprite, 1); sprite->data[0] = 60; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } diff --git a/src/battle/anim/shadow_minimize.c b/src/battle/anim/shadow_minimize.c index 94069374f..61645bc59 100644 --- a/src/battle/anim/shadow_minimize.c +++ b/src/battle/anim/shadow_minimize.c @@ -93,7 +93,7 @@ void sub_80D04E0(u8 taskId) sub_8078F40(task->data[0]); gSprites[task->data[15]].pos2.y = 0; DestroyAnimVisualTask(taskId); - break; + break; } } @@ -110,10 +110,11 @@ void sub_80D0614(struct Task* task, u8 taskId) } else { - gSprites[r8].oam.objMode = 1; - gSprites[r8].oam.affineMode = 3; - gSprites[r8].affineAnimPaused = 1; - gSprites[r8].oam.matrixNum = r6; + gSprites[r8].oam.objMode = ST_OAM_OBJ_BLEND; + gSprites[r8].oam.affineMode = ST_OAM_AFFINE_DOUBLE; + gSprites[r8].affineAnimPaused = TRUE; + r6 &= 0x1f; + gSprites[r8].oam.matrixNum = r6; // need to inhibit optimizing out the mov r0, 0x3f / neg r0, r0 gSprites[r8].subpriority = task->data[7] - task->data[3]; task->data[3]++; task->data[6]++; @@ -132,7 +133,7 @@ __attribute__((naked)) void sub_80D0614(struct Task* task, u8 taskId) { asm(".syntax unified\n\ - push {r4-r7,lr}\n\ + push {r4-r7,lr}\n\ mov r7, r9\n\ mov r6, r8\n\ push {r6,r7}\n\ diff --git a/src/battle/anim/slash.c b/src/battle/anim/slash.c index 6adcaf098..306968111 100644 --- a/src/battle/anim/slash.c +++ b/src/battle/anim/slash.c @@ -60,7 +60,7 @@ void sub_80CDE78(struct Sprite* sprite) sprite->data[1] = 8; sprite->data[2] = 0; StoreSpriteCallbackInData(sprite, sub_80CDEB0); - sprite->callback = sub_8078364; + sprite->callback = TranslateSpriteOverDuration; } } diff --git a/src/battle/anim/slice.c b/src/battle/anim/slice.c index fe8745483..80c58dddf 100644 --- a/src/battle/anim/slice.c +++ b/src/battle/anim/slice.c @@ -8,19 +8,21 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -static void sub_80CCB00(struct Sprite* sprite); +static void AnimSliceStep(struct Sprite* sprite); -// slice (the cutting animation showing as a yellow line drawn diagonally) -// Used in Cut, Fury Cutter, Aerial Ace, and Air Cutter. - -void sub_80CC914(struct Sprite* sprite) +// Moves the sprite in a diagonally slashing motion across the target mon. +// Used by moves such as MOVE_CUT and MOVE_AERIAL_ACE. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: slice direction; 0 = right-to-left, 1 = left-to-right +void AnimCuttingSlice(struct Sprite* sprite) { sprite->pos1.x = GetBankPosition(gAnimBankTarget, 0); sprite->pos1.y = GetBankPosition(gAnimBankTarget, 1); if (GetBankSide(gAnimBankTarget) == 0) sprite->pos1.y += 8; - sprite->callback = sub_80CCB00; + sprite->callback = AnimSliceStep; if (gBattleAnimArgs[2] == 0) { sprite->pos1.x += gBattleAnimArgs[0]; @@ -70,7 +72,7 @@ void sub_80CC9BC(struct Sprite* sprite) if (GetBankSide(gAnimBankTarget) == 0) sprite->pos1.y += 8; - sprite->callback = sub_80CCB00; + sprite->callback = AnimSliceStep; if (gBattleAnimArgs[2] == 0) { sprite->pos1.x += gBattleAnimArgs[0]; @@ -89,7 +91,7 @@ void sub_80CC9BC(struct Sprite* sprite) sprite->data[1] = -sprite->data[1]; } -void sub_80CCB00(struct Sprite* sprite) +static void AnimSliceStep(struct Sprite* sprite) { sprite->data[3] += sprite->data[1]; sprite->data[4] += sprite->data[2]; @@ -106,6 +108,6 @@ void sub_80CCB00(struct Sprite* sprite) { StoreSpriteCallbackInData(sprite, DestroyAnimSprite); sprite->data[0] = 3; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; } } diff --git a/src/battle/anim/sonic.c b/src/battle/anim/sonic.c index 0897ec6e3..1501f51f1 100644 --- a/src/battle/anim/sonic.c +++ b/src/battle/anim/sonic.c @@ -9,14 +9,18 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -// sonic (shoots a projectile towards the target.) -// Used in Sonic Boom and Air Cutter. - -void sub_80CF6DC(struct Sprite* sprite) +// Moves a projectile towards the target mon. The sprite is rotated to be pointing +// in the same direction it's moving. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: target x pixel offset +// arg 3: target y pixel offset +// arg 4: duration +void AnimSonicBoomProjectile(struct Sprite* sprite) { - s16 a; - s16 b; - u16 c; + s16 targetXPos; + s16 targetYPos; + u16 rotation; if (IsContest()) { @@ -29,19 +33,19 @@ void sub_80CF6DC(struct Sprite* sprite) gBattleAnimArgs[3] = -gBattleAnimArgs[3]; } - sub_80787B0(sprite, 1); - a = GetBankPosition(gAnimBankTarget, 2) + gBattleAnimArgs[2]; - b = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3]; - c = sub_80790F0(a - sprite->pos1.x, b - sprite->pos1.y); - c += 0xF000; + InitAnimSpritePos(sprite, 1); + targetXPos = GetBankPosition(gAnimBankTarget, 2) + gBattleAnimArgs[2]; + targetYPos = GetBankPosition(gAnimBankTarget, 3) + gBattleAnimArgs[3]; + rotation = ArcTan2Neg(targetXPos - sprite->pos1.x, targetYPos - sprite->pos1.y); + rotation += 0xF000; if (IsContest()) - c -= 0x6000; + rotation -= 0x6000; - sub_8078FDC(sprite, 0, 0x100, 0x100, c); + sub_8078FDC(sprite, 0, 0x100, 0x100, rotation); sprite->data[0] = gBattleAnimArgs[4]; - sprite->data[2] = a; - sprite->data[4] = b; - sprite->callback = sub_8078B34; + sprite->data[2] = targetXPos; + sprite->data[4] = targetYPos; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } diff --git a/src/battle/anim/sonic_task.c b/src/battle/anim/sonic_task.c index 924b1b568..260ae544c 100644 --- a/src/battle/anim/sonic_task.c +++ b/src/battle/anim/sonic_task.c @@ -87,7 +87,7 @@ void sub_80CFB04(u8 taskId) if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsAnimBankSpriteVisible(gAnimBankTarget ^ 2)) { - sub_807A3FC(gAnimBankTarget, 0, &sp1, &sp2); + SetAverageBattlerPositions(gAnimBankTarget, 0, &sp1, &sp2); } else { diff --git a/src/battle/anim/sunlight.c b/src/battle/anim/sunlight.c index e6fd49a11..88112c74a 100644 --- a/src/battle/anim/sunlight.c +++ b/src/battle/anim/sunlight.c @@ -12,6 +12,6 @@ void sub_80D517C(struct Sprite *sprite) sprite->data[0] = 60; sprite->data[2] = 140; sprite->data[4] = 80; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } diff --git a/src/battle/anim/sword.c b/src/battle/anim/sword.c index b46fe6759..3367cca07 100644 --- a/src/battle/anim/sword.c +++ b/src/battle/anim/sword.c @@ -15,7 +15,7 @@ static void sub_80CF6B4(struct Sprite* sprite); void sub_80CF690(struct Sprite* sprite) { - sub_80787B0(sprite, 0); + InitAnimSpritePos(sprite, 0); sprite->callback = sub_80785E4; StoreSpriteCallbackInData(sprite, sub_80CF6B4); } @@ -25,6 +25,6 @@ void sub_80CF6B4(struct Sprite* sprite) sprite->data[0] = 6; sprite->data[2] = sprite->pos1.x; sprite->data[4] = sprite->pos1.y - 32; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } diff --git a/src/battle/anim/tile_out.c b/src/battle/anim/tile_out.c index 50468a440..39d4ff01f 100644 --- a/src/battle/anim/tile_out.c +++ b/src/battle/anim/tile_out.c @@ -37,7 +37,7 @@ void sub_80CE1AC(struct Sprite* sprite) sprite->data[0] = 30; sprite->data[2] = GetBankPosition(gAnimBankAttacker, 2); sprite->data[4] = GetBankPosition(gAnimBankAttacker, 3); - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } } diff --git a/src/battle/anim/unused_4.c b/src/battle/anim/unused_4.c index bda476a0a..50ffaba4a 100644 --- a/src/battle/anim/unused_4.c +++ b/src/battle/anim/unused_4.c @@ -8,7 +8,7 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -extern u8 gObjectBankIDs[]; +extern u8 gBankSpriteIds[]; static void sub_80CD9D4(struct Sprite* sprite); @@ -27,7 +27,7 @@ void sub_80CD9D4(struct Sprite* sprite) { case 0: sprite->data[1] = 0; - sprite->data[2] = gObjectBankIDs[gAnimBankAttacker]; + sprite->data[2] = gBankSpriteIds[gAnimBankAttacker]; sprite->data[3] = GetBankSide(gAnimBankAttacker); sprite->data[4] = (sprite->data[3] != 0) ? 0x200 : -0x200; sprite->data[5] = 0; diff --git a/src/battle/anim/unused_7.c b/src/battle/anim/unused_7.c index 2be6e7633..5a2de33c3 100644 --- a/src/battle/anim/unused_7.c +++ b/src/battle/anim/unused_7.c @@ -8,7 +8,7 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -extern u8 gObjectBankIDs[]; +extern u8 gBankSpriteIds[]; // unused_7 @@ -32,7 +32,7 @@ void sub_80CF3C4(struct Sprite* sprite) u8 a; sprite->pos1.x = GetBankPosition(gAnimBankAttacker, 2); sprite->pos1.y = GetBankPosition(gAnimBankAttacker, 3); - a = gObjectBankIDs[gAnimBankTarget]; + a = gBankSpriteIds[gAnimBankTarget]; if (GetBankSide(gAnimBankAttacker) != 0) { sprite->pos1.x -= gBattleAnimArgs[0]; diff --git a/src/battle/anim/unused_8.c b/src/battle/anim/unused_8.c index 03772f951..c67ec2754 100644 --- a/src/battle/anim/unused_8.c +++ b/src/battle/anim/unused_8.c @@ -15,11 +15,11 @@ static void sub_80CF4B8(struct Sprite* sprite); void sub_80CF458(struct Sprite* sprite) { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); sprite->data[0] = gBattleAnimArgs[2]; sprite->data[1] = gBattleAnimArgs[3]; sprite->data[5] = gBattleAnimArgs[4]; - sprite->callback = sub_80782D8; + sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, sub_80CF490); } @@ -28,7 +28,7 @@ void sub_80CF490(struct Sprite* sprite) sprite->data[0] = sprite->data[1]; sprite->data[2] = sprite->pos1.x; sprite->data[4] = sprite->pos1.y + 15; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, sub_80CF4B8); } diff --git a/src/battle/anim/unused_9.c b/src/battle/anim/unused_9.c index cf3ccb0d4..6e0d0321b 100644 --- a/src/battle/anim/unused_9.c +++ b/src/battle/anim/unused_9.c @@ -3,6 +3,7 @@ #include "trig.h" #include "battle_anim.h" #include "sound.h" +#include "palette.h" extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; @@ -17,7 +18,7 @@ static void sub_80CFE2C(struct Sprite* sprite); void sub_80CFDFC(struct Sprite* sprite) { - sub_80787B0(sprite, 0); + InitAnimSpritePos(sprite, 0); sprite->data[0] = 0x100 + (IndexOfSpritePaletteTag(gSpriteTemplate_83D75AC.paletteTag) << 4); sprite->callback = sub_80CFE2C; } @@ -26,23 +27,19 @@ void sub_80CFDFC(struct Sprite* sprite) void sub_80CFE2C(struct Sprite* sprite) { u16 r7; - u16* r1; - u16* r2; + u16 r5; int i; if (++sprite->data[1] == 2) { sprite->data[1] = 0; - r7 = gPlttBufferFaded[sprite->data[0] + 8]; - r2 = &gPlttBufferFaded[0x10]; - r1 = &gPlttBufferFaded[sprite->data[0] + 9]; - for (i = 7; i >= 0; i--) + r5 = sprite->data[0]; + r7 = gPlttBufferFaded[r5 + 8]; + for (i = 0; i < 8; i++) { - *r2 = *r1; - r1++; - r2++; + gPlttBufferFaded[r5 + i + 8] = gPlttBufferFaded[r5 + i + 9]; } + gPlttBufferFaded[r5 + 15] = r7; - gPlttBufferFaded[sprite->data[0] + 15] = r7; if (++sprite->data[2] == 0x18) DestroyAnimSprite(sprite); } diff --git a/src/battle/anim/water.c b/src/battle/anim/water.c index 4068cbe78..e6945f9b2 100644 --- a/src/battle/anim/water.c +++ b/src/battle/anim/water.c @@ -18,7 +18,7 @@ void sub_80D37FC(struct Sprite *sprite) sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2]; sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[4]; - sprite->callback = sub_8078B34; + sprite->callback = StartTranslateAnimSpriteByDeltas; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } @@ -30,7 +30,7 @@ void sub_80D3838(struct Sprite *sprite) } else { - sub_80787B0(sprite, 1); + InitAnimSpritePos(sprite, 1); } sprite->data[7] = gBattleAnimArgs[2]; diff --git a/src/battle/anim/wisp_fire.c b/src/battle/anim/wisp_fire.c index 348ce6426..24cecb60c 100644 --- a/src/battle/anim/wisp_fire.c +++ b/src/battle/anim/wisp_fire.c @@ -10,7 +10,7 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankTarget; extern u8 gAnimBankAttacker; -extern u8 gObjectBankIDs[]; +extern u8 gBankSpriteIds[]; extern s8 gUnknown_083D9794[16]; extern s8 gUnknown_083D97A4[16]; @@ -175,7 +175,7 @@ void sub_80D60B4(u8 taskId) } gTasks[taskId].data[0]++; - spriteId = gObjectBankIDs[gAnimBankTarget]; + spriteId = gBankSpriteIds[gAnimBankTarget]; if (!gTasks[taskId].data[4]) unk = gUnknown_083D9794[gTasks[taskId].data[0] % 10]; diff --git a/src/battle/anim/wisp_orb.c b/src/battle/anim/wisp_orb.c index 0cbe6eed7..7c22b7f13 100644 --- a/src/battle/anim/wisp_orb.c +++ b/src/battle/anim/wisp_orb.c @@ -21,7 +21,7 @@ void sub_80D5B0C(struct Sprite *sprite) switch (sprite->data[0]) { case 0: - sub_80787B0(sprite, 0); + InitAnimSpritePos(sprite, 0); StartSpriteAnim(sprite, gBattleAnimArgs[2]); sprite->data[7] = gBattleAnimArgs[2]; @@ -86,7 +86,7 @@ static void sub_80D5C5C(struct Sprite *sprite) s16 initialData5; s16 newData5; - if (!sub_8078B5C(sprite)) + if (!TranslateAnimSpriteByDeltas(sprite)) { sprite->pos2.x += Sin(sprite->data[5], 16); initialData5 = sprite->data[5]; diff --git a/src/battle/anim/withdraw.c b/src/battle/anim/withdraw.c index e67248b9f..933c97fa9 100644 --- a/src/battle/anim/withdraw.c +++ b/src/battle/anim/withdraw.c @@ -8,7 +8,7 @@ extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; -extern u8 gObjectBankIDs[]; +extern u8 gBankSpriteIds[]; static void sub_80CF514(u8 taskId); @@ -17,13 +17,13 @@ static void sub_80CF514(u8 taskId); void sub_80CF4D8(u8 taskId) { - sub_8078E70(gObjectBankIDs[gAnimBankAttacker], 0); + sub_8078E70(gBankSpriteIds[gAnimBankAttacker], 0); gTasks[taskId].func = sub_80CF514; } void sub_80CF514(u8 taskId) { - u8 a = gObjectBankIDs[gAnimBankAttacker]; + u8 a = gBankSpriteIds[gAnimBankAttacker]; s16 b; if (GetBankSide(gAnimBankAttacker) == 0) { |