mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-28 06:49:47 -04:00
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:
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user