mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
fix(phase-30 S43): family_remap now carries TYPEDEFS (transitive, brace-aware) — the §146/§152 gap closed
- ROOT CAUSE PINNED, and my first hypothesis was WRONG (R14, corrected in the log): I wrote that a gate transform ate a `/*` opener and turned comment prose into code. REFUTED — cast_call_sites, sig_unify and reconcile_tu each run with the gate's real --src-file all preserve it. The real cause is family_remap's preamble backscan, whose accept-set (blank/extern/comment/typedef) HALTS AT THE FIRST `#define` and never reaches typedefs above the macro block. `_carry_macros` then re-attaches the macros, which HIDES the truncation — the unit looks complete and is not. "parse error before 'unsigned'" was that failure surfacing at the next token (the following `extern unsigned char` line): a misleading label, not a second defect. - FIX: _carry_typedefs() — additive, TRANSITIVE (a carried typedef may name another; measured: carrying Vec8_80182FD4 alone then failed on SVECTOR_8016E7C8), and BRACE-AWARE (a `;`-terminated scan stops INSIDE the struct at its first member line, emitting a truncated unclosed typedef). Emits dependency-first for C89. Only types the unit actually names and does not already carry. - VERIFIED: the 0x80182FD4 unit now carries its Prim_8016E7C8 block complete; the 0xECC family's remaps now carry the four typedefs I had prepended BY HAND before gating them — i.e. the fix automates the exact workaround that banked those three siblings. Residual isolated-compile failure on SVECTOR_8016E7C8 is a match_one artifact: that type lives in src/shared/engine_types.h, which the real TU includes — the typedef gap is fatal ONLY when the target TU lacks the type, which is why this class failed loudly for some families and silently succeeded for others.
This commit is contained in:
@@ -0,0 +1,459 @@
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2; } PF3_C6F4;
|
||||
typedef struct { s16 vx, vy; } DVEC2_C6F4;
|
||||
typedef struct { u8 *vtx; u32 f4; u32 xx, yy, zz; Prim126 *prim, *end; } Cell126;
|
||||
typedef struct { u32 w0, w1, w2; } Prim126;
|
||||
#define gte_ldv0(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_ldv3(r0, r1, r2) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 0( %1 );" \
|
||||
"lwc2 $3, 4( %1 );" \
|
||||
"lwc2 $4, 0( %2 );" \
|
||||
"lwc2 $5, 4( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) )
|
||||
#define gte_ldv3c(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 8( %0 );" \
|
||||
"lwc2 $3, 12( %0 );" \
|
||||
"lwc2 $4, 16( %0 );" \
|
||||
"lwc2 $5, 20( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_rtps() __asm__ volatile ("nop;nop;rtps")
|
||||
#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt")
|
||||
#define gte_nclip() __asm__ volatile ("nop;nop;nclip")
|
||||
#define gte_avsz3() __asm__ volatile ("nop;nop;avsz3")
|
||||
#define gte_avsz4() __asm__ volatile ("nop;nop;avsz4")
|
||||
#define gte_stsxy(r0) __asm__ volatile ( \
|
||||
"swc2 $14, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 0( %1 );" \
|
||||
"swc2 $14, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3c(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 4( %0 );" \
|
||||
"swc2 $14, 8( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3_f3(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 8( %0 );" \
|
||||
"swc2 $13, 12( %0 );" \
|
||||
"swc2 $14, 16( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $17, 0( %0 );" \
|
||||
"swc2 $18, 0( %1 );" \
|
||||
"swc2 $19, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \
|
||||
"swc2 $16, 0( %0 );" \
|
||||
"swc2 $17, 0( %1 );" \
|
||||
"swc2 $18, 0( %2 );" \
|
||||
"swc2 $19, 0( %3 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) \
|
||||
: "memory" )
|
||||
#define gte_stflg(r0) __asm__ volatile ( \
|
||||
"cfc2 $12, $31;" \
|
||||
"nop;" \
|
||||
"sw $12, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "$12", "memory" )
|
||||
#define gte_stopz(r0) __asm__ volatile ( \
|
||||
"swc2 $24, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
void func_8017C6F4(s32 arg0)
|
||||
{
|
||||
extern s32 func_800491EC(void);
|
||||
extern void func_800547D8(s32, MTX_C6F4 *);
|
||||
extern void func_80052E38(MTX_C6F4 *);
|
||||
extern void func_8017C014(void *, void *, s32);
|
||||
extern u8 D_8018FA10[];
|
||||
extern u8 *D_800A5E60;
|
||||
extern u8 D_800A6610[];
|
||||
extern short D_800B9A02;
|
||||
|
||||
s16 rect[4];
|
||||
DVEC2_C6F4 tmpxy[4];
|
||||
SVEC2_C6F4 box[8];
|
||||
SVEC2_C6F4 sxy[8];
|
||||
MTX_C6F4 mtx;
|
||||
struct { long flag, opz, sz0, sz1, sz2, sz3; } g;
|
||||
|
||||
s32 cx0, cx1, cy0, cy1, y, col;
|
||||
Cell126 **rowptr;
|
||||
Cell126 **p;
|
||||
Cell126 *cell;
|
||||
Prim126 *prim;
|
||||
Prim126 *end;
|
||||
u8 *pkt;
|
||||
u32 ot;
|
||||
u8 *vtx;
|
||||
u8 *va, *vb, *vc, *vd;
|
||||
u32 w, code;
|
||||
u32 wx, wy, wz;
|
||||
u32 xlo, xhi, ylo, yhi, zlo, zhi;
|
||||
s32 xa32, xb32, t32;
|
||||
s32 xmn1, xmx1, xmn2, xmx2;
|
||||
s32 ymn1, ymx1, ymn2, ymx2;
|
||||
s32 my, mny, mx, mn;
|
||||
|
||||
func_800491EC();
|
||||
func_800547D8(arg0 + 0x10, &mtx);
|
||||
func_80052E38(&mtx);
|
||||
func_8017C014(D_8018FA10, rect, *(s32 *)(arg0 + 0x60));
|
||||
|
||||
pkt = D_800A5E60;
|
||||
ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14];
|
||||
|
||||
cx0 = (rect[0] + 0x4000) / 512;
|
||||
cx1 = (rect[0] + rect[2] + 0x4000) / 512 + 2;
|
||||
cx0 = (cx0 < 0) ? 0 : ((cx0 > 0x3F) ? 0x3F : cx0);
|
||||
cx1 = (cx1 < 0) ? 0 : ((cx1 > 0x3F) ? 0x3F : cx1);
|
||||
cy0 = (rect[1] + 0x4000) / 512 - 1;
|
||||
cy1 = (rect[1] + rect[3] + 0x4000) / 512 + 2;
|
||||
cy0 = (cy0 < 0) ? 0 : ((cy0 > 0x3F) ? 0x3F : cy0);
|
||||
cy1 = (cy1 < 0) ? 0 : ((cy1 > 0x3F) ? 0x3F : cy1);
|
||||
|
||||
rowptr = (Cell126 **)(*(s32 *)(arg0 + 0xC)) + (cy0 * 64 + cx0);
|
||||
|
||||
for (y = cy0; y < cy1; y++, rowptr += 0x40) {
|
||||
for (col = cx0, p = rowptr; col < cx1; col++, p++) {
|
||||
cell = *p;
|
||||
if (cell == 0) continue;
|
||||
|
||||
wx = cell->xx;
|
||||
xlo = wx & 0xFFFF;
|
||||
xhi = wx >> 16;
|
||||
wy = cell->yy;
|
||||
ylo = wy & 0xFFFF;
|
||||
yhi = wy >> 16;
|
||||
wz = cell->zz;
|
||||
zlo = wz & 0xFFFF;
|
||||
zhi = wz >> 16;
|
||||
|
||||
box[0].vx = xlo; box[0].vy = ylo; box[0].vz = zlo;
|
||||
box[1].vx = xhi; box[1].vy = ylo; box[1].vz = zlo;
|
||||
box[2].vx = xlo; box[2].vy = ylo; box[2].vz = zhi;
|
||||
box[3].vx = xhi; box[3].vy = ylo; box[3].vz = zhi;
|
||||
box[4].vx = xlo; box[4].vy = yhi; box[4].vz = zlo;
|
||||
box[5].vx = xhi; box[5].vy = yhi; box[5].vz = zlo;
|
||||
box[6].vx = xlo; box[6].vy = yhi; box[6].vz = zhi;
|
||||
box[7].vx = xhi; box[7].vy = yhi; box[7].vz = zhi;
|
||||
|
||||
gte_ldv3c(&box[0]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]);
|
||||
gte_ldv0(&box[3]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[3]);
|
||||
gte_ldv3c(&box[4]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]);
|
||||
gte_ldv0(&box[7]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[7]);
|
||||
|
||||
xa32 = sxy[0].vx;
|
||||
xb32 = sxy[1].vx;
|
||||
if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; }
|
||||
t32 = sxy[2].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
t32 = sxy[3].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
xa32 = sxy[4].vx;
|
||||
xb32 = sxy[5].vx;
|
||||
if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; }
|
||||
t32 = sxy[6].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
t32 = sxy[7].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
mn = xmn1;
|
||||
if (xmn2 < mn) mn = xmn2;
|
||||
mx = xmx1;
|
||||
if (mx < xmx2) mx = xmx2;
|
||||
if (mx < -0xA0) continue;
|
||||
if (!(mn < 0xA1)) continue;
|
||||
|
||||
xa32 = sxy[0].vy;
|
||||
xb32 = sxy[1].vy;
|
||||
if (xb32 < xa32) { ymx1 = xa32; ymn1 = xb32; } else { ymn1 = xa32; ymx1 = xb32; }
|
||||
t32 = sxy[2].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
t32 = sxy[3].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
xa32 = sxy[4].vy;
|
||||
xb32 = sxy[5].vy;
|
||||
if (xb32 < xa32) { ymx2 = xa32; ymn2 = xb32; } else { ymn2 = xa32; ymx2 = xb32; }
|
||||
t32 = sxy[6].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
t32 = sxy[7].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
mny = ymn1;
|
||||
if (ymn2 < mny) mny = ymn2;
|
||||
my = ymx1;
|
||||
if (my < ymx2) my = ymx2;
|
||||
if (my < -0x78) continue;
|
||||
if (!(mny < 0x79)) continue;
|
||||
|
||||
prim = cell->prim;
|
||||
end = cell->end;
|
||||
vtx = cell->vtx;
|
||||
while (prim < end) {
|
||||
w = prim->w1;
|
||||
va = vtx + (w & 0xFFFF);
|
||||
vb = vtx + (w >> 16);
|
||||
w = prim->w2;
|
||||
vc = vtx + (w & 0xFFFF);
|
||||
w = w >> 16;
|
||||
gte_ldv3(va, vb, vc);
|
||||
gte_rtpt();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_nclip();
|
||||
code = w & 0xF;
|
||||
vd = vtx + ((w & 0xFFF0) >> 1);
|
||||
gte_stopz(&g.opz);
|
||||
if (g.opz > 0) {
|
||||
switch (code) {
|
||||
case 4:
|
||||
case 5:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (((PFT3_C6F4 *)pkt)->x0 > ((PFT3_C6F4 *)pkt)->x1) {
|
||||
mx = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mn = ((PFT3_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mx = ((PFT3_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->x2 > mx) mx = ((PFT3_C6F4 *)pkt)->x2;
|
||||
else if (((PFT3_C6F4 *)pkt)->x2 < mn) mn = ((PFT3_C6F4 *)pkt)->x2;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PFT3_C6F4 *)pkt)->y0 > ((PFT3_C6F4 *)pkt)->y1) {
|
||||
my = ((PFT3_C6F4 *)pkt)->y0;
|
||||
mny = ((PFT3_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PFT3_C6F4 *)pkt)->y0;
|
||||
my = ((PFT3_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->y2 > my) my = ((PFT3_C6F4 *)pkt)->y2;
|
||||
else if (((PFT3_C6F4 *)pkt)->y2 < mny) mny = ((PFT3_C6F4 *)pkt)->y2;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 4) g.opz = za + 0x200;
|
||||
((PF3_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x4000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x14;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
gte_avsz3();
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 6) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT3_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT3_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT3_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
((PFT3_C6F4 *)pkt)->uv2 = tp[3];
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x7000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x20;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
if (((PF4_C6F4 *)pkt)->x0 > ((PF4_C6F4 *)pkt)->x1) {
|
||||
mx = ((PF4_C6F4 *)pkt)->x0;
|
||||
mn = ((PF4_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PF4_C6F4 *)pkt)->x0;
|
||||
mx = ((PF4_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->x2 > mx) mx = ((PF4_C6F4 *)pkt)->x2;
|
||||
else if (((PF4_C6F4 *)pkt)->x2 < mn) mn = ((PF4_C6F4 *)pkt)->x2;
|
||||
if (((PF4_C6F4 *)pkt)->y0 > ((PF4_C6F4 *)pkt)->y1) {
|
||||
my = ((PF4_C6F4 *)pkt)->y0;
|
||||
mny = ((PF4_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PF4_C6F4 *)pkt)->y0;
|
||||
my = ((PF4_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->y2 > my) my = ((PF4_C6F4 *)pkt)->y2;
|
||||
else if (((PF4_C6F4 *)pkt)->y2 < mny) mny = ((PF4_C6F4 *)pkt)->y2;
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
gte_stsxy((long *)&((PF4_C6F4 *)pkt)->x3);
|
||||
if (((PF4_C6F4 *)pkt)->x3 < mn) mn = ((PF4_C6F4 *)pkt)->x3;
|
||||
else if (mx < ((PF4_C6F4 *)pkt)->x3) mx = ((PF4_C6F4 *)pkt)->x3;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PF4_C6F4 *)pkt)->y3 < mny) mny = ((PF4_C6F4 *)pkt)->y3;
|
||||
else if (my < ((PF4_C6F4 *)pkt)->y3) my = ((PF4_C6F4 *)pkt)->y3;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 0) g.opz = za + 0x200;
|
||||
((PF4_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x5000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x18;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsxy(&tmpxy[3]);
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (tmpxy[3].vx > mx) mx = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mn) mn = tmpxy[3].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (tmpxy[3].vx > my) my = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mny) mny = tmpxy[3].vx;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
u32 uvw;
|
||||
gte_avsz4();
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 2) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x3 = *(u32 *)&tmpxy[3];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT4_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT4_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT4_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
uvw = tp[3];
|
||||
((PFT4_C6F4 *)pkt)->uv2 = uvw;
|
||||
((PFT4_C6F4 *)pkt)->uv3 = uvw >> 16;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x9000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x28;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
prim++;
|
||||
}
|
||||
}
|
||||
}
|
||||
D_800A5E60 = pkt;
|
||||
}
|
||||
@@ -0,0 +1,459 @@
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2; } PF3_C6F4;
|
||||
typedef struct { s16 vx, vy; } DVEC2_C6F4;
|
||||
typedef struct { u8 *vtx; u32 f4; u32 xx, yy, zz; Prim126 *prim, *end; } Cell126;
|
||||
typedef struct { u32 w0, w1, w2; } Prim126;
|
||||
#define gte_ldv0(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_ldv3(r0, r1, r2) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 0( %1 );" \
|
||||
"lwc2 $3, 4( %1 );" \
|
||||
"lwc2 $4, 0( %2 );" \
|
||||
"lwc2 $5, 4( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) )
|
||||
#define gte_ldv3c(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 8( %0 );" \
|
||||
"lwc2 $3, 12( %0 );" \
|
||||
"lwc2 $4, 16( %0 );" \
|
||||
"lwc2 $5, 20( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_rtps() __asm__ volatile ("nop;nop;rtps")
|
||||
#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt")
|
||||
#define gte_nclip() __asm__ volatile ("nop;nop;nclip")
|
||||
#define gte_avsz3() __asm__ volatile ("nop;nop;avsz3")
|
||||
#define gte_avsz4() __asm__ volatile ("nop;nop;avsz4")
|
||||
#define gte_stsxy(r0) __asm__ volatile ( \
|
||||
"swc2 $14, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 0( %1 );" \
|
||||
"swc2 $14, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3c(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 4( %0 );" \
|
||||
"swc2 $14, 8( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3_f3(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 8( %0 );" \
|
||||
"swc2 $13, 12( %0 );" \
|
||||
"swc2 $14, 16( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $17, 0( %0 );" \
|
||||
"swc2 $18, 0( %1 );" \
|
||||
"swc2 $19, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \
|
||||
"swc2 $16, 0( %0 );" \
|
||||
"swc2 $17, 0( %1 );" \
|
||||
"swc2 $18, 0( %2 );" \
|
||||
"swc2 $19, 0( %3 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) \
|
||||
: "memory" )
|
||||
#define gte_stflg(r0) __asm__ volatile ( \
|
||||
"cfc2 $12, $31;" \
|
||||
"nop;" \
|
||||
"sw $12, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "$12", "memory" )
|
||||
#define gte_stopz(r0) __asm__ volatile ( \
|
||||
"swc2 $24, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
void func_8017C6F4(s32 arg0)
|
||||
{
|
||||
extern s32 func_800491EC(void);
|
||||
extern void func_800547D8(s32, MTX_C6F4 *);
|
||||
extern void func_80052E38(MTX_C6F4 *);
|
||||
extern void func_8017C014(void *, void *, s32);
|
||||
extern u8 D_8018F9C0[];
|
||||
extern u8 *D_800A5E60;
|
||||
extern u8 D_800A6610[];
|
||||
extern short D_800B9A02;
|
||||
|
||||
s16 rect[4];
|
||||
DVEC2_C6F4 tmpxy[4];
|
||||
SVEC2_C6F4 box[8];
|
||||
SVEC2_C6F4 sxy[8];
|
||||
MTX_C6F4 mtx;
|
||||
struct { long flag, opz, sz0, sz1, sz2, sz3; } g;
|
||||
|
||||
s32 cx0, cx1, cy0, cy1, y, col;
|
||||
Cell126 **rowptr;
|
||||
Cell126 **p;
|
||||
Cell126 *cell;
|
||||
Prim126 *prim;
|
||||
Prim126 *end;
|
||||
u8 *pkt;
|
||||
u32 ot;
|
||||
u8 *vtx;
|
||||
u8 *va, *vb, *vc, *vd;
|
||||
u32 w, code;
|
||||
u32 wx, wy, wz;
|
||||
u32 xlo, xhi, ylo, yhi, zlo, zhi;
|
||||
s32 xa32, xb32, t32;
|
||||
s32 xmn1, xmx1, xmn2, xmx2;
|
||||
s32 ymn1, ymx1, ymn2, ymx2;
|
||||
s32 my, mny, mx, mn;
|
||||
|
||||
func_800491EC();
|
||||
func_800547D8(arg0 + 0x10, &mtx);
|
||||
func_80052E38(&mtx);
|
||||
func_8017C014(D_8018F9C0, rect, *(s32 *)(arg0 + 0x60));
|
||||
|
||||
pkt = D_800A5E60;
|
||||
ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14];
|
||||
|
||||
cx0 = (rect[0] + 0x4000) / 512;
|
||||
cx1 = (rect[0] + rect[2] + 0x4000) / 512 + 2;
|
||||
cx0 = (cx0 < 0) ? 0 : ((cx0 > 0x3F) ? 0x3F : cx0);
|
||||
cx1 = (cx1 < 0) ? 0 : ((cx1 > 0x3F) ? 0x3F : cx1);
|
||||
cy0 = (rect[1] + 0x4000) / 512 - 1;
|
||||
cy1 = (rect[1] + rect[3] + 0x4000) / 512 + 2;
|
||||
cy0 = (cy0 < 0) ? 0 : ((cy0 > 0x3F) ? 0x3F : cy0);
|
||||
cy1 = (cy1 < 0) ? 0 : ((cy1 > 0x3F) ? 0x3F : cy1);
|
||||
|
||||
rowptr = (Cell126 **)(*(s32 *)(arg0 + 0xC)) + (cy0 * 64 + cx0);
|
||||
|
||||
for (y = cy0; y < cy1; y++, rowptr += 0x40) {
|
||||
for (col = cx0, p = rowptr; col < cx1; col++, p++) {
|
||||
cell = *p;
|
||||
if (cell == 0) continue;
|
||||
|
||||
wx = cell->xx;
|
||||
xlo = wx & 0xFFFF;
|
||||
xhi = wx >> 16;
|
||||
wy = cell->yy;
|
||||
ylo = wy & 0xFFFF;
|
||||
yhi = wy >> 16;
|
||||
wz = cell->zz;
|
||||
zlo = wz & 0xFFFF;
|
||||
zhi = wz >> 16;
|
||||
|
||||
box[0].vx = xlo; box[0].vy = ylo; box[0].vz = zlo;
|
||||
box[1].vx = xhi; box[1].vy = ylo; box[1].vz = zlo;
|
||||
box[2].vx = xlo; box[2].vy = ylo; box[2].vz = zhi;
|
||||
box[3].vx = xhi; box[3].vy = ylo; box[3].vz = zhi;
|
||||
box[4].vx = xlo; box[4].vy = yhi; box[4].vz = zlo;
|
||||
box[5].vx = xhi; box[5].vy = yhi; box[5].vz = zlo;
|
||||
box[6].vx = xlo; box[6].vy = yhi; box[6].vz = zhi;
|
||||
box[7].vx = xhi; box[7].vy = yhi; box[7].vz = zhi;
|
||||
|
||||
gte_ldv3c(&box[0]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]);
|
||||
gte_ldv0(&box[3]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[3]);
|
||||
gte_ldv3c(&box[4]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]);
|
||||
gte_ldv0(&box[7]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[7]);
|
||||
|
||||
xa32 = sxy[0].vx;
|
||||
xb32 = sxy[1].vx;
|
||||
if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; }
|
||||
t32 = sxy[2].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
t32 = sxy[3].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
xa32 = sxy[4].vx;
|
||||
xb32 = sxy[5].vx;
|
||||
if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; }
|
||||
t32 = sxy[6].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
t32 = sxy[7].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
mn = xmn1;
|
||||
if (xmn2 < mn) mn = xmn2;
|
||||
mx = xmx1;
|
||||
if (mx < xmx2) mx = xmx2;
|
||||
if (mx < -0xA0) continue;
|
||||
if (!(mn < 0xA1)) continue;
|
||||
|
||||
xa32 = sxy[0].vy;
|
||||
xb32 = sxy[1].vy;
|
||||
if (xb32 < xa32) { ymx1 = xa32; ymn1 = xb32; } else { ymn1 = xa32; ymx1 = xb32; }
|
||||
t32 = sxy[2].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
t32 = sxy[3].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
xa32 = sxy[4].vy;
|
||||
xb32 = sxy[5].vy;
|
||||
if (xb32 < xa32) { ymx2 = xa32; ymn2 = xb32; } else { ymn2 = xa32; ymx2 = xb32; }
|
||||
t32 = sxy[6].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
t32 = sxy[7].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
mny = ymn1;
|
||||
if (ymn2 < mny) mny = ymn2;
|
||||
my = ymx1;
|
||||
if (my < ymx2) my = ymx2;
|
||||
if (my < -0x78) continue;
|
||||
if (!(mny < 0x79)) continue;
|
||||
|
||||
prim = cell->prim;
|
||||
end = cell->end;
|
||||
vtx = cell->vtx;
|
||||
while (prim < end) {
|
||||
w = prim->w1;
|
||||
va = vtx + (w & 0xFFFF);
|
||||
vb = vtx + (w >> 16);
|
||||
w = prim->w2;
|
||||
vc = vtx + (w & 0xFFFF);
|
||||
w = w >> 16;
|
||||
gte_ldv3(va, vb, vc);
|
||||
gte_rtpt();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_nclip();
|
||||
code = w & 0xF;
|
||||
vd = vtx + ((w & 0xFFF0) >> 1);
|
||||
gte_stopz(&g.opz);
|
||||
if (g.opz > 0) {
|
||||
switch (code) {
|
||||
case 4:
|
||||
case 5:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (((PFT3_C6F4 *)pkt)->x0 > ((PFT3_C6F4 *)pkt)->x1) {
|
||||
mx = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mn = ((PFT3_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mx = ((PFT3_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->x2 > mx) mx = ((PFT3_C6F4 *)pkt)->x2;
|
||||
else if (((PFT3_C6F4 *)pkt)->x2 < mn) mn = ((PFT3_C6F4 *)pkt)->x2;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PFT3_C6F4 *)pkt)->y0 > ((PFT3_C6F4 *)pkt)->y1) {
|
||||
my = ((PFT3_C6F4 *)pkt)->y0;
|
||||
mny = ((PFT3_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PFT3_C6F4 *)pkt)->y0;
|
||||
my = ((PFT3_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->y2 > my) my = ((PFT3_C6F4 *)pkt)->y2;
|
||||
else if (((PFT3_C6F4 *)pkt)->y2 < mny) mny = ((PFT3_C6F4 *)pkt)->y2;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 4) g.opz = za + 0x200;
|
||||
((PF3_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x4000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x14;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
gte_avsz3();
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 6) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT3_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT3_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT3_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
((PFT3_C6F4 *)pkt)->uv2 = tp[3];
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x7000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x20;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
if (((PF4_C6F4 *)pkt)->x0 > ((PF4_C6F4 *)pkt)->x1) {
|
||||
mx = ((PF4_C6F4 *)pkt)->x0;
|
||||
mn = ((PF4_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PF4_C6F4 *)pkt)->x0;
|
||||
mx = ((PF4_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->x2 > mx) mx = ((PF4_C6F4 *)pkt)->x2;
|
||||
else if (((PF4_C6F4 *)pkt)->x2 < mn) mn = ((PF4_C6F4 *)pkt)->x2;
|
||||
if (((PF4_C6F4 *)pkt)->y0 > ((PF4_C6F4 *)pkt)->y1) {
|
||||
my = ((PF4_C6F4 *)pkt)->y0;
|
||||
mny = ((PF4_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PF4_C6F4 *)pkt)->y0;
|
||||
my = ((PF4_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->y2 > my) my = ((PF4_C6F4 *)pkt)->y2;
|
||||
else if (((PF4_C6F4 *)pkt)->y2 < mny) mny = ((PF4_C6F4 *)pkt)->y2;
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
gte_stsxy((long *)&((PF4_C6F4 *)pkt)->x3);
|
||||
if (((PF4_C6F4 *)pkt)->x3 < mn) mn = ((PF4_C6F4 *)pkt)->x3;
|
||||
else if (mx < ((PF4_C6F4 *)pkt)->x3) mx = ((PF4_C6F4 *)pkt)->x3;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PF4_C6F4 *)pkt)->y3 < mny) mny = ((PF4_C6F4 *)pkt)->y3;
|
||||
else if (my < ((PF4_C6F4 *)pkt)->y3) my = ((PF4_C6F4 *)pkt)->y3;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 0) g.opz = za + 0x200;
|
||||
((PF4_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x5000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x18;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsxy(&tmpxy[3]);
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (tmpxy[3].vx > mx) mx = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mn) mn = tmpxy[3].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (tmpxy[3].vx > my) my = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mny) mny = tmpxy[3].vx;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
u32 uvw;
|
||||
gte_avsz4();
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 2) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x3 = *(u32 *)&tmpxy[3];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT4_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT4_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT4_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
uvw = tp[3];
|
||||
((PFT4_C6F4 *)pkt)->uv2 = uvw;
|
||||
((PFT4_C6F4 *)pkt)->uv3 = uvw >> 16;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x9000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x28;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
prim++;
|
||||
}
|
||||
}
|
||||
}
|
||||
D_800A5E60 = pkt;
|
||||
}
|
||||
@@ -0,0 +1,459 @@
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2; } PF3_C6F4;
|
||||
typedef struct { s16 vx, vy; } DVEC2_C6F4;
|
||||
typedef struct { u8 *vtx; u32 f4; u32 xx, yy, zz; Prim126 *prim, *end; } Cell126;
|
||||
typedef struct { u32 w0, w1, w2; } Prim126;
|
||||
#define gte_ldv0(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_ldv3(r0, r1, r2) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 0( %1 );" \
|
||||
"lwc2 $3, 4( %1 );" \
|
||||
"lwc2 $4, 0( %2 );" \
|
||||
"lwc2 $5, 4( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) )
|
||||
#define gte_ldv3c(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 8( %0 );" \
|
||||
"lwc2 $3, 12( %0 );" \
|
||||
"lwc2 $4, 16( %0 );" \
|
||||
"lwc2 $5, 20( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_rtps() __asm__ volatile ("nop;nop;rtps")
|
||||
#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt")
|
||||
#define gte_nclip() __asm__ volatile ("nop;nop;nclip")
|
||||
#define gte_avsz3() __asm__ volatile ("nop;nop;avsz3")
|
||||
#define gte_avsz4() __asm__ volatile ("nop;nop;avsz4")
|
||||
#define gte_stsxy(r0) __asm__ volatile ( \
|
||||
"swc2 $14, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 0( %1 );" \
|
||||
"swc2 $14, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3c(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 4( %0 );" \
|
||||
"swc2 $14, 8( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3_f3(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 8( %0 );" \
|
||||
"swc2 $13, 12( %0 );" \
|
||||
"swc2 $14, 16( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $17, 0( %0 );" \
|
||||
"swc2 $18, 0( %1 );" \
|
||||
"swc2 $19, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \
|
||||
"swc2 $16, 0( %0 );" \
|
||||
"swc2 $17, 0( %1 );" \
|
||||
"swc2 $18, 0( %2 );" \
|
||||
"swc2 $19, 0( %3 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) \
|
||||
: "memory" )
|
||||
#define gte_stflg(r0) __asm__ volatile ( \
|
||||
"cfc2 $12, $31;" \
|
||||
"nop;" \
|
||||
"sw $12, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "$12", "memory" )
|
||||
#define gte_stopz(r0) __asm__ volatile ( \
|
||||
"swc2 $24, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
void func_8017C6F4(s32 arg0)
|
||||
{
|
||||
extern s32 func_800491EC(void);
|
||||
extern void func_800547D8(s32, MTX_C6F4 *);
|
||||
extern void func_80052E38(MTX_C6F4 *);
|
||||
extern void func_8017C014(void *, void *, s32);
|
||||
extern u8 D_8018F9C0[];
|
||||
extern u8 *D_800A5E60;
|
||||
extern u8 D_800A6610[];
|
||||
extern short D_800B9A02;
|
||||
|
||||
s16 rect[4];
|
||||
DVEC2_C6F4 tmpxy[4];
|
||||
SVEC2_C6F4 box[8];
|
||||
SVEC2_C6F4 sxy[8];
|
||||
MTX_C6F4 mtx;
|
||||
struct { long flag, opz, sz0, sz1, sz2, sz3; } g;
|
||||
|
||||
s32 cx0, cx1, cy0, cy1, y, col;
|
||||
Cell126 **rowptr;
|
||||
Cell126 **p;
|
||||
Cell126 *cell;
|
||||
Prim126 *prim;
|
||||
Prim126 *end;
|
||||
u8 *pkt;
|
||||
u32 ot;
|
||||
u8 *vtx;
|
||||
u8 *va, *vb, *vc, *vd;
|
||||
u32 w, code;
|
||||
u32 wx, wy, wz;
|
||||
u32 xlo, xhi, ylo, yhi, zlo, zhi;
|
||||
s32 xa32, xb32, t32;
|
||||
s32 xmn1, xmx1, xmn2, xmx2;
|
||||
s32 ymn1, ymx1, ymn2, ymx2;
|
||||
s32 my, mny, mx, mn;
|
||||
|
||||
func_800491EC();
|
||||
func_800547D8(arg0 + 0x10, &mtx);
|
||||
func_80052E38(&mtx);
|
||||
func_8017C014(D_8018F9C0, rect, *(s32 *)(arg0 + 0x60));
|
||||
|
||||
pkt = D_800A5E60;
|
||||
ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14];
|
||||
|
||||
cx0 = (rect[0] + 0x4000) / 512;
|
||||
cx1 = (rect[0] + rect[2] + 0x4000) / 512 + 2;
|
||||
cx0 = (cx0 < 0) ? 0 : ((cx0 > 0x3F) ? 0x3F : cx0);
|
||||
cx1 = (cx1 < 0) ? 0 : ((cx1 > 0x3F) ? 0x3F : cx1);
|
||||
cy0 = (rect[1] + 0x4000) / 512 - 1;
|
||||
cy1 = (rect[1] + rect[3] + 0x4000) / 512 + 2;
|
||||
cy0 = (cy0 < 0) ? 0 : ((cy0 > 0x3F) ? 0x3F : cy0);
|
||||
cy1 = (cy1 < 0) ? 0 : ((cy1 > 0x3F) ? 0x3F : cy1);
|
||||
|
||||
rowptr = (Cell126 **)(*(s32 *)(arg0 + 0xC)) + (cy0 * 64 + cx0);
|
||||
|
||||
for (y = cy0; y < cy1; y++, rowptr += 0x40) {
|
||||
for (col = cx0, p = rowptr; col < cx1; col++, p++) {
|
||||
cell = *p;
|
||||
if (cell == 0) continue;
|
||||
|
||||
wx = cell->xx;
|
||||
xlo = wx & 0xFFFF;
|
||||
xhi = wx >> 16;
|
||||
wy = cell->yy;
|
||||
ylo = wy & 0xFFFF;
|
||||
yhi = wy >> 16;
|
||||
wz = cell->zz;
|
||||
zlo = wz & 0xFFFF;
|
||||
zhi = wz >> 16;
|
||||
|
||||
box[0].vx = xlo; box[0].vy = ylo; box[0].vz = zlo;
|
||||
box[1].vx = xhi; box[1].vy = ylo; box[1].vz = zlo;
|
||||
box[2].vx = xlo; box[2].vy = ylo; box[2].vz = zhi;
|
||||
box[3].vx = xhi; box[3].vy = ylo; box[3].vz = zhi;
|
||||
box[4].vx = xlo; box[4].vy = yhi; box[4].vz = zlo;
|
||||
box[5].vx = xhi; box[5].vy = yhi; box[5].vz = zlo;
|
||||
box[6].vx = xlo; box[6].vy = yhi; box[6].vz = zhi;
|
||||
box[7].vx = xhi; box[7].vy = yhi; box[7].vz = zhi;
|
||||
|
||||
gte_ldv3c(&box[0]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]);
|
||||
gte_ldv0(&box[3]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[3]);
|
||||
gte_ldv3c(&box[4]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]);
|
||||
gte_ldv0(&box[7]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[7]);
|
||||
|
||||
xa32 = sxy[0].vx;
|
||||
xb32 = sxy[1].vx;
|
||||
if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; }
|
||||
t32 = sxy[2].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
t32 = sxy[3].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
xa32 = sxy[4].vx;
|
||||
xb32 = sxy[5].vx;
|
||||
if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; }
|
||||
t32 = sxy[6].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
t32 = sxy[7].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
mn = xmn1;
|
||||
if (xmn2 < mn) mn = xmn2;
|
||||
mx = xmx1;
|
||||
if (mx < xmx2) mx = xmx2;
|
||||
if (mx < -0xA0) continue;
|
||||
if (!(mn < 0xA1)) continue;
|
||||
|
||||
xa32 = sxy[0].vy;
|
||||
xb32 = sxy[1].vy;
|
||||
if (xb32 < xa32) { ymx1 = xa32; ymn1 = xb32; } else { ymn1 = xa32; ymx1 = xb32; }
|
||||
t32 = sxy[2].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
t32 = sxy[3].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
xa32 = sxy[4].vy;
|
||||
xb32 = sxy[5].vy;
|
||||
if (xb32 < xa32) { ymx2 = xa32; ymn2 = xb32; } else { ymn2 = xa32; ymx2 = xb32; }
|
||||
t32 = sxy[6].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
t32 = sxy[7].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
mny = ymn1;
|
||||
if (ymn2 < mny) mny = ymn2;
|
||||
my = ymx1;
|
||||
if (my < ymx2) my = ymx2;
|
||||
if (my < -0x78) continue;
|
||||
if (!(mny < 0x79)) continue;
|
||||
|
||||
prim = cell->prim;
|
||||
end = cell->end;
|
||||
vtx = cell->vtx;
|
||||
while (prim < end) {
|
||||
w = prim->w1;
|
||||
va = vtx + (w & 0xFFFF);
|
||||
vb = vtx + (w >> 16);
|
||||
w = prim->w2;
|
||||
vc = vtx + (w & 0xFFFF);
|
||||
w = w >> 16;
|
||||
gte_ldv3(va, vb, vc);
|
||||
gte_rtpt();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_nclip();
|
||||
code = w & 0xF;
|
||||
vd = vtx + ((w & 0xFFF0) >> 1);
|
||||
gte_stopz(&g.opz);
|
||||
if (g.opz > 0) {
|
||||
switch (code) {
|
||||
case 4:
|
||||
case 5:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (((PFT3_C6F4 *)pkt)->x0 > ((PFT3_C6F4 *)pkt)->x1) {
|
||||
mx = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mn = ((PFT3_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mx = ((PFT3_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->x2 > mx) mx = ((PFT3_C6F4 *)pkt)->x2;
|
||||
else if (((PFT3_C6F4 *)pkt)->x2 < mn) mn = ((PFT3_C6F4 *)pkt)->x2;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PFT3_C6F4 *)pkt)->y0 > ((PFT3_C6F4 *)pkt)->y1) {
|
||||
my = ((PFT3_C6F4 *)pkt)->y0;
|
||||
mny = ((PFT3_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PFT3_C6F4 *)pkt)->y0;
|
||||
my = ((PFT3_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->y2 > my) my = ((PFT3_C6F4 *)pkt)->y2;
|
||||
else if (((PFT3_C6F4 *)pkt)->y2 < mny) mny = ((PFT3_C6F4 *)pkt)->y2;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 4) g.opz = za + 0x200;
|
||||
((PF3_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x4000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x14;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
gte_avsz3();
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 6) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT3_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT3_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT3_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
((PFT3_C6F4 *)pkt)->uv2 = tp[3];
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x7000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x20;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
if (((PF4_C6F4 *)pkt)->x0 > ((PF4_C6F4 *)pkt)->x1) {
|
||||
mx = ((PF4_C6F4 *)pkt)->x0;
|
||||
mn = ((PF4_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PF4_C6F4 *)pkt)->x0;
|
||||
mx = ((PF4_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->x2 > mx) mx = ((PF4_C6F4 *)pkt)->x2;
|
||||
else if (((PF4_C6F4 *)pkt)->x2 < mn) mn = ((PF4_C6F4 *)pkt)->x2;
|
||||
if (((PF4_C6F4 *)pkt)->y0 > ((PF4_C6F4 *)pkt)->y1) {
|
||||
my = ((PF4_C6F4 *)pkt)->y0;
|
||||
mny = ((PF4_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PF4_C6F4 *)pkt)->y0;
|
||||
my = ((PF4_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->y2 > my) my = ((PF4_C6F4 *)pkt)->y2;
|
||||
else if (((PF4_C6F4 *)pkt)->y2 < mny) mny = ((PF4_C6F4 *)pkt)->y2;
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
gte_stsxy((long *)&((PF4_C6F4 *)pkt)->x3);
|
||||
if (((PF4_C6F4 *)pkt)->x3 < mn) mn = ((PF4_C6F4 *)pkt)->x3;
|
||||
else if (mx < ((PF4_C6F4 *)pkt)->x3) mx = ((PF4_C6F4 *)pkt)->x3;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PF4_C6F4 *)pkt)->y3 < mny) mny = ((PF4_C6F4 *)pkt)->y3;
|
||||
else if (my < ((PF4_C6F4 *)pkt)->y3) my = ((PF4_C6F4 *)pkt)->y3;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 0) g.opz = za + 0x200;
|
||||
((PF4_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x5000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x18;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsxy(&tmpxy[3]);
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (tmpxy[3].vx > mx) mx = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mn) mn = tmpxy[3].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (tmpxy[3].vx > my) my = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mny) mny = tmpxy[3].vx;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
u32 uvw;
|
||||
gte_avsz4();
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 2) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x3 = *(u32 *)&tmpxy[3];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT4_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT4_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT4_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
uvw = tp[3];
|
||||
((PFT4_C6F4 *)pkt)->uv2 = uvw;
|
||||
((PFT4_C6F4 *)pkt)->uv3 = uvw >> 16;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x9000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x28;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
prim++;
|
||||
}
|
||||
}
|
||||
}
|
||||
D_800A5E60 = pkt;
|
||||
}
|
||||
@@ -2462,14 +2462,24 @@ re-verified three ways: image SHA == locked SHA, stub gone, real definition pres
|
||||
| ov_SC03_104 | func_80184934 | ov_SC04_007 | func_8017FF08 |
|
||||
| ov_SC04_003 | func_8017E4F4 | | |
|
||||
|
||||
**THE DEFECT THIS PROVES:** `family_sweep --hseq` reported this family **0/5 with
|
||||
`PLUMBING: parse error before 'unsigned'`** — but the remapped drafts are byte-CORRECT. The parse error
|
||||
comes from the sweep's own **gate-pipeline transform**, not from the remap: the only `unsigned` in the
|
||||
draft sits inside a comment, so a transform is eating a `/*` opener and turning comment text into code.
|
||||
Isolated per-transform runs (`canon_resident_calls` / `cast_call_sites` / `sig_unify`, each on the draft
|
||||
alone) all preserve it — so the corruption needs the gate's real invocation (with `--src-file`) to
|
||||
reproduce. **NOT YET PINNED — and it is silently costing banks in every sweep it touches.** Next
|
||||
session: run the three transforms with `--src-file` set to the target TU and diff the output.
|
||||
**THE DEFECT, PINNED — and my first hypothesis was WRONG (R14, corrected in place).** I wrote that a
|
||||
gate-pipeline transform was eating a `/*` opener and turning comment prose into code, because the only
|
||||
`unsigned` in the draft sits inside a comment. **Refuted by test:** every ladder step —
|
||||
`cast_call_sites`, `sig_unify`, `reconcile_tu`, each run with the gate's real `--src-file` — preserves
|
||||
the comment intact.
|
||||
|
||||
**The real cause is the `family_remap` TYPEDEF-CARRY GAP (§146/§152), full stop.** The staged draft
|
||||
fails as `` `Vec8_80182FD4' undeclared (first use this function) `` — the type the body needs was never
|
||||
carried, because `family_remap`'s unit backscan halts at the first `#define`. `parse error before
|
||||
'unsigned'` was simply that failure surfacing at the next recognizable token, the following
|
||||
`extern unsigned char …` line. **A misleading label, not a second defect.**
|
||||
|
||||
**Why direct gating banked all 5 anyway:** the TARGET TUs already declare that type at file scope, so
|
||||
the splice compiles even though the draft fails in isolation. **That is the rule worth keeping — the
|
||||
typedef gap is fatal only when the target TU does not already declare the type**, which is exactly why
|
||||
this family looked like an intractable "parse error" wall in the sweep and banked instantly when gated
|
||||
directly. Fixing `family_remap`'s backscan (let it skip `#define` continuation blocks) closes the whole
|
||||
class; until then, gate remapped drafts DIRECTLY rather than through `family_sweep`'s ladder.
|
||||
|
||||
**The workaround that banked them:** carry the exemplar's typedefs onto each remapped draft by hand
|
||||
(the same `family_remap` `_carry_macros` gap as §146/§152) and gate directly, bypassing the sweep's
|
||||
|
||||
@@ -880,6 +880,9 @@ def extract_unit(ov, addr):
|
||||
macros = _carry_macros(lines, start, end, unit_text) # gte_* etc. the body needs (T5)
|
||||
if macros:
|
||||
unit_text = "\n".join(macros) + "\n" + unit_text
|
||||
tds = _carry_typedefs(lines, unit_text) # types above a #define (S43)
|
||||
if tds:
|
||||
unit_text = "\n".join(tds) + "\n" + unit_text
|
||||
return unit_text, cf
|
||||
if alias_ident:
|
||||
# R32: we PROVED the function is defined here (the asm label binds the symbol) but could
|
||||
@@ -891,6 +894,69 @@ def extract_unit(ov, addr):
|
||||
return _macro_unit(addr)
|
||||
|
||||
|
||||
_TD_NAME_RE = re.compile(r'^\s*typedef\b.*?([A-Za-z_]\w*)\s*(?:\[[^\]]*\])?\s*;', re.S)
|
||||
|
||||
|
||||
def _carry_typedefs(lines, unit_text):
|
||||
"""Carry any file-scope typedef the extracted unit actually USES but did not carry.
|
||||
|
||||
P30 S43. The preamble backscan's accept-set is blank/`extern`/comment/`typedef`, so it **halts at
|
||||
the first `#define`** and never reaches typedefs declared above the macro block. `_carry_macros`
|
||||
then re-attaches the macros, which hides the truncation — the unit looks complete and is not.
|
||||
Measured on the 0x80182FD4 family: 16/16 gte macros carried, **0/10 typedefs**, silently; the
|
||||
staged sibling failed as `` `Vec8_80182FD4' undeclared `` and the sweep booked it
|
||||
`PLUMBING: parse error before 'unsigned'` (the error surfacing at the next token), which read as
|
||||
an intractable wall. It banked instantly once the type was carried by hand.
|
||||
|
||||
Additive by construction: only typedefs whose NAME appears as a word in the unit and which are not
|
||||
already present are prepended, so a unit that was already complete is byte-unchanged. Whether the
|
||||
gap is fatal depends on whether the TARGET TU happens to declare the type itself — which is why
|
||||
this failed loudly for some families and silently succeeded for others."""
|
||||
# index every file-scope typedef once: name -> full (possibly multi-line) block
|
||||
defs = []
|
||||
for k, ln in enumerate(lines):
|
||||
if not ln.lstrip().startswith("typedef"):
|
||||
continue
|
||||
# BRACE-AWARE block capture. A `;`-terminated scan stops INSIDE the struct — the first
|
||||
# member line (`SVECTOR_8016E7C8 v[4];`) ends in `;` — yielding a truncated, unclosed
|
||||
# typedef that cc1 reports at the member's type name. Close on the brace depth instead,
|
||||
# then take the `;` that follows `}` (P30 S43, measured).
|
||||
blk, j, depth, opened = ln, k, ln.count("{") - ln.count("}"), "{" in ln
|
||||
while j + 1 < len(lines) and j - k < 60 and (
|
||||
(opened and depth > 0) or (not opened and ";" not in blk)):
|
||||
j += 1
|
||||
blk += "\n" + lines[j]
|
||||
depth += lines[j].count("{") - lines[j].count("}")
|
||||
opened = opened or "{" in lines[j]
|
||||
while opened and ";" not in blk.rsplit("}", 1)[-1] and j + 1 < len(lines) and j - k < 60:
|
||||
j += 1
|
||||
blk += "\n" + lines[j]
|
||||
m = _TD_NAME_RE.match(blk)
|
||||
if m:
|
||||
defs.append((m.group(1), blk))
|
||||
|
||||
# TRANSITIVE closure: a carried typedef may itself name another typedef (measured — carrying
|
||||
# `Vec8_80182FD4` alone then failed on `SVECTOR_8016E7C8`, which it references). Iterate to a
|
||||
# fixpoint, emitting DEPENDENCY-FIRST so C89 sees each name before its use.
|
||||
out, seen, want = [], set(), unit_text
|
||||
for _ in range(12): # depth guard; real chains here are 2-3
|
||||
added = False
|
||||
for name, blk in defs:
|
||||
if name in seen:
|
||||
continue
|
||||
if re.search(r'^\s*typedef\b[^\n]*\b' + re.escape(name) + r'\b', unit_text, re.M):
|
||||
seen.add(name) # already carried by the backscan
|
||||
continue
|
||||
if re.search(r'\b' + re.escape(name) + r'\b', want):
|
||||
seen.add(name)
|
||||
out.insert(0, blk) # dependency-first: later finds precede earlier ones
|
||||
want += "\n" + blk
|
||||
added = True
|
||||
if not added:
|
||||
break
|
||||
return out
|
||||
|
||||
|
||||
def _macro_unit(addr):
|
||||
r"""Fallback: reconstruct the unit from its SHARED `DEFINE_func_<ADDR>()` macro.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user