Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 26 additions & 15 deletions config/sym_ovl_export.us.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1878,20 +1878,31 @@ func_800B00DC = 0x800b00dc;
func_800B01B0 = 0x800b01b0;
func_800B0E7C = 0x800b0e7c;
MAGIC_Barrier = 0x801b0000;
BarrierBaseScale = 0x801b0cc0;
BarrierPrimBuffer = 0x801b0cc4;
BarrierBufferPtr = 0x801d0cc4;
barrier_base_scale = 0x801b0cc0;
barrier_prim_buffer = 0x801b0cc4;
barrier_buffer_ptr = 0x801d0cc4;
MAGIC_Brizad = 0x801b037c;
BrizadRenderDesc = 0x801b1004;
BrizadPrimBuffer = 0x801b1014;
BrizadBufferPtr = 0x801d1014;
g_BrizadRenderDesc = 0x801b1004;
brizad_prim_buffer = 0x801b1014;
brizad_buffer_ptr = 0x801d1014;
MAGIC_Lv5Death = 0x801b0054;
Lv5DeathTexture = 0x801b05e0;
Lv5DeathSpriteModel = 0x801c0700;
Lv5DeathRingModel = 0x801c0868;
Lv5DeathSpriteDesc = 0x801c0e44;
Lv5DeathPrimBuffer0 = 0x801c0e50;
Lv5DeathPrimBuffer1 = 0x801cce50;
Lv5DeathBufferPtr = 0x801d8e50;
Lv5DeathFlipEffect = 0x801d8e54;
Lv5DeathTargetsRemaining = 0x801d8e58;
g_Lv5DeathTexture = 0x801b05e0;
g_Lv5DeathSpriteModel = 0x801c0700;
g_Lv5DeathRingModel = 0x801c0868;
g_Lv5DeathSpriteDesc = 0x801c0e44;
g_Lv5DeathPrimBuffer0 = 0x801c0e50;
g_Lv5DeathPrimBuffer1 = 0x801cce50;
g_Lv5DeathBufferPtr = 0x801d8e50;
g_Lv5DeathFlipEffect = 0x801d8e54;
g_Lv5DeathTargetsRemaining = 0x801d8e58;
MAGIC_Thunder = 0x801b0000;
g_ThunderRenderData0 = 0x801b073c;
g_ThunderRenderData1 = 0x801b07d0;
g_ThunderModel = 0x801b0898;
g_ThunderTexture = 0x801b0dac;
g_ThunderModelMatrix = 0x801c0e2c;
g_ThunderModelDesc = 0x801c0e4c;
g_ThunderRenderDesc0 = 0x801c0e5c;
g_ThunderRenderDesc1 = 0x801c0e68;
MAGIC_MBarrier = 0x801b0000;
g_MabariaRenderDesc = 0x801b0c90;
4 changes: 1 addition & 3 deletions config/symbols.magic-brizad.us.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@ BrizadAttachToTargetUnused = 0x801B028C;
BrizadAttachToTarget = 0x801B02D4;
BrizadDoubleBufferFlip = 0x801B031C;
MAGIC_Brizad = 0x801B037C;
BrizadRenderDesc = 0x801B1004; // size:0x10
BrizadPrimBuffer = 0x801B1014;
BrizadBufferPtr = 0x801D1014;
g_BrizadRenderDesc = 0x801B1004; // size:0x10
18 changes: 9 additions & 9 deletions config/symbols.magic-lv5deth.us.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Lv5DeathTexture = 0x801B05E0;
Lv5DeathSpriteModel = 0x801C0700;
Lv5DeathRingModel = 0x801C0868;
Lv5DeathSpriteDesc = 0x801C0E44; // size:0xC
Lv5DeathPrimBuffer0 = 0x801C0E50;
Lv5DeathPrimBuffer1 = 0x801CCE50;
Lv5DeathBufferPtr = 0x801D8E50;
Lv5DeathFlipEffect = 0x801D8E54;
Lv5DeathTargetsRemaining = 0x801D8E58;
g_Lv5DeathTexture = 0x801B05E0;
g_Lv5DeathSpriteModel = 0x801C0700;
g_Lv5DeathRingModel = 0x801C0868;
g_Lv5DeathSpriteDesc = 0x801C0E44; // size:0xC
g_Lv5DeathPrimBuffer0 = 0x801C0E50;
g_Lv5DeathPrimBuffer1 = 0x801CCE50;
g_Lv5DeathBufferPtr = 0x801D8E50;
g_Lv5DeathFlipEffect = 0x801D8E54;
g_Lv5DeathTargetsRemaining = 0x801D8E58;
9 changes: 9 additions & 0 deletions config/symbols.magic-mabaria.us.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
MAGIC_MBarrier = 0x801B0000;
MabariaRenderModel = 0x801B0020;
MabariaAnimationUpdate = 0x801B01C0;
MabariaAttachToTarget = 0x801B0378;
MabariaDoubleBufferFlip = 0x801B04DC;
MabariaMainSetup = 0x801B053C;
g_MabariaRenderDesc = 0x801B0C90; // size:0x10
g_MabariaPrimBuffer = 0x801B0CA8;
g_MabariaBufferPtr = 0x801D0CA8;
16 changes: 16 additions & 0 deletions config/symbols.magic-thunder.us.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
MAGIC_Thunder = 0x801B0000;
ThunderRenderModel = 0x801B0020;
ThunderSpawnBolt = 0x801B0350;
ThunderAttachToTarget = 0x801B05A4;
ThunderDoubleBufferFlip = 0x801B066C;
ThunderMainSetup = 0x801B06CC;
g_ThunderRenderData0 = 0x801B073C;
g_ThunderRenderData1 = 0x801B07D0;
g_ThunderModel = 0x801B0898;
g_ThunderTexture = 0x801B0DAC;
g_ThunderModelMatrix = 0x801C0E2C; // size:0x20
g_ThunderModelDesc = 0x801C0E4C; // size:0x10
g_ThunderRenderDesc0 = 0x801C0E5C; // size:0xC
g_ThunderRenderDesc1 = 0x801C0E68; // size:0xC
g_ThunderPrimBuffer = 0x801C0E78;
g_ThunderBufferPtr = 0x801E0E78;
26 changes: 26 additions & 0 deletions config/us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,29 @@ overlays:
segments:
- [0, c, lv5deth]
- [0x5e0, data, lv5deth]
# THUNDER.BIN -- "Bolt", the tier-1 lightning spell
- name: thunder
disk_path: disks/us/MAGIC/THUNDER.BIN
sha1: 5767aed5f73876075f01b3958a2e4738fa33b043
base_path: magic
vram_start: 0x801B0000
symbol_addrs_path:
- config/sym_export.us.txt
- config/symbols.magic-thunder.us.txt
- config/sym_export_battle.us.txt
segments:
- [0, c, thunder]
- [0x73c, data, thunder]
# MABARIA.BIN -- "MBarrier", the magic-damage half of Wall
- name: mabaria
disk_path: disks/us/MAGIC/MABARIA.BIN
sha1: 9169442d3e1702b7ad4425d95367f52334f84d60
base_path: magic
vram_start: 0x801B0000
symbol_addrs_path:
- config/sym_export.us.txt
- config/symbols.magic-mabaria.us.txt
- config/sym_export_battle.us.txt
segments:
- [0, c, mabaria]
- [0x5b4, data, mabaria]
57 changes: 46 additions & 11 deletions src/battle/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,14 +382,43 @@ typedef struct {

} Unk800BB75C; // size:0x38

