From a67c82d340b548c52db53df085fa9dea7df536b1 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Tue, 11 Aug 2026 21:14:46 -0600 Subject: [PATCH] =?UTF-8?q?fix(phase-30=20S48):=20bank=20func=5F80187960?= =?UTF-8?q?=20=E2=80=94=20=C2=A7161c=20decl=20agreement,=20not=20a=20codeg?= =?UTF-8?q?en=20wall?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wave-2 draft declared `extern void func_8012CAE4(void *a0);` at block scope while the host TU already declares it twice at file scope (K&R at :2790, `s32 a0` at :2849), so the gate reported PLUMBING: conflicting types. Dropping the decl is wrong — match_one compiles the draft STANDALONE and then the symbol is undeclared (gcc-2.7.2 prints that with no `error:` prefix, so it reads as CC1 FAIL). The fix is to AGREE with the TU's visible decl and cast the ARGUMENT (`(s32)a0` — same bits in $a0, codegen unchanged). MATCH (99 ins) standalone, then BANKED on the whole-binary gate. --- src/ov_SC06_018/ov_SC06_018_jr_80186270.c | 89 ++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/src/ov_SC06_018/ov_SC06_018_jr_80186270.c b/src/ov_SC06_018/ov_SC06_018_jr_80186270.c index 0a8907671..39de5a5a8 100644 --- a/src/ov_SC06_018/ov_SC06_018_jr_80186270.c +++ b/src/ov_SC06_018/ov_SC06_018_jr_80186270.c @@ -3417,4 +3417,91 @@ void func_80187924(void *a0) { } -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80186270", func_80187960); +#include "common.h" + +/* + * func_80187960 — "spawn init" state handler. + * + * Sibling-search hit (cookbook §160g): func_8018523C + * (src/ov_SC03_119/ov_SC03_119_jr_8017FB84.c) shares the exact opening + * idiom — func_8012C1B8() -> store result to a0+0x20 -> if zero, + * func_8012CAE4(a0); return; else func_8001C214(v0, TABLE[idx]) — and the + * same shared-engine-core template also lives at + * src/shared/engine_core.h:10060 DEFINE_func_80144A98(). Both establish the + * house style used here: `extern void func_8012C1B8(void);` called through + * a `(s32 (*)(void))` cast (the canonical decl elsewhere is void-returning; + * §161c — cast at the call site rather than fighting it), and + * func_8012CAE4/func_8001C214 declared exactly as they already appear + * in this TU (grep hits at src/ov_SC06_018/ov_SC06_018_jr_80186270.c + * lines 2783/2790/2849/2895/2896). + * + * D_811B53E4 is stored by ADDRESS only (lui/addiu, no lw) — §160f array + * declaration to force the address-only store. + * + * The three `lhu ...,0x70($s1); andi ...,0xF` sequences are NOT cached in + * a local — the target re-loads/re-masks independently at the array index, + * the ==4 compare, and the ==5 compare (three separate `lhu+andi` pairs in + * the .s), so the raw expression is repeated at each site rather than + * hoisted into one named temp. + */ + +void func_80187960(void *a0) { + extern void func_8012C1B8(void); + extern void func_8012CAE4(s32 a0); + extern void func_8001C214(s32 a0, s32 a1); + extern void func_80049CAC(s32 a0, s32 a1); + extern void func_800484EC(s32 a0, s32 a1, s32 a2); + extern s32 rand(void); + extern s32 D_801B53CC[]; + extern u8 D_811B53E4[]; + + s16 buf[16]; /* sp+0x10 — output of func_80049CAC / input to func_800484EC */ + s16 rv[3]; /* sp+0x30 — random SVECTOR-ish {x,y,z} */ + s32 w[3]; /* sp+0x38 — {0, 0, 0xFFE80000} scratch handed to func_800484EC */ + s32 v0; + s32 m; + + v0 = ((s32 (*)(void))func_8012C1B8)(); + *(s32 *)((s32)a0 + 0x20) = v0; + if (v0 == 0) { + func_8012CAE4((s32)a0); + return; + } + + func_8001C214(v0, D_801B53CC[*(u16 *)((s32)a0 + 0x70) & 0xF]); + + *(u16 *)((s32)a0 + 0x10A) = *(u16 *)(*(s32 *)((s32)a0 + 0x64) + 0x36); + + if ((*(u16 *)((s32)a0 + 0x70) & 0xF) == 4) { + *(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x20) = (s32)D_811B53E4; + } + + if ((*(u16 *)((s32)a0 + 0x70) & 0xF) == 5) { + *(s16 *)((s32)a0 + 0x2) = 2; + return; + } + + w[1] = 0; + w[0] = 0; + w[2] = -0x180000; + m = rand() % 0x80; + if ((rand() & 1) == 0) { + rv[0] = m - 0x380; + } else { + rv[0] = -0x380 - m; + } + + rv[1] = *(u16 *)(*(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0x20) + 0x12) + 0x800; + rv[2] = 0; + func_80049CAC((s32)rv, (s32)buf); + + func_800484EC((s32)buf, (s32)w, (s32)a0 + 0x10); + + *(s32 *)((s32)a0 + 0x48) = 0x18000; + *(u16 *)((s32)a0 + 0xFC) = rand() & 0xF0; + *(u16 *)((s32)a0 + 0xFE) = rand() & 0x7F; + *(u16 *)((s32)a0 + 0x100) = rand() & 0x30; + *(s32 *)((s32)a0 + 0x1C) = 0; + *(u16 *)((s32)a0 + 0x2) = *(u16 *)((s32)a0 + 0x2) + 1; +} +