diff --git a/CMakeLists.txt b/CMakeLists.txt index 14280eff..3abfbaf7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,8 @@ set(FF7_MINI set(FF7_MAGIC src/magic/barrier.c src/magic/brizad.c + src/magic/daionpa.c + src/magic/jammer.c src/magic/lv5deth.c src/magic/mabaria.c src/magic/sennkoku.c diff --git a/config/symbols.magic-daionpa.us.txt b/config/symbols.magic-daionpa.us.txt new file mode 100644 index 00000000..d94a2852 --- /dev/null +++ b/config/symbols.magic-daionpa.us.txt @@ -0,0 +1,22 @@ +MAGIC_Daionpa = 0x801B0000; +DaionpaDoubleBufferFlip = 0x801B0020; +DaionpaWaveSpriteTick = 0x801B008C; +DaionpaImpactModelTick = 0x801B01AC; +DaionpaScreenWaveModelTick = 0x801B0324; +DaionpaRingSpriteTick = 0x801B04FC; +DaionpaMainTick = 0x801B06E4; +DaionpaStart = 0x801B0D98; +g_DaionpaSpriteDesc = 0x801D4410; +g_DaionpaSpriteAnims = 0x801D441C; +g_DaionpaModelDesc = 0x801D4434; +g_DaionpaRotation = 0x801D4444; +g_DaionpaUnk4C = 0x801D444C; +g_DaionpaScale = 0x801D4450; +g_DaionpaModelDesc2 = 0x801D4460; +g_DaionpaSpriteDesc2 = 0x801D4470; +g_DaionpaSpriteAnims2 = 0x801D447C; +g_DaionpaGeomX = 0x801D44AC; +g_DaionpaGeomY = 0x801D44B0; +g_DaionpaPrimBuffer = 0x801D44B4; +g_DaionpaBufferPtr = 0x801EC4B4; +g_DaionpaTargetMask = 0x801EC4B8; diff --git a/config/symbols.magic-jammer.us.txt b/config/symbols.magic-jammer.us.txt new file mode 100644 index 00000000..c8c67aec --- /dev/null +++ b/config/symbols.magic-jammer.us.txt @@ -0,0 +1,16 @@ +MAGIC_Jammer = 0x801B0000; +JammerDoubleBufferFlip = 0x801B0020; +JammerWaveSpriteTick = 0x801B008C; +JammerImpactModelTick = 0x801B01AC; +JammerRingSpriteTick = 0x801B0324; +JammerTargetTick = 0x801B050C; +JammerTargetSetup = 0x801B0A68; +JammerStart = 0x801B0B44; +g_JammerSpriteDesc = 0x801D126C; +g_JammerSpriteAnims = 0x801D1278; +g_JammerModelDesc = 0x801D1284; +g_JammerRotation = 0x801D1294; +g_JammerSpriteDesc2 = 0x801D129C; +g_JammerSpriteAnims2 = 0x801D12A8; +g_JammerPrimBuffer = 0x801D12D8; +g_JammerBufferPtr = 0x801E92D8; diff --git a/config/us.yaml b/config/us.yaml index 69eaa150..ff78b748 100644 --- a/config/us.yaml +++ b/config/us.yaml @@ -807,3 +807,29 @@ overlays: - [0, c, sennkoku] - [0x930, data, sennkoku_model] - [0x559C, data, sennkoku_buffers] + # DAIONPA.BIN -- effect overlay + - name: daionpa + disk_path: disks/us/MAGIC/DAIONPA.BIN + sha1: 488a65ffbefca1b7ea5acbe7749d6a9b46ca2fd0 + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-daionpa.us.txt + segments: + - [0, c, daionpa] + - [0xE98, data, daionpa_model] + - [0x24498, data, daionpa_buffers] # REVIEW (split): first aligned word after the last non-zero byte; a cut inside the zero fill is byte-neutral + # JAMMER.BIN -- effect overlay + - name: jammer + disk_path: disks/us/MAGIC/JAMMER.BIN + sha1: cc65acc7832a3d3b242def924b4544dbfc4dbdc9 + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-jammer.us.txt + segments: + - [0, c, jammer] + - [0xBB0, data, jammer_model] + - [0x212C4, data, jammer_buffers] # REVIEW (split): first aligned word after the last non-zero byte; a cut inside the zero fill is byte-neutral diff --git a/src/magic/daionpa.c b/src/magic/daionpa.c new file mode 100644 index 00000000..075caece --- /dev/null +++ b/src/magic/daionpa.c @@ -0,0 +1,304 @@ +//! PSYQ=3.3 CC1=2.6.3 + +#include "common.h" +#include "magic.h" +#include "daionpa.h" +#include "../battle/battle.h" + +// Effect shared by Big Sound (大音波) and Voice of Ages (ときのこえ). + +void DaionpaStart(s32 targetMask, s32 callbackArg); +extern u_long D_801B0E98[]; +void DaionpaRingSpriteTick(void); +void DaionpaImpactModelTick(void); +void DaionpaScreenWaveModelTick(void); +void DaionpaWaveSpriteTick(void); +void DaionpaMainTick(void); +extern s32 g_DaionpaTargetMask; +extern u8 D_800F5B70; +extern u8 D_800F5B71; +extern u8 D_800F5B72; + +// Primitive buffer pages, one 0xC000 page per double-buffered frame. +extern u8 g_DaionpaPrimBuffer[2][0xC000]; +extern void* g_DaionpaBufferPtr; + +// Only StartFrame/AnimationFrame are common to every magic overlay. +typedef struct { + /* 0x00 */ s16 StartFrame; + /* 0x02 */ s16 AnimationFrame; + /* 0x04 */ SVECTOR Pos; + /* 0x0C */ SVECTOR unkC; + /* 0x14 */ s16 unk14; + /* 0x16 */ s16 unk16; + /* 0x18 */ s16 unk18; + /* 0x1A */ char pad1A[6]; +} DaionpaData; // size:0x20 + +extern DaionpaData g_BattleEffectSlots[]; + +void MAGIC_Daionpa(s32 targetMask, s32 callbackArg) { DaionpaStart(targetMask, callbackArg); } + +// Same as BarrierDoubleBufferFlip. +void DaionpaDoubleBufferFlip(void) { + DaionpaData* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + g_DaionpaBufferPtr = g_DaionpaPrimBuffer[effect->AnimationFrame]; + effect->AnimationFrame ^= 1; + if (g_BattleEffectCount < 2) { + effect->StartFrame = -1; + } +} + +extern SpriteRenderDesc g_DaionpaSpriteDesc; +extern SpriteAnim* g_DaionpaSpriteAnims[]; + +extern ModelRenderDesc g_DaionpaModelDesc; +extern SVECTOR g_DaionpaRotation; +extern s16 g_DaionpaUnk4C; +extern VECTOR g_DaionpaScale; +extern s32 g_DaionpaGeomX; +extern s32 g_DaionpaGeomY; +extern ModelRenderDesc g_DaionpaModelDesc2; + +extern SpriteRenderDesc g_DaionpaSpriteDesc2; +extern SpriteAnim* g_DaionpaSpriteAnims2[]; + +void DaionpaWaveSpriteTick(void) { + DaionpaData* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + BattleSetBillboardMatrix(&effect->Pos, 0x1800, 0); + g_DaionpaSpriteDesc.frameIndex = effect->AnimationFrame; + g_DaionpaSpriteDesc.frames = g_DaionpaSpriteAnims[effect->unk14]; + g_DaionpaBufferPtr = func_800D4D90(&g_DaionpaSpriteDesc, g_cDb->unk70, 12, g_DaionpaBufferPtr); + if (!D_80062D98) { + effect->Pos.vx += effect->unkC.vx; + effect->Pos.vy += effect->unkC.vy; + effect->Pos.vz += effect->unkC.vz; + effect->AnimationFrame++; + if (effect->AnimationFrame == g_DaionpaSpriteAnims[effect->unk14]->frameCount) { + effect->StartFrame = -1; + } + } +} + +void DaionpaImpactModelTick(void) { + DaionpaData* effect; + MATRIX matrix; + MATRIX rotated; + s32 flag; + s16 i; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + for (i = 0; i < 3; i++) { + matrix.m[2][i] = 0; + matrix.m[1][i] = 0; + matrix.m[0][i] = 0; + } + SetRotMatrix(&g_BattleWorldView.m); + SetTransMatrix(&g_BattleWorldView.m); + RotTrans(&effect->Pos, (VECTOR*)matrix.t, &flag); + matrix.m[0][0] = matrix.m[1][1] = matrix.m[2][2] = effect->AnimationFrame * 600 + 0x800; + RotMatrixYXZ(&g_DaionpaRotation, &rotated); + MulMatrix(&matrix, &rotated); + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + SetFarColor(0, 0, 0); + g_DaionpaModelDesc.color = effect->AnimationFrame * 0x100; + g_DaionpaBufferPtr = func_800D29D4(&g_DaionpaModelDesc, g_cDb->unk70, 12, g_DaionpaBufferPtr); + if (!D_80062D98) { + effect->AnimationFrame++; + if (effect->AnimationFrame == 15) { + effect->StartFrame = -1; + } + } +} + +void DaionpaScreenWaveModelTick(void) { + DaionpaData* effect; + MATRIX matrix; + MATRIX unused; + SVECTOR rot; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + ReadGeomOffset(&g_DaionpaGeomX, &g_DaionpaGeomY); + SetGeomOffset(0xA0, 0x64); + g_DaionpaScale.vy = effect->AnimationFrame * 300 + 0x2000; + rot.vx = 0x400; + rot.vy = effect->AnimationFrame << 5; + rot.vz = 0; + RotMatrix(&rot, &matrix); + ScaleMatrix(&matrix, &g_DaionpaScale); + matrix.t[0] = 0; + matrix.t[1] = 0; + matrix.t[2] = 0x1F40; + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + SetFarColor(0, 0, 0); + g_DaionpaModelDesc2.color = 0x1000 - (g_DaionpaUnk4C * 0x100); + g_DaionpaBufferPtr = func_800D29D4(&g_DaionpaModelDesc2, g_cDb->unk70, 12, g_DaionpaBufferPtr); + SetGeomOffset(g_DaionpaGeomX, g_DaionpaGeomY); + if (!D_80062D98) { + if (effect->AnimationFrame < 8) { + g_DaionpaUnk4C++; + } + if (effect->AnimationFrame >= 0x17) { + g_DaionpaUnk4C--; + } + effect->AnimationFrame++; + if (effect->AnimationFrame == 0x1E) { + effect->StartFrame = -1; + } + } +} + +void DaionpaRingSpriteTick(void) { + DaionpaData* effect; + MATRIX matrix; + MATRIX rotated; + SVECTOR rot; + s32 flag; + s16 shade; + s16 i; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + rot.vx = rot.vy = 0; + rot.vz = effect->AnimationFrame << 8; + for (i = 0; i < 3; i++) { + matrix.m[i][0] = matrix.m[i][1] = matrix.m[i][2] = 0; + } + SetRotMatrix(&g_BattleWorldView.m); + SetTransMatrix(&g_BattleWorldView.m); + RotTrans(&effect->Pos, (VECTOR*)matrix.t, &flag); + matrix.m[0][0] = matrix.m[1][1] = matrix.m[2][2] = 0x1400; + RotMatrixYXZ(&rot, &rotated); + MulMatrix(&matrix, &rotated); + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + shade = effect->AnimationFrame < 12 ? 8 : 0x14 - effect->AnimationFrame; + shade <<= 4; + g_DaionpaSpriteDesc2.frames = g_DaionpaSpriteAnims2[effect->unk14]; + g_DaionpaSpriteDesc2.color.r = g_DaionpaSpriteDesc2.color.g = g_DaionpaSpriteDesc2.color.b = shade; + g_DaionpaBufferPtr = func_800D4D90(&g_DaionpaSpriteDesc2, g_cDb->unk70, 12, g_DaionpaBufferPtr); + if (!D_80062D98) { + effect->Pos.vx += effect->unkC.vx; + effect->Pos.vy += effect->unkC.vy; + effect->Pos.vz += effect->unkC.vz; + effect->AnimationFrame++; + if (effect->AnimationFrame == 0x14) { + effect->StartFrame = -1; + } + } +} + +void DaionpaMainTick(void) { + DaionpaData* effect; + DaionpaData* child; + SVECTOR vec; + SVECTOR rot; + MATRIX matrix; + s32 flag; + s16 ang; + s16 i; + s16 j; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + if (!D_80062D98) { + if (effect->AnimationFrame < 20) { + for (i = 0; i < 2; i++) { + child = &g_BattleEffectSlots[BattleEffectRegister(DaionpaRingSpriteTick)]; + child->Pos.vx = effect->Pos.vx; + child->Pos.vy = effect->Pos.vy; + child->Pos.vz = effect->Pos.vz; + child->unkC.vx = (effect->unkC.vx - effect->Pos.vx) / 15; + child->unkC.vy = (effect->unkC.vy - effect->Pos.vy) / 15; + child->unkC.vz = (effect->unkC.vz - effect->Pos.vz) / 15; + ang = rand() % 4096; + vec.vx = (u32)(rcos(ang) * 25) >> 10; + vec.vy = (u32)(rsin(ang) * 25) >> 10; + vec.vz = 0; + rot.vz = 0; + rot.vx = 0; + rot.vy = child->unk16 = ratan2(effect->unkC.vx - effect->Pos.vx, effect->unkC.vz - effect->Pos.vz); + RotMatrixYXZ(&rot, &matrix); + matrix.t[0] = child->unkC.vx; + matrix.t[1] = child->unkC.vy; + matrix.t[2] = child->unkC.vz; + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + RotTransSV(&vec, &child->unkC, &flag); + child->unk14 = rand() % 7; + } + } + if (effect->AnimationFrame == 30) { + BattleEffectRegister(DaionpaScreenWaveModelTick); + func_800BBA84(0xF6, -1, 0x40); + } + if (effect->AnimationFrame == 54) { + for (i = 0; i < 10; i++) { + if ((g_DaionpaTargetMask >> i) & 1) { + child = &g_BattleEffectSlots[BattleEffectRegister(DaionpaImpactModelTick)]; + BattleGetPartPosition(i, g_BattleModels[i].boneIndices[0], &child->Pos); + } + } + func_800BBA84(0x189, -1, 0x40); + } + if (effect->AnimationFrame >= 57 && effect->AnimationFrame < 64) { + for (i = 0; i < 10; i++) { + if ((g_DaionpaTargetMask >> i) & 1) { + for (j = 0; j < 2; j++) { + child = &g_BattleEffectSlots[BattleEffectRegister(DaionpaWaveSpriteTick)]; + BattleGetPartPosition(i, g_BattleModels[i].boneIndices[0], &child->Pos); + child->Pos.vx += rand() % 1200 - 600; + child->Pos.vy += rand() % 1200 - 600; + child->Pos.vz += rand() % 1200 - 600; + child->unk14 = rand() % 6; + child->unk18 = (rand() % 3 << 11) + 0x1000; + ang = rand() % 4096; + vec.vx = (u32)(rcos(ang) * 15) >> 10; + vec.vy = (u32)(rsin(ang) * 15) >> 10; + vec.vz = 0; + rot.vz = 0; + rot.vx = 0; + rot.vy = rand() % 4096; + RotMatrixYXZ(&rot, &matrix); + matrix.t[0] = matrix.t[1] = matrix.t[2] = 0; + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + RotTransSV(&vec, &child->unkC, &flag); + } + } + } + } + if (effect->AnimationFrame == 60) { + for (i = 0; i < 10; i++) { + if ((g_DaionpaTargetMask >> i) & 1) { + func_800D5774(i); + } + } + } + effect->AnimationFrame++; + if (effect->AnimationFrame == 70) { + BattleFixedPointRampUpdateInit(0, 10); + effect->StartFrame = -1; + } + } +} + +void DaionpaStart(s32 targetMask, s32 callbackArg) { + DaionpaData* effect; + + BattleEffectRegister(DaionpaDoubleBufferFlip); + g_DaionpaTargetMask = targetMask; + BattleSetLoadTimToVram(D_801B0E98, 0, 0, 0); + effect = &g_BattleEffectSlots[BattleEffectRegister(DaionpaMainTick)]; + BattleGetPartPosition(callbackArg, g_BattleModels[callbackArg].boneIndices[8], &effect->Pos); + BattleEntityGetCenter(targetMask, &effect->unkC); + func_800BBA84(0x118, callbackArg, 0); + BattleFixedPointRampUpdateInit(0xF00, 10); + D_800F5B70 = 0; + D_800F5B71 = 0; + D_800F5B72 = 0x20; +} diff --git a/src/magic/daionpa.h b/src/magic/daionpa.h new file mode 100644 index 00000000..9cb9bef3 --- /dev/null +++ b/src/magic/daionpa.h @@ -0,0 +1,6 @@ +#ifndef DAIONPA_H +#define DAIONPA_H + +#include "magic.h" + +#endif diff --git a/src/magic/jammer.c b/src/magic/jammer.c new file mode 100644 index 00000000..4512c2c7 --- /dev/null +++ b/src/magic/jammer.c @@ -0,0 +1,239 @@ +//! PSYQ=3.3 CC1=2.6.3 + +#include "common.h" +#include "magic.h" +#include "jammer.h" +#include "../battle/battle.h" + +// Magic Extinguish (魔法消滅 / Maho Shometsu). + +void JammerStart(s32 targetMask, s32 callbackArg); +void JammerTargetTick(void); +void JammerTargetSetup(s32 target, s32 callbackArg); +extern u_long D_801B0BB0[]; + +// Primitive buffer pages, one 0xC000 page per double-buffered frame. +extern u8 g_JammerPrimBuffer[2][0xC000]; +extern void* g_JammerBufferPtr; + +// Only StartFrame/AnimationFrame are common to every magic overlay. +typedef struct { + /* 0x00 */ s16 StartFrame; + /* 0x02 */ s16 AnimationFrame; + /* 0x04 */ SVECTOR Pos; + /* 0x0C */ SVECTOR unkC; + /* 0x14 */ s16 unk14; + /* 0x16 */ s16 unk16; + /* 0x18 */ s16 unk18; + /* 0x1A */ char pad1A[2]; + /* 0x1C */ s16 unk1C; + /* 0x1E */ s16 unk1E; +} JammerData; // size:0x20 + +extern JammerData g_BattleEffectSlots[]; + +void MAGIC_Jammer(s32 targetMask, s32 callbackArg) { JammerStart(targetMask, callbackArg); } + +// Same as BarrierDoubleBufferFlip. +void JammerDoubleBufferFlip(void) { + JammerData* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + g_JammerBufferPtr = g_JammerPrimBuffer[effect->AnimationFrame]; + effect->AnimationFrame ^= 1; + if (g_BattleEffectCount < 2) { + effect->StartFrame = -1; + } +} + +extern SpriteRenderDesc g_JammerSpriteDesc; +extern SpriteAnim* g_JammerSpriteAnims[]; + +extern ModelRenderDesc g_JammerModelDesc; +extern SVECTOR g_JammerRotation; + +extern SpriteRenderDesc g_JammerSpriteDesc2; +extern SpriteAnim* g_JammerSpriteAnims2[]; + +void JammerWaveSpriteTick(void) { + JammerData* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + BattleSetBillboardMatrix(&effect->Pos, 0x1800, 0); + g_JammerSpriteDesc.frameIndex = effect->AnimationFrame; + g_JammerSpriteDesc.frames = g_JammerSpriteAnims[effect->unk14]; + g_JammerBufferPtr = func_800D4D90(&g_JammerSpriteDesc, g_cDb->unk70, 12, g_JammerBufferPtr); + if (!D_80062D98) { + effect->Pos.vx += effect->unkC.vx; + effect->Pos.vy += effect->unkC.vy; + effect->Pos.vz += effect->unkC.vz; + effect->AnimationFrame++; + if (effect->AnimationFrame == g_JammerSpriteAnims[effect->unk14]->frameCount) { + effect->StartFrame = -1; + } + } +} + +void JammerImpactModelTick(void) { + JammerData* effect; + MATRIX matrix; + MATRIX rotated; + s32 flag; + s16 i; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + for (i = 0; i < 3; i++) { + matrix.m[2][i] = 0; + matrix.m[1][i] = 0; + matrix.m[0][i] = 0; + } + SetRotMatrix(&g_BattleWorldView.m); + SetTransMatrix(&g_BattleWorldView.m); + RotTrans(&effect->Pos, (VECTOR*)matrix.t, &flag); + matrix.m[0][0] = matrix.m[1][1] = matrix.m[2][2] = effect->AnimationFrame * 600 + 0x800; + RotMatrixYXZ(&g_JammerRotation, &rotated); + MulMatrix(&matrix, &rotated); + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + SetFarColor(0, 0, 0); + g_JammerModelDesc.color = effect->AnimationFrame * 0x100; + g_JammerBufferPtr = func_800D29D4(&g_JammerModelDesc, g_cDb->unk70, 12, g_JammerBufferPtr); + if (!D_80062D98) { + effect->AnimationFrame++; + if (effect->AnimationFrame == 15) { + effect->StartFrame = -1; + } + } +} + +void JammerRingSpriteTick(void) { + JammerData* effect; + MATRIX matrix; + MATRIX rotated; + SVECTOR rot; + s32 flag; + s16 shade; + s16 i; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + rot.vx = rot.vy = 0; + rot.vz = effect->AnimationFrame << 8; + for (i = 0; i < 3; i++) { + matrix.m[i][0] = matrix.m[i][1] = matrix.m[i][2] = 0; + } + SetRotMatrix(&g_BattleWorldView.m); + SetTransMatrix(&g_BattleWorldView.m); + RotTrans(&effect->Pos, (VECTOR*)matrix.t, &flag); + matrix.m[0][0] = matrix.m[1][1] = matrix.m[2][2] = 0x1400; + RotMatrixYXZ(&rot, &rotated); + MulMatrix(&matrix, &rotated); + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + shade = effect->AnimationFrame < 12 ? 8 : 0x14 - effect->AnimationFrame; + shade <<= 4; + g_JammerSpriteDesc2.frames = g_JammerSpriteAnims2[effect->unk14]; + g_JammerSpriteDesc2.color.r = g_JammerSpriteDesc2.color.g = g_JammerSpriteDesc2.color.b = shade; + g_JammerBufferPtr = func_800D4D90(&g_JammerSpriteDesc2, g_cDb->unk70, 12, g_JammerBufferPtr); + if (!D_80062D98) { + effect->Pos.vx += effect->unkC.vx; + effect->Pos.vy += effect->unkC.vy; + effect->Pos.vz += effect->unkC.vz; + effect->AnimationFrame++; + if (effect->AnimationFrame == 0x14) { + effect->StartFrame = -1; + } + } +} + +void JammerTargetTick(void) { + JammerData* effect; + JammerData* child; + SVECTOR vec; + SVECTOR rot; + MATRIX matrix; + s32 flag; + s16 ang; + s16 j; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + if (!D_80062D98) { + if (effect->AnimationFrame < 20) { + child = &g_BattleEffectSlots[BattleEffectRegister(JammerRingSpriteTick)]; + child->Pos.vx = effect->Pos.vx; + child->Pos.vy = effect->Pos.vy; + child->Pos.vz = effect->Pos.vz; + child->unkC.vx = (effect->unkC.vx - effect->Pos.vx) / 15; + child->unkC.vy = (effect->unkC.vy - effect->Pos.vy) / 15; + child->unkC.vz = (effect->unkC.vz - effect->Pos.vz) / 15; + ang = rand() % 4096; + vec.vx = (u32)(rcos(ang) * 15) >> 10; + vec.vy = (u32)(rsin(ang) * 15) >> 10; + vec.vz = 0; + rot.vz = 0; + rot.vx = 0; + rot.vy = child->unk16 = ratan2(effect->unkC.vx - effect->Pos.vx, effect->unkC.vz - effect->Pos.vz); + RotMatrixYXZ(&rot, &matrix); + matrix.t[0] = child->unkC.vx; + matrix.t[1] = child->unkC.vy; + matrix.t[2] = child->unkC.vz; + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + RotTransSV(&vec, &child->unkC, &flag); + child->unk14 = rand() % 7; + } + if (effect->AnimationFrame == 24) { + child = &g_BattleEffectSlots[BattleEffectRegister(JammerImpactModelTick)]; + child->Pos.vx = effect->unkC.vx; + child->Pos.vy = effect->unkC.vy; + child->Pos.vz = effect->unkC.vz; + func_800BBA84(0x189, effect->unk1C, 0); + } + if (effect->AnimationFrame >= 25 && effect->AnimationFrame < 36) { + for (j = 0; j < 2; j++) { + child = &g_BattleEffectSlots[BattleEffectRegister(JammerWaveSpriteTick)]; + BattleGetPartPosition(effect->unk1C, g_BattleModels[effect->unk1C].boneIndices[0], &child->Pos); + child->Pos.vx += rand() % 1200 - 600; + child->Pos.vy += rand() % 1200 - 600; + child->Pos.vz += rand() % 1200 - 600; + child->unk14 = rand() % 3; + child->unk18 = (rand() % 3 << 11) + 0x1000; + ang = rand() % 4096; + vec.vx = (u32)(rcos(ang) * 15) >> 10; + vec.vy = (u32)(rsin(ang) * 15) >> 10; + vec.vz = 0; + rot.vz = 0; + rot.vx = 0; + rot.vy = rand() % 4096; + RotMatrixYXZ(&rot, &matrix); + matrix.t[0] = matrix.t[1] = matrix.t[2] = 0; + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + RotTransSV(&vec, &child->unkC, &flag); + } + } + if (effect->AnimationFrame == 30) { + func_800D5774(effect->unk1C); + } + effect->AnimationFrame++; + if (effect->AnimationFrame == 50) { + effect->StartFrame = -1; + } + } +} + +void JammerTargetSetup(s32 target, s32 callbackArg) { + JammerData* effect; + + effect = &g_BattleEffectSlots[BattleEffectRegister(JammerTargetTick)]; + BattleGetPartPosition(callbackArg, g_BattleModels[callbackArg].boneIndices[9], &effect->Pos); + BattleGetPartPosition(target, g_BattleModels[target].boneIndices[0], &effect->unkC); + effect->unk1C = target; + effect->unk1E = callbackArg; + func_800BBA84(0x11E, callbackArg, 0); +} + +void JammerStart(s32 targetMask, s32 callbackArg) { + BattleEffectRegister(JammerDoubleBufferFlip); + BattleSetLoadTimToVram(D_801B0BB0, 0, 0, 0); + MagicAnimationRegister(targetMask, callbackArg, 4, JammerTargetSetup); +} diff --git a/src/magic/jammer.h b/src/magic/jammer.h new file mode 100644 index 00000000..01c818a2 --- /dev/null +++ b/src/magic/jammer.h @@ -0,0 +1,6 @@ +#ifndef JAMMER_H +#define JAMMER_H + +#include "magic.h" + +#endif diff --git a/tools/builder/builder/objdiff.go b/tools/builder/builder/objdiff.go index 23967455..7281e732 100644 --- a/tools/builder/builder/objdiff.go +++ b/tools/builder/builder/objdiff.go @@ -113,6 +113,8 @@ var metaOverlays = map[string]metaOverlay{ "lv5deth": {"lv5deth", "magic", "LV.5 Death"}, "choco0": {"choco0", "magic", "choco0"}, "sennkoku": {"sennkoku", "magic", "Death Sentence / Roulette"}, + "daionpa": {"daionpa", "magic", "DAIONPA"}, + "jammer": {"jammer", "magic", "JAMMER"}, } func makeObjdiffConfig(b BuildConfig) objdiffConfig {