// Flag word at offset 4, as func_800D29D4 tests it. Each mirror bit negates
// one rotation column, reversing polygon winding, so the cull test XORs their
// parity back out. Readings agree with Akari's q-gears_reverse
// (ffvii/DISC/BATTLE/BATTLE.X_model.cpp, "funcd29d4").
enum ModelRenderFlags {
MODEL_MIRROR_X = 0x1, // negates R11/R21/R31
MODEL_MIRROR_Y = 0x2, // negates R12/R22/R32
MODEL_MIRROR_Z = 0x4, // negates R13/R23/R33
MODEL_SEMI_TRANS = 0x8, // sets bit 1 of the GPU command byte
MODEL_NO_DEPTH_CUE = 0x10, // skips dpcs/dpct under MODEL_DEPTH_CUE
MODEL_NO_CULL = 0x20, // skips nclip; both faces emitted
MODEL_PRIM_TPAGE = 0x40, // tpage from primitive byte 7, not tpage
MODEL_DEPTH_CUE = 0x80, // offset 0xA feeds GTE IR0; see below
MODEL_PRIM_PACKET_BITS = 0x100, // primitive byte 7 << 18 ORed into colour
};

// Model descriptor read by func_800D29D4. Field readings agree with Akari's
// q-gears_reverse (ffvii/DISC/BATTLE/BATTLE.X_model.cpp, "funcd29d4").
typedef struct {
s32* unk0;
s32 unk4;
s16 unk8;
s16 unkA;
s16 unkC;
s16 unkE;
} Unk801B0C98;
/* 0x0 */ s32* model;
/* 0x4 */ s32 flags; // ModelRenderFlags
/* 0x8 */ u16 uvOffset; // added to every UV halfword; all callers pass 0
/* 0xA */ s16 color; // grey level ORed into the colour word; under
// MODEL_DEPTH_CUE it feeds GTE IR0 instead, so
// 0x1000 blends the model fully into SetFarColor
/* 0xC */ s16 tpage; // packet +0x16; Akari: "blending option"
/* 0xE */ s16 clut; // packet clut halfword
} ModelRenderDesc; // size:0x10

