diff --git a/config/symbols.magic-boost.us.txt b/config/symbols.magic-boost.us.txt new file mode 100644 index 00000000..08f594ce --- /dev/null +++ b/config/symbols.magic-boost.us.txt @@ -0,0 +1,7 @@ +MAGIC_Boost = 0x801B0000; // type:func +func_boost_801B0028 = 0x801B0028; // type:func +func_boost_801B00E0 = 0x801B00E0; // type:func +func_boost_801B01C8 = 0x801B01C8; // type:func +func_boost_801B03D8 = 0x801B03D8; // type:func +func_boost_801B046C = 0x801B046C; // type:func +D_801B868C = 0x801B868C; diff --git a/config/symbols.magic-echoes.us.txt b/config/symbols.magic-echoes.us.txt new file mode 100644 index 00000000..da65a8be --- /dev/null +++ b/config/symbols.magic-echoes.us.txt @@ -0,0 +1,6 @@ +MAGIC_Echoes = 0x801B0000; // type:func +func_echoes_801B0020 = 0x801B0020; // type:func +func_echoes_801B0108 = 0x801B0108; // type:func +func_echoes_801B02BC = 0x801B02BC; // type:func +func_echoes_801B03A4 = 0x801B03A4; // type:func +func_echoes_801B0404 = 0x801B0404; // type:func diff --git a/config/symbols.magic-gattai.us.txt b/config/symbols.magic-gattai.us.txt new file mode 100644 index 00000000..7d07d3ae --- /dev/null +++ b/config/symbols.magic-gattai.us.txt @@ -0,0 +1,2 @@ +func_gattai_801B0000 = 0x801B0000; // type:func +MAGIC_Gattai = 0x801B007C; // type:func diff --git a/config/symbols.magic-hakai.us.txt b/config/symbols.magic-hakai.us.txt new file mode 100644 index 00000000..bc8fd4c2 --- /dev/null +++ b/config/symbols.magic-hakai.us.txt @@ -0,0 +1,6 @@ +MAGIC_Hakai = 0x801B0000; // type:func +func_hakai_801B0020 = 0x801B0020; // type:func +func_hakai_801B008C = 0x801B008C; // type:func +func_hakai_801B0180 = 0x801B0180; // type:func +func_hakai_801B03F4 = 0x801B03F4; // type:func +func_hakai_801B0448 = 0x801B0448; // type:func diff --git a/config/symbols.magic-jinrai.us.txt b/config/symbols.magic-jinrai.us.txt new file mode 100644 index 00000000..6d6f0452 --- /dev/null +++ b/config/symbols.magic-jinrai.us.txt @@ -0,0 +1,7 @@ +MAGIC_Jinrai = 0x801B0000; // type:func +func_jinrai_801B0028 = 0x801B0028; // type:func +func_jinrai_801B00E0 = 0x801B00E0; // type:func +func_jinrai_801B01E4 = 0x801B01E4; // type:func +func_jinrai_801B02B0 = 0x801B02B0; // type:func +D_801B3470 = 0x801B3470; +D_801B5220 = 0x801B5220; // size:0xC diff --git a/config/symbols.magic-magend.us.txt b/config/symbols.magic-magend.us.txt new file mode 100644 index 00000000..8ae09cc6 --- /dev/null +++ b/config/symbols.magic-magend.us.txt @@ -0,0 +1,6 @@ +MAGIC_Magend = 0x801B0000; // type:func +func_magend_801B0020 = 0x801B0020; // type:func +func_magend_801B0080 = 0x801B0080; // type:func +func_magend_801B0174 = 0x801B0174; // type:func +func_magend_801B03F4 = 0x801B03F4; // type:func +func_magend_801B0448 = 0x801B0448; // type:func diff --git a/config/symbols.magic-minimam.us.txt b/config/symbols.magic-minimam.us.txt new file mode 100644 index 00000000..635c6d93 --- /dev/null +++ b/config/symbols.magic-minimam.us.txt @@ -0,0 +1,6 @@ +func_minimam_801B0000 = 0x801B0000; // type:func +MAGIC_Minimam = 0x801B0054; // type:func +func_minimam_801B0074 = 0x801B0074; // type:func +func_minimam_801B0190 = 0x801B0190; // type:func +func_minimam_801B0414 = 0x801B0414; // type:func +func_minimam_801B0514 = 0x801B0514; // type:func diff --git a/config/symbols.magic-smkball.us.txt b/config/symbols.magic-smkball.us.txt new file mode 100644 index 00000000..77e3673a --- /dev/null +++ b/config/symbols.magic-smkball.us.txt @@ -0,0 +1,5 @@ +MAGIC_Smkball = 0x801B0000; // type:func +func_smkball_801B0020 = 0x801B0020; // type:func +func_smkball_801B0124 = 0x801B0124; // type:func +func_smkball_801B0250 = 0x801B0250; // type:func +func_smkball_801B02B0 = 0x801B02B0; // type:func diff --git a/config/symbols.magic-tears.us.txt b/config/symbols.magic-tears.us.txt new file mode 100644 index 00000000..e8fd4ac6 --- /dev/null +++ b/config/symbols.magic-tears.us.txt @@ -0,0 +1,6 @@ +MAGIC_Tears = 0x801B0000; // type:func +func_tears_801B0020 = 0x801B0020; // type:func +func_tears_801B0158 = 0x801B0158; // type:func +func_tears_801B0304 = 0x801B0304; // type:func +func_tears_801B0384 = 0x801B0384; // type:func +func_tears_801B03E4 = 0x801B03E4; // type:func diff --git a/config/symbols.magic-threat.us.txt b/config/symbols.magic-threat.us.txt new file mode 100644 index 00000000..3153be4a --- /dev/null +++ b/config/symbols.magic-threat.us.txt @@ -0,0 +1,6 @@ +MAGIC_Threat = 0x801B0000; // type:func +func_threat_801B0020 = 0x801B0020; // type:func +func_threat_801B00DC = 0x801B00DC; // type:func +func_threat_801B01D8 = 0x801B01D8; // type:func +func_threat_801B0304 = 0x801B0304; // type:func +MAGIC_ThreatSetup = 0x801B0364; // type:func diff --git a/config/us.yaml b/config/us.yaml index 50e1cd55..658e1d53 100644 --- a/config/us.yaml +++ b/config/us.yaml @@ -365,7 +365,8 @@ overlays: base_path: battle imports: [ main, batini, batres, - barrier, brizad, lv5deth, thunder, mabaria, refrec, fire, faira, brizara, thundera, choco0 + barrier, brizad, lv5deth, thunder, mabaria, refrec, fire, faira, brizara, thundera, choco0, + gattai, jinrai, smkball, threat, tears, echoes, magend, hakai, boost, minimam ] symbol_addrs_path: - config/symbols.battle.txt @@ -808,3 +809,134 @@ overlays: - [0, c, sennkoku] - [0x930, data, sennkoku_model] - [0x559C, data, sennkoku_buffers] + + - name: gattai + disk_path: disks/us/MAGIC/GATTAI.BIN + sha1: 1e3c0b5dd198f0a2c8d93bc575adeaed66a3d057 + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-gattai.us.txt + segments: + - [0, c, gattai] + + - name: jinrai + disk_path: disks/us/MAGIC/JINRAI.BIN + sha1: d28d5e991126ca8500f410377a2ef73d93324f67 + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-jinrai.us.txt + segments: + - [0, c, jinrai] + - [0x310, tim, jinrai_texture] + - [0x3350, .data, jinrai_data] + - [0x3470, databin, jinrai_model] + - [0x5220, .data, jinrai_render] + + - name: smkball + disk_path: disks/us/MAGIC/SMKBALL.BIN + sha1: 1888a8fe8e808e76598bdd396a38d3c264238873 + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-smkball.us.txt + segments: + - [0, c, smkball] + - [0x310, tim, smkball_texture] + - [0x6350, .data, smkball_data] + + - name: threat + disk_path: disks/us/MAGIC/THREAT.BIN + sha1: 1ceaba779b289a572ad08fe67d36ba90996f1566 + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-threat.us.txt + segments: + - [0, c, threat] + - [0x410, tim, threat_texture] + - [0x8450, .data, threat_data] + + - name: tears + disk_path: disks/us/MAGIC/TEARS.BIN + sha1: decdeb398bcfb4e8c09d0600bfba9edb4766fe4b + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-tears.us.txt + segments: + - [0, c, tears] + - [0x450, .data, tears_data] + + - name: echoes + disk_path: disks/us/MAGIC/ECHOES.BIN + sha1: cf7b802d0a7807fb8cc32bba1e51fb5c994b064c + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-echoes.us.txt + segments: + - [0, c, echoes] + - [0x474, tim, echoes_texture] + - [0x64B4, .data, echoes_data] + + - name: magend + disk_path: disks/us/MAGIC/MAGEND.BIN + sha1: 2af3b214c94b309918fb2a8664f7512a9c60d5ca + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-magend.us.txt + segments: + - [0, c, magend] + - [0x4B4, tim, magend_texture] + - [0x16D4, .data, magend_data] + + - name: hakai + disk_path: disks/us/MAGIC/HAKAI.BIN + sha1: 90098828bf03bd13ae535a566c10ff522158963b + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-hakai.us.txt + segments: + - [0, c, hakai] + - [0x4C4, tim, hakai_texture] + - [0x6504, .data, hakai_data] + + - name: boost + disk_path: disks/us/MAGIC/BOOST.BIN + sha1: 119e4dccbf935a2636540d309e6592f3f73dc596 + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-boost.us.txt + segments: + - [0, c, boost] + - [0x4CC, tim, boost_texture] + - [0x852C, .data, boost_data] + - [0x868C, databin, boost_model] + - [0xA264, .data, boost_render] + + - name: minimam + disk_path: disks/us/MAGIC/MINIMAM.BIN + sha1: f2ec8681e080b3f24c48b34e5f92c37b2c8c1aa9 + base_path: magic + imports: [main, battle] + vram_start: 0x801B0000 + symbol_addrs_path: + - config/symbols.magic-minimam.us.txt + segments: + - [0, c, minimam] + - [0x5B8, tim, minimam_texture] + - [0x45F8, .data, minimam_data] diff --git a/src/battle/battle.h b/src/battle/battle.h index 098a6157..d0ae3f1a 100644 --- a/src/battle/battle.h +++ b/src/battle/battle.h @@ -765,6 +765,8 @@ extern Unk80166F78 D_80166F78[NUM_ENEMY][16]; extern SavePartyMember D_80167938; s32 BattleEffectRegister(void (*callback)(void)); +void BattleSpawnFloatingIcon(s32 actor, s32 arg1); +void BattleSpawnFloatingIconAtPart(s32 actor, s32 arg1, s32 arg2); void BattleSetLoadTimToVram(u_long* addr, s16 imgXY, s16 clutX, s16 clutY); void BattleEnqueueClearImage(RECT* rect, s32 arg1, s32 arg2, s32 arg3); void* func_800D29D4(ModelRenderDesc*, u_long**, int, void*); diff --git a/src/battle/battle2.c b/src/battle/battle2.c index aa3385bd..eb08b001 100644 --- a/src/battle/battle2.c +++ b/src/battle/battle2.c @@ -39,7 +39,7 @@ s32 BattleModelReadAnimStream(BattleModelSub* arg0, s32 arg1, s16 nItems, u8* ar void func_800D3AF0(); void func_800D4710(); MATRIX* BattleSetMatrixPosition(SVECTOR* pos, s32 depthBias, MATRIX* m); -static void BattleSpawnFloatingIcon(s32 actor, s32 arg1); +void BattleSpawnFloatingIcon(s32 actor, s32 arg1); void BattleQueueImpactEffect(s32 arg0, s16 arg1); void BattleInitMagicCastEffect(void); void BattleStartEffectWithModel(s32 targetMask, s32 callbackArg); @@ -627,14 +627,14 @@ MagicEntry D_800EF9D8[] = { (MagicEntry)0x801B0A8C, // 6 CAREL.BIN (MagicEntry)0x801B0EEC, // 7 CAREL.BIN (MagicEntry)0x801B0B60, // 8 CAREL.BIN - (MagicEntry)0x801B0364, // 9 THREAT.BIN + (MagicEntry)MAGIC_ThreatSetup, // 9 THREAT.BIN (MagicEntry)0x801B0054, // 10 TODO.BIN - (MagicEntry)0x801B0054, // 11 MINIMAM.BIN - (MagicEntry)0x801B0000, // 12 ECHOES.BIN - (MagicEntry)0x801B0000, // 13 HAKAI.BIN - (MagicEntry)0x801B0000, // 14 TEARS.BIN + (MagicEntry)MAGIC_Minimam, // 11 MINIMAM.BIN + (MagicEntry)MAGIC_Echoes, // 12 ECHOES.BIN + (MagicEntry)MAGIC_Hakai, // 13 HAKAI.BIN + (MagicEntry)MAGIC_Tears, // 14 TEARS.BIN (MagicEntry)0x801B0000, // 15 ALMIGHTY.BIN - (MagicEntry)0x801B0000, // 16 SMKBALL.BIN + (MagicEntry)MAGIC_Smkball, // 16 SMKBALL.BIN (MagicEntry)0x801B0054, // 17 HEIST.BIN (MagicEntry)0x801B0054, // 18 MYTYG.BIN (MagicEntry)0x801B0564, // 19 RESIST.BIN @@ -652,7 +652,7 @@ MagicEntry D_800EF9D8[] = { (MagicEntry)0x801B0084, // 31 FAIGA2.BIN MAGIC_Brizara, // 32 BRIZARA.BIN (MagicEntry)0x801B0054, // 33 BRIZAG2.BIN - MAGIC_Thundera, // 34 THUNDERA.BIN + MAGIC_Thundera, // 34 THUNDERA.BIN (MagicEntry)0x801B000C, // 35 THUNDG2.BIN (MagicEntry)0x801B0074, // 36 QUEIR.BIN (MagicEntry)0x801B0054, // 37 QUEIG.BIN @@ -669,7 +669,7 @@ MagicEntry D_800EF9D8[] = { (MagicEntry)0x801B0054, // 48 DAISENP.BIN (MagicEntry)0x801B0054, // 49 AQUA.BIN (MagicEntry)0x801B0054, // 50 TODO.BIN - (MagicEntry)0x801B0054, // 51 MINIMAM.BIN + (MagicEntry)MAGIC_Minimam, // 51 MINIMAM.BIN (MagicEntry)0x801B0000, // 52 ESNA.BIN MAGIC_Fire, // 53 FIRE.BIN (MagicEntry)0x801B0000, // 54 HAKUGEK2.BIN @@ -701,7 +701,7 @@ MagicEntry D_800EFAF0[] = { (MagicEntry)0x801B0564, // 6 RESIST.BIN BattleStartEffectWithModel, // 7 RAISE.BIN BattleStartEffectWithModel, // 8 RAISE.BIN - (MagicEntry)0x801B0054, // 9 MINIMAM.BIN + (MagicEntry)MAGIC_Minimam, // 9 MINIMAM.BIN (MagicEntry)0x801B0054, // 10 TODO.BIN (MagicEntry)0x801B0054, // 11 SLIPL.BIN BattleStartEffectWithModel, // 12 CONF.BIN @@ -842,7 +842,7 @@ MagicEntry D_800EFC28[] = { (MagicEntry)0x801B0000, // 61 TOBOE.BIN (MagicEntry)0x801B0F18, // 62 KAFUN.BIN (MagicEntry)0x801B0000, // 63 ROCKET.BIN - (MagicEntry)0x801B0364, // 64 THREAT.BIN + (MagicEntry)MAGIC_ThreatSetup, // 64 THREAT.BIN (MagicEntry)0x801B1028, // 65 Q_SHU.BIN (MagicEntry)0x801B0000, // 66 JIBASIRI.BIN (MagicEntry)0x801B0000, // 67 JIBAKU2.BIN @@ -868,7 +868,7 @@ MagicEntry D_800EFC28[] = { (MagicEntry)0x801B0008, // 87 SEKIKA.BIN (MagicEntry)0x801B0000, // 88 HAKUGEK1.BIN (MagicEntry)0x801B0000, // 89 HAKUGEK2.BIN - (MagicEntry)0x801B0000, // 90 HAKAI.BIN + (MagicEntry)MAGIC_Hakai, // 90 HAKAI.BIN (MagicEntry)0x801B0000, // 91 WLASER.BIN (MagicEntry)0x801B0000, // 92 AEROGA.BIN (MagicEntry)0x801B0054, // 93 ZENBAKU.BIN @@ -892,7 +892,7 @@ MagicEntry D_800EFC28[] = { (MagicEntry)0x801B0000, // 111 KONA.BIN (MagicEntry)0x801B0000, // 112 PINK.BIN (MagicEntry)0x801B0000, // 113 JAMMER.BIN - (MagicEntry)0x801B0000, // 114 TEARS.BIN + (MagicEntry)MAGIC_Tears, // 114 TEARS.BIN (MagicEntry)0x801B0E98, // 115 ELECBALL.BIN (MagicEntry)0x801B0054, // 116 UTAGOE.BIN (MagicEntry)0x801B0000, // 117 SAIKYO.BIN @@ -923,7 +923,7 @@ MagicEntry D_800EFC28[] = { (MagicEntry)0x801B0040, // 142 LASBOSS.BIN (MagicEntry)0x801B0040, // 143 file id 318 BattleStartEffectWithModel, // 144 RAISE.BIN - (MagicEntry)0x801B0000, // 145 MAGEND.BIN + (MagicEntry)MAGIC_Magend, // 145 MAGEND.BIN (MagicEntry)0x801B0000, // 146 TO_SEKI.BIN (MagicEntry)BattleInitMagicCastEffect, // 147 DEADSEF.BIN (MagicEntry)0x801B0A8C, // 148 CAREL.BIN @@ -968,7 +968,7 @@ MagicEntryResult D_800EFEA0[] = { (MagicEntryResult)0x801B0000, // 25 TIFA.BIN (MagicEntryResult)0x801B0000, // 26 TIFA.BIN (MagicEntryResult)0x801B0000, // 27 TIFA.BIN - (MagicEntryResult)0x801B0000, // 28 BOOST.BIN + (MagicEntryResult)MAGIC_Boost, // 28 BOOST.BIN (MagicEntryResult)0x801B0000, // 29 MOD.BIN (MagicEntryResult)0x801B0000, // 30 HYPER.BIN (MagicEntryResult)0x801B0000, // 31 DYNAMITE.BIN @@ -989,18 +989,18 @@ MagicEntryResult D_800EFEA0[] = { (MagicEntryResult)0x801B0000, // 46 FIRE.BIN (MagicEntryResult)0x801B0000, // 47 FIRE.BIN (MagicEntryResult)0x801B0000, // 48 FIRE.BIN - (MagicEntryResult)0x801B0000, // 49 JINRAI.BIN + (MagicEntryResult)MAGIC_Jinrai, // 49 JINRAI.BIN (MagicEntryResult)0x801B0000, // 50 MEIKYO.BIN (MagicEntryResult)0x801B0000, // 51 GAISEI.BIN (MagicEntryResult)0x801B0000, // 52 CHI.BIN (MagicEntryResult)0x801B0000, // 53 GAISHU.BIN (MagicEntryResult)0x801B0000, // 54 SEIJA.BIN (MagicEntryResult)0x801B0000, // 55 SHINRA.BIN - (MagicEntryResult)0x801B007C, // 56 GATTAI.BIN + (MagicEntryResult)MAGIC_Gattai, // 56 GATTAI.BIN (MagicEntryResult)BattleStartEffectWithModel, // 57 MDANCE.BIN (MagicEntryResult)BattleStartEffectWithModel, // 58 TSOL.BIN (MagicEntryResult)0x801B0054, // 59 LGIRL.BIN - (MagicEntryResult)MAGIC_Lv5Death,// 60 LV5DETH.BIN + (MagicEntryResult)MAGIC_Lv5Death, // 60 LV5DETH.BIN (MagicEntryResult)BattleStartEffectWithModel, // 61 DEATH.BIN (MagicEntryResult)0x801B0054, // 62 BEAST.BIN (MagicEntryResult)0x801B0054, // 63 BEAST.BIN @@ -2448,14 +2448,14 @@ void func_800D4C08(SVECTOR* pos, s32 scriptAndFlags, s32 scale, s32 depthBias) { slot->depthBias = depthBias; } -static void BattleSpawnFloatingIconAtPart(s32 actor, s32 arg1, s32 arg2) { +void BattleSpawnFloatingIconAtPart(s32 actor, s32 arg1, s32 arg2) { SVECTOR pos; BattleGetPartPosition(actor, g_BattleModels[actor].boneIndices[0], &pos); func_800D4C08(&pos, arg1, arg2, -g_BattleModels[actor].collisionRadius); } -static void BattleSpawnFloatingIcon(s32 actor, s32 arg1) { BattleSpawnFloatingIconAtPart(actor, arg1, 0x1000); } +void BattleSpawnFloatingIcon(s32 actor, s32 arg1) { BattleSpawnFloatingIconAtPart(actor, arg1, 0x1000); } static void BattleSpawnFloatingIconAt(void* arg0, s32 arg1, s32 arg2) { func_800D4C08(arg0, arg1, 0x1000, arg2); } diff --git a/src/magic/barrier.c b/src/magic/barrier.c index 6c5792b9..3eacb389 100644 --- a/src/magic/barrier.c +++ b/src/magic/barrier.c @@ -25,8 +25,9 @@ typedef struct { // Battle effect instances. extern BarrierData g_BattleEffectSlots[]; -static s32 bari_a1[] = { // Embedded Model - // 6 verts, 12 polys,1 group +static s32 bari_a1[] = { + // Embedded Model + // 6 verts, 12 polys,1 group 0x00000030, // Vertex data size: 6 verts × 8 bytes 0xFE0C0000, 0x000001CA, // (-500, 0, 458, 0) 0x00000000, 0x0000FFD7, // (0, 0, -41, 0) @@ -51,8 +52,9 @@ static s32 bari_a1[] = { // Embedded Model 0x00080000, 0x00280020, 0x38C0C0C0, 0x00FFFFFF, 0x006A6A6A, 0x006A6A6A, 0x00000010, 0x00200018, 0x38C0C0C0, 0x00C0C0C0, 0x006A6A6A, 0x006A6A6A}; -static s32 bari_a2[] = { // Embedded Model - // 3 verts 2 ploys 1 group +static s32 bari_a2[] = { + // Embedded Model + // 3 verts 2 ploys 1 group 0x00000018, // Vertex data size: 3 × 8 bytes 0xFFEDFE2F, 0x000002C2, // vertex 0 (-19, -465, 706) 0xFE2AFFF2, 0x000001C2, // vertex 1 (-470, -14, 450) diff --git a/src/magic/boost.c b/src/magic/boost.c new file mode 100644 index 00000000..e805664c --- /dev/null +++ b/src/magic/boost.c @@ -0,0 +1,126 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "boost_assets.h" +// BOOST.BIN: A timed sequence of radial sprites followed by a target-position burst. + +extern s32 rand(void); + +typedef struct { + s16 StartFrame, AnimationFrame; + SVECTOR Pos, Velocity; + s16 unk14, unk16, unk18, unk1A, TargetIndex, SourceIndex; +} BoostEffect; +extern BoostEffect g_BattleEffectSlots[]; +extern s32 D_801B85F8; +extern s32 D_801B8530; +extern EffectModel D_801B868C; +extern void* D_80163C74; +void func_800BBA84(s32, s32, s32); +static void func_boost_801B046C(s32 arg0, s32 arg1); + +EffectModel* MAGIC_Boost(s32 targetMask, s32 callbackArg) { + func_boost_801B046C(targetMask, callbackArg); + return &D_801B868C; +} + +static void func_boost_801B0028(void) { + BoostEffect* effect; + s16 nextFrame; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + BattleSetBillboardMatrix(&effect->Pos, 0x2000, 0); + D_801BA264.frameIndex = (u16)effect->AnimationFrame; + D_80163C74 = func_800D4D90(&D_801BA264, g_cDb->unk70, 0xC, D_80163C74); + if (D_80062D98 != 0) { + return; + } + nextFrame = (u16)effect->AnimationFrame + 1; + effect->AnimationFrame = nextFrame; + if (nextFrame == D_801B85F8) { + effect->StartFrame = -1; + } +} + +static void func_boost_801B00E0(void) { + BoostEffect* effect; + s16 nextFrame; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + BattleSetBillboardMatrix(&effect->Pos, 0x2000, 0); + D_801BA270.frameIndex = (u16)effect->AnimationFrame; + D_80163C74 = func_800D4D90(&D_801BA270, g_cDb->unk70, 0xC, D_80163C74); + if (D_80062D98 != 0) { + return; + } + effect->Pos.vx += effect->Velocity.vx; + effect->Pos.vy += effect->Velocity.vy; + effect->Pos.vz += effect->Velocity.vz; + nextFrame = ++effect->AnimationFrame; + if (nextFrame == D_801B8530) { + effect->StartFrame = -1; + } +} + +static void func_boost_801B01C8(void) { + BoostEffect* particle; + BoostEffect* effect; + s16 nextIndex; + u16 nextX; + s16 nextFrame; + s16 i; + s32 modelOffset; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + if (D_80062D98 != 0) { + return; + } + if (effect->AnimationFrame == 0x20) { + func_800BBA84(0x30, (s32)effect->SourceIndex, 0); + } + if (effect->AnimationFrame == 0x3A) { + i = 0; + do { + particle = &g_BattleEffectSlots[BattleEffectRegister(func_boost_801B00E0)]; + modelOffset = (s32)(i << 0x10) >> 8; + nextX = effect->Velocity.vx; + particle->Pos.vy = 0; + particle->Pos.vx = nextX; + particle->Pos.vz = (s16)(u16)effect->Velocity.vz; + particle->Velocity.vx = (s16)((u32)(rsin(modelOffset) * 0x19) >> 9); + particle->Velocity.vz = (s16)((u32)(rcos(modelOffset) * 0x19) >> 9); + nextIndex = i + 1; + i = nextIndex; + particle->Velocity.vy = -rand() % 200; + } while (nextIndex < 0x10); + BattleSpawnFloatingIconAtPart((s32)effect->TargetIndex, 0x21, 0x1000); + func_800BBA84(0x15A, (s32)effect->SourceIndex, 0); + } + if (effect->AnimationFrame == 0x44) { + particle = &g_BattleEffectSlots[BattleEffectRegister(func_boost_801B0028)]; + particle->Pos.vx = (s16)(u16)effect->Velocity.vx; + particle->Pos.vy = (s16)(u16)effect->Velocity.vy; + particle->Pos.vz = (s16)(u16)effect->Velocity.vz; + func_800D5774((u32)effect->TargetIndex); + func_800BBA84(0x141, (s32)effect->SourceIndex, 0); + } + nextFrame = (u16)effect->AnimationFrame + 1; + effect->AnimationFrame = nextFrame; + if (nextFrame == 0x64) { + effect->StartFrame = -1; + } +} + +static void func_boost_801B03D8(s32 arg0, s32 arg1) { + BoostEffect* effect; + + effect = &g_BattleEffectSlots[BattleEffectRegister(func_boost_801B01C8)]; + BattleGetPartPosition(arg0, g_BattleModels[arg0].boneIndices[0], &effect->Velocity); + effect->TargetIndex = (s16)arg0; + effect->SourceIndex = arg1; +} + +static void func_boost_801B046C(s32 arg0, s32 arg1) { + BattleSetLoadTimToVram(boost_texture_tim, 0, 0, 0); + MagicAnimationRegister(arg0, arg1, 4, func_boost_801B03D8); +} diff --git a/src/magic/boost_assets.h b/src/magic/boost_assets.h new file mode 100644 index 00000000..4c64badf --- /dev/null +++ b/src/magic/boost_assets.h @@ -0,0 +1,30 @@ +#ifndef BOOST_ASSETS_H +#define BOOST_ASSETS_H +#include "magic_assets.h" + +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame1 frame0; + MagicSpriteFrame1 frame1; + MagicSpriteFrame1 frame2; + MagicSpriteFrame1 frame3; + MagicSpriteFrame1 frame4; + MagicSpriteFrame1 frame5; + MagicSpriteFrame1 frame6; + MagicSpriteFrame1 frame7; +} BoostAnimation0; +extern BoostAnimation0 g_BoostAnimation0; +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame1 frame0; + MagicSpriteFrame1 frame1; + MagicSpriteFrame1 frame2; + MagicSpriteFrame1 frame3; + MagicSpriteFrame1 frame4; + MagicSpriteFrame1 frame5; +} BoostAnimation1; +extern BoostAnimation1 g_BoostAnimation1; +extern SpriteRenderDesc D_801BA264; +extern SpriteRenderDesc D_801BA270; +extern u_long boost_texture_tim[]; +#endif diff --git a/src/magic/boost_data.c b/src/magic/boost_data.c new file mode 100644 index 00000000..50378ce3 --- /dev/null +++ b/src/magic/boost_data.c @@ -0,0 +1,22 @@ +#include "boost_assets.h" + +BoostAnimation0 g_BoostAnimation0 = { + 0x2023, + 8, + {0, 1, {{0x100, -32, -32, 0x0, 0x0, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x100, -32, -32, 0x40, 0x0, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x100, -32, -32, 0x80, 0x0, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x300, -32, -32, 0xC0, 0x0, 0x2C, 0x7808, 0x40, 0x3F, 0x40, 0x40}}}, + {0, 1, {{0x100, -32, -32, 0x0, 0x40, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x100, -32, -32, 0x40, 0x40, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x100, -32, -32, 0x80, 0x40, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x300, -32, -32, 0xC0, 0x40, 0x2C, 0x7808, 0x40, 0x3F, 0x40, 0x40}}}}; +BoostAnimation1 g_BoostAnimation1 = { + 0x2023, + 6, + {0, 1, {{0x100, -32, -32, 0x0, 0x0, 0x2D, 0x7848, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x100, -32, -32, 0x40, 0x0, 0x2D, 0x7848, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x100, -32, -32, 0x0, 0x40, 0x2D, 0x7848, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x100, -32, -32, 0x40, 0x40, 0x2D, 0x7848, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x100, -32, -32, 0x80, 0x0, 0x2D, 0x7848, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x300, -32, -32, 0xC0, 0x0, 0x2D, 0x7848, 0x40, 0x3F, 0x40, 0x40}}}}; diff --git a/src/magic/boost_render.c b/src/magic/boost_render.c new file mode 100644 index 00000000..07b90caf --- /dev/null +++ b/src/magic/boost_render.c @@ -0,0 +1,4 @@ +#include "boost_assets.h" + +SpriteRenderDesc D_801BA264 = {(SpriteAnim*)&g_BoostAnimation1, {0x80, 0x80, 0x80, 0x2E}, 0, 0}; +SpriteRenderDesc D_801BA270 = {(SpriteAnim*)&g_BoostAnimation0, {0x80, 0x80, 0x80, 0x2E}, 0, 0}; diff --git a/src/magic/echoes.c b/src/magic/echoes.c new file mode 100644 index 00000000..a098fd6a --- /dev/null +++ b/src/magic/echoes.c @@ -0,0 +1,125 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "echoes_assets.h" +// ECHOES.BIN: Seven billboard sprites per update, with random offsets bounded by the target radius. + +extern s32 rand(void); + +typedef struct { + s16 StartFrame, AnimationFrame; + SVECTOR Pos, Velocity; + s16 unk14, unk16, unk18, unk1A, TargetIndex, SourceIndex; +} EchoesEffect; +extern EchoesEffect g_BattleEffectSlots[]; +extern void* D_801D687C; +static void func_echoes_801B0404(s32 arg0, s32 arg1); + +void MAGIC_Echoes(s32 targetMask, s32 callbackArg) { func_echoes_801B0404(targetMask, callbackArg); } + +static void func_echoes_801B0020(void) { + EchoesEffect* effect; + MATRIX* matrix; + u16 nextFrame; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + matrix = BattleSetBillboardMatrix(&effect->Pos, (s32)effect->Velocity.vz, (s32)effect->Velocity.pad); + matrix->t[0] += effect->Velocity.vx; + matrix->t[1] = effect->Velocity.vy + matrix->t[1]; + SetTransMatrix(matrix); + D_801B6870.frameIndex = (u16)effect->AnimationFrame; + D_801D687C = func_800D4D90(&D_801B6870, g_cDb->unk70, 0xC, D_801D687C); + if (D_80062D98 != 0) { + return; + } + nextFrame = (u16)effect->AnimationFrame + 1; + effect->AnimationFrame = nextFrame; + if ((s16)nextFrame >= (s32)(u8)g_EchoesAnimation0.frameCount) { + effect->StartFrame = -1; + } +} + +static void func_echoes_801B0108(void) { + EchoesEffect* particle; + EchoesEffect* effect; + s32 angle; + s32 angleY; + s32 i; + s32 fullTurn; + s32 randomValue; + s32 offset; + s32 offsetY; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + if (D_80062D98 != 0) { + return; + } + if (effect->AnimationFrame < 0xF) { + i = 0; + fullTurn = 0x1000; + do { + particle = &g_BattleEffectSlots[BattleEffectRegister(func_echoes_801B0020)]; + particle->Pos = effect->Pos; + angle = rand() & 0x7FF; + if (angle < 0x400) { + offset = rsin(angle) - 0x1000; + } else { + offset = fullTurn - rsin(angle); + } + particle->Velocity.vx = (s16)((s32)(effect->Velocity.vx * offset) >> 0xC); + angleY = rand() & 0x7FF; + if (angleY < 0x400) { + offsetY = rsin(angleY) - 0x1000; + } else { + offsetY = fullTurn - rsin(angleY); + } + particle->Velocity.vy = (s16)((s32)(effect->Velocity.vy * offsetY) >> 0xC); + randomValue = rand(); + // match: the quotient form keeps one shared shift after the sign correction. + particle->Velocity.vz = (randomValue - (randomValue / 4096) * 4096) + 0x2000; + i += 1; + particle->Velocity.pad = (s16)(u16)effect->Velocity.pad; + } while (i < 7); + } else { + func_800D5774((u32)effect->StartFrame); + effect->StartFrame = -1; + } + effect->AnimationFrame = (u16)effect->AnimationFrame + 1; +} + +static void func_echoes_801B02BC(s32 arg0, s32 callbackArg) { + EchoesEffect* effect; + SVECTOR* position; + s32 modelOffset; + u32 nextFrame; + + effect = &g_BattleEffectSlots[BattleEffectRegister(func_echoes_801B0108)]; + // Keep a byte offset across the part-position call for the model-field views. + modelOffset = arg0 * sizeof(BattleModel); + position = &effect->Pos; + effect->StartFrame = arg0; + BattleGetPartPosition((s32)arg0, *(u8*)((u8*)g_BattleModels + modelOffset + 0x2B), position); + nextFrame = (u32)(*(s16*)((u8*)g_BattleModels + modelOffset + 0x12) * 3) >> 1; + effect->Velocity.vy = (s16)nextFrame; + effect->Velocity.vx = (s16)nextFrame; + // match: division preserves the signed halfword load used for the depth bias. + effect->Velocity.pad = *(s16*)((u8*)g_BattleModels + modelOffset + 0x12) / -1; + BattleAkaoCommand(0x20, BattlePositionToStereoPan(position), 0x134); +} + +static void func_echoes_801B03A4(void) { + EchoesEffect* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + D_801D687C = (effect->AnimationFrame << 0x10) + D_801B687C; + effect->AnimationFrame = (u16)effect->AnimationFrame ^ 1; + if (g_BattleEffectCount < 2) { + effect->StartFrame = -1; + } +} + +static void func_echoes_801B0404(s32 arg0, s32 arg1) { + BattleSetLoadTimToVram(echoes_texture_tim, 0, 0, 0); + BattleEffectRegister(func_echoes_801B03A4); + MagicAnimationRegister(arg0, arg1, 0, func_echoes_801B02BC); +} diff --git a/src/magic/echoes_assets.h b/src/magic/echoes_assets.h new file mode 100644 index 00000000..114d6f09 --- /dev/null +++ b/src/magic/echoes_assets.h @@ -0,0 +1,24 @@ +#ifndef ECHOES_ASSETS_H +#define ECHOES_ASSETS_H +#include "magic_assets.h" + +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame4 frame0; + MagicSpriteFrame4 frame1; + MagicSpriteFrame4 frame2; + MagicSpriteFrame4 frame3; + MagicSpriteFrame4 frame4; + MagicSpriteFrame4 frame5; + MagicSpriteFrame4 frame6; + MagicSpriteFrame4 frame7; + MagicSpriteFrame4 frame8; + MagicSpriteFrame4 frame9; + MagicSpriteFrame3 frame10; + MagicSpriteFrame2 frame11; +} EchoesAnimation0; +extern EchoesAnimation0 g_EchoesAnimation0; +extern SpriteRenderDesc D_801B6870; +extern u8 D_801B687C[]; +extern u_long echoes_texture_tim[]; +#endif diff --git a/src/magic/echoes_data.c b/src/magic/echoes_data.c new file mode 100644 index 00000000..3b39039a --- /dev/null +++ b/src/magic/echoes_data.c @@ -0,0 +1,75 @@ +#include "echoes_assets.h" + +EchoesAnimation0 g_EchoesAnimation0 = { + 0x2023, + 12, + {0, + 4, + {{0x0, -32, -32, 0x0, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x20, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x0, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0x20, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x40, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x60, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x40, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0x60, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x80, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0xA0, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x80, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0xA0, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0xC0, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, 0x0, -32, 0xE0, 0x0, 0x2C, 0x7808, 0x20, 0x1F, 0x20, 0x20}, + {0x0, -32, 0x0, 0xC0, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, 0x0, 0x0, 0xE0, 0x20, 0x2C, 0x7808, 0x20, 0x1F, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x0, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x20, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x0, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0x20, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x40, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x60, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x40, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0x60, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x80, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0xA0, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x80, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0xA0, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0xC0, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, 0x0, -32, 0xE0, 0x40, 0x2C, 0x7808, 0x20, 0x1F, 0x20, 0x20}, + {0x0, -32, 0x0, 0xC0, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, 0x0, 0x0, 0xE0, 0x60, 0x2C, 0x7808, 0x20, 0x1F, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x0, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x20, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, -32, 0x0, 0x0, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}, + {0x200, 0x0, 0x0, 0x20, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}}}, + {0, + 4, + {{0x0, -32, -32, 0x40, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x60, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, -32, 0x0, 0x40, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}, + {0x200, 0x0, 0x0, 0x60, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}}}, + {0, + 3, + {{0x0, -32, -32, 0x80, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, -32, 0x0, 0x80, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}, + {0x200, 0x0, 0x0, 0xA0, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}}}, + {0, + 2, + {{0x0, -32, -32, 0xC0, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, -32, 0x0, 0xC0, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}}}}; +SpriteRenderDesc D_801B6870 = {(SpriteAnim*)&g_EchoesAnimation0, {0x80, 0x80, 0x80, 0x2E}, 0, 0}; diff --git a/src/magic/gattai.c b/src/magic/gattai.c new file mode 100644 index 00000000..a032d774 --- /dev/null +++ b/src/magic/gattai.c @@ -0,0 +1,57 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "../battle/battle.h" + +// GATTAI.BIN: A thirty-frame gate accompanies the detached model fade and animation flags. + +typedef struct { + s16 StartFrame; + s16 AnimationFrame; + s16 Countdown; + char pad6[0x1A]; +} GattaiEffect; + +// Detached slot fields are separated by sixteen halfwords. +extern GattaiEffect g_BattleEffectSlots[]; +extern s16 D_801621F2[]; +extern s16 D_801621F4[]; +extern s16 D_801621F6[]; +extern u8 D_80151922[]; +extern u8 D_801524BE; +extern u8 D_8015305A; +extern s8 g_BattleModelFadeFrames; +void D_800C55B8(void); +s32 BattleDetachedRegister(void (*callback)(void)); +void func_800BBA40(s32); + +static void func_gattai_801B0000(void) { + if (g_BattleEffectSlots[g_BattleEffectCursor].Countdown == 0) { + g_BattleEffectSlots[g_BattleEffectCursor].StartFrame = -1; + } + g_BattleEffectSlots[g_BattleEffectCursor].Countdown--; +} + +s32 MAGIC_Gattai(s32 targetMask, s32 callbackArg) { + s32 slot; + g_BattleEffectSlots[BattleEffectRegister(func_gattai_801B0000)].Countdown = 30; + slot = BattleDetachedRegister(D_800C55B8); + D_801621F4[slot * 16] = 16; + D_801621F6[slot * 16] = callbackArg; + D_801621F2[slot * 16] = 0x100; + g_BattleModelFadeFrames = 14; + func_800BBA40(0x29); + if (callbackArg == 0) { + D_80151922[sizeof(BattleModel)] |= 2; + D_8015305A |= 2; + } + if (callbackArg == 1) { + D_80151922[0] |= 2; + D_8015305A |= 2; + } + if (callbackArg == 2) { + D_80151922[0] |= 2; + D_801524BE |= 2; + } + return 0; +} diff --git a/src/magic/hakai.c b/src/magic/hakai.c new file mode 100644 index 00000000..02c6d9c2 --- /dev/null +++ b/src/magic/hakai.c @@ -0,0 +1,96 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "hakai_assets.h" +// HAKAI.BIN: Random body-part sprites alternate between two frame sequences while the screen effect pulses. + +extern s32 rand(void); + +typedef struct { + s16 StartFrame, AnimationFrame; + SVECTOR Pos, Velocity; + s16 unk14, unk16, unk18, unk1A, TargetIndex, SourceIndex; +} HakaiEffect; +extern HakaiEffect g_BattleEffectSlots[]; +extern s32 D_80163C74; +void func_800BBA84(s32, s32, s32); +s32 func_800C4FC8(s32, s32, s16); +static void func_hakai_801B0448(s32 arg0, s32 arg1); + +void MAGIC_Hakai(s32 targetMask, s32 callbackArg) { func_hakai_801B0448(targetMask, callbackArg); } + +static void func_hakai_801B0020(void) { + HakaiEffect* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + D_801CE768 = (effect->AnimationFrame * 0xC000) + D_801B6768; + effect->AnimationFrame = (u16)effect->AnimationFrame ^ 1; + if (g_BattleEffectCount < 2) { + effect->StartFrame = -1; + } +} + +static void func_hakai_801B008C(void) { + HakaiEffect* effect; + s16 nextFrame; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + BattleSetBillboardMatrix(&effect->Pos, (s32)effect->unk18, (s32)effect->unk14); + D_801B6754.frames = D_801B6760[effect->unk16]; + D_801B6754.frameIndex = (u16)effect->AnimationFrame; + D_801CE768 = func_800D4D90(&D_801B6754, g_cDb->unk70, 0xC, D_801CE768); + if (D_80062D98 != 0) { + return; + } + nextFrame = (u16)effect->AnimationFrame + 1; + effect->AnimationFrame = nextFrame; + if (nextFrame == D_801B6760[effect->unk16]->frameCount) { + effect->StartFrame = -1; + } +} + +static void func_hakai_801B0180(void) { + HakaiEffect* effect; + HakaiEffect* particle; + s16 nextFrameValue; + u16 randomScale; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + D_80163C74 = func_800C4FC8(0, 0, (effect->AnimationFrame % 2) * 32 + 32); + if (D_80062D98 != 0) { + return; + } + if (effect->AnimationFrame < 0x16) { + particle = &g_BattleEffectSlots[BattleEffectRegister(func_hakai_801B008C)]; + BattleGetPartPosition( + effect->TargetIndex, rand() % g_BattleModels[effect->TargetIndex].numBones, &particle->Pos); + particle->unk14 = -(s16)g_BattleModels[effect->TargetIndex].collisionRadius; + randomScale = g_BattleModels[effect->TargetIndex].collisionRadius; + if (g_BattleModels[effect->TargetIndex].collisionRadius >= 0xAAB) { + randomScale = 0xAAA; + } + particle->unk18 = (s16)randomScale * 6 + rand() % ((s16)randomScale * 6); + particle->unk16 = rand() % 2; + } + nextFrameValue = (u16)effect->AnimationFrame + 1; + effect->AnimationFrame = nextFrameValue; + if (nextFrameValue == 0x1E) { + func_800D5774((u32)effect->TargetIndex); + effect->StartFrame = -1; + } +} + +static void func_hakai_801B03F4(s32 arg0, s32 arg1) { + HakaiEffect* effect; + + effect = &g_BattleEffectSlots[BattleEffectRegister(func_hakai_801B0180)]; + effect->TargetIndex = arg0; + effect->SourceIndex = arg1; +} + +static void func_hakai_801B0448(s32 arg0, s32 arg1) { + BattleEffectRegister(func_hakai_801B0020); + BattleSetLoadTimToVram(hakai_texture_tim, 0, 0, 0); + MagicAnimationRegister(arg0, arg1, 4, func_hakai_801B03F4); + func_800BBA84(0x186, arg1, 0); +} diff --git a/src/magic/hakai_assets.h b/src/magic/hakai_assets.h new file mode 100644 index 00000000..159ae1c0 --- /dev/null +++ b/src/magic/hakai_assets.h @@ -0,0 +1,42 @@ +#ifndef HAKAI_ASSETS_H +#define HAKAI_ASSETS_H +#include "magic_assets.h" + +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame1 frame0; + MagicSpriteFrame1 frame1; + MagicSpriteFrame1 frame2; + MagicSpriteFrame1 frame3; + MagicSpriteFrame1 frame4; + MagicSpriteFrame1 frame5; + MagicSpriteFrame1 frame6; + MagicSpriteFrame1 frame7; + MagicSpriteFrame1 frame8; + MagicSpriteFrame1 frame9; + MagicSpriteFrame1 frame10; + MagicSpriteFrame1 frame11; +} HakaiAnimation0; +extern HakaiAnimation0 g_HakaiAnimation0; +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame1 frame0; + MagicSpriteFrame1 frame1; + MagicSpriteFrame1 frame2; + MagicSpriteFrame1 frame3; + MagicSpriteFrame1 frame4; + MagicSpriteFrame1 frame5; + MagicSpriteFrame1 frame6; + MagicSpriteFrame1 frame7; + MagicSpriteFrame1 frame8; + MagicSpriteFrame1 frame9; + MagicSpriteFrame1 frame10; + MagicSpriteFrame1 frame11; +} HakaiAnimation1; +extern HakaiAnimation1 g_HakaiAnimation1; +extern SpriteRenderDesc D_801B6754; +extern SpriteAnim* D_801B6760[]; +extern u8 D_801B6768[]; +extern void* D_801CE768; +extern u_long hakai_texture_tim[]; +#endif diff --git a/src/magic/hakai_data.c b/src/magic/hakai_data.c new file mode 100644 index 00000000..21e9e1ec --- /dev/null +++ b/src/magic/hakai_data.c @@ -0,0 +1,36 @@ +#include "hakai_assets.h" + +HakaiAnimation0 g_HakaiAnimation0 = { + 0x2023, + 12, + {0, 1, {{0x100, -32, -24, 0x0, 0x0, 0x2C, 0x7808, 0x30, 0x30, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0x40, 0x0, 0x2C, 0x7808, 0x30, 0x30, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0x80, 0x0, 0x2C, 0x7808, 0x30, 0x30, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0xC0, 0x0, 0x2C, 0x7808, 0x30, 0x30, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0x0, 0x40, 0x2C, 0x7808, 0x40, 0x40, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0x40, 0x40, 0x2C, 0x7808, 0x40, 0x40, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0x80, 0x40, 0x2C, 0x7808, 0x40, 0x40, 0x30, 0x30}}}, + {0, 1, {{0x300, -32, -24, 0xC0, 0x40, 0x2C, 0x7808, 0x40, 0x3F, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0x0, 0x80, 0x2C, 0x7808, 0x40, 0x40, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0x40, 0x80, 0x2C, 0x7808, 0x40, 0x40, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0x80, 0x80, 0x2C, 0x7808, 0x30, 0x30, 0x30, 0x30}}}, + {0, 1, {{0x100, -32, -24, 0xC0, 0x80, 0x2C, 0x7808, 0x30, 0x30, 0x30, 0x30}}}}; +HakaiAnimation1 g_HakaiAnimation1 = { + 0x2023, + 12, + {0, 1, {{0x102, -32, -32, 0x0, 0x0, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x102, -32, -32, 0x40, 0x0, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x102, -32, -32, 0x80, 0x0, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x302, -32, -32, 0xC0, 0x0, 0x2C, 0x7808, 0x40, 0x3F, 0x40, 0x40}}}, + {0, 1, {{0x102, -32, -32, 0x0, 0x40, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x102, -32, -32, 0x40, 0x40, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x102, -32, -32, 0x80, 0x40, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x40}}}, + {0, 1, {{0x302, -32, -32, 0xC0, 0x40, 0x2C, 0x7808, 0x40, 0x3F, 0x40, 0x40}}}, + {0, 1, {{0x302, -32, -32, 0x0, 0x80, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x3F}}}, + {0, 1, {{0x302, -32, -32, 0x40, 0x80, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x3F}}}, + {0, 1, {{0x302, -32, -32, 0x80, 0x80, 0x2C, 0x7808, 0x40, 0x40, 0x40, 0x3F}}}, + {0, 1, {{0x302, -32, -32, 0xC0, 0x80, 0x2C, 0x7808, 0x40, 0x3F, 0x40, 0x3F}}}}; +SpriteRenderDesc D_801B6754 = {NULL, {0x80, 0x80, 0x80, 0x2C}, 0, 0}; +SpriteAnim* D_801B6760[] = {(SpriteAnim*)&g_HakaiAnimation0, (SpriteAnim*)&g_HakaiAnimation1}; +u8 D_801B6768[0x18000] = {0}; +void* D_801CE768 = NULL; diff --git a/src/magic/jinrai.c b/src/magic/jinrai.c new file mode 100644 index 00000000..2ef4e8a4 --- /dev/null +++ b/src/magic/jinrai.c @@ -0,0 +1,87 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "jinrai_assets.h" +// JINRAI.BIN: Two target-position sprite bursts, scheduled at frames 22 and 55. + +typedef struct { + s16 StartFrame, AnimationFrame; + SVECTOR Pos, TargetPos; + s16 unk14, unk16, unk18, unk1A, TargetIndex, SourceIndex; +} JinraiEffect; +extern JinraiEffect g_BattleEffectSlots[]; +extern s32 D_801B3354; +extern EffectModel D_801B3470; +extern void* D_80163C74; +static void func_jinrai_801B02B0(s32 arg0, s32 arg1); + +void func_800BBA84(s32, s32, s32); + +EffectModel* MAGIC_Jinrai(s32 targetMask, s32 callbackArg) { + func_jinrai_801B02B0(targetMask, callbackArg); + return &D_801B3470; +} + +static void func_jinrai_801B0028(void) { + JinraiEffect* effect; + s16 nextFrame; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + BattleSetBillboardMatrix(&effect->Pos, 0x3000, 0); + D_801B5220.frameIndex = (u16)effect->AnimationFrame; + D_80163C74 = func_800D4D90(&D_801B5220, g_cDb->unk70, 0xC, D_80163C74); + if (D_80062D98 != 0) { + return; + } + nextFrame = (u16)effect->AnimationFrame + 1; + effect->AnimationFrame = nextFrame; + if (nextFrame == D_801B3354) { + effect->StartFrame = -1; + } +} + +static void func_jinrai_801B00E0(void) { + JinraiEffect* effect; + JinraiEffect* particle; + s16 nextFrame; + s16 startFrame; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + if (D_80062D98 != 0) { + return; + } + startFrame = effect->AnimationFrame; + if ((startFrame == 0x16) || (startFrame == 0x37)) { + particle = &g_BattleEffectSlots[BattleEffectRegister(func_jinrai_801B0028)]; + particle->Pos.vx = (s16)(u16)effect->TargetPos.vx; + particle->Pos.vy = (s16)(u16)effect->TargetPos.vy; + particle->Pos.vz = (s16)(u16)effect->TargetPos.vz; + func_800BBA84(0x155, (s32)effect->SourceIndex, 0); + } + if (effect->AnimationFrame == 0x1E) { + func_800BBA84(0x30, (s32)effect->SourceIndex, 0); + } + if (effect->AnimationFrame == 0x37) { + func_800D5774((u32)effect->TargetIndex); + } + nextFrame = (u16)effect->AnimationFrame + 1; + effect->AnimationFrame = nextFrame; + if (nextFrame == 0x46) { + effect->StartFrame = -1; + } +} + +static void func_jinrai_801B01E4(s32 arg0, s32 arg1) { + JinraiEffect* effect; + + effect = &g_BattleEffectSlots[BattleEffectRegister(func_jinrai_801B00E0)]; + BattleGetPartPosition(arg1, g_BattleModels[arg1].boneIndices[0], &effect->Pos); + BattleGetPartPosition(arg0, g_BattleModels[arg0].boneIndices[0], &effect->TargetPos); + effect->TargetIndex = (s16)arg0; + effect->SourceIndex = (s16)arg1; +} + +static void func_jinrai_801B02B0(s32 arg0, s32 arg1) { + BattleSetLoadTimToVram(jinrai_texture_tim, 0, 0, 0); + MagicAnimationRegister(arg0, arg1, 4, func_jinrai_801B01E4); +} diff --git a/src/magic/jinrai_assets.h b/src/magic/jinrai_assets.h new file mode 100644 index 00000000..da4f0bcc --- /dev/null +++ b/src/magic/jinrai_assets.h @@ -0,0 +1,16 @@ +#ifndef JINRAI_ASSETS_H +#define JINRAI_ASSETS_H +#include "magic_assets.h" + +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame3 frame0; + MagicSpriteFrame3 frame1; + MagicSpriteFrame3 frame2; + MagicSpriteFrame2 frame3; + MagicSpriteFrame2 frame4; +} JinraiAnimation0; +extern JinraiAnimation0 g_JinraiAnimation0; +extern SpriteRenderDesc D_801B5220; +extern u_long jinrai_texture_tim[]; +#endif diff --git a/src/magic/jinrai_data.c b/src/magic/jinrai_data.c new file mode 100644 index 00000000..77c1f6ca --- /dev/null +++ b/src/magic/jinrai_data.c @@ -0,0 +1,28 @@ +#include "jinrai_assets.h" + +JinraiAnimation0 g_JinraiAnimation0 = { + 0x2023, + 5, + {0, + 3, + {{0x100, -32, -32, 0x0, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x100, 0x0, -32, 0x20, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x100, -32, 0x0, 0x0, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 3, + {{0x100, -32, -32, 0x40, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x100, 0x0, -32, 0x60, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x100, -32, 0x0, 0x40, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 3, + {{0x100, -32, -32, 0x0, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x100, -32, 0x0, 0x0, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x100, 0x0, -32, 0x20, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 2, + {{0x100, -32, 0x0, 0x40, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x100, -32, -32, 0x40, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 2, + {{0x100, -32, -32, 0x80, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x100, -32, 0x0, 0x80, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}}; diff --git a/src/magic/jinrai_render.c b/src/magic/jinrai_render.c new file mode 100644 index 00000000..068c5b34 --- /dev/null +++ b/src/magic/jinrai_render.c @@ -0,0 +1,3 @@ +#include "jinrai_assets.h" + +SpriteRenderDesc D_801B5220 = {(SpriteAnim*)&g_JinraiAnimation0, {0x80, 0x80, 0x80, 0x2E}, 0, 0}; diff --git a/src/magic/magend.c b/src/magic/magend.c new file mode 100644 index 00000000..bab3aca3 --- /dev/null +++ b/src/magic/magend.c @@ -0,0 +1,95 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "magend_assets.h" +// MAGEND.BIN: One particle per update; random rotation determines its velocity and gravity pulls it down. + +extern s32 rand(void); + +typedef struct { + s16 StartFrame, AnimationFrame; + SVECTOR Pos, Velocity; + s16 unk14, unk16, unk18, unk1A, TargetIndex, SourceIndex; +} MagendEffect; +extern MagendEffect g_BattleEffectSlots[]; +void RotTransSV(SVECTOR*, SVECTOR*, s32*); +static void func_magend_801B0448(s32 arg0, s32 arg1); + +void MAGIC_Magend(s32 targetMask, s32 callbackArg) { func_magend_801B0448(targetMask, callbackArg); } + +static void func_magend_801B0020(void) { + MagendEffect* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + D_801C1748 = (effect->AnimationFrame << 0xF) + D_801B1748; + effect->AnimationFrame = (u16)effect->AnimationFrame ^ 1; + if (g_BattleEffectCount < 2) { + effect->StartFrame = -1; + } +} + +static void func_magend_801B0080(void) { + MagendEffect* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + BattleSetBillboardMatrix(&effect->Pos, 0x200, 0); + D_801C1748 = func_800D4D90(&D_801B1734, g_cDb->unk70, 0xC, D_801C1748); + if (D_80062D98 != 0) { + return; + } + effect->Velocity.vy = (u16)effect->Velocity.vy + 3; + effect->Pos.vx = (u16)effect->Pos.vx + (u16)effect->Velocity.vx; + effect->Pos.vy = (u16)effect->Pos.vy + (u16)effect->Velocity.vy; + effect->Pos.vz = (u16)effect->Pos.vz + (u16)effect->Velocity.vz; + if ((effect->Pos.vy > 0) || (D_801B1730 == 1)) { + effect->StartFrame = -1; + } + effect->AnimationFrame = (u16)effect->AnimationFrame + 1; +} + +static void func_magend_801B0174(void) { + SVECTOR rotation; + MATRIX matrix; + s32 flags; + MagendEffect* particle; + MagendEffect* effect; + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + if (D_80062D98 != 0) { + return; + } + if (effect->AnimationFrame < 56) { + particle = &g_BattleEffectSlots[BattleEffectRegister(func_magend_801B0080)]; + BattleGetPartPosition(effect->SourceIndex, g_BattleModels[effect->SourceIndex].boneIndices[0], &particle->Pos); + particle->Pos.vx += rand() % 200 - 100; + particle->Pos.vy += rand() % 200 - 100; + particle->Pos.vz += rand() % 200 - 100; + rotation.vx = rand() % 500 + 350; + rotation.vy = rand() % 500 - 250; + rotation.vz = 0; + RotMatrixYXZ(&rotation, &matrix); + matrix.t[0] = matrix.t[1] = matrix.t[2] = 0; + SetRotMatrix(&matrix); + SetTransMatrix(&matrix); + RotTransSV(&D_801B1740, &particle->Velocity, &flags); + } + effect->AnimationFrame++; + if (effect->AnimationFrame == 56) { + func_800D5774(effect->TargetIndex); + D_801B1730 = 1; + effect->StartFrame = -1; + } +} + +static void func_magend_801B03F4(s32 arg0, s32 arg1) { + MagendEffect* effect; + + effect = &g_BattleEffectSlots[BattleEffectRegister(func_magend_801B0174)]; + effect->TargetIndex = arg0; + effect->SourceIndex = arg1; +} + +static void func_magend_801B0448(s32 arg0, s32 arg1) { + BattleEffectRegister(func_magend_801B0020); + BattleSetLoadTimToVram(magend_texture_tim, 0, 0, 0); + MagicAnimationRegister(arg0, arg1, 4, func_magend_801B03F4); +} diff --git a/src/magic/magend_assets.h b/src/magic/magend_assets.h new file mode 100644 index 00000000..1bf577ff --- /dev/null +++ b/src/magic/magend_assets.h @@ -0,0 +1,16 @@ +#ifndef MAGEND_ASSETS_H +#define MAGEND_ASSETS_H +#include "magic_assets.h" + +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame4 frame0; +} MagendAnimation0; +extern MagendAnimation0 g_MagendAnimation0; +extern s16 D_801B1730; +extern SpriteRenderDesc D_801B1734; +extern SVECTOR D_801B1740; +extern u8 D_801B1748[]; +extern void* D_801C1748; +extern u_long magend_texture_tim[]; +#endif diff --git a/src/magic/magend_data.c b/src/magic/magend_data.c new file mode 100644 index 00000000..b3cd09ac --- /dev/null +++ b/src/magic/magend_data.c @@ -0,0 +1,17 @@ +#include "magend_assets.h" + +MagendAnimation0 g_MagendAnimation0 = { + 0x2023, + 1, + {0, + 4, + {{0x100, -32, -32, 0x0, 0x0, 0xAC, 0x3FF0, 0x20, 0x20, 0x20, 0x20}, + {0x300, 0x0, -32, 0x20, 0x0, 0xAC, 0x3FF0, 0x20, 0x1F, 0x20, 0x20}, + {0x300, -32, 0x0, 0x0, 0x20, 0xAC, 0x3FF0, 0x20, 0x20, 0x20, 0x1F}, + {0x300, 0x0, 0x0, 0x20, 0x20, 0xAC, 0x3FF0, 0x20, 0x1F, 0x20, 0x1F}}}}; +s16 D_801B1730 = 0; +s16 D_801B1732 = 0; +SpriteRenderDesc D_801B1734 = {(SpriteAnim*)&g_MagendAnimation0, {0x80, 0x80, 0x80, 0x2E}, 0, 0}; +SVECTOR D_801B1740 = {0, 0, 100, 0}; +u8 D_801B1748[0x10000] = {0}; +void* D_801C1748 = NULL; diff --git a/src/magic/magic.h b/src/magic/magic.h index d75cbb71..003f2fd7 100644 --- a/src/magic/magic.h +++ b/src/magic/magic.h @@ -36,4 +36,16 @@ void MAGIC_Refrec(s32 targetMask, s32 callbackArg); void MAGIC_Lv5Death(s32 targetMask, s32 callbackArg); EffectModel* MAGIC_Choco0(s32 targetMask, s32 callbackArg); +s32 MAGIC_Gattai(s32 targetMask, s32 callbackArg); +EffectModel* MAGIC_Jinrai(s32 targetMask, s32 callbackArg); +void MAGIC_Smkball(s32 targetMask, s32 callbackArg); +void MAGIC_Threat(s32 targetMask, s32 callbackArg); +void MAGIC_Tears(s32 targetMask, s32 callbackArg); +void MAGIC_Echoes(s32 targetMask, s32 callbackArg); +void MAGIC_Magend(s32 targetMask, s32 callbackArg); +void MAGIC_Hakai(s32 targetMask, s32 callbackArg); +EffectModel* MAGIC_Boost(s32 targetMask, s32 callbackArg); +void MAGIC_Minimam(s32 targetMask, s32 callbackArg); +void MAGIC_ThreatSetup(s32 targetMask, s32 callbackArg); + #endif diff --git a/src/magic/magic_assets.h b/src/magic/magic_assets.h new file mode 100644 index 00000000..7e6abf84 --- /dev/null +++ b/src/magic/magic_assets.h @@ -0,0 +1,21 @@ +#ifndef MAGIC_ASSETS_H +#define MAGIC_ASSETS_H +#include "../battle/battle.h" + +typedef struct { + s16 unk0, quadCount; + SpriteQuad quads[1]; +} MagicSpriteFrame1; +typedef struct { + s16 unk0, quadCount; + SpriteQuad quads[2]; +} MagicSpriteFrame2; +typedef struct { + s16 unk0, quadCount; + SpriteQuad quads[3]; +} MagicSpriteFrame3; +typedef struct { + s16 unk0, quadCount; + SpriteQuad quads[4]; +} MagicSpriteFrame4; +#endif diff --git a/src/magic/minimam.c b/src/magic/minimam.c new file mode 100644 index 00000000..a2d66937 --- /dev/null +++ b/src/magic/minimam.c @@ -0,0 +1,136 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "minimam_assets.h" +// MINIMAM.BIN: A circular pool of 444 position/scale records feeds groups of three billboard sprites. + +extern s32 rand(void); + +typedef struct { + s16 StartFrame, AnimationFrame; + SVECTOR Pos; + s16 Radius, Width, HeightBias, HeightRange, Scale, unk16, TargetIndex; + char pad1A[6]; +} MinimamEffect; +extern MinimamEffect g_BattleEffectSlots[]; +static void func_minimam_801B0514(s32 arg0, s32 arg1); + +static void func_minimam_801B0000(void) { + u8* offset; + + offset = D_801C08AC; + if (g_dbIndex == 0) { + offset = D_801B48AC; + } + D_801CC8AC = offset; + if (g_BattleEffectCount < 2) { + *D_801CC8B0 = -1; + } +} + +void MAGIC_Minimam(s32 targetMask, s32 callbackArg) { func_minimam_801B0514(targetMask, callbackArg); } + +static void func_minimam_801B0074(void) { + MinimamEffect* effect; + SVECTOR* position; + s32 randomScale; + s32 i; + s32 temp_a2; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + D_801B48A0.frameIndex = (u16)effect->AnimationFrame; + randomScale = effect->TargetIndex * 8; + for (i = 0; i < 3; i++) { + position = (SVECTOR*)((u8*)g_MinimamParticles + randomScale); + temp_a2 = *(s16*)((u8*)&g_MinimamParticles[0].pad + randomScale); + randomScale += 8; + BattleSetBillboardMatrix(position, temp_a2, -(temp_a2 >> 2)); + D_801CC8AC = func_800D4D90(&D_801B48A0, g_cDb->unk70, 0xC, D_801CC8AC); + if (randomScale >= 0xDE0) { + randomScale = 0; + } + } + if (effect->AnimationFrame >= 7) { + effect->StartFrame = -1; + } + if (D_80062D98 != 0) { + return; + } + effect->AnimationFrame = (u16)effect->AnimationFrame + 1; +} + +static void func_minimam_801B0190(void) { + MinimamEffect* effect; + MinimamEffect* particle; + s32 randomScale; + s32 i; + s32 iValue; + s32 iValueValue; + + if (D_80062D98 != 0) { + return; + } + particle = g_BattleEffectSlots; + effect = &particle[g_BattleEffectCursor]; + if ((u32)((u16)effect->AnimationFrame - 2) < 0x1AU) { + iValue = D_801CC8B4; + i = iValue * 8; + particle[BattleEffectRegister(func_minimam_801B0074)].TargetIndex = (s16)iValue; + for (iValueValue = 0; iValueValue < 3; iValueValue++) { + randomScale = rand() % 4096 + 2048; + *(s16*)((u8*)g_MinimamParticles + i) = + ((u16)effect->Pos.vx + (rand() % (s16)effect->Width)) - (u16)effect->Radius; + iValue += 1; + *(s16*)((u8*)&g_MinimamParticles[0].vy + i) = + ((u16)effect->Pos.vy - (rand() % (s16)effect->HeightRange)) + (u16)effect->HeightBias; + *(s16*)((u8*)&g_MinimamParticles[0].vz + i) = + ((u16)effect->Pos.vz + (rand() % (s16)effect->Width)) - (u16)effect->Radius; + *(s16*)((u8*)&g_MinimamParticles[0].pad + i) = (s16)((s32)(effect->Scale * randomScale) >> 0xC); + i += 8; + if (iValue >= 0x1BC) { + i = 0; + iValue = 0; + } + } + D_801CC8B4 = iValue; + } + if (effect->AnimationFrame == 0x1C) { + func_800D5774((u32)effect->TargetIndex); + BattleAkaoCommand(0x20, BattlePositionToStereoPan(&effect->Pos), 0xB1); + } + if (effect->AnimationFrame >= 0x23) { + effect->StartFrame = -1; + } + effect->AnimationFrame = (u16)effect->AnimationFrame + 1; +} + +static void func_minimam_801B0414(s32 arg0, s32 arg1) { + MinimamEffect* effect; + s32 offset; + s32 modelOffset; + s32 nextFrame; + + effect = &g_BattleEffectSlots[BattleEffectRegister(func_minimam_801B0190)]; + // Keep a byte offset across the part-position call for the model-field views. + modelOffset = arg0 * 0xB9C; + BattleGetPartPosition(arg0, *(u8*)((u8*)g_BattleModels + modelOffset + 0x2B), &effect->Pos); + offset = *(s16*)((u8*)g_BattleModels + modelOffset + 0x12) + 0xE0; + if (offset >= 0x4F3) { + offset = 0x4F2; + } + effect->Radius = offset; + effect->Width = offset * 2; + effect->TargetIndex = (s16)arg0; + nextFrame = -(effect->Pos.vy >> 1); + effect->HeightBias = nextFrame; + effect->HeightRange = nextFrame * 4; + effect->Scale = (offset << 0xC) / 540; +} + +static void func_minimam_801B0514(s32 arg0, s32 arg1) { + D_801CC8B0 = (s32*)&g_BattleEffectSlots[BattleEffectRegister(func_minimam_801B0000)]; + BattleSetLoadTimToVram(minimam_texture_tim, 0, 0, 0); + MagicAnimationRegister(arg0, arg1, 1, func_minimam_801B0414); + D_801CC8B4 = 0; + BattleAkaoCommand(0x20, BattleEntityGetStereoPan(arg0), 0x134); +} diff --git a/src/magic/minimam_assets.h b/src/magic/minimam_assets.h new file mode 100644 index 00000000..1dce3276 --- /dev/null +++ b/src/magic/minimam_assets.h @@ -0,0 +1,25 @@ +#ifndef MINIMAM_ASSETS_H +#define MINIMAM_ASSETS_H +#include "magic_assets.h" + +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame4 frame0; + MagicSpriteFrame4 frame1; + MagicSpriteFrame4 frame2; + MagicSpriteFrame4 frame3; + MagicSpriteFrame4 frame4; + MagicSpriteFrame4 frame5; + MagicSpriteFrame4 frame6; + MagicSpriteFrame4 frame7; +} MinimamAnimation0; +extern MinimamAnimation0 g_MinimamAnimation0; +extern SpriteRenderDesc D_801B48A0; +extern SVECTOR g_MinimamParticles[444]; +extern u8 D_801B48AC[]; +extern u8 D_801C08AC[]; +extern void* D_801CC8AC; +extern s32* D_801CC8B0; +extern s32 D_801CC8B4; +extern u_long minimam_texture_tim[]; +#endif diff --git a/src/magic/minimam_data.c b/src/magic/minimam_data.c new file mode 100644 index 00000000..3c5d3f5e --- /dev/null +++ b/src/magic/minimam_data.c @@ -0,0 +1,60 @@ +#include "minimam_assets.h" + +MinimamAnimation0 g_MinimamAnimation0 = { + 0x2023, + 8, + {0, + 4, + {{0x100, -32, 0x0, 0x0, 0x0, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x0, 0x20, 0x0, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, -32, 0x20, 0x0, 0x20, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x20, 0x20, 0x20, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}}}, + {0, + 4, + {{0x100, -32, 0x0, 0x40, 0x0, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x0, 0x60, 0x0, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, -32, 0x20, 0x40, 0x20, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x20, 0x60, 0x20, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}}}, + {0, + 4, + {{0x100, -32, 0x0, 0x80, 0x0, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x0, 0xA0, 0x0, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, -32, 0x20, 0x80, 0x20, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x20, 0xA0, 0x20, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}}}, + {0, + 4, + {{0x100, -32, 0x0, 0xC0, 0x0, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x0, 0xE0, 0x0, 0x2C, 0x7808, 0x1F, 0x0, 0x20, 0x0}, + {0x100, -32, 0x20, 0xC0, 0x20, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x20, 0xE0, 0x20, 0x2C, 0x7808, 0x1F, 0x0, 0x20, 0x0}}}, + {0, + 4, + {{0x100, -32, 0x0, 0x0, 0x40, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x0, 0x20, 0x40, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, -32, 0x20, 0x0, 0x60, 0x2C, 0x7808, 0x20, 0x0, 0x1F, 0x0}, + {0x100, 0x0, 0x20, 0x20, 0x60, 0x2C, 0x7808, 0x20, 0x0, 0x1F, 0x0}}}, + {0, + 4, + {{0x100, -32, 0x0, 0x40, 0x40, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x0, 0x60, 0x40, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, -32, 0x20, 0x40, 0x60, 0x2C, 0x7808, 0x20, 0x0, 0x1F, 0x0}, + {0x100, 0x0, 0x20, 0x60, 0x60, 0x2C, 0x7808, 0x20, 0x0, 0x1F, 0x0}}}, + {0, + 4, + {{0x100, -32, 0x0, 0x80, 0x40, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x0, 0xA0, 0x40, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, -32, 0x20, 0x80, 0x60, 0x2C, 0x7808, 0x20, 0x0, 0x1F, 0x0}, + {0x100, 0x0, 0x20, 0xA0, 0x60, 0x2C, 0x7808, 0x20, 0x0, 0x1F, 0x0}}}, + {0, + 4, + {{0x100, -32, 0x0, 0xC0, 0x40, 0x2C, 0x7808, 0x20, 0x0, 0x20, 0x0}, + {0x100, 0x0, 0x0, 0xE0, 0x40, 0x2C, 0x7808, 0x1F, 0x0, 0x20, 0x0}, + {0x100, -32, 0x20, 0xC0, 0x60, 0x2C, 0x7808, 0x20, 0x0, 0x1F, 0x0}, + {0x100, 0x0, 0x20, 0xE0, 0x60, 0x2C, 0x7808, 0x1F, 0x0, 0x1F, 0x0}}}}; +SpriteRenderDesc D_801B48A0 = {(SpriteAnim*)&g_MinimamAnimation0, {0x80, 0x80, 0x80, 0x2E}, 0, 0}; +u8 D_801B48AC[0xC000] = {0}; +u8 D_801C08AC[0xC000] = {0}; +void* D_801CC8AC = NULL; +s32* D_801CC8B0 = NULL; +s32 D_801CC8B4 = 0; +SVECTOR g_MinimamParticles[444] = {0}; diff --git a/src/magic/smkball.c b/src/magic/smkball.c new file mode 100644 index 00000000..1793c709 --- /dev/null +++ b/src/magic/smkball.c @@ -0,0 +1,84 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "smkball_assets.h" +// SMKBALL.BIN: Seven screen-space sprites per update, with random x/y positions and double buffering. + +extern s32 rand(void); + +typedef struct { + s16 StartFrame, AnimationFrame; + SVECTOR Pos, Velocity; + s16 unk14, unk16, unk18, unk1A, TargetIndex, SourceIndex; +} SmkballEffect; +extern SmkballEffect g_BattleEffectSlots[]; +extern void* D_801D6738; +static void func_smkball_801B02B0(s32 arg0, s32 arg1); + +void MAGIC_Smkball(s32 targetMask, s32 callbackArg) { func_smkball_801B02B0(targetMask, callbackArg); } + +static void func_smkball_801B0020(void) { + SmkballEffect* effect; + s16 nextFrame; + MATRIX* matrix; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + D_801B670C.t[0] = effect->Pos.vx * 4; + D_801B670C.t[1] = effect->Pos.vy * 4; + matrix = &D_801B670C; + D_801B670C.t[2] = ReadGeomScreen() * 4; + SetRotMatrix(matrix); + SetTransMatrix(matrix); + D_801B672C.frameIndex = (u16)effect->AnimationFrame; + D_801D6738 = func_800D4D90(&D_801B672C, &g_cDb->unk4080[1], 0, D_801D6738); + if (D_80062D98 != 0) { + return; + } + effect->AnimationFrame++; + nextFrame = effect->AnimationFrame; + if ((s16)nextFrame >= (s32)((u8*)&g_SmkballAnimation0)[4]) { + effect->StartFrame = -1; + } +} + +static void func_smkball_801B0124(void) { + SmkballEffect* particle; + s32 i; + SmkballEffect* effect; + s32 randomValue; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + if (D_80062D98 != 0) { + return; + } + if (effect->AnimationFrame < 0x1E) { + for (i = 0; i < 7;) { + i += 1; + particle = &g_BattleEffectSlots[BattleEffectRegister(func_smkball_801B0020)]; + randomValue = rand(); + particle->Pos.vx = (randomValue % 320) - 0xA0; + particle->Pos.vy = (rand() % 166) - 0x78; + } + } else { + effect->StartFrame = -1; + } + effect->AnimationFrame = (u16)effect->AnimationFrame + 1; +} + +static void func_smkball_801B0250(void) { + SmkballEffect* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + D_801D6738 = (effect->AnimationFrame << 0x10) + D_801B6738; + effect->AnimationFrame = (u16)effect->AnimationFrame ^ 1; + if (g_BattleEffectCount < 2) { + effect->StartFrame = -1; + } +} + +static void func_smkball_801B02B0(s32 arg0, s32 arg1) { + BattleSetLoadTimToVram(smkball_texture_tim, 0, 0, 0); + BattleEffectRegister(func_smkball_801B0250); + BattleEffectRegister(func_smkball_801B0124); + BattleAkaoCommand(0x20, 0x40, 0x261); +} diff --git a/src/magic/smkball_assets.h b/src/magic/smkball_assets.h new file mode 100644 index 00000000..ca0a137a --- /dev/null +++ b/src/magic/smkball_assets.h @@ -0,0 +1,25 @@ +#ifndef SMKBALL_ASSETS_H +#define SMKBALL_ASSETS_H +#include "magic_assets.h" + +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame4 frame0; + MagicSpriteFrame4 frame1; + MagicSpriteFrame4 frame2; + MagicSpriteFrame4 frame3; + MagicSpriteFrame4 frame4; + MagicSpriteFrame4 frame5; + MagicSpriteFrame4 frame6; + MagicSpriteFrame4 frame7; + MagicSpriteFrame4 frame8; + MagicSpriteFrame4 frame9; + MagicSpriteFrame3 frame10; + MagicSpriteFrame2 frame11; +} SmkballAnimation0; +extern SmkballAnimation0 g_SmkballAnimation0; +extern MATRIX D_801B670C; +extern SpriteRenderDesc D_801B672C; +extern u8 D_801B6738[]; +extern u_long smkball_texture_tim[]; +#endif diff --git a/src/magic/smkball_data.c b/src/magic/smkball_data.c new file mode 100644 index 00000000..af69b5a2 --- /dev/null +++ b/src/magic/smkball_data.c @@ -0,0 +1,76 @@ +#include "smkball_assets.h" + +SmkballAnimation0 g_SmkballAnimation0 = { + 0x2023, + 12, + {0, + 4, + {{0x0, -32, -32, 0x0, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x20, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x0, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0x20, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x40, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x60, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x40, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0x60, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x80, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0xA0, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x80, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0xA0, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0xC0, 0x0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, 0x0, -32, 0xE0, 0x0, 0x2C, 0x7808, 0x20, 0x1F, 0x20, 0x20}, + {0x0, -32, 0x0, 0xC0, 0x20, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, 0x0, 0x0, 0xE0, 0x20, 0x2C, 0x7808, 0x20, 0x1F, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x0, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x20, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x0, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0x20, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x40, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x60, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x40, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0x60, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x80, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0xA0, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, -32, 0x0, 0x80, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, 0x0, 0xA0, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0xC0, 0x40, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, 0x0, -32, 0xE0, 0x40, 0x2C, 0x7808, 0x20, 0x1F, 0x20, 0x20}, + {0x0, -32, 0x0, 0xC0, 0x60, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, 0x0, 0x0, 0xE0, 0x60, 0x2C, 0x7808, 0x20, 0x1F, 0x20, 0x20}}}, + {0, + 4, + {{0x0, -32, -32, 0x0, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x20, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, -32, 0x0, 0x0, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}, + {0x200, 0x0, 0x0, 0x20, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}}}, + {0, + 4, + {{0x0, -32, -32, 0x40, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x0, 0x0, -32, 0x60, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, -32, 0x0, 0x40, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}, + {0x200, 0x0, 0x0, 0x60, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}}}, + {0, + 3, + {{0x0, -32, -32, 0x80, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, -32, 0x0, 0x80, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}, + {0x200, 0x0, 0x0, 0xA0, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}}}, + {0, + 2, + {{0x0, -32, -32, 0xC0, 0x80, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x20}, + {0x200, -32, 0x0, 0xC0, 0xA0, 0x2C, 0x7808, 0x20, 0x20, 0x20, 0x1F}}}}; +MATRIX D_801B670C = {{{4096, 0, 0}, {0, 4096, 0}, {0, 0, 4096}}, 0, {0, 0, 0}}; +SpriteRenderDesc D_801B672C = {(SpriteAnim*)&g_SmkballAnimation0, {0x80, 0x80, 0x80, 0x2E}, 0, 0}; diff --git a/src/magic/tears.c b/src/magic/tears.c new file mode 100644 index 00000000..7596b351 --- /dev/null +++ b/src/magic/tears.c @@ -0,0 +1,108 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "tears_assets.h" +// TEARS.BIN: Three falling sprites per update, distributed around the target in the x/z plane. + +extern s32 rand(void); + +typedef struct { + s16 StartFrame, AnimationFrame; + SVECTOR Pos, Velocity; + s16 unk14, unk16, unk18, unk1A, TargetIndex, SourceIndex; +} TearsEffect; +extern TearsEffect g_BattleEffectSlots[]; +extern void* D_801D0460; +static void func_tears_801B03E4(s32 arg0, s32 arg1); + +void MAGIC_Tears(s32 targetMask, s32 callbackArg) { func_tears_801B03E4(targetMask, callbackArg); } + +static void func_tears_801B0020(void) { + TearsEffect* effect; + s16 startFrame; + u8 nextFrame; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + startFrame = effect->AnimationFrame; + if (startFrame < 5) { + nextFrame = (startFrame << 7) / 5; + D_801B0450.b = nextFrame; + D_801B0450.g = nextFrame; + D_801B0450.r = nextFrame; + } else { + *(u32*)&D_801B0450.r = 0x2E808080; + } + BattleSetBillboardMatrix(&effect->Pos, (s32)effect->unk14, 0); + D_801B0450.u = ((effect->AnimationFrame + effect->StartFrame) & 7) * 32; + D_801D0460 = BattleEffectSpriteAdd(&D_801B0450, g_cDb->unk70, 0xC, D_801D0460); + if (D_80062D98 != 0) { + return; + } + effect->Pos.vy = (u16)effect->Pos.vy + (u16)effect->Velocity.vy; + effect->AnimationFrame = (u16)effect->AnimationFrame + 1; + effect->Velocity.vy = (s16)(u16)effect->Velocity.vy; + if (effect->Pos.vy > 0) { + effect->StartFrame = -1; + } +} + +static void func_tears_801B0158(void) { + TearsEffect* particle; + TearsEffect* effect; + s32 zOffset; + s32 temp_s1; + s32 temp_s2; + s32 i; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + if (D_80062D98 != 0) { + return; + } + i = 0; + if (effect->AnimationFrame < 0x1E) { + loop_2: + i += 1; + particle = &g_BattleEffectSlots[BattleEffectRegister(func_tears_801B0020)]; + temp_s1 = rand() & 0xFFF; + temp_s2 = rand() % 1000; + particle->Pos.vx = (u16)effect->Pos.vx + ((s32)(rsin(temp_s1) * temp_s2) >> 0xC); + particle->Pos.vy = (rand() % 100) - 0x834; + zOffset = rcos(temp_s1) * temp_s2; + particle->Pos.vz = (u16)effect->Pos.vz + (zOffset >> 0xC); + particle->Velocity.vy = 0x64; + particle->unk14 = 0x1000; + particle->StartFrame = rand() & 7; + if (i < 3) { + goto loop_2; + } + } else { + func_800D5774((u32)effect->StartFrame); + effect->StartFrame = -1; + } + effect->AnimationFrame = (u16)effect->AnimationFrame + 1; +} + +static void func_tears_801B0304(s32 arg0, s32 callbackArg) { + TearsEffect* effect; + + effect = &g_BattleEffectSlots[BattleEffectRegister(func_tears_801B0158)]; + effect->StartFrame = arg0; + BattleGetPartPosition((s32)arg0, g_BattleModels[arg0].boneIndices[0], &effect->Pos); +} + +static void func_tears_801B0384(void) { + TearsEffect* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + D_801D0460 = (effect->AnimationFrame << 0x10) + D_801B0460; + effect->AnimationFrame = (u16)effect->AnimationFrame ^ 1; + if (g_BattleEffectCount < 2) { + effect->StartFrame = -1; + } +} + +static void func_tears_801B03E4(s32 arg0, s32 arg1) { + BattleEffectRegister(func_tears_801B0384); + MagicAnimationRegister(arg0, arg1, 0, func_tears_801B0304); + BattleAkaoCommand(0x20, BattleEntityGetStereoPan(arg0), 0x11E); +} diff --git a/src/magic/tears_assets.h b/src/magic/tears_assets.h new file mode 100644 index 00000000..f0c0cf2a --- /dev/null +++ b/src/magic/tears_assets.h @@ -0,0 +1,7 @@ +#ifndef TEARS_ASSETS_H +#define TEARS_ASSETS_H +#include "magic_assets.h" + +extern BattleSpriteDesc D_801B0450; +extern u8 D_801B0460[]; +#endif diff --git a/src/magic/tears_data.c b/src/magic/tears_data.c new file mode 100644 index 00000000..bf2fff48 --- /dev/null +++ b/src/magic/tears_data.c @@ -0,0 +1,3 @@ +#include "tears_assets.h" + +BattleSpriteDesc D_801B0450 = {-16, -16, 0, 0, 31, 31, 128, 128, 128, 46, 58, 31047}; diff --git a/src/magic/threat.c b/src/magic/threat.c new file mode 100644 index 00000000..cbb3d725 --- /dev/null +++ b/src/magic/threat.c @@ -0,0 +1,104 @@ +//! PSYQ=3.3 CC1=2.6.3 +#include "common.h" +#include "magic.h" +#include "threat_assets.h" +// THREAT.BIN: An emitter travels from the source to the target over sixteen updates, leaving a sprite trail. + +typedef struct { + s16 StartFrame, AnimationFrame; + SVECTOR Pos, Velocity; + s16 unk14, unk16, unk18, unk1A, TargetIndex, SourceIndex; +} ThreatEffect; +extern ThreatEffect g_BattleEffectSlots[]; +extern s32 D_801B8454; +extern void* D_801D8554; + +void MAGIC_Threat(s32 targetMask, s32 callbackArg) { MAGIC_ThreatSetup(targetMask, callbackArg); } + +static void func_threat_801B0020(void) { + ThreatEffect* effect; + s16 nextFrame; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + BattleSetBillboardMatrix(&effect->Pos, (s32)effect->unk14, 0); + D_801B8548.frameIndex = (u16)effect->AnimationFrame; + D_801D8554 = func_800D4D90(&D_801B8548, g_cDb->unk70, 0xC, D_801D8554); + if (D_80062D98 != 0) { + return; + } + nextFrame = (u16)effect->AnimationFrame + 1; + effect->AnimationFrame = nextFrame; + if (nextFrame >= D_801B8454) { + effect->StartFrame = -1; + } +} + +static void func_threat_801B00DC(void) { + ThreatEffect* effect; + ThreatEffect* particle; + s16 nextFrame; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + if (D_80062D98 != 0) { + return; + } + effect->Pos.vx = (u16)effect->Pos.vx + (u16)effect->Velocity.vx; + effect->Pos.vy = (u16)effect->Pos.vy + (u16)effect->Velocity.vy; + effect->Pos.vz = (u16)effect->Pos.vz + (u16)effect->Velocity.vz; + particle = &g_BattleEffectSlots[BattleEffectRegister(func_threat_801B0020)]; + particle->Pos = effect->Pos; + particle->unk14 = 0x2000; + nextFrame = (u16)effect->AnimationFrame + 1; + effect->AnimationFrame = nextFrame; + if (nextFrame >= 0x10) { + BattleSpawnFloatingIcon(effect->unk16, 0x32); + func_800D5774((u32)effect->unk16); + effect->StartFrame = -1; + } +} + +static void func_threat_801B01D8(s32 arg0, s32 arg1) { + SVECTOR sp10; + ThreatEffect* effect; + s32 randomValue; + s32 var_v0_2; + s32 var_v0_3; + + effect = &g_BattleEffectSlots[BattleEffectRegister(func_threat_801B00DC)]; + BattleGetPartPosition(arg1, g_BattleModels[arg1].boneIndices[8], &effect->Pos); + BattleGetPartPosition(arg0, g_BattleModels[arg0].boneIndices[0], &sp10); + randomValue = sp10.vx - effect->Pos.vx; + if (randomValue < 0) { + randomValue += 0xF; + } + effect->Velocity.vx = (s16)(randomValue >> 4); + var_v0_2 = sp10.vy - effect->Pos.vy; + if (var_v0_2 < 0) { + var_v0_2 += 0xF; + } + effect->Velocity.vy = (s16)(var_v0_2 >> 4); + var_v0_3 = sp10.vz - effect->Pos.vz; + if (var_v0_3 < 0) { + var_v0_3 += 0xF; + } + effect->Velocity.vz = (s16)(var_v0_3 >> 4); + effect->unk16 = (s16)arg0; +} + +static void func_threat_801B0304(void) { + ThreatEffect* effect; + + effect = &g_BattleEffectSlots[g_BattleEffectCursor]; + D_801D8554 = (effect->AnimationFrame << 0x10) + D_801B8554; + effect->AnimationFrame = (u16)effect->AnimationFrame ^ 1; + if (g_BattleEffectCount < 2) { + effect->StartFrame = -1; + } +} + +void MAGIC_ThreatSetup(s32 targetMask, s32 callbackArg) { + BattleSetLoadTimToVram(threat_texture_tim, 0, 0, 0); + BattleEffectRegister(func_threat_801B0304); + MagicAnimationRegister(targetMask, callbackArg, 4, func_threat_801B01D8); + BattleAkaoCommand(0x20, BattlePositionToStereoPan(&g_BattleModels[callbackArg].rootTrans), 0x31); +} diff --git a/src/magic/threat_assets.h b/src/magic/threat_assets.h new file mode 100644 index 00000000..c3b25b62 --- /dev/null +++ b/src/magic/threat_assets.h @@ -0,0 +1,22 @@ +#ifndef THREAT_ASSETS_H +#define THREAT_ASSETS_H +#include "magic_assets.h" + +typedef struct { + s32 unk0, frameCount; + MagicSpriteFrame1 frame0; + MagicSpriteFrame1 frame1; + MagicSpriteFrame1 frame2; + MagicSpriteFrame1 frame3; + MagicSpriteFrame1 frame4; + MagicSpriteFrame1 frame5; + MagicSpriteFrame1 frame6; + MagicSpriteFrame1 frame7; + MagicSpriteFrame1 frame8; + MagicSpriteFrame1 frame9; +} ThreatAnimation0; +extern ThreatAnimation0 g_ThreatAnimation0; +extern SpriteRenderDesc D_801B8548; +extern u8 D_801B8554[]; +extern u_long threat_texture_tim[]; +#endif diff --git a/src/magic/threat_data.c b/src/magic/threat_data.c new file mode 100644 index 00000000..a27fe95f --- /dev/null +++ b/src/magic/threat_data.c @@ -0,0 +1,16 @@ +#include "threat_assets.h" + +ThreatAnimation0 g_ThreatAnimation0 = { + 0x2023, + 10, + {0, 1, {{0x100, -32, -32, 0x0, 0x0, 0x2C, 0x7808, 0x40, 0x0, 0x40, 0x0}}}, + {0, 1, {{0x100, -32, -32, 0x40, 0x0, 0x2C, 0x7808, 0x40, 0x0, 0x40, 0x0}}}, + {0, 1, {{0x100, -32, -32, 0x80, 0x0, 0x2C, 0x7808, 0x40, 0x0, 0x40, 0x0}}}, + {0, 1, {{0x100, -32, -32, 0xC0, 0x0, 0x2C, 0x7808, 0x3F, 0x0, 0x40, 0x0}}}, + {0, 1, {{0x100, -32, -32, 0x0, 0x40, 0x2C, 0x7808, 0x40, 0x0, 0x40, 0x0}}}, + {0, 1, {{0x100, -32, -32, 0x40, 0x40, 0x2C, 0x7808, 0x40, 0x0, 0x40, 0x0}}}, + {0, 1, {{0x100, -32, -32, 0x80, 0x40, 0x2C, 0x7808, 0x40, 0x0, 0x40, 0x0}}}, + {0, 1, {{0x100, -32, -32, 0xC0, 0x40, 0x2C, 0x7808, 0x3F, 0x0, 0x40, 0x0}}}, + {0, 1, {{0x100, -32, -32, 0x0, 0x80, 0x2C, 0x7808, 0x40, 0x0, 0x40, 0x0}}}, + {0, 1, {{0x100, -32, -32, 0x40, 0x80, 0x2C, 0x7808, 0x40, 0x0, 0x40, 0x0}}}}; +SpriteRenderDesc D_801B8548 = {(SpriteAnim*)&g_ThreatAnimation0, {0x80, 0x80, 0x80, 0x2C}, 0, 0}; diff --git a/tools/builder/builder/objdiff.go b/tools/builder/builder/objdiff.go index 23967455..71476b2e 100644 --- a/tools/builder/builder/objdiff.go +++ b/tools/builder/builder/objdiff.go @@ -79,6 +79,7 @@ var metaCategories = map[string]string{ } var metaOverlays = map[string]metaOverlay{ + "main": {"main", "main", "Game engine"}, "batini": {"batini", "battle", "Battle init"}, @@ -113,6 +114,16 @@ var metaOverlays = map[string]metaOverlay{ "lv5deth": {"lv5deth", "magic", "LV.5 Death"}, "choco0": {"choco0", "magic", "choco0"}, "sennkoku": {"sennkoku", "magic", "Death Sentence / Roulette"}, + "gattai": {"gattai", "magic", "GATTAI"}, + "jinrai": {"jinrai", "magic", "JINRAI"}, + "smkball": {"smkball", "magic", "SMKBALL"}, + "threat": {"threat", "magic", "THREAT"}, + "tears": {"tears", "magic", "TEARS"}, + "echoes": {"echoes", "magic", "ECHOES"}, + "magend": {"magend", "magic", "MAGEND"}, + "hakai": {"hakai", "magic", "HAKAI"}, + "boost": {"boost", "magic", "BOOST"}, + "minimam": {"minimam", "magic", "Mini"}, } func makeObjdiffConfig(b BuildConfig) objdiffConfig { diff --git a/tools/ninja/gen.py b/tools/ninja/gen.py index 2a6513c0..af289c4c 100644 --- a/tools/ninja/gen.py +++ b/tools/ninja/gen.py @@ -338,6 +338,10 @@ def add_splat_config(ovl_name: str, file_name: str): name = str.format("{0:X}", offset) if kind == "data": add_s(cfg, f"data/{name}.data") + elif kind == "databin": + asset_file = f"{asset_path(cfg)}/{name}.databin.bin" + nw.build(rule="phony", outputs=[asset_file], implicit=[ld_path(cfg)]) + add_s(cfg, f"data/{name}", implicit=[asset_file]) elif kind == "rodata": add_s(cfg, f"data/{name}.rodata") elif kind == "bss":