#include "global.h" #include "rom_8077ABC.h" #include "trig.h" #include "battle_anim.h" #include "sound.h" #include "palette.h" extern s16 gBattleAnimArgs[]; extern u8 gBattleAnimAttacker; extern u8 gBattleAnimTarget; void sub_80CEB0C(struct Sprite* sprite); void sub_80CECE8(struct Sprite* sprite); void sub_80CEDF0(struct Sprite* sprite); void sub_80CEE60(struct Sprite* sprite); static void sub_80CEBC4(s16 a, s16 b, s16* c, s16* d, s8 e); static void sub_80CEC1C(struct Sprite* sprite); static void sub_80CED78(struct Sprite* sprite); static void sub_80CEEE8(struct Sprite* sprite); const union AnimCmd gSpriteAnim_83D7098[] = { ANIMCMD_FRAME(0, 10), ANIMCMD_END, }; const union AnimCmd gSpriteAnim_83D70A0[] = { ANIMCMD_FRAME(4, 10), ANIMCMD_END, }; const union AnimCmd gSpriteAnim_83D70A8[] = { ANIMCMD_FRAME(8, 41), ANIMCMD_END, }; const union AnimCmd gSpriteAnim_83D70B0[] = { ANIMCMD_FRAME(12, 10), ANIMCMD_END, }; const union AnimCmd gSpriteAnim_83D70B8[] = { ANIMCMD_FRAME(16, 10), ANIMCMD_END, }; const union AnimCmd gSpriteAnim_83D70C0[] = { ANIMCMD_FRAME(20, 10), ANIMCMD_END, }; const union AnimCmd gSpriteAnim_83D70C8[] = { ANIMCMD_FRAME(0, 10, .vFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gSpriteAnim_83D70D0[] = { ANIMCMD_FRAME(4, 10, .vFlip = TRUE), ANIMCMD_END, }; const union AnimCmd *const gSpriteAnimTable_83D70D8[] = { gSpriteAnim_83D7098, gSpriteAnim_83D70A0, gSpriteAnim_83D70A8, gSpriteAnim_83D70B0, gSpriteAnim_83D70B8, gSpriteAnim_83D70C0, gSpriteAnim_83D70C8, gSpriteAnim_83D70D0, }; const union AffineAnimCmd gSpriteAffineAnim_83D70F8[] = { AFFINEANIMCMD_FRAME(0xC, 0xC, 0, 16), AFFINEANIMCMD_FRAME(0xFFF4, 0xFFF4, 0, 16), AFFINEANIMCMD_JUMP(0), }; const union AffineAnimCmd *const gSpriteAffineAnimTable_83D7110[] = { gSpriteAffineAnim_83D70F8, }; const struct SpriteTemplate gBattleAnimSpriteTemplate_83D7114 = { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, .oam = &gOamData_837DFEC, .anims = gSpriteAnimTable_83D70D8, .images = NULL, .affineAnims = gSpriteAffineAnimTable_83D7110, .callback = sub_80CEB0C, }; const u16 gUnknown_083D712C[][6] = { {10072, RGB(31, 31, 31), RGB(31, 26, 28), RGB(31, 22, 26), RGB(31, 17, 24), RGB(31, 13, 22)}, {10097, RGB(31, 31, 31), RGB(25, 31, 26), RGB(20, 31, 21), RGB(15, 31, 16), RGB(10, 31, 12)}, {10185, RGB(31, 31, 31), RGB(31, 31, 24), RGB(31, 31, 17), RGB(31, 31, 10), RGB(31, 31, 3)}, {10175, RGB(31, 31, 31), RGB(26, 28, 31), RGB(21, 26, 31), RGB(16, 24, 31), RGB(12, 22, 31)}, }; const struct SpriteTemplate gBattleAnimSpriteTemplate_83D715C = { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, .oam = &gOamData_837DFEC, .anims = gSpriteAnimTable_83D70D8, .images = NULL, .affineAnims = gSpriteAffineAnimTable_83D7110, .callback = sub_80CECE8, }; const struct SpriteTemplate gBattleAnimSpriteTemplate_83D7174 = { .tileTag = ANIM_TAG_PURPLE_HAND_OUTLINE, .paletteTag = ANIM_TAG_PURPLE_HAND_OUTLINE, .oam = &gOamData_837DF34, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_80CEDF0, }; const union AffineAnimCmd gSpriteAffineAnim_83D718C[] = { AFFINEANIMCMD_FRAME(0xA0, 0xA0, 0, 0), AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 1), AFFINEANIMCMD_JUMP(1), }; const union AffineAnimCmd *const gSpriteAffineAnimTable_83D71A4[] = { gSpriteAffineAnim_83D718C, }; const struct SpriteTemplate gBattleAnimSpriteTemplate_83D71A8 = { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, .oam = &gOamData_837DFEC, .anims = gSpriteAnimTable_83D70D8, .images = NULL, .affineAnims = gSpriteAffineAnimTable_83D71A4, .callback = sub_80CEE60, }; // musical (music notes, drum) // Used by Grasswhistle, Belly Drum, and Sing. // rainbow effect for musical notes void sub_80CEA20(u8 taskId) { u16 i; u16 j; u16 index; index = IndexOfSpritePaletteTag(gUnknown_083D712C[0][0]); if (index != 0xFF) { index = (index << 4) + 0x100; for (i = 1; i < 6; i++) { gPlttBufferFaded[index + i] = gUnknown_083D712C[0][i]; } } for (j = 1; j < 4; j++) { index = AllocSpritePalette(gUnknown_083D712C[j][0]); if (index != 0xFF) { index = (index << 4) + 0x100; for (i = 1; i < 6; i++) { gPlttBufferFaded[index + i] = gUnknown_083D712C[j][i]; } } } DestroyAnimVisualTask(taskId); } // clears the rainbow effect for musical notes. void sub_80CEAD8(u8 taskId) { u16 i; for (i = 1; i < 4; i++) { FreeSpritePaletteByTag(gUnknown_083D712C[i][0]); } DestroyAnimVisualTask(taskId); } void sub_80CEB0C(struct Sprite* sprite) { u8 index; u8 a; u8 b; sub_8078650(sprite); StartSpriteAnim(sprite, gBattleAnimArgs[0]); if ((index = IndexOfSpritePaletteTag(gUnknown_083D712C[gBattleAnimArgs[1]][0])) != 0xFF) sprite->oam.paletteNum = index; sprite->data[1] = gBattleAnimArgs[1]; sprite->data[2] = 0; sprite->data[3] = gBattleAnimArgs[2]; if (IsContest()) { a = 0x30; b = 0x28; } else { a = GetBattlerSpriteCoord(gBattleAnimTarget, 2); b = GetBattlerSpriteCoord(gBattleAnimTarget, 3); } sprite->data[4] = sprite->x << 4; sprite->data[5] = sprite->y << 4; sub_80CEBC4(a - sprite->x, b - sprite->y, &sprite->data[6], &sprite->data[7], 0x28); sprite->callback = sub_80CEC1C; } static void sub_80CEBC4(s16 a, s16 b, s16* c, s16* d, s8 e) { int f; int g; if (a < 0) e = -e; f = a << 8; g = f / e; if (g == 0) g = 1; *c = f / g; *d = (b << 8) / g; } static void sub_80CEC1C(struct Sprite* sprite) { int b; s16 a; int c; u8 index; sprite->data[0]++; b = sprite->data[0] * 5 - ((sprite->data[0] * 5 / 256) << 8); sprite->data[4] += sprite->data[6]; sprite->data[5] += sprite->data[7]; sprite->x = sprite->data[4] >> 4; sprite->y = sprite->data[5] >> 4; sprite->y2 = Sin(b, 15); a = (u16)sprite->y; c = (u16)sprite->x; if ((u32)((c + 16) << 16) > (0x110) << 16 || a < -16 || a > 0x80) { DestroySpriteAndMatrix(sprite); } else { if (sprite->data[3] && ++sprite->data[2] > sprite->data[3]) { sprite->data[2] = 0; if (++sprite->data[1] > 3) sprite->data[1] = 0; index = IndexOfSpritePaletteTag(gUnknown_083D712C[sprite->data[1]][0]); if (index != 0xFF) sprite->oam.paletteNum = index; } } } // note_scatter // Used by Teeter Dance. void sub_80CECE8(struct Sprite* sprite) { int a; if (GetBattlerSide(gBattleAnimAttacker) == 1) { a = gBattleAnimArgs[1]; *(u16*)&gBattleAnimArgs[1] = -a; } sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + gBattleAnimArgs[1]; sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[2]; StartSpriteAnim(sprite, gBattleAnimArgs[0]); sprite->data[2] = 0; sprite->data[3] = 0; sprite->data[4] = sprite->x << 4; sprite->data[5] = sprite->y << 4; sprite->data[6] = (gBattleAnimArgs[1] << 4) / 5; sprite->data[7] = (gBattleAnimArgs[2] << 7) / 5; sprite->callback = sub_80CED78; } static void sub_80CED78(struct Sprite* sprite) { sprite->data[4] += sprite->data[6]; sprite->data[5] += sprite->data[7]; sprite->x = sprite->data[4] >> 4; sprite->y = sprite->data[5] >> 4; if (sprite->data[0] > 5 && sprite->data[3] == 0) { sprite->data[2] = (sprite->data[2] + 16) & 0xFF; sprite->x2 = Cos(sprite->data[2], 18); sprite->y2 = Sin(sprite->data[2], 18); if (sprite->data[2] == 0) sprite->data[3] = 1; } if (++sprite->data[0] == 0x30) DestroySpriteAndMatrix(sprite); } // drum (using hands to slap the Pokemon's belly in a rhythm.) // Used in Belly Drum. void sub_80CEDF0(struct Sprite* sprite) { s16 a; if (gBattleAnimArgs[0] == 1) { sprite->oam.matrixNum = 8; a = 16; } else { a = -16; } sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + a; sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + 8; sprite->data[0] = 8; sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData(sprite, DestroyAnimSprite); } // note_scatter_2 (slower scatter of notes.) // Used in Belly Drum. void sub_80CEE60(struct Sprite* sprite) { s16 a; u8 index; sub_8078650(sprite); sprite->y += 8; StartSpriteAnim(sprite, gBattleAnimArgs[1]); index = IndexOfSpritePaletteTag(gUnknown_083D712C[gBattleAnimArgs[2]][0]); if (index != 0xFF) sprite->oam.paletteNum = index; a = (gBattleAnimArgs[0] == 0) ? 0xFFE0 : 0x20; sprite->data[0] = 40; sprite->data[1] = sprite->x; sprite->data[2] = a + sprite->data[1]; sprite->data[3] = sprite->y; sprite->data[4] = sprite->data[3] - 40; InitAnimLinearTranslation(sprite); sprite->data[5] = gBattleAnimArgs[3]; sprite->callback = sub_80CEEE8; } static void sub_80CEEE8(struct Sprite* sprite) { if (TranslateAnimLinear(sprite) == 0) { s16 a; a = Sin(sprite->data[5], 8); if (sprite->x2 < 0) a = -a; sprite->x2 += a; sprite->y2 += Sin(sprite->data[5], 4); sprite->data[5] = (sprite->data[5] + 8) & 0xFF; } else { DestroyAnimSprite(sprite); } }