feat(decomp): parallel gate — 14 fns across 11 binaries (6 workers)

md_SC07_003    func_801A38E4
  md_MAIN_027    func_800CB4A4
  ov_SC02_037    func_8013DD68
  ov_SC02_003    func_8018046C
  ov_SC01_084    func_8017EA98 func_80181F80 func_80184138
  ov_SC03_107    func_8013DD68
  ov_SC05_003    func_8017E380
  ov_SC05_008    func_8017DF68 func_8017EBB8
  ov_SC05_010    func_8017FAF4
  ov_SC06_032    func_80190D70
  ov_SC06_025    func_8017EA74
This commit is contained in:
Drew T
2026-08-31 13:43:44 -06:00
parent 21a2212ae3
commit d989ed08ae
12 changed files with 1621 additions and 15 deletions
+136 -1
View File
@@ -282,7 +282,142 @@ void func_800CB3E0(s32 a0) {
}
INCLUDE_ASM("asm/md_MAIN_027/nonmatchings/md_MAIN_027", func_800CB4A4);
extern s32 D_80078EC8;
extern void func_800CB82C(s32 a0, s32 a1);
extern s32 func_801488A8(s32 a0);
extern void func_80146D90(s32 a0);
extern s32 func_80148D44(s32 a0);
extern void func_80162FF4(s32 a0, s32 a1, s32 a2, s32 a3);
extern void func_800134FC(s32 a0, void *a1, void *a2);
extern void func_8001599C(void *a0, void *a1);
extern void func_80162FC0(s32 a0);
extern void func_800CBCB4(void *a0);
extern s32 func_80012F74(s32 a0, s32 a1, s32 a2, s32 a3);
extern s16 currentLocationId;
extern u8 D_800CC298[];
extern s16 D_800CC29A;
extern s16 D_800CC29C;
typedef struct { s32 w[4]; } CB4A4_V4;
void func_800CB4A4(s32 a0) {
u8 *ap;
s32 s1;
s32 s3;
s32 *s2;
s32 v0;
s32 d;
s32 flag;
CB4A4_V4 bak[2];
s16 *dig;
s1 = a0;
s3 = *(s32 *)(s1 + 0x4C);
ap = *(u8 **)(s1 + 0x20);
if (D_80078EC8 < 0x28) {
*(u16 *)(ap + 0x18) = *(u16 *)(ap + 0x18) - 0x40;
*(u16 *)(ap + 0x1A) = *(u16 *)(ap + 0x1A) - 0x40;
}
func_800CB82C(s1, *(s32 *)(s1 + 0x58));
if (func_801488A8(s3) != 0) {
bak[1] = *(CB4A4_V4 *)(s1 + 0x10);
func_80146D90(s1);
*(s32 *)(s1 + 0x18) = 0;
*(s32 *)(s1 + 0x14) = 0;
v0 = func_80148D44((*(s32 *)(s1 + 0x10) = 0, s1));
*(u16 *)(*(s32 *)(s1 + 0x20) + 0x12) = v0;
func_80162FF4(s1, 0, 0, 0xFFFE4000);
s2 = (s32 *)(s1 + 0x10);
if (currentLocationId == 0x3038) {
bak[0] = *(CB4A4_V4 *)s2;
func_800134FC(0x400, &bak[0], &bak[0]);
func_8001599C(&bak[0], s2);
}
*(s32 *)(s1 + 0x10) += bak[1].w[0];
*(s32 *)(s1 + 0x14) += bak[1].w[1];
*(s32 *)(s1 + 0x18) += bak[1].w[2];
if (*(s32 *)(s1 + 0x10) > 0xE0000) {
*(s32 *)(s1 + 0x10) = 0xE0000;
} else if (*(s32 *)(s1 + 0x10) < -0xE0000) {
*(s32 *)(s1 + 0x10) = -0xE0000;
}
if (*(s32 *)(s1 + 0x14) > 0xE0000) {
*(s32 *)(s1 + 0x14) = 0xE0000;
} else if (*(s32 *)(s1 + 0x14) < -0xE0000) {
*(s32 *)(s1 + 0x14) = -0xE0000;
}
if (*(s32 *)(s1 + 0x18) > 0xE0000) {
*(s32 *)(s1 + 0x18) = 0xE0000;
} else if (*(s32 *)(s1 + 0x18) < -0xE0000) {
*(s32 *)(s1 + 0x18) = -0xE0000;
}
} else {
flag = 0;
if (*(s32 *)(s1 + 0x10) != 0) {
flag = 1;
if (*(s32 *)(s1 + 0x10) >= 0) {
d = *(s32 *)(s1 + 0x10) - 0x8000;
*(s32 *)(s1 + 0x10) = d;
if (d < 0) {
*(s32 *)(s1 + 0x10) = 0;
}
} else {
d = *(s32 *)(s1 + 0x10) + 0x8000;
*(s32 *)(s1 + 0x10) = d;
if (d >= 0) {
*(s32 *)(s1 + 0x10) = 0;
}
}
}
if (*(s32 *)(s1 + 0x14) != 0) {
flag = 1;
if (*(s32 *)(s1 + 0x14) >= 0) {
d = *(s32 *)(s1 + 0x14) - 0x8000;
*(s32 *)(s1 + 0x14) = d;
if (d < 0) {
*(s32 *)(s1 + 0x14) = 0;
}
} else {
d = *(s32 *)(s1 + 0x14) + 0x8000;
*(s32 *)(s1 + 0x14) = d;
if (d >= 0) {
*(s32 *)(s1 + 0x14) = 0;
}
}
}
if (*(s32 *)(s1 + 0x18) != 0) {
flag = 1;
if (*(s32 *)(s1 + 0x18) >= 0) {
d = *(s32 *)(s1 + 0x18) - 0x8000;
*(s32 *)(s1 + 0x18) = d;
if (d < 0) {
*(s32 *)(s1 + 0x18) = 0;
}
} else {
d = *(s32 *)(s1 + 0x18) + 0x8000;
*(s32 *)(s1 + 0x18) = d;
if (d >= 0) {
*(s32 *)(s1 + 0x18) = 0;
}
}
}
if (flag == 0) {
goto tail;
}
}
func_80162FC0(s1);
tail:
func_800CBCB4((void *)s1);
dig = (s16 *)D_800CC298;
v0 = func_80012F74(dig[0], *(s16 *)(s1 + 6), 0xA, 1);
dig[0] = v0;
v0 = func_80012F74(D_800CC29A, *(s16 *)(s1 + 0xA), 0xA, 1);
D_800CC29A = v0;
v0 = func_80012F74(D_800CC29C, *(s16 *)(s1 + 0xE), 0xA, 1);
D_800CC29C = v0;
memcpy((void *)(s3 + 0x154), &D_800CC298[0], 8);
}
extern void func_801662F4(void);
extern void func_80162CCC(void);
+179 -1
View File
@@ -2053,7 +2053,185 @@ void func_801A38A8(s32 arg0) {
}
INCLUDE_ASM("asm/md_SC07_003/nonmatchings/md_SC07_003", func_801A38E4);
/*
* func_801A38E4 (md_SC07_003, 0x801A38E4, 186 ins) == MATCH, byte-exact.
*
* Rotates one of D_801A6CE8's 16-byte bounding-box records into view space and
* writes the six min/max halfwords at +4..+0xE of the caller's record. a4 == 0
* takes the three-axis path (each axis is fed through RotTransSV as a lone
* non-zero component); a4 != 0 rotates the two corner SVECTORs directly.
*
* Frame 0xC8: 0x10 MATRIX m, 0x30/0x38 sv0/sv1, 0x40/0x48 o0/o1, 0x50 flag,
* 0x58..0xB8 = 12 combine-orphaned sign-extend slots (§147-B as CORRECTED in
* P30 S43 — 2 per min/max block x 6 blocks, 8 bytes each). NO dead local is
* needed: writing the six blocks in the shape below produces the hole for free.
*
* LEVERS (each verified by reverting it and re-scoring with match_one):
* 1. NO `s16 *out` LOCAL — the six pairs index the parameter as
* `((s16 *)a1)[k]`. Binding a1 to a local makes `addu $s1,$a1,$zero` an
* ordinary body insn that sched1 sinks below the D_801A6CE8 address chain
* (target: sw $s1 / addu $s1 at idx 1-2, draft: idx 6-7). As a parameter
* copy it is an assign_parms insn and stays at the top. 7 -> 0.
* 2. The compare is spelled `o0.f > o1.f`, NOT `o1.f < o0.f`. Both fold to
* `slt $v0,$v0,$v1`, but the `>` form evaluates o0 first, so the target's
* `lh 0x40 ; lh 0x48 ; nop` load-delay nop appears (the `<` form fills that
* slot with the second load and loses 8 instructions across the 6 blocks).
* 3. Each SVECTOR is filled VALUE FIRST, then the two zeroed components in
* DESCENDING field order (vz before vy before vx). sched1 hoists the `lhu`
* and sinks its dependent `sh`, so the emitted order is
* lhu / zero / zero / value — source order any other way transposes the two
* `sh $zero` or floats one above the `lhu`.
* 4. Arm B's second corner needs `q = p; p += 4;` BEFORE the first call.
* `RotTransSV((s32)(p + 4), ...)` after it folds into `addiu $a0,$s2,8`
* (-1 instruction); the copy-then-bump form is what emits the target's
* `addu $a0,$s2,$zero` (branch delay slot) + `addiu $s2,$s2,8`.
*
* SYMBOL AUDIT (law 1c, after MATCH) — every symbol re-checked against the
* relocation lines of asm/md_SC07_003/nonmatchings/md_SC07_003/func_801A38E4.s:
* 1x jal func_8012EA90 (a0, a2, &m) · 8x jal RotTransSV (6 in arm A,
* 2 in arm B) · one %hi/%lo pair, D_801A6CE8. No other relocation exists
* in the target.
*
* BANK NOTE (law 2): src/md_SC07_003/md_SC07_003.c already prototypes
* `extern void func_801A38E4(void *a0, void *a1, s32 a2, s32 a3, s32 a4);`
* (4x, all above the INCLUDE_ASM) — the definition below is spelled to match it
* exactly, which is what the last gate rejected. `RotTransSV` and the two
* gte_Set*Matrix macros are copied VERBATIM from the same TU; D_801A6CE8 and
* func_8012EA90 are declared nowhere in it, so those two are free-standing
* (func_8012EA90 follows the fleet-modal `(void, (s32, s32, s32*))`).
*/
#include "common.h"
typedef struct {
s16 vx;
s16 vy;
s16 vz;
s16 pad;
} SVec801A38E4;
extern void func_8012EA90(s32 a0, s32 a1, s32 *a2);
extern void RotTransSV(s32 a0, s32 a1, void *a2);
extern u8 D_801A6CE8[];
#define gte_SetRotMatrix(r0) __asm__ volatile ( \
"lw $12, 0( %0 );" \
"lw $13, 4( %0 );" \
"ctc2 $12, $0;" \
"ctc2 $13, $1;" \
"lw $12, 8( %0 );" \
"lw $13, 12( %0 );" \
"lw $14, 16( %0 );" \
"ctc2 $12, $2;" \
"ctc2 $13, $3;" \
"ctc2 $14, $4" \
: \
: "r"( r0 ) \
: "$12", "$13", "$14" )
#define gte_SetTransMatrix(r0) __asm__ volatile ( \
"lw $12, 20( %0 );" \
"lw $13, 24( %0 );" \
"ctc2 $12, $5;" \
"lw $14, 28( %0 );" \
"ctc2 $13, $6;" \
"ctc2 $14, $7" \
: \
: "r"( r0 ) \
: "$12", "$13", "$14" )
void func_801A38E4(void *a0, void *a1, s32 a2, s32 a3, s32 a4)
{
s32 m[8];
SVec801A38E4 sv0;
SVec801A38E4 sv1;
SVec801A38E4 o0;
SVec801A38E4 o1;
s32 flag;
u16 *p;
u16 *q;
p = (u16 *)(D_801A6CE8 + (a3 << 4));
func_8012EA90((s32)a0, a2, m);
gte_SetRotMatrix(m);
gte_SetTransMatrix(m);
if (a4 == 0) {
sv0.vx = p[0];
sv0.vz = 0;
sv0.vy = 0;
sv1.vx = p[4];
sv1.vz = 0;
sv1.vy = 0;
RotTransSV((s32)&sv0, (s32)&o0, &flag);
RotTransSV((s32)&sv1, (s32)&o1, &flag);
if (o0.vx > o1.vx) {
((s16 *)a1)[3] = o0.vx;
((s16 *)a1)[2] = o1.vx;
} else {
((s16 *)a1)[3] = o1.vx;
((s16 *)a1)[2] = o0.vx;
}
sv0.vy = p[1];
sv0.vz = 0;
sv0.vx = 0;
sv1.vy = p[5];
sv1.vz = 0;
sv1.vx = 0;
RotTransSV((s32)&sv0, (s32)&o0, &flag);
RotTransSV((s32)&sv1, (s32)&o1, &flag);
if (o0.vy > o1.vy) {
((s16 *)a1)[5] = o0.vy;
((s16 *)a1)[4] = o1.vy;
} else {
((s16 *)a1)[5] = o1.vy;
((s16 *)a1)[4] = o0.vy;
}
sv0.vz = p[2];
sv0.vy = 0;
sv0.vx = 0;
sv1.vz = p[6];
sv1.vy = 0;
sv1.vx = 0;
RotTransSV((s32)&sv0, (s32)&o0, &flag);
RotTransSV((s32)&sv1, (s32)&o1, &flag);
if (o0.vz > o1.vz) {
((s16 *)a1)[7] = o0.vz;
((s16 *)a1)[6] = o1.vz;
} else {
((s16 *)a1)[7] = o1.vz;
((s16 *)a1)[6] = o0.vz;
}
} else {
q = p;
p += 4;
RotTransSV((s32)q, (s32)&o0, &flag);
RotTransSV((s32)p, (s32)&o1, &flag);
if (o0.vx > o1.vx) {
((s16 *)a1)[3] = o0.vx;
((s16 *)a1)[2] = o1.vx;
} else {
((s16 *)a1)[3] = o1.vx;
((s16 *)a1)[2] = o0.vx;
}
if (o0.vy > o1.vy) {
((s16 *)a1)[5] = o0.vy;
((s16 *)a1)[4] = o1.vy;
} else {
((s16 *)a1)[5] = o1.vy;
((s16 *)a1)[4] = o0.vy;
}
if (o0.vz > o1.vz) {
((s16 *)a1)[7] = o0.vz;
((s16 *)a1)[6] = o1.vz;
} else {
((s16 *)a1)[7] = o1.vz;
((s16 *)a1)[6] = o0.vz;
}
}
}
#include "common.h"
+148 -1
View File
@@ -3895,7 +3895,154 @@ void func_8017EA4C(s32 param_1) {
}
INCLUDE_ASM("asm/ov_SC01_084/nonmatchings/ov_SC01_084_jr_8017CA80", func_8017EA98);
#include "common.h"
/* func_8017EA98 - ov_SC01_084 / ov_SC01_084_jr_8017CA80 (177 ins, MATCH)
*
* Layout: the whole 0x10..0x37 local block is one s16[20] (frame -0x48 = 0x10
* outgoing-arg area + 40 bytes of locals + ra/s1/s0). Both arms index it with
* hard offsets: [0..2] = the (D_80126B5E, D_80126B62, D_80126B66) triple, the
* 3-word "high-half only" struct at &sp10[8] (arm 1) / &sp10[4] (arm 2), and the
* func_8012B77C output word at &sp10[16] / &sp10[12].
*
* Idioms that were load-bearing here:
* - The interval scan uses an EXPLICIT byte-offset variable (`off += 4`), not
* `tbl[i * 2]`. With an array subscript, loop.c strength-reduces the address
* into two pointer givs (`la`+`addiu` per table); with `(s32)&sym + off` the
* address stays `sym($off)` and the assembler expands the lui/addu/lh macro,
* which is what the target does.
* - abs(): the SECOND difference is computed UNCONDITIONALLY into its own
* variable (dz2) so the delay-slot filler takes it from before the branch;
* that is what keeps the `bltz` un-inverted and pays for the `j` + duplicated
* `addu` in both arms (an `if (t < 0) t = -t;` merge comes out 1 ins short).
* - `D_80126B62 - 0xA0` is its own statement: written as one expression, fold
* reassociates it to `62 - (0xA0 + (x << 5))` (addiu on the shift instead).
* - `amt` is computed BEFORE the sp10[5]/[7]/[9] stores (source order is the
* sched1 order here); after them, the second `lh 0x70` sinks 3 slots.
* - Separate tmp/tmp2: reusing one variable for both `lw`s makes it one
* long-lived pseudo, which loses the $a1 copy-preference on the
* func_8012B608 argument.
* - The two $v1/$a0 pins are the last residual: global-alloc ranks the loaded
* `*(s16*)(a0+6)` above `dx` by a knife-edge live-length margin and hands it
* $v1. No source shape tried (declared temps, if/else abs, decl order,
* ternary, variable merging) moved it; the pins are dead before every call in
* scope, and the emitted bytes are the target's, so no §175 exposure.
*/
extern u16 D_80126B5E;
extern u16 D_80126B62;
extern u16 D_80126B66;
extern s16 D_801C7748;
extern s16 D_8018A6D4;
extern s16 D_8018A6D6;
extern u8 D_8018A6C8[];
extern void func_8012B0B4(u32 *a0, s32 a1, s32 a2);
extern void func_8012B14C(s32 a0, s32 a1);
extern void func_8012AD80(s32 a0);
extern void func_8012B77C(void *a0, s32 a1, void *a2);
extern s32 func_8012B608(s32 a0, s32 a1, s32 a2);
void func_8017EA98(s32 a0) {
extern void func_8017ED5C();
s16 sp10[20];
s32 i;
s32 off;
s32 ang;
if (*(u16 *)(a0 + 0x5C) & 1) {
func_8017ED5C();
return;
}
off = 0;
ang = D_801C7748;
for (i = 0; i < 3; i++) {
if (ang >= *(s16 *)((s32)&D_8018A6D4 + off) && ang < *(s16 *)((s32)&D_8018A6D6 + off)) {
break;
}
off += 4;
}
if (i == 3) {
s32 tmp;
s32 tmp2;
register s32 dx __asm__("$3");
register s32 dz __asm__("$4");
s32 dz2;
s32 sum;
func_8012B0B4((u32 *)&sp10[4], -ang & 0xFFF, 0x400);
tmp = *(s32 *)&sp10[4];
sp10[0] = D_80126B5E;
sp10[1] = D_80126B62;
sp10[2] = D_80126B66;
sp10[0] = tmp;
sp10[2] = tmp >> 16;
sp10[9] = tmp;
sp10[11] = D_80126B62;
sp10[13] = tmp >> 16;
func_8012B14C(a0, (s32)D_8018A6C8);
func_8012AD80(a0);
dx = *(s16 *)(a0 + 6) - sp10[0];
if (dx < 0) {
dx = sp10[0] - *(s16 *)(a0 + 6);
}
dz = *(s16 *)(a0 + 0xE) - sp10[2];
dz2 = sp10[2] - *(s16 *)(a0 + 0xE);
if (dz >= 0) {
sum = dx + dz;
} else {
sum = dx + dz2;
}
if (sum >= 0x80) {
func_8012B77C(&sp10[16], a0 + 4, &sp10[8]);
tmp2 = *(s32 *)&sp10[16];
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = tmp2;
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += func_8012B608(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12), tmp2 >> 16, 3);
}
} else {
s32 tmp;
s32 tmp2;
register s32 dx __asm__("$3");
register s32 dz __asm__("$4");
s32 dz2;
s32 sum;
s32 amt;
sp10[0] = D_80126B5E;
sp10[1] = D_80126B62;
sp10[2] = D_80126B66;
tmp = D_80126B62 - 0xA0;
tmp = tmp - (*(s16 *)(a0 + 0x70) << 5);
sp10[1] = tmp;
amt = (*(s16 *)(a0 + 0x70) << 2) + 6;
sp10[5] = D_80126B5E;
sp10[7] = tmp;
sp10[9] = D_80126B66;
func_8012B14C(a0, (s32)D_8018A6C8);
func_8012AD80(a0);
dx = *(s16 *)(a0 + 6) - sp10[0];
if (dx < 0) {
dx = sp10[0] - *(s16 *)(a0 + 6);
}
dz = *(s16 *)(a0 + 0xE) - sp10[2];
dz2 = sp10[2] - *(s16 *)(a0 + 0xE);
if (dz >= 0) {
sum = dx + dz;
} else {
sum = dx + dz2;
}
if (sum >= 0x80) {
func_8012B77C(&sp10[12], a0 + 4, &sp10[4]);
tmp2 = *(s32 *)&sp10[12];
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = tmp2;
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += func_8012B608(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12), tmp2 >> 16, amt);
}
*(s32 *)(*(s32 *)(a0 + 0x20) + 4) &= 0x7FFFFFFF;
}
}
#include "common.h"
+264 -3
View File
@@ -4002,7 +4002,133 @@ void func_80181F3C(s32 a0) {
}
INCLUDE_ASM("asm/ov_SC01_084/nonmatchings/ov_SC01_084_jr_8017F690", func_80181F80);
extern s32 func_80047948(s32 a0);
extern s32 func_8004787C(s32 a0);
extern s32 func_80047D3C(s32 a0);
extern s32 func_801807D8(s16 *a0);
extern void func_8012A828(s32 a0, void *a1);
extern s32 func_8012B608(s32 a0, s32 a1, s32 a2);
extern void func_8012C098(void *a0);
extern s32 func_80143B6C(s32 a0, s32 a1);
extern void func_801822A4(void *a0);
extern s16 D_801C7748;
extern s16 D_801C774A;
extern s32 D_801270D4;
extern s32 D_801270E4;
extern s32 D_801A1A10;
void func_80181F80(s32 param_1) {
s16 sp10[3];
s32 t;
u16 m, y, f, g;
s16 h;
s32 cur, lim;
s32 tt, x, angle, spd, q1, sinVal, cosVal;
s32 d;
s16 c;
h = *(u16 *)(param_1 + 0xDC) - 8;
*(s16 *)(param_1 + 0xDC) = h;
if (h < 0x400) {
*(s16 *)(param_1 + 0xFC) = 1;
*(u8 *)(param_1 + 0xC1) = 0;
*(s16 *)(param_1 + 2) = 1;
*(s16 *)(param_1 + 0x34) = 0;
*(u16 *)(param_1 + 0x100) |= 3;
func_8012A828(param_1, &D_801A1A10);
m = *(u16 *)(param_1 + 0x5C);
y = *(u16 *)(param_1 + 6);
f = *(u16 *)(param_1 + 0xFC);
*(s32 *)(param_1 + 0x1C) = 0xA;
t = (s32)(s16)y * (s32)(s16)y;
*(u16 *)(param_1 + 0x5E) = 0;
g = m | 0x8000;
*(u16 *)(param_1 + 0x5C) = g;
*(u16 *)(param_1 + 0xFC) = f ^ 1;
sp10[0] = y;
sp10[1] = *(u16 *)(param_1 + 0xA);
sp10[2] = *(u16 *)(param_1 + 0xE);
t += (s32)(s16)sp10[2] * (s32)(s16)sp10[2];
*(s16 *)(param_1 + 0xDE) = func_80047D3C(t);
*(s16 *)(param_1 + 0xDC) = func_801807D8(sp10);
}
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) +=
func_8012B608(*(s16 *)(*(s32 *)(param_1 + 0x20) + 0x12),
-*(s16 *)(param_1 + 0xDC) & 0xFFF, 0x10);
cur = *(s16 *)(param_1 + 0xDE);
lim = D_801C774A;
if (lim < cur) {
if (cur - lim < 6) {
*(s16 *)(param_1 + 0xDE) = lim;
} else {
*(s16 *)(param_1 + 0xDE) -= 6;
}
} else if (cur < lim) {
if (lim - cur < 6) {
*(s16 *)(param_1 + 0xDE) = lim;
} else {
*(s16 *)(param_1 + 0xDE) += 6;
}
}
tt = *(s16 *)(param_1 + 0xDC);
spd = *(s16 *)(param_1 + 0xDE);
x = -(tt * 1536);
angle = tt & 0xFFF;
q1 = x / 12288 - 0x22;
sinVal = func_80047948(angle) * spd >> 12;
cosVal = func_8004787C(angle) * spd >> 12;
sp10[0] = sinVal;
sp10[1] = q1;
sp10[2] = cosVal;
*(u16 *)(param_1 + 6) = sp10[0];
*(u16 *)(param_1 + 0xA) = sp10[1];
*(u16 *)(param_1 + 0xE) = sp10[2];
d = *(s16 *)(param_1 + 0xDC) - D_801C7748;
if (d < -0xFF) {
if (*(s16 *)(param_1 + 0x70) == 2) {
D_801270E4--;
} else {
D_801270D4--;
}
func_8012C098((void *)param_1);
return;
}
if (d <= 0) {
*(u16 *)(param_1 + 0x100) |= 1;
} else if ((*(u16 *)(param_1 + 0x100) & 1) == 0) {
if (*(s16 *)(param_1 + 0x70) == 0) {
if (d >= 0x51) {
goto skip;
}
/* LOAD-BEARING (cookbook §5a): a zero-byte volatile-asm makes this arm's
* RTL tail differ from the sibling arm's, so find_cross_jump refuses to
* merge the two `beqz`+join tails. Removing it costs 4 instructions. */
__asm__ __volatile__("");
} else {
if (d >= 0x201) {
goto skip;
}
}
func_801822A4((void *)param_1);
return;
}
skip:
c = *(u16 *)(param_1 + 0xFE) - 1;
*(s16 *)(param_1 + 0xFE) = c;
if (c <= 0) {
func_80143B6C(param_1, 0);
*(s16 *)(param_1 + 0xFE) = 8;
}
}
extern void func_8012A828(s32 a0, void *a1);
@@ -5225,7 +5351,142 @@ void func_801840FC(void *a0) {
}
INCLUDE_ASM("asm/ov_SC01_084/nonmatchings/ov_SC01_084_jr_8017F690", func_80184138);
#include "common.h"
/* func_80184138 - ov_SC01_084 / ov_SC01_084_jr_8017F690 (187 ins)
*
* Structural twin of func_80183DA4 (same TU, MATCH, 187 ins) -- the same
* vertical "beam"/ribbon builder with a different texture window and step:
* D_801C74D8 -> D_801C74DC, GetClut y 0x14C -> 0x14D, uu 0xF0 -> 0xF8,
* the u1/u3 literal 0xF7 -> 0xFF, and the tail step vec.vy -= 0x40 -> 0x3C.
* All three of func_80183DA4's levers carry over verbatim:
* 1. sxy0/sxy1 are s32 SCALARS read through a cast-to-struct-pointer, so the
* four stack slots are handed out in &-order (0x20/0x24/0x28/0x2C) while
* the loads stay MEM_IN_STRUCT_P and are re-killed by the p->x0 store.
* 2. `otz2 = RotTransPers(...); d = D_801C74DC; if ((d >> 3) >= otz2)` forces
* the reload the target has, and that reload feeds the `d << 3` dividend.
* 3. `uu = 0xF8; vv = 0;` are ordinary pre-loop statements (they precede the
* &pp/&flag address movables in the preheader); 0xFF stays a literal and is
* the one true loop.c movable, landing last.
*/
typedef struct { s32 a; s32 b[4]; } OtBlk_80184138; /* 0x14 stride */
typedef struct { u16 vx, vy, vz, pad; } SVec_80184138; /* 0x08 stride */
typedef struct { u16 vx, vy; } DVec_80184138; /* read through a cast */
typedef struct {
u32 tag; /* 0x00 */
u8 r0, g0, b0, code; /* 0x04 */
s16 x0, y0; /* 0x08 */
u8 u0, v0; u16 clut; /* 0x0C */
s16 x1, y1; /* 0x10 */
u8 u1, v1; u16 tpage; /* 0x14 */
s16 x2, y2; /* 0x18 */
u8 u2, v2; u16 pad2; /* 0x1C */
s16 x3, y3; /* 0x20 */
u8 u3, v3; u16 pad3; /* 0x24 */
} Ft4_80184138; /* 0x28 */
extern void func_8004914C(void *a0);
extern void func_800491AC(void *a0);
extern s32 GetTPage(s32 a0, s32 a1, s32 a2, s32 a3);
extern s32 GetClut(s32 a0, s32 a1);
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
extern void *func_80010A08(s32 a0);
extern void SetPolyFT4(void *a0);
extern s32 AddPrim(s32 a0, void *a1);
void func_80184138(SVec_80184138 *arg0) {
extern s32 D_801C74DC;
extern OtBlk_80184138 D_800A651C[];
SVec_80184138 tmp; /* 0x10 */
SVec_80184138 vec; /* 0x18 */
s32 sxy0; /* 0x20 */
s32 pp; /* 0x24 */
s32 flag; /* 0x28 */
s32 sxy1; /* 0x2C */
u16 tpage;
u16 clut;
Ft4_80184138 *p;
s32 ot;
s32 otz;
s32 otz2;
s32 d;
s32 w;
s32 uu;
s32 vv;
if ((s16)D_801270C0 == 3) {
return;
}
func_8004914C(&D_800AF648);
func_800491AC(&D_800AF648);
D_801C74DC = D_80126950;
tpage = GetTPage(0, 0, 0x300, 0x100);
clut = GetClut(0x160, 0x14D);
vec.vx = arg0->vx;
vec.vy = arg0->vy;
vec.vz = arg0->vz;
uu = 0xF8;
vv = 0;
for (;;) {
tmp.vx = vec.vx;
tmp.vy = vec.vy - 0x40;
tmp.vz = vec.vz;
otz = RotTransPers((s32)&tmp, (s32)&sxy0, &pp, &flag);
if ((D_801C74DC >> 3) >= otz) {
return;
}
if (flag < 0) {
return;
}
otz2 = RotTransPers((s32)&vec, (s32)&sxy1, &pp, &flag);
d = D_801C74DC;
if ((d >> 3) >= otz2) {
return;
}
if (flag < 0) {
return;
}
ot = D_800A651C[(u16)D_800B9A02].a + otz * 4;
w = (d << 3) / (otz * 4);
if ((s16)((DVec_80184138 *)&sxy0)->vy < 120) {
if ((s16)((DVec_80184138 *)&sxy1)->vy < -119) {
return;
}
if ((s16)w >= 2) {
p = (Ft4_80184138 *)func_80010A08(0x28);
*(s32 *)((u8 *)p + 4) = 0x808080;
SetPolyFT4(p);
p->x0 = ((DVec_80184138 *)&sxy0)->vx - w;
p->y0 = ((DVec_80184138 *)&sxy0)->vy;
p->x1 = ((DVec_80184138 *)&sxy0)->vx + w;
p->y1 = ((DVec_80184138 *)&sxy0)->vy;
p->x2 = ((DVec_80184138 *)&sxy1)->vx - w;
p->y2 = ((DVec_80184138 *)&sxy1)->vy;
p->x3 = ((DVec_80184138 *)&sxy1)->vx + w;
p->y3 = ((DVec_80184138 *)&sxy1)->vy;
p->u0 = uu;
p->v0 = vv;
p->u1 = 0xFF;
p->v1 = vv;
p->u2 = uu;
p->v2 = vv + 0x3F;
p->u3 = 0xFF;
p->v3 = vv + 0x3F;
p->tpage = tpage;
p->clut = clut;
AddPrim(ot, p);
}
}
vec.vy -= 0x3C;
}
}
extern void (*D_8018AC2C[])(void);
@@ -6137,7 +6398,7 @@ void func_801855EC(s32 param_1)
}
extern void func_80184138(u16 *a0);
extern void func_80184138();
extern void func_80183DA4();
extern s16 D_8018A914;
extern s16 D_8018A91A;
+135 -1
View File
@@ -3057,7 +3057,141 @@ void func_80180428(int param_1)
}
INCLUDE_ASM("asm/ov_SC02_003/nonmatchings/ov_SC02_003_jr_8017FCB0", func_8018046C);
#include "common.h"
/* @class: struct
* @stuck: none — remap of the banked byte-MATCH twin src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c
* :3089 (same name, same 158 ins, IDENTICAL symbol set — verified against THIS .s's relocation
* lines: func_8012E544, func_80180A64, rand, func_801803D0, func_8012F214, D_8018E66C,
* func_8012C51C, func_8012B2CC, func_8018A660, func_8012BEE8, func_80180428, func_8012A828,
* D_801A6344). The prior stranded draft was cc1-FAIL only because it inherited the twin's
* *enclosing TU* decl environment implicitly: struct Prim, rand, func_801803D0, func_80180428
* were undeclared. Every one of them is now declared here.
* Levers carried from the twin's note: (1) switch(s32 st34){0,1,2} -> beq==1/slti<2/beq==2
* decision tree; (2) struct Prim {s16 f0..fE; s32 f10} + s16 buf[4] gives prim@sp+0x10,
* buf@sp+0x28 byte-exact, store order f6,f8,fA,f10,fE,f0,f2,f4,fC; (3) the uninitialised $s0
* flag CFG needs the explicit compute/flag_zero goto labels (p==0 leaves flag live-undefined);
* (4) `d=-d; flag=d<0x20` written twice so bgez keeps slti in its delay slot and retargets past
* the copy; (5) 0xAA10 stored through u16 -> ori (an s16 store gives addiu -22000);
* (6) the zero-byte __asm__ memory barrier after the 0x102 store forces `c & 0xff` (not the sb)
* into the `jal rand` delay slot. */
struct Prim { s16 f0, f2, f4, f6, f8, fA, fC, fE; s32 f10; };
extern void func_8012F214(s32 a0, s32 a1, s32 a2);
extern s32 func_8012C51C(void *a0, s32 a1);
extern s32 func_8012BEE8(s32 a0);
extern void func_8012B2CC(s32 a0);
extern void func_8012A828(s32 a0, void *a1);
extern s32 rand(void);
extern void func_801803D0(int param_1);
extern void func_80180428(int param_1);
void func_8018046C(s32 arg0) {
extern s32 func_8012E544(s32 a0);
extern void func_80180A64(s32 param_1);
extern s32 func_8018A660(s32 a0, s32 a1);
extern s32 D_8018E66C[];
extern s32 D_801A6344;
s32 cond;
s32 flag;
s32 d;
u16 mode;
s32 st34;
mode = *(u16 *)(arg0 + 0x70);
cond = 1;
if ((u32)(mode - 0x505) >= 2) {
cond = ((mode & 0xff00) == 0x700);
}
if (cond == 0) {
goto flag_zero;
}
cond = func_8012E544(0x298);
if (cond == 0) {
goto lab_ab0;
}
if (*(u16 *)(cond + 2) == 2) {
goto compute;
}
flag_zero:
flag = 0;
goto lab_ab0;
compute:
d = *(s16 *)(cond + 0xe) - *(s16 *)(arg0 + 0xe);
flag = (d < 0x20);
if (d < 0) {
d = -d;
flag = (d < 0x20);
}
lab_ab0:
if (flag != 0) {
func_80180A64(arg0);
return;
}
st34 = *(u16 *)(arg0 + 0x34);
switch (st34) {
case 0:
if (*(u16 *)(arg0 + 0x72) & 0x4000) {
s32 c = *(u8 *)(arg0 + 0x102) + 1;
*(u8 *)(arg0 + 0x102) = c;
__asm__ __volatile__("" ::: "memory");
if ((((s32(*)())rand)() & 1) < (c & 0xff)) {
((void(*)(s32))func_801803D0)(arg0);
}
}
break;
case 1: {
s32 s1c = *(s32 *)(arg0 + 0x1c);
if (s1c == 0xc) {
struct Prim sp;
s16 buf[4];
s32 tv0;
func_8012F214(arg0, (s32)&(*(s32 *)&D_8018E66C), (s32)buf);
sp.f6 = 0x20;
sp.f8 = 2;
sp.fA = 0;
sp.f10 = 0;
sp.fE = 0;
sp.f0 = buf[0];
sp.f2 = buf[1];
sp.f4 = buf[2];
sp.fC = *(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12);
tv0 = func_8012C51C(&sp, arg0);
if (tv0 != 0) {
*(u16 *)(*(s32 *)(tv0 + 0x20) + 0x12) = *(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12);
func_8012B2CC(tv0);
}
} else if (s1c == 0xf) {
func_8018A660(arg0, (s32)&(*(s32 *)&D_8018E66C));
}
if (func_8012BEE8(arg0) != 0) {
s32 c = *(u8 *)(arg0 + 0x102) + 1;
*(u8 *)(arg0 + 0x102) = c;
if ((u32)(c & 0xff) >= 3) {
((void(*)(s32))func_80180428)(arg0);
return;
}
*(s32 *)(arg0 + 0x1c) = 0x1e;
return;
}
break;
}
case 2:
if (*(u16 *)(arg0 + 0x72) & 0x4000) {
*(s16 *)(arg0 + 2) = 0xb;
*(u16 *)(arg0 + 0x34) = 0;
*(s16 *)(arg0 + 0x5e) = 0;
*(u16 *)(arg0 + 0x5c) = 0xaa10;
func_8012A828(arg0, &D_801A6344);
*(u8 *)(arg0 + 0x102) = 0;
}
break;
}
}
extern void func_8012B178(s32 a0, s32 a1);
+100 -1
View File
@@ -1641,7 +1641,106 @@ void func_8013DBE4(int param_1)
}
INCLUDE_ASM("asm/ov_SC02_037/nonmatchings/ov_SC02_037_jr_8013C98C", func_8013DD68);
#include "common.h"
/* func_8013DD68 (ov_SC02_037) — 187 ins.
* @class: regalloc-order
* Family exemplar: src/ov_SC06_008/ov_SC06_008_jr_8013C98C.c:1685 (banked MATCH).
* Mechanical per-overlay symbol remap:
* D_801A8DAC -> D_801C84A4, D_801A8DDC -> D_801C84D4,
* D_801A8DE0 -> D_801C84D8, D_801A8DE4 -> D_801C84DC,
* D_801861B8 -> D_801845B0. Every symbol re-checked against this .s's own relocs.
* Levers (carried from the exemplar): struct-assign DRAWENV copy (align via type); `pbase`
* local so D_800B9A02 is reached $s2-relative as D_800AF630[0xA3D2]; two-biv SPRT loop
* (q anchored one-above -> gcc re-anchors, no bare-deref); P_TAG_8013DD68 addPrim;
* a single `p` var coalesces the two prim cursors; pins uVar2=$v1, iVar14=$a3, c5=$t3;
* biv-increment order sets q-init-before-puVar10-init; Buf_8013DD68 0x68 -> frame 0xA0. */
#ifndef BFM_ENGINE_TYPES_H
#endif
extern u8 D_800AF630[];
extern s32 D_800A5E60;
extern s16 *D_801C84A4;
extern s32 D_801C84D4;
extern s32 D_801C84D8;
extern s32 D_801C84DC;
#define IDVAL (*(u16 *)(pbase + 0xA3D2))
#define OTE ((P_TAG_8013DD68 *)(D_800BA0E4 + IDVAL * 0x10))
void func_8013DD68() {
extern void SetDrawEnv(void *p, void *env);
extern u16 D_800AF7B8;
extern u8 D_800BA0E4[];
extern u8 D_801845B0[];
u32 *p;
u16 uVar1;
u16 *puVar16;
u16 *q;
u16 *puVar10;
register u16 uVar2 __asm__("$3");
int uVar5;
register int iVar14 __asm__("$7");
Buf_8013DD68 buf;
u8 *pbase;
u8 *base;
pbase = D_800AF630;
puVar16 = (*(u16 * *)&D_801C84A4);
p = (*(u32 * *)&D_800A5E60);
uVar1 = *puVar16;
puVar16 = puVar16 + 1;
base = pbase + (u32)D_800AF7B8 * 0x5C;
buf.env = *(DrawEnv_8013DD68 *)(base + 0x38);
*((u8 *)&buf + 0x18) = 0;
SetDrawEnv(p, &buf);
((P_TAG_8013DD68 *)p)->addr = OTE->addr;
OTE->addr = (u32)p;
p = p + 0x10;
iVar14 = 0;
if (uVar1 != 0) {
register int c5 __asm__("$11") = 5;
puVar10 = (u16 *)((int)p + 0x18);
q = puVar16 + 8;
do {
*(u8 *)((int)puVar10 + -0x15) = c5;
uVar2 = q[-6];
*(u8 *)((int)puVar10 + -0xd) = 100;
*(u8 *)((int)puVar10 + -0x10) = (u8)(*(int*)&D_801C84D4);
*(u8 *)((int)puVar10 + -0xf) = (u8)(*(int*)&D_801C84D8);
uVar5 = (*(int*)&D_801C84DC);
*(u32 *)((int)puVar10 + -0x14) = uVar2 & 0x9ff | 0xe1000400;
*(u8 *)((int)puVar10 + -0xe) = (u8)uVar5;
*(u16 *)((int)puVar10 + -0xc) = q[-4];
iVar14 = iVar14 + 1;
*(u16 *)((int)puVar10 + -0xa) = q[-3];
*(u8 *)((int)puVar10 + -8) = (u8)*puVar16;
uVar2 = q[-7];
*(u16 *)((int)puVar10 + -6) = 0x7800;
*(u8 *)((int)puVar10 + -7) = (u8)uVar2;
puVar16 = puVar16 + 8;
*(u16 *)((int)puVar10 + -4) = q[-2];
*(u16 *)((int)puVar10 + -2) = q[-1];
((P_TAG_8013DD68 *)p)->addr = OTE->addr;
puVar10 = puVar10 + 0xc;
OTE->addr = (u32)p;
p = p + 6;
q = q + 8;
} while (iVar14 < (int)(u32)uVar1);
}
SetDrawEnv(p, D_801845B0);
((P_TAG_8013DD68 *)p)->addr = OTE->addr;
OTE->addr = (u32)p;
p = p + 0x10;
(*(u32 * *)&D_800A5E60) = p;
return;
}
+87 -1
View File
@@ -1644,7 +1644,93 @@ void func_8013DBE4(int param_1)
}
INCLUDE_ASM("asm/ov_SC03_107/nonmatchings/ov_SC03_107_jr_8013C98C", func_8013DD68);
#include "common.h"
#ifndef BFM_ENGINE_TYPES_H
#endif
extern u8 D_800AF630[];
extern s32 D_800A5E60;
extern s16 *D_8019A804;
extern s32 D_8019A834;
extern s32 D_8019A838;
extern s32 D_8019A83C;
#define IDVAL (*(u16 *)(pbase + 0xA3D2))
#define OTE ((P_TAG_8013DD68 *)(D_800BA0E4 + IDVAL * 0x10))
void func_8013DD68() {
extern void SetDrawEnv(void *p, void *env);
extern u16 D_800AF7B8;
extern u8 D_800BA0E4[];
extern u8 D_80182E4C[];
u32 *p;
u16 uVar1;
u16 *puVar16;
u16 *q;
u16 *puVar10;
register u16 uVar2 __asm__("$3");
int uVar5;
register int iVar14 __asm__("$7");
Buf_8013DD68 buf;
u8 *pbase;
u8 *base;
pbase = D_800AF630;
puVar16 = (*(u16 * *)&D_8019A804);
p = (*(u32 * *)&D_800A5E60);
uVar1 = *puVar16;
puVar16 = puVar16 + 1;
base = pbase + (u32)D_800AF7B8 * 0x5C;
buf.env = *(DrawEnv_8013DD68 *)(base + 0x38);
*((u8 *)&buf + 0x18) = 0;
SetDrawEnv(p, &buf);
((P_TAG_8013DD68 *)p)->addr = OTE->addr;
OTE->addr = (u32)p;
p = p + 0x10;
iVar14 = 0;
if (uVar1 != 0) {
register int c5 __asm__("$11") = 5;
puVar10 = (u16 *)((int)p + 0x18);
q = puVar16 + 8;
do {
*(u8 *)((int)puVar10 + -0x15) = c5;
uVar2 = q[-6];
*(u8 *)((int)puVar10 + -0xd) = 100;
*(u8 *)((int)puVar10 + -0x10) = (u8)(*(int*)&D_8019A834);
*(u8 *)((int)puVar10 + -0xf) = (u8)(*(int*)&D_8019A838);
uVar5 = (*(int*)&D_8019A83C);
*(u32 *)((int)puVar10 + -0x14) = uVar2 & 0x9ff | 0xe1000400;
*(u8 *)((int)puVar10 + -0xe) = (u8)uVar5;
*(u16 *)((int)puVar10 + -0xc) = q[-4];
iVar14 = iVar14 + 1;
*(u16 *)((int)puVar10 + -0xa) = q[-3];
*(u8 *)((int)puVar10 + -8) = (u8)*puVar16;
uVar2 = q[-7];
*(u16 *)((int)puVar10 + -6) = 0x7800;
*(u8 *)((int)puVar10 + -7) = (u8)uVar2;
puVar16 = puVar16 + 8;
*(u16 *)((int)puVar10 + -4) = q[-2];
*(u16 *)((int)puVar10 + -2) = q[-1];
((P_TAG_8013DD68 *)p)->addr = OTE->addr;
puVar10 = puVar10 + 0xc;
OTE->addr = (u32)p;
p = p + 6;
q = q + 8;
} while (iVar14 < (int)(u32)uVar1);
}
SetDrawEnv(p, D_80182E4C);
((P_TAG_8013DD68 *)p)->addr = OTE->addr;
OTE->addr = (u32)p;
p = p + 0x10;
(*(u32 * *)&D_800A5E60) = p;
return;
}
+85 -1
View File
@@ -3988,7 +3988,91 @@ void func_8017E1E8(s32 param_1, s16 *param_2) {
}
INCLUDE_ASM("asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC", func_8017E380);
extern s32 D_80126B58;
extern u16 D_80126B5E;
extern s32 func_8017267C(s32 *a0);
extern s32 func_800CF8B4();
extern s32 func_8014CB8C(void);
extern void func_8002D4C8(s32 a0, s32 a1);
extern s32 func_80143C74(s32 a0, s32 a1);
extern s32 rand(void);
extern void func_80016714(void *a0, s32 a1);
extern void func_8012C218(void *a0);
void func_8017E380(s32 arg0) {
s32 s0;
s32 a1;
s32 s1;
s32 v1;
s32 t;
s0 = -1;
if (func_8017267C(&D_80126B58) != 0) goto b9;
if (func_800CF8B4() == 0) goto b9;
if (func_8014CB8C() != 0) goto b9;
a1 = (s16)D_80126B5E;
if (a1 < -0xE8E) goto after;
if (a1 < -0xCEC) goto arm_a;
if (a1 < -0x87) goto arm_m;
if (a1 < 0xF7) goto arm_c;
b9:
if (*(s16 *)(arg0 + 0x84) != 0) {
func_8002D4C8(4, 0xAFA);
*(s16 *)(arg0 + 0x84) = 0;
}
goto after;
arm_c:
s0 = (0xF6 - a1) * 10 / 382;
D_80126B5E = (s16)D_80126B5E - s0;
goto after;
arm_m:
D_80126B5E = (s16)D_80126B5E - 10;
s0 = 10;
goto after;
arm_a:
s0 = (a1 + 0xE8F) * 10 / 418;
D_80126B5E = (s16)D_80126B5E - s0;
after:
if (s0 >= 0) {
s0 = s0 * 127 / 10;
func_8002D4C8(0xAFA, (u16)(s0 | 0x1000));
*(s16 *)(arg0 + 0x84) = 1;
}
if (*(s32 *)(arg0 + 0x1C) != 0) {
*(s32 *)(arg0 + 0x1C) = *(s32 *)(arg0 + 0x1C) - 1;
} else {
*(s32 *)(arg0 + 0x1C) = 3;
s1 = func_80143C74(arg0, 0);
if (s1 != 0) {
*(s16 *)(s1 + 0xE) = rand() % 0xC0 - 0x60;
t = D_80126B5E + rand() % 0x300;
*(s16 *)(s1 + 6) = t - 0x180;
if ((u16)(t + 0xD0F) >= 0xF86) {
*(s32 *)(arg0 + 0x1C) = 0;
func_80016714(*(void **)(s1 + 0xCC), 0x38);
func_8012C218((void *)s1);
} else {
*(s32 *)(s1 + 0x48) = -((rand() & 0x1FF) << 7);
a1 = *(s16 *)(s1 + 6);
if (a1 < -0xCEC) goto arm2_a;
if (a1 < -0x87) goto arm2_m;
v1 = (0xF6 - a1) * 20 / 382;
*(s16 *)(s1 + 0x12) = -v1;
goto done;
arm2_m:
*(u16 *)(s1 + 0x12) -= 0x14;
goto done;
arm2_a:
v1 = (a1 + 0xE8F) * 20 / 418;
*(s16 *)(s1 + 0x12) = -v1;
*(s16 *)(s1 + 0x16) = v1 - 0x14;
}
}
}
done:
;
}
s32 func_8017E67C(void) {
+145 -2
View File
@@ -4424,7 +4424,67 @@ void func_8017DEC4(void) {
}
INCLUDE_ASM("asm/ov_SC05_008/nonmatchings/ov_SC05_008_jr_8017AE2C", func_8017DF68);
typedef struct { u16 vx, vy, vz, pad; } SVEC_8017DF68;
void func_8017DF68(SVEC_8017DF68 *p0, SVEC_8017DF68 *p1, s32 a2)
{
extern void func_8012EF70(s32 a0, s32 a1);
extern void func_8017E230(void *a0, void *a1, void *a2, void *a3, s32 *a4);
extern u8 D_801A10B8[];
SVEC_8017DF68 lo0;
SVEC_8017DF68 lo1;
SVEC_8017DF68 dead1;
SVEC_8017DF68 dead2;
SVEC_8017DF68 sv0;
SVEC_8017DF68 sv1;
SVEC_8017DF68 sv2;
SVEC_8017DF68 sv3;
s32 col;
s32 tx;
s32 ty;
col = 0x80 - (a2 * 128) / 80;
if (D_801A10B8[a2] != 0) {
col += D_801A10B8[a2] * 15;
}
col |= (col << 16) | (col << 8);
lo0 = *p0;
lo1 = *p1;
if ((((s32 (*)(void *, void *))func_8012EF70)(&lo0, &sv0) & ~0x1000) == 0 &&
(((s32 (*)(void *, void *))func_8012EF70)(&lo1, &sv1) & ~0x1000) == 0) {
lo0 = *p0;
tx = lo0.vx + 8;
ty = lo0.vy - 8;
lo0.vx = tx;
lo0.vy = ty;
lo1 = *p1;
tx = lo1.vx + 8;
ty = lo1.vy - 8;
lo1.vx = tx;
lo1.vy = ty;
if ((((s32 (*)(void *, void *))func_8012EF70)(&lo0, &sv2) & ~0x1000) == 0 &&
(((s32 (*)(void *, void *))func_8012EF70)(&lo1, &sv3) & ~0x1000) == 0) {
func_8017E230(&sv0, &sv1, &sv2, &sv3, &col);
lo0 = *p0;
tx = lo0.vx - 8;
ty = lo0.vy - 8;
lo0.vx = tx;
lo0.vy = ty;
lo1 = *p1;
tx = lo1.vx - 8;
ty = lo1.vy - 8;
lo1.vx = tx;
lo1.vy = ty;
if ((((s32 (*)(void *, void *))func_8012EF70)(&lo0, &sv2) & ~0x1000) == 0 &&
(((s32 (*)(void *, void *))func_8012EF70)(&lo1, &sv3) & ~0x1000) == 0) {
func_8017E230(&sv0, &sv1, &sv2, &sv3, &col);
}
}
}
}
@@ -4666,7 +4726,90 @@ void func_8017EB7C(void *a0) {
}
INCLUDE_ASM("asm/ov_SC05_008/nonmatchings/ov_SC05_008_jr_8017AE2C", func_8017EBB8);
typedef struct { u8 b[8]; } Blk8_EBB8;
typedef struct { u16 x, y, z, p0, p1, p2; } Rec12_EBB8;
extern s32 D_801151D4;
extern s32 D_80186558[];
extern s32 D_8019E64C;
extern Rec12_EBB8 D_8019E666[];
extern s32 D_801A1098;
extern s32 D_801A10A0;
extern s32 D_801A10A8;
extern s32 D_801A10B0;
extern void func_8012C1B8(void);
extern void func_8001C214();
extern void func_8012B2CC(s32 a0);
extern void func_8012F214(s32 a0, s32 a1, s32 a2);
extern s32 rand(void);
extern void func_8017EFE4(s32 a0);
extern void func_8012BF4C(s32 *a0, s32 a1);
extern s32 func_8012AD50(void *a0);
void func_8017EBB8(void *a0) {
register s32 s1 __asm__("$17");
register s32 s2 __asm__("$18");
register s32 idx __asm__("$4");
s32 tbl;
s32 sum;
s32 ent;
s32 copy;
s32 v;
s1 = (s32)a0;
__asm__ __volatile__("" : : : "memory");
idx = *(s16 *)(s1 + 0x70);
tbl = D_801151D4;
s2 = D_80186558[idx];
sum = *(s32 *)(tbl + 0x34) + ((*(u16 *)(tbl + 0x38) + 8) * 6);
ent = ((s32 (*)(void))func_8012C1B8)();
copy = ent;
*(s32 *)(s1 + 0x20) = ent;
if (ent != 0) {
if (s2 == (s32)&D_801A1098) goto L64;
if (s2 == (s32)&D_801A10A0) goto L64;
if (s2 == (s32)&D_801A10A8) goto L64;
if (s2 != (s32)&D_801A10B0) goto L48;
L64:
*(s32 *)(s1 + 0xDC) = 0;
v = ((s32 *)&D_8019E64C)[*(s16 *)(s1 + 0x70)];
*(s32 *)(s2 + 4) = 0;
*(s32 *)(s2 + 0) = v;
func_8001C214(copy, s2);
*(u16 *)(s1 + 0x88) = *(u16 *)((u8 *)D_8019E666 + *(s16 *)(s1 + 0x70) * 12 - 2);
*(u16 *)(s1 + 0x8A) = D_8019E666[*(s16 *)(s1 + 0x70)].x;
*(u16 *)(s1 + 0x8C) = D_8019E666[*(s16 *)(s1 + 0x70)].y;
*(Blk8_EBB8 *)(copy + 0x10) = *(Blk8_EBB8 *)(*(s32 *)(*(s32 *)(s1 + 0x64) + 0x20) + 0x10);
*(s32 *)(s1 + 0xC) = 0;
*(s32 *)(s1 + 8) = 0;
*(s32 *)(s1 + 4) = 0;
func_8012B2CC(s1);
func_8012F214(s1, s1 + 0x88, s1 + 0x88);
goto tail;
L48:
*(s32 *)(s1 + 0xDC) = 1;
*(u16 *)(s1 + 0x88) = *(u16 *)(sum + 0) - *(u16 *)(*(s32 *)(s1 + 0x64) + 6);
*(u16 *)(s1 + 0x8A) = *(u16 *)(sum + 2) - *(u16 *)(*(s32 *)(s1 + 0x64) + 0xA);
*(u16 *)(s1 + 0x8C) = *(u16 *)(sum + 4) - *(u16 *)(*(s32 *)(s1 + 0x64) + 0xE);
func_8001C214(ent, s2);
*(u16 *)(ent + 0x2C) = *(u16 *)(ent + 0x2C) | 0x80;
*(Blk8_EBB8 *)(s1 + 0xCC) = *(Blk8_EBB8 *)(*(s32 *)(s1 + 0x64) + 0xCC);
*(s32 *)(ent + 0x80) = s1 + 0xCC;
*(Blk8_EBB8 *)(ent + 0x10) = *(Blk8_EBB8 *)(*(s32 *)(*(s32 *)(s1 + 0x64) + 0x20) + 0x10);
*(s32 *)(s1 + 0xC) = 0;
*(s32 *)(s1 + 8) = 0;
*(s32 *)(s1 + 4) = 0;
func_8012B2CC(s1);
tail:
*(u16 *)(s1 + 0xFC) = (0x20 - rand()) & 0x3F;
*(u16 *)(s1 + 0xFE) = (0x20 - rand()) & 0x3F;
*(s32 *)(s1 + 0x44) = 0x1000 - ((rand() & 0x3F) << 7);
*(s32 *)(s1 + 0x48) = 0x1000 - ((rand() & 0x3F) << 7);
func_8017EFE4(s1);
func_8012BF4C((s32 *)s1, 0x1E);
func_8012AD50((void *)s1);
}
}
extern s32 func_8012BEE8(s32 a0);
extern s32 func_8012AD50(void *a0);
+98 -1
View File
@@ -4229,7 +4229,104 @@ void func_8017F9B4(s32 param_1)
}
INCLUDE_ASM("asm/ov_SC05_010/nonmatchings/ov_SC05_010_jr_8017C8D0", func_8017FAF4);
void func_8017FAF4(s32 param_1)
{
extern s32 D_801A3D5C;
extern u8 D_801202A0[];
extern volatile s32 D_801C7E4C;
extern s32 D_80126B60;
extern u16 D_80126B5E;
extern s32 func_8014CB8C(void);
extern s32 func_80172658(s32 *a0);
extern s32 func_801726A0(s32 *a0);
extern u8 D_801A3E2C[];
extern s32 D_801C7E78;
extern s32 D_801A3D94;
extern s32 D_801A33AC;
extern u8 *D_801C7E60[];
extern u8 D_80192480[];
extern u8 D_80192488[];
/* Second-copy aliases of the same two symbols. cse.c hashes a SYMBOL_REF by the
* interned-string POINTER, so a second decl with the same __asm__ name is a distinct
* rtx: the two halves of case 2 no longer unify, each address stays used exactly once,
* local-alloc's update_equiv_regs substitutes the constant back, and gcc emits `la $a0,…`
* at all four call sites (nop delay slot) instead of hoisting them into $s3/$s4. */
extern u8 D_80192480_b[] __asm__("D_80192480");
extern u8 D_80192488_b[] __asm__("D_80192488");
extern void *D_801C39FC[];
extern void func_800599B8(void *a0, void *a1);
extern void func_8012A828(s32 a0, void *a1);
extern void func_8002D4C8(s32 a0, s32 a1);
switch (*(u16 *)(param_1 + 0x34)) {
case 0:
if (*(s16 *)(param_1 + 0x98) == 0) {
u16 *ptr;
s32 i;
*(s16 *)(param_1 + 0x34) = 1;
func_8012A828(param_1, &D_801A3D5C);
*(s32 *)(param_1 + 0x1C) = 0x5A;
ptr = (u16 *)D_801202A0;
for (i = 0; i < 0x60; i++) {
if (ptr[0] == 0x2B5) {
ptr[0x1A] = 1;
}
ptr += 0x86;
}
*(s32 *)(D_801C7E4C + 0xE0) = 0x78;
}
break;
case 1:
if (func_8014CB8C() == 0) {
s32 *p = &D_80126B60;
if (*p < 0) {
if (func_80172658(p - 2) != 0 || func_801726A0(p - 2) != 0) {
D_80126B5E = D_80126B5E + 4;
} else {
D_80126B5E = D_80126B5E + 0x18;
}
}
}
if (--*(s32 *)(param_1 + 0x1C) == 0) {
*(s16 *)(param_1 + 0x34) = 2;
func_8012A828(param_1, &D_801A3E2C);
*(u8 *)(param_1 + 0xC2) = 0;
func_8002D4C8(4, 0x89F);
*(s32 *)(param_1 + 0x1C) = 7 - D_801C7E78 * 2;
}
break;
case 2: {
u8 t;
t = (*(u8 *)(param_1 + 0xC2) + 2) & 0xF;
*(u8 *)(param_1 + 0xC2) = t;
func_800599B8(D_80192480, D_801C39FC[t]);
func_800599B8(D_80192488, D_801C39FC[*(u8 *)(param_1 + 0xC2) + 1]);
if (*(u16 *)(param_1 + 0x72) & 0x4000) {
if (--*(s32 *)(param_1 + 0x1C) == 0) {
*(s16 *)(param_1 + 0x34) = 3;
func_8012A828(param_1, &D_801A3D94);
*(u8 *)(param_1 + 0xC2) = 0;
func_800599B8(D_80192480_b, D_801C39FC[*(u8 *)(param_1 + 0xC2)]);
func_800599B8(D_80192488_b, D_801C39FC[*(u8 *)(param_1 + 0xC2) + 1]);
}
}
break;
}
case 3:
if (*(s16 *)(param_1 + 0x98) == 0) {
func_8012A828(param_1, &D_801A33AC);
*(s16 *)(param_1 + 2) = 1;
*(s32 *)(param_1 + 0x1C) = 0x5A;
*(s16 *)(D_801C7E60[0] + 0xAE) = -1;
*(u16 *)(param_1 + 0x70) &= 0xFFFE;
}
break;
}
}
void func_8017FDE0(s32 param_1)
{
+98 -1
View File
@@ -4375,7 +4375,104 @@ void func_8017E9B8(void) {
}
INCLUDE_ASM("asm/ov_SC06_025/nonmatchings/ov_SC06_025_jr_8017BEBC", func_8017EA74);
#include "common.h"
typedef struct {
u16 v[4];
} Tbl8_801AFF3C; /* 8 bytes, align 2 -> lwl/lwr/swl/swr copy */
typedef struct {
u16 a, b, c, d;
} Ent8_80188; /* 8-byte stride record */
extern Tbl8_801AFF3C D_801AFF3C;
extern Ent8_80188 D_801888CC[];
extern Ent8_80188 D_801888EC[];
extern u16 D_80126B5E;
extern u16 D_80126B62;
extern u16 D_80126B66;
extern s32 func_8012E544(s32 a0);
extern void func_8012B0B4(u32 *a0, s32 a1, s32 a2);
extern s32 func_80182090(s32, s32);
extern void func_80181CA4();
void func_8017EA74(s32 a0) {
Tbl8_801AFF3C tbl;
s16 vecA[4];
s16 vecB[4];
s32 buf[6];
s32 rec;
s16 mode;
s32 ret;
tbl = D_801AFF3C;
rec = func_8012E544(0x2CD);
if (rec == 0) {
return;
}
if (*(u16 *)(rec + 0x2) >= 8) {
return;
}
mode = *(s16 *)(a0 + 0x2);
switch (mode) {
case 0:
if (*(u16 *)(rec + 0x2) == 3) {
*(s16 *)(a0 + 0x2) = mode + 1;
}
break;
case 1:
*(u16 *)(a0 + 0x16) = D_801888CC[*(s16 *)(a0 + 0x8)].a;
*(u16 *)(a0 + 0x1A) = D_801888CC[*(s16 *)(a0 + 0x8)].b;
*(u16 *)(a0 + 0x1E) = D_801888CC[*(s16 *)(a0 + 0x8)].c;
*(u16 *)(a0 + 0x2) = *(u16 *)(a0 + 0x2) + 1;
*(s16 *)(a0 + 0xA) = 0;
break;
case 2:
if (*(s16 *)(a0 + 0x8) < 2) {
vecA[0] = *(u16 *)(rec + 0x6);
vecA[1] = *(u16 *)(rec + 0xA);
vecA[2] = *(u16 *)(rec + 0xE);
*(s32 *)(a0 + 0xC) = 1;
} else {
vecA[0] = D_80126B5E;
vecA[1] = D_80126B62;
vecA[2] = D_80126B66;
if (*(u16 *)(rec + 0x2) == 4) {
*(s32 *)(a0 + 0xC) = 1;
} else {
*(s32 *)(a0 + 0xC) = 0;
}
}
vecA[1] = D_801888EC[*(s16 *)(a0 + 0x8)].b;
vecA[0] = vecA[0] + D_801888EC[*(s16 *)(a0 + 0x8)].a;
vecA[2] = vecA[2] + D_801888EC[*(s16 *)(a0 + 0x8)].c;
vecB[0] = *(u16 *)(a0 + 0x16);
vecB[1] = *(u16 *)(a0 + 0x1A);
vecB[2] = *(u16 *)(a0 + 0x1E);
func_8012B0B4((u32 *)buf, *(s16 *)(a0 + 0x4), 0x50);
vecA[0] = vecA[0] + ((s16)buf[0] * 2);
vecA[2] = vecA[2] + (buf[0] >> 16);
*(u16 *)(a0 + 0x4) = *(u16 *)(a0 + 0x4) + tbl.v[*(s16 *)(a0 + 0x8)];
*(u16 *)(a0 + 0xA) = *(u16 *)(a0 + 0xA) + 0x200;
if (*(s16 *)(a0 + 0xA) >= 0x1000) {
*(s16 *)(a0 + 0xA) = 0x1000;
}
ret = func_80182090(0x105050, *(s16 *)(a0 + 0xA));
func_80181CA4(a0, vecA, 0x60, ret, vecB, 8, ret, 3);
break;
}
}
#include "common.h"
+146 -1
View File
@@ -3405,7 +3405,152 @@ set_state6_timeout:
}
INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_801902EC", func_80190D70);
#include "common.h"
/* func_80190D70 - ov_SC06_032 / ov_SC06_032_jr_801902EC (192 ins). MATCH, closeness 0.
*
* Body verified byte-exact standalone AND against the REAL 3407-line TU prefix
* (every file-scope decl + engine_core.h) -- see the decl notes below.
*
* Structure straight from the .s: a "did my owner change?" reinit guard, then a
* 3-case state machine on *(u16 *)(a0 + 0x34) (an if/else chain, not a jump table
* -- the .s dispatches with beq 1 / slti 2 / beqz / beq 2).
* guard : owner-stamp mismatch -> reset state, re-arm, randomise 0xFC/0xFE/0x100
* case 0: countdown, then snapshot the owner's world XYZ, RotTransPers it, and if
* the projected point is on-screen fire a positional SFX whose low byte is
* the distance-attenuated volume ((0xA0 - |sx|) * 0x7F / 0xA0) and whose
* pan nibble is (sx + 0xA0) / 0x14 clamped 0x10 -> 0xF, << 8, | 0x3000.
* case 1: countdown, walking the entity back along its heading (rcos/rsin * 32).
* case 2: spin the owner's 0x10 angle by 0x20 until it hits 0x380.
* Cases 1 and 2 share the ".L80191058: sh $v0, 0x34($s0)" tail via a cross-jump; both
* are written as the same `*(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;` statement,
* and gcc's cross-jumper re-merges them (case 1's arm reuses the $a0 copy of the
* switch value that the dispatch already loaded).
*/
/* ---- DECLARATION LAYER: block scope, but NOT free-form (this is what sank the
* previous attempt on this function -- it was byte-perfect in isolation and a hard
* cc1 error inside the TU, which reads as an unexplained gate rejection).
*
* §55a says a block-scope extern conflicts with nothing at file scope. That is FALSE
* in this direction for gcc-2.7.2: an inner redeclaration is merged with the outer one
* into the C89 COMPOSITE type, so
* - `extern void func_8012B1B4(s32, s32);` against this TU's file-scope
* `extern void func_8012B1B4(void *, void *);` (L2939) -> ERROR "conflicting types"
* - `extern void func_8012B23C();` does NOT hide the file-scope prototype
* `extern void func_8012B23C(void *);` (L2938); the composite keeps the parameter
* list, so the zero-arg call -> ERROR "too few arguments to function"
* Both were reproduced by compiling the real TU prefix + this body.
*
* So: spell every redeclaration EXACTLY as the TU already spells it (law 2), and where
* the TU's arity is wrong for this call site, do not fight the prototype -- go through
* a cast function pointer, this TU's own house idiom (L3060,
* `((s32 (*)(s32))func_8012BE54)(param_1)`), which still emits a direct `jal`.
*
* The .s proves func_8012B23C takes ZERO arguments here: $a0 is never set up before the
* jal, and its delay slot holds `sh $zero, 0x34($s0)` -- an invented argument would cost
* an `addu $a0, $s0, $zero` and move the store out of the slot (SYS law 4).
*
* D_800AF648 is the scalar `extern u8` spelling engine_core.h uses everywhere; the two
* $a0-pinned scopes below are its §2 remat lever (hoisting the lui/addiu out would emit
* one `la` + two `move $4,$sN` instead of the target's two `la $4,...`).
*/
void func_80190D70(s32 a0) {
extern void func_8012B23C(void *);
extern void func_8012B1B4(void *a0, void *a1);
extern s32 rand(void);
extern void func_8004914C(void *a0);
extern void func_800491AC(void *a0);
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
extern s32 func_8004787C(s32 a0);
extern s32 func_80047948(s32 a0);
extern void func_8002D4C8(s32 a0, s32 a1);
extern u8 D_800AF648;
extern u8 D_801CC7D4[];
struct {
s16 v[3]; /* sp+0x10 */
s16 pad; /* sp+0x16 */
u16 sxy[2]; /* sp+0x18 */
s32 z; /* sp+0x1C */
s32 flag; /* sp+0x20 */
} L;
if (*(s16 *)(a0 + 0xFC) != *(s16 *)(*(s32 *)(a0 + 0x64) + 0x36)) {
*(s16 *)(a0 + 2) = 5;
*(s16 *)(a0 + 0x34) = 0;
((void (*)(void))func_8012B23C)();
func_8012B1B4((void *)a0, D_801CC7D4);
*(s16 *)(a0 + 0x16) = (rand() & 3) - 0x1B;
*(s16 *)(a0 + 0xA) = *(u16 *)(a0 + 0xA) - 0x38;
*(s16 *)(a0 + 0xFC) = (rand() & 0xFF) - 0x80;
*(s16 *)(a0 + 0xFE) = (rand() & 0xFF) - 0x80;
*(s16 *)(a0 + 0x100) = (rand() & 0xFF) - 0x80;
*(s32 *)(a0 + 0x1C) = 0x3C;
return;
}
switch (*(u16 *)(a0 + 0x34)) {
case 0:
if (*(s32 *)(a0 + 0x1C) != 0) {
*(s32 *)(a0 + 0x1C) = *(s32 *)(a0 + 0x1C) - 1;
*(s16 *)(a0 + 0xA) = *(u16 *)(a0 + 0xA) - 4;
return;
}
*(s32 *)(a0 + 0x1C) = 0x14;
*(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48);
L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C);
L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50);
/* $a0-pinned scopes: rematerialise &D_800AF648 (lui/addiu) before EACH call */
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); }
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); }
RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag);
if (L.flag >= 0 && (u32)((L.sxy[0] + 0x9F) & 0xFFFF) < 0x13F
&& (u32)((L.sxy[1] + 0x77) & 0xFFFF) < 0xEF) {
s32 sx; /* screen X, then REUSED as the pan field */
register s32 av __asm__("$5"); /* |X| */
s32 vol;
sx = (s16)L.sxy[0];
av = sx;
if (sx < 0) {
av = -sx;
}
vol = ((0xA0 - av) * 0x7F) / 0xA0;
/* sched1 otherwise hoists the PAN multiply ahead of this one */
__asm__("" : "=r"(vol) : "0"(vol));
sx = (sx + 0xA0) / 0x14;
if (sx == 0x10) {
sx = 0xF;
}
sx = sx << 8; /* in place, so reorg can steal it into the bne delay slot */
func_8002D4C8(0x9E5, (vol | (0x3000 | sx)) & 0xFFFF);
}
return;
case 1:
if (*(s32 *)(a0 + 0x1C) != 0) {
*(s32 *)(a0 + 0x1C) = *(s32 *)(a0 + 0x1C) - 1;
*(s32 *)(a0 + 4) =
*(s32 *)(a0 + 4) - (func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) << 5);
*(s32 *)(a0 + 0xC) =
*(s32 *)(a0 + 0xC) - (func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) << 5);
return;
}
*(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
return;
case 2:
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + 0x20;
if (*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) != 0x380) {
return;
}
*(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
return;
}
}
typedef struct {
SVECTOR_8016E7C8 v[4]; /* 0x00 */