// Textured-quad descriptor read by func_800D4D90; ROM instances are packed
// 0xC apart. Akari: BATTLE.X_units_functions.cpp, "funcd4d90".
typedef struct {
/* 0x0 */ s32* frames; // per-frame quad blocks, count in each header
/* 0x4 */ CVECTOR color; // packet colour word; cd is 0x2C or 0x2E (POLY_FT4)
/* 0x8 */ u16 frameIndex; // blocks skipped; bit 15 enables clutBias
/* 0xA */ s16 clutBias; // added to each quad's clut halfword
} SpriteRenderDesc; // size:0xC

typedef struct {
s16 unk0;
Expand Down Expand Up @@ -478,13 +507,19 @@ extern u16 D_8016376A;

int BattleEffectRegister(void (*func)(void));
void func_800D2980(u_long* addr, s16 imgXY, s16 clutX, s16 clutY);
void* func_800D29D4(Unk801B0C98*, u_long**, int, void*);
void func_800D4368(SVECTOR* pos, s32 scale, s32 depthBias);
void* func_800D4D90(void* desc, u_long** ot, int otLen, void* prim);
void* func_800D29D4(ModelRenderDesc*, u_long**, int, void*);
// Build the model matrix for a battle effect: `scale` goes on the matrix
// diagonal, `pos` is transformed into view space to become the translation,
// and `depthBias` nudges it along that view vector (negative pulls it toward
// the camera). Leaves the result installed as the rot/trans matrix.
MATRIX* func_800D4368(SVECTOR* pos, s32 scale, s32 depthBias);
void* func_800D4D90(SpriteRenderDesc* desc, u_long** ot, int otLen, void* prim);
void func_800D5444(int, int, int, void (*func)(int));
// Returns a scale derived from the target's model size.
s32 func_800D55A4(s32 target);
void BattleCommandSend(s32 cmdId, ...);
int func_800D574C(int);
void BattleGetPartPosition(s32 arg0, s32 arg1, void* arg2);
// Runs `func` once per set bit in targetMask, frameStep frames apart.
void MagicAnimationRegister(s32 targetMask, s32 arg1, s32 frameStep, void (*func)(int));
s32 BattlePositionToStereoPan(SVECTOR* sv);
s32 BattleEntityGetStereoPan(s32 arg0);
Expand Down
16 changes: 8 additions & 8 deletions src/battle/battle1.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,9 +724,9 @@ static void func_800BAFF8(MATRIX* m, VECTOR* v) {

static void func_800BB030(s16 arg0) {
s32 i;
Unk801B0C98* unk;
ModelRenderDesc* unk;

unk = (Unk801B0C98*)0x1F800020;
unk = (ModelRenderDesc*)0x1F800020;
SetFarColor(D_801518E4[arg0].D_8015190C, D_801518E4[arg0].D_8015190D, D_801518E4[arg0].D_8015190E);
SetRotMatrix(&D_801518E4[arg0].m);
SetTransMatrix(&D_801518E4[arg0].m);
Expand All @@ -738,12 +738,12 @@ static void func_800BB030(s16 arg0) {
func_800BAF34(&D_800FA6D8[arg0].unk8[i]);
if (!D_800FA6D8[arg0].unk4[i])
continue;
unk->unk0 = D_800FA6D8[arg0].unk4[i];
unk->unk4 = D_800FA6D8[arg0].unk3E[i] | 0x180;
unk->unk8 = 0;
unk->unkA = D_801518E4[arg0].unk14[0];
unk->unkC = 0x20;
unk->unkE = D_801518E4[arg0].unk14[1];
unk->model = D_800FA6D8[arg0].unk4[i];
unk->flags = D_800FA6D8[arg0].unk3E[i] | MODEL_PRIM_PACKET_BITS | MODEL_DEPTH_CUE;
unk->uvOffset = 0;
unk->color = D_801518E4[arg0].unk14[0];
unk->tpage = 0x20;
unk->clut = D_801518E4[arg0].unk14[1];
if (D_801518E4[arg0].D_80151909 & 4) {
continue;
}
Expand Down
31 changes: 17 additions & 14 deletions src/battle/battle2.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,14 @@ static void func_800CE638(void) {
}
}

// Shell over a covered unit; MBarrier wins when both masks are set. Masks
// named by Akari's q-gears_reverse (ffvii/address_battle.txt): D_800FA69C is
// the magic barrier mask, D_80163608 the physical one.
static void func_800CE75C(void) {
if ((D_800FA69C >> D_80162978[D_8015169C].D_80162980) & 1) {
func_800D67E8(D_80162978[D_8015169C].D_80162980);
func_800D67E8(D_80162978[D_8015169C].D_80162980); // MBarrier
} else if ((D_80163608 >> D_80162978[D_8015169C].D_80162980) & 1) {
func_800D67BC(D_80162978[D_8015169C].D_80162980);
func_800D67BC(D_80162978[D_8015169C].D_80162980); // Barrier
}
}

Expand Down Expand Up @@ -1268,29 +1271,30 @@ INCLUDE_ASM("asm/us/battle/nonmatchings/battle2", func_800D61AC);

INCLUDE_ASM("asm/us/battle/nonmatchings/battle2", func_800D6260);

extern Unk801B0C98 D_800F14D0;
extern ModelRenderDesc D_800F14D0;

// Draw a model 4 times through func_800D29D4 (same request-struct pattern as
// barrier.c's D_801B0C98/D_801B0CB0), toggling the 0x1/0x2 flag bits between
// passes.
// passes. Those bits mirror on X and Y, so the four passes are the four
// quadrants of a symmetric model built from one quarter.
static void func_800D6394(s32* arg0, s16 arg1) {
D_800F14D0.unk0 = arg0;
D_800F14D0.unkA = arg1;
D_800F14D0.model = arg0;
D_800F14D0.color = arg1;
SetFarColor(0, 0, 0);
PushMatrix();
D_80163C74 = func_800D29D4(&D_800F14D0, g_cDb->unk70, 0xC, D_80163C74);
PopMatrix();
PushMatrix();
D_800F14D0.unk4 |= 1;
D_800F14D0.flags |= MODEL_MIRROR_X;
D_80163C74 = func_800D29D4(&D_800F14D0, g_cDb->unk70, 0xC, D_80163C74);
PopMatrix();
PushMatrix();
D_800F14D0.unk4 |= 2;
D_800F14D0.flags |= MODEL_MIRROR_Y;
D_80163C74 = func_800D29D4(&D_800F14D0, g_cDb->unk70, 0xC, D_80163C74);
PopMatrix();
D_800F14D0.unk4 &= ~1;
D_800F14D0.flags &= ~MODEL_MIRROR_X;
D_80163C74 = func_800D29D4(&D_800F14D0, g_cDb->unk70, 0xC, D_80163C74);
D_800F14D0.unk4 &= ~2;
D_800F14D0.flags &= ~MODEL_MIRROR_Y;
}

INCLUDE_ASM("asm/us/battle/nonmatchings/battle2", func_800D650C);
Expand All @@ -1302,20 +1306,19 @@ u8* const D_800A0DC8[] = {D_800F10EC, D_800F11E8, D_800F1304};
INCLUDE_ASM("asm/us/battle/nonmatchings/battle2", func_800D6734);

void func_800D6734(s32, s32);
extern s32 D_800F14D4;

static void func_800D67BC(s32 arg0) {
D_800F14D4 = 0x88;
D_800F14D0.flags = MODEL_DEPTH_CUE | MODEL_SEMI_TRANS; // Barrier
func_800D6734(arg0, 0);
}

static void func_800D67E8(s32 arg0) {
D_800F14D4 = 0xA8;
D_800F14D0.flags = MODEL_DEPTH_CUE | MODEL_NO_CULL | MODEL_SEMI_TRANS; // MBarrier
func_800D6734(arg0, 1);
}

void func_800D6814(s32 arg0) {
D_800F14D4 = 0x88;
D_800F14D0.flags = MODEL_DEPTH_CUE | MODEL_SEMI_TRANS;
func_800D6734(arg0, 2);
}

Expand Down
Loading