From 80c548a59bcc73aec60f9973ee07445b2a37b414 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Sun, 30 Aug 2026 20:32:26 -0600 Subject: [PATCH] =?UTF-8?q?feat(decomp):=20O41=20overlay=20lane=20?= =?UTF-8?q?=E2=80=94=2017=20fns,=20clean-R22=20verified=20213/213?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit parallel_gate merged 17 across 16 binaries, aborted on a real red (ov_SC04_011). Reverted that one file (func_80181F0C); the other 17 fns verify green from a full clean rebuild. CORRECTION to my own first read: I attributed the ov_SC04_011 failure to func_80182DCC, whose agent had flagged a needed jtbl carve for that same binary. The merged-and-failing draft was actually func_80181F0C — I inferred from the binary name matching the carve note instead of reading the diff. The carve-prediction pattern is still real and worth acting on, on the evidence that does hold: three agents this session named, in advance, the integration reason the whole-binary gate would refuse a draft they had just matched in isolation (func_801588CC's §8e/§260-A tail-class jtbl carve; func_80182DCC's jtbl_801ED970 8-word carve in tail19.data.s; func_8001AF34's JTBL_PADS residual). Those are gate-side work, not drafting failures, and must not be re-drafted — that is how ov_SC06_022:func_80181664 burned three slots. --- src/md_MAIN_013/md_MAIN_013.c | 96 ++++++++++++- src/md_MAIN_037/md_MAIN_037.c | 18 ++- src/md_SC07_004/md_SC07_004.c | 104 +++++++++++++- src/ov_MAIN_012/ov_MAIN_012_jr_8016AE5C.c | 91 +++++++++++- src/ov_SC01_001/ov_SC01_001_jr_8017D2DC.c | 121 +++++++++++++++- src/ov_SC01_080/ov_SC01_080_jr_8017AE2C.c | 74 +++++++++- src/ov_SC02_005/ov_SC02_005_jr_80181D30.c | 162 +++++++++++++++++++++- src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c | 81 ++++++++++- src/ov_SC02_017/ov_SC02_017_jr_8017DF34.c | 91 +++++++++++- src/ov_SC03_028/ov_SC03_028_jr_80183A74.c | 59 +++++++- src/ov_SC05_008/ov_SC05_008_jr_8017AE2C.c | 82 ++++++++++- src/ov_SC06_016/ov_SC06_016_jr_8017C8D0.c | 96 ++++++++++++- src/ov_SC06_025/ov_SC06_025_jr_8017BEBC.c | 56 +++++++- src/ov_SC06_025/ov_SC06_025_jr_8017EEC4.c | 71 +++++++++- src/ov_SC06_029/ov_SC06_029_jr_8017C954.c | 63 ++++++++- src/ov_SC07_007/ov_SC07_007_jr_8017BEBC.c | 76 +++++++++- 16 files changed, 1324 insertions(+), 17 deletions(-) diff --git a/src/md_MAIN_013/md_MAIN_013.c b/src/md_MAIN_013/md_MAIN_013.c index f38bee388..6ebcd7f32 100644 --- a/src/md_MAIN_013/md_MAIN_013.c +++ b/src/md_MAIN_013/md_MAIN_013.c @@ -136,7 +136,101 @@ void func_800CB0E8(void *a0) { } -INCLUDE_ASM("asm/md_MAIN_013/nonmatchings/md_MAIN_013", func_800CB138); +#include "common.h" + +void func_800CB138(s32 arg0) { + + typedef struct { s32 w[8]; } Blk20; + + extern Blk20 D_800AE620; + extern u8 D_800CB8FC[]; + extern u8 D_800CB88C[]; + extern s32 rand(void); + extern u8 *func_800D222C(s32 a0, s32 a1, s32 a2); + extern void func_800D20C0(void *a0, void *a1, s32 a2); + extern void func_800D23D0(void *a0); + extern void RotMatrixYXZ(); + extern void RotMatrixZ(s32 a0, void *a1); + extern void ApplyMatrixSV(); + extern void MulMatrix0(s32 a0, void *a1, s32 a2); + extern void func_8012F14C(s32 a0, s32 a1, s32 a2); + extern void func_80128EA8(); + extern void func_80146C3C(); + + s16 sp10[4]; + s16 sp18[4]; + s16 mtx[16]; + u16 vec[4]; + s16 sv2[4]; + Blk20 blk; + + s32 ent; + u8 *p; + s32 m; + s32 ang; + register s32 ang2 __asm__("$4"); + + ent = *(s32 *)(arg0 + 0x34); + if ((*(s32 *)(arg0 + 0x2C) & 0x8000) == 0) { + sp10[0] = *(u16 *)(ent + 6); + sp10[1] = *(u16 *)(ent + 0xA); + sp10[2] = *(u16 *)(ent + 0xE); + func_800D20C0(sp10, sp18, 0); + func_800D23D0(sp18); + RotMatrixYXZ(sp18, arg0 + 0x38); + *(s16 *)(arg0 + 2) = 2; + } else { + p = func_800D222C(arg0, (s32)D_800CB8FC, 0x1A); + if (p != 0) { + *(s16 *)(arg0 + 0x10) = rand() & 0xFFF; + m = *(s32 *)(arg0 + 0x34); + __asm__ __volatile__("" : : : "memory"); + { register Blk20 *s __asm__("$5") = &D_800AE620; s32 t0, t1, t2; + __asm__ __volatile__("" : "=r"(s) : "0"(s)); + t0 = s->w[0]; t1 = s->w[1]; t2 = s->w[2]; + blk.w[0] = t0; blk.w[1] = t1; blk.w[2] = t2; + t0 = s->w[3]; t1 = s->w[4]; t2 = s->w[5]; + blk.w[3] = t0; blk.w[4] = t1; blk.w[5] = t2; + t0 = s->w[6]; t1 = s->w[7]; + blk.w[6] = t0; blk.w[7] = t1; } + ang = *(s16 *)(arg0 + 0x10); + { void *q = &blk; RotMatrixZ(ang, q); __asm__ __volatile__("" : "=r"(q)); } + vec[0] = *(s32 *)(arg0 + 0x30) << 2; + vec[1] = 0; + vec[2] = 0x30; + { void *q = &blk; ApplyMatrixSV(q, vec, vec); __asm__ __volatile__("" : "=r"(q)); } + m += 0x38; + func_8012F14C(m, (s32)vec, (s32)vec); + *(s16 *)(arg0 + 6) = vec[0]; + *(s16 *)(arg0 + 0xA) = vec[1]; + ang2 = ang + 0x200; + __asm__ __volatile__("" : : : "memory"); + *(s16 *)(arg0 + 0xE) = vec[2]; + __asm__ __volatile__("" : : : "memory"); + { register Blk20 *s __asm__("$7") = &D_800AE620; + s32 t0, t1; register s32 t2 __asm__("$6"); + __asm__ __volatile__("" : "=r"(s) : "0"(s)); + t0 = s->w[0]; t1 = s->w[1]; t2 = s->w[2]; + blk.w[0] = t0; blk.w[1] = t1; blk.w[2] = t2; + t0 = s->w[3]; t1 = s->w[4]; t2 = s->w[5]; + blk.w[3] = t0; blk.w[4] = t1; blk.w[5] = t2; + t0 = s->w[6]; t1 = s->w[7]; + blk.w[6] = t0; blk.w[7] = t1; } + { void *q; __asm__ __volatile__("" : : : "memory"); q = &blk; + RotMatrixZ(ang2, q); __asm__ __volatile__("" : "=r"(q)); } + MulMatrix0(m, &blk, arg0 + 0x38); + *(s32 *)(arg0 + 0x20) = (s32)p; + *(s32 *)(p + 0x34) = arg0 + 0x38; + *(u16 *)(p + 0x1A) = 0x2000; + *(u16 *)(p + 0x18) = 0x2000; + func_80128EA8(p, arg0 + 0x24, D_800CB88C); + *(s16 *)(arg0 + 2) = *(u16 *)(arg0 + 2) + 1; + } else { + func_80146C3C(arg0); + } + } +} + extern void func_80146C3C(void); diff --git a/src/md_MAIN_037/md_MAIN_037.c b/src/md_MAIN_037/md_MAIN_037.c index 983bb3afa..a4a9b3e8e 100644 --- a/src/md_MAIN_037/md_MAIN_037.c +++ b/src/md_MAIN_037/md_MAIN_037.c @@ -1,6 +1,22 @@ #include "common.h" -INCLUDE_ASM("asm/md_MAIN_037/nonmatchings/md_MAIN_037", func_800CAE0C); +extern s32 func_800183E0(s32 *a0); + +extern s32 D_800CB95C; +extern s32 *D_800CB5D4[]; + +s32 func_800CAE0C(void) { + s32 idx = D_800CB95C; + s32 *p = D_800CB5D4[idx]; + + D_800CB95C = idx + 1; + if (p == NULL) { + p = D_800CB5D4[0]; + D_800CB95C = 1; + } + return func_800183E0(p); +} + extern s32 func_800183E0(s32 *a0); diff --git a/src/md_SC07_004/md_SC07_004.c b/src/md_SC07_004/md_SC07_004.c index eab8b9110..feb8cb28c 100644 --- a/src/md_SC07_004/md_SC07_004.c +++ b/src/md_SC07_004/md_SC07_004.c @@ -1088,7 +1088,109 @@ void func_801A3B08(s32 a0) { } -INCLUDE_ASM("asm/md_SC07_004/nonmatchings/md_SC07_004", func_801A3B18); +#include "common.h" + +typedef struct { s16 m[3][3]; s32 t[3]; } Mtx32_801A3B18; +typedef struct { s16 vx, vy, vz, pad; } SVec_801A3B18; + +extern void RotMatrixY(s32 a0, void *a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void RotTransSV(s32 a0, s32 a1, void *a2); +extern s32 func_8012B70C(s16 *a0, s16 *a1); +extern void func_8012BE54(s32 a0); +extern s32 func_8014CB8C(void); +extern s32 func_8017267C(s32 *a0); +extern void ApplyRotMatrixLV(void *in, void *out); + +extern s16 D_80126B5E; +extern s16 D_80126B62; +extern s16 D_80126B66; +extern s32 D_80126B58[4]; +extern s32 D_801F8864; + +void func_801A3B18(s32 param_1) +{ + Mtx32_801A3B18 mtx; /* sp+0x10 */ + SVec_801A3B18 sv; /* sp+0x30 */ + SVec_801A3B18 sv2; /* sp+0x38 */ + s32 vec[4]; /* sp+0x40 */ + s32 flag; /* sp+0x50 */ + s32 v0; + s32 amt; + s32 d; + s32 e; + s32 ang; + s32 mag; + register s32 zr __asm__("$0"); + s32 *p; + /* D_800AE620 is the shared 32-byte matrix global; this TU already declares it + * later as `extern Mtx32_801A90D8 D_800AE620;` (md_SC07_004.c:1569). Declared + * here at BLOCK scope on purpose: a second file-scope spelling is a hard + * `conflicting types` error in gcc-2.7.2, while a block-scope one is only a + * warning — and re-typedef'ing Mtx32_801A90D8 above line 1565 would break the + * definition that already lives there. */ + extern s32 D_800AE620[8]; + + mtx = *(Mtx32_801A3B18 *)&D_800AE620; + + RotMatrixY(*(s16 *)(*(s32 *)(param_1 + 0x20) + 0x12), &mtx); + + mtx.t[0] = *(s16 *)(param_1 + 0x6); + mtx.t[1] = *(s16 *)(param_1 + 0xA); + mtx.t[2] = *(s16 *)(param_1 + 0xE); + func_8004914C(&mtx); + func_800491AC(&mtx); + + sv.vy = 0; + sv.vx = 0; + sv.vz = 0x80; + RotTransSV((s32)&sv, (s32)&sv, &flag); + + sv2.vx = (u16)D_80126B5E; + sv2.vy = (u16)D_80126B62; + sv2.vz = (u16)D_80126B66; + + p = D_80126B58; + d = func_8012B70C((s16 *)&sv, (s16 *)&sv2) - + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12); + e = d & 0xFFF; + ang = e + zr; + if (e >= 0x800) { + ang = e | 0xF000; + } + mag = ang + zr; + if ((s16)ang < 0) { + mag = -ang; + } + + v0 = ((s32 (*)(s32))func_8012BE54)(param_1); + + if (func_8014CB8C() == 0 && v0 <= 0x23FFF && (s16)mag < 0x200 && + func_8017267C(p) == 0) { + if (D_801F8864 > -0x1E0000) { + D_801F8864 -= 0xC000; + } + } else { + if (D_801F8864 < 0) { + D_801F8864 += 0x10000; + if (D_801F8864 > 0) { + D_801F8864 = 0; + } + } + } + + amt = D_801F8864; + if (amt != 0) { + vec[1] = 0; + vec[0] = 0; + vec[2] = amt; + ApplyRotMatrixLV(vec, vec); + p[1] += vec[0]; + p[3] += vec[2]; + } +} + INCLUDE_ASM("asm/md_SC07_004/nonmatchings/md_SC07_004", func_801A3D60); diff --git a/src/ov_MAIN_012/ov_MAIN_012_jr_8016AE5C.c b/src/ov_MAIN_012/ov_MAIN_012_jr_8016AE5C.c index a528eacd6..33f794a49 100644 --- a/src/ov_MAIN_012/ov_MAIN_012_jr_8016AE5C.c +++ b/src/ov_MAIN_012/ov_MAIN_012_jr_8016AE5C.c @@ -3964,7 +3964,96 @@ void func_8016D19C(void *a0) { } -INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_8016AE5C", func_8016D1D8); +extern void func_801465C0(void); +extern void func_800233CC(void *, unsigned short); +extern void func_8001CD9C(int, void *); +extern void func_80147324(int); +extern int rand(void); +extern void RotMatrixYXZ(void *, void *); +extern void ApplyMatrixSV(); + +extern unsigned char D_80184851[]; +extern unsigned char D_80184852; +extern unsigned char D_80184854; +extern unsigned char D_80184855; +extern unsigned char D_80184856; +extern unsigned char D_80184891[]; +extern unsigned char D_80184892; +extern unsigned char D_80184894; +extern unsigned char D_80184895; +extern unsigned char D_80184896; + +void func_8016D1D8(int param_1) +{ + int iVar5; + int iVar2; + unsigned int uVar3; + short sVar4; + short sv[4]; + int mtx[8]; + + iVar5 = *(int *)(param_1 + 0x34); + if (*(int *)(param_1 + 0x2c) == 0) { + int pp; + D_80184851[0] = 0xE0; + D_80184852 = 0xE0; + D_80184851[-1] = 0xE0; + D_80184856 = 0; + D_80184855 = 0; + D_80184854 = 0; + iVar5 = ((int (*)(void))func_801465C0)(); + if (iVar5 != 0) { + *(int *)(param_1 + 0x20) = iVar5; + func_800233CC(&D_80184851[-1], 0x28); + func_8001CD9C(iVar5, &D_80184851[-1]); + *(short *)(iVar5 + 0x1a) = 0x1400; + *(unsigned int *)(iVar5 + 4) = *(unsigned int *)(iVar5 + 4) | 0x50000000; + pp = *(int *)(param_1 + 0x30); + *(unsigned short *)(param_1 + 0x28) = *(unsigned short *)(pp + 0x36); + *(unsigned short *)(param_1 + 0x12) = *(unsigned short *)(pp + 6); + *(short *)(param_1 + 0x16) = *(unsigned short *)(pp + 0xa) - 0x28; + *(unsigned short *)(param_1 + 0x1a) = *(unsigned short *)(pp + 0xe); + *(unsigned short *)(param_1 + 2) = *(unsigned short *)(param_1 + 2) + 1; + } + *(int *)(param_1 + 0x1c) = 8; + func_80147324(0x647); + } else { + D_80184891[0] = 0xE0; + D_80184892 = 0x20; + D_80184891[-1] = 0x20; + D_80184895 = 0; + D_80184896 = 0; + D_80184894 = 0; + iVar2 = ((int (*)(void))func_801465C0)(); + if (iVar2 != 0) { + *(int *)(param_1 + 0x20) = iVar2; + func_800233CC(&D_80184891[-1], 0x18); + func_8001CD9C(iVar2, &D_80184891[-1]); + *(unsigned int *)(iVar2 + 4) = *(unsigned int *)(iVar2 + 4) | 0x50000000; + *(unsigned short *)(param_1 + 6) = *(unsigned short *)(iVar5 + 6); + *(unsigned short *)(param_1 + 0xa) = *(unsigned short *)(iVar5 + 0xa); + *(unsigned short *)(param_1 + 0xe) = *(unsigned short *)(iVar5 + 0xe); + uVar3 = rand(); + sv[0] = ((uVar3 & 0x7F) * 8) - 0x80; + sv[1] = (uVar3 & 0x7F00) >> 3; + sv[2] = 0; + RotMatrixYXZ(sv, mtx); + sv[1] = 0; + sv[0] = 0; + sv[2] = 0x240; + ((void (*)(void *, void *, void *))ApplyMatrixSV)(mtx, sv, sv); + *(int *)(param_1 + 0x10) = sv[0] << 12; + *(int *)(param_1 + 0x14) = sv[1] << 12; + sVar4 = (uVar3 & 0x3F0) + 0x200; + *(int *)(param_1 + 0x18) = sv[2] << 12; + *(short *)(iVar2 + 0x1a) = sVar4; + *(short *)(iVar2 + 0x18) = sVar4; + *(int *)(param_1 + 0x1c) = 0x10; + *(short *)(param_1 + 2) = 2; + } + } +} + diff --git a/src/ov_SC01_001/ov_SC01_001_jr_8017D2DC.c b/src/ov_SC01_001/ov_SC01_001_jr_8017D2DC.c index bc2e39684..42fe42ee9 100644 --- a/src/ov_SC01_001/ov_SC01_001_jr_8017D2DC.c +++ b/src/ov_SC01_001/ov_SC01_001_jr_8017D2DC.c @@ -5717,7 +5717,126 @@ void func_80182238(void) { } -INCLUDE_ASM("asm/ov_SC01_001/nonmatchings/ov_SC01_001_jr_8017D2DC", func_80182284); +#include "common.h" + +/* §200 alias: this TU spells func_8001D074 `void (s32,s32)` (lines 119/124), but the target + stores its $v0 into the slot pointer. Bind our own identifier to the same link name so the + TU's spelling stays untouched (same trick already used for func_8018183C at line 5156). */ +extern s32 aF8001D074(s32, s32) __asm__("func_8001D074"); +extern void func_800233CC(void *, unsigned short); +extern void func_8001CD9C(int, void *); + +extern u8 D_801F2A44[]; +extern u8 D_801F2A48[]; +extern u8 D_801F2A50[]; +extern u8 D_801F2A51[]; +extern u8 D_801F2A52[]; +extern u8 D_801F2A54[]; +extern u8 D_801F2A55[]; +extern u8 D_801F2A56[]; +extern u8 D_80188B74[]; +extern u8 D_80188B76[]; +extern u8 D_80188B78[]; +extern s32 D_801F3044; +extern s32 D_801F3048; +/* Scalar alias for D_801EDA34: the TU spells it `s32 []`, and `D_801EDA34[0] += 4` makes gcc + CSE the array base into a register (`la $v1,sym; lw 0($v1); sw 0($v1)`). The target uses the + plain global form (`lui/lw %lo`, then a fresh `lui/sw %lo`), which only a SCALAR ref emits. */ +extern s32 aD_801EDA34 __asm__("D_801EDA34"); + +/* The object func_8001D074 hands back. It is spelled as a struct (not `*(u16 *)(p + 8)`) on + purpose: gcc-2.7.2's alias oracle (alias.c true_/output_dependence) disambiguates a + MEM_IN_STRUCT_P + varying-address reference against a fixed-address non-struct global, which + is what lets the `D_801F3044` store schedule up into the `lhu` shadow, ahead of the `sh 0xC`. */ +typedef struct { + s32 unk0; /* 0x0 */ + u32 unk4; /* 0x4 */ + u16 unk8; /* 0x8 */ + u16 unkA; /* 0xA */ + u16 unkC; /* 0xC */ +} Obj_80182284; + +s32 func_80182284(void) { + s32 i; + u8 *bytes; + s32 *ct; + s32 off; + s32 *en; + s32 *ct2; + s32 *st; + s32 off2; + s32 n; + u8 *p; + + i = 0; + bytes = D_801F2A50; + ct = (s32 *)(bytes - 4); + off = 0; + do { + if (*(s32 *)(D_801F2A44 + off) != 0 && *ct >= 0x11) { + func_800233CC(bytes, (*ct -= 4)); + } + bytes += 0x4C; + ct += 0x13; + i++; + off += 0x4C; + } while (i < 0x14); + + if (D_801F3044 >= 0xC) { + return 1; + } + if (--D_801F3048 == -1) { + /* if/else, NOT `?:` — the two stores cross_jump into one merged tail block, which is why + the `sw %lo(D_801F3048)` lands first at .L80182358 instead of being scheduled down. */ + if (D_801F3044 >= 4) { + D_801F3048 = 1; + } else { + D_801F3048 = 8; + } + i = 0; + en = (s32 *)D_801F2A48; + ct2 = en + 1; + st = en - 1; + off2 = 0; + aD_801EDA34 += 4; + for (; i < 0x14; i++) { + if (*st == 0) { + *en = aF8001D074(0x3E, 0x7D); + if (*en == 0) break; + *st = 1; + *ct2 = 0x80; + p = D_801F2A50 + off2; + func_8001CD9C(*en, p); + D_801F2A51[off2] = 0xE0; + D_801F2A50[off2] = 0; + D_801F2A52[off2] = 0x88; + D_801F2A54[off2] = 0; + D_801F2A55[off2] = 0; + D_801F2A56[off2] = 0; + func_800233CC(p, *(u16 *)ct2); + n = D_801F3044; + ((Obj_80182284 *)*en)->unk8 = *(u16 *)(D_80188B74 + n * 8); + ((Obj_80182284 *)*en)->unkA = *(u16 *)(D_80188B76 + n * 8); + ((Obj_80182284 *)*en)->unkC = *(u16 *)(D_80188B78 + n * 8); + D_801F3044 = n + 1; + { + /* $3 pin: without it local-alloc hands $v1 to the 0x50000040 constant and + $a0 to this pointer — the exact inverse of the target (closeness 6). */ + register Obj_80182284 *o __asm__("$3"); + o = (Obj_80182284 *)*en; + o->unk4 |= 0x50000040; + } + break; + } + en += 0x13; + ct2 += 0x13; + st += 0x13; + off2 += 0x4C; + } + } + return 0; +} + INCLUDE_ASM("asm/ov_SC01_001/nonmatchings/ov_SC01_001_jr_8017D2DC", func_801824EC); diff --git a/src/ov_SC01_080/ov_SC01_080_jr_8017AE2C.c b/src/ov_SC01_080/ov_SC01_080_jr_8017AE2C.c index 51bd3f2fc..32a988200 100644 --- a/src/ov_SC01_080/ov_SC01_080_jr_8017AE2C.c +++ b/src/ov_SC01_080/ov_SC01_080_jr_8017AE2C.c @@ -6947,7 +6947,79 @@ void func_80182B90(void *a0, s32 a1, s16 a2) { } -INCLUDE_ASM("asm/ov_SC01_080/nonmatchings/ov_SC01_080_jr_8017AE2C", func_80182CB8); +// @class: struct + if/else-arm placement (delay-slot fill) + global-base pointer hoist +// @stuck: none — MATCH 144/144 via tools/rtu_match.py (real TU). NOTE: this draft is NOT +// standalone-compilable for match_one, ON PURPOSE: this TU already declares +// `extern void func_80182CB8(void *a0, S8Blob *a1, S8Blob *a2, s16 a3, s16 a4);` (line 6924, +// used by the banked caller func_80182B90), and S8Blob is a file-scope typedef of the TU +// (line 6915). Copying that declaration EXACTLY (SYS law "copy the TU's declaration") means +// the S8Blob typedef cannot be repeated here (C89: duplicate typedef = hard error), so +// match_one alone reports cc1-fail. A byte-identical standalone twin (4-arg, s16* params, +// local typedefs) is match_one MATCH 144/144: .run/O41/opus/scratch_func_80182CB8/v3.c +// +// func_80182CB8 — the segmented "bolt" drawer. +// Builds a local matrix at sp+0x10 (func_80017D98 + t[] = a1's xyz), walks 16 segments from +// a1 toward a2, jitters each joint's height by (rand()&0x1F)+(rand()&0x1F)+8 scaled through +// func_8004787C(angle<<9) / 4096, and pushes the previous/current joint pair into the global +// prim D_801C7560 as two quads (±10 in y) through func_80017758. a4 is passed by +// func_80182B90 but never read. +typedef struct { s16 vx, vy, vz, pad; } SV_80182CB8; +typedef struct { s16 m[3][3]; s16 pad; s32 t[3]; } MTX_80182CB8; + +extern void func_80017D98(void *a0); +extern s32 rand(void); +extern s32 func_8004787C(s32 a0); +extern s32 func_80017758(void *a0, void *a1); +extern s32 D_801C7560[]; + +void func_80182CB8(void *a0, S8Blob *a1, S8Blob *a2, s16 a3, s16 a4) +{ + MTX_80182CB8 m; + SV_80182CB8 delta; + SV_80182CB8 b; + SV_80182CB8 c; + SV_80182CB8 tmp[3]; + SV_80182CB8 *q; + s32 i; + s32 r; + + func_80017D98(&m); + m.t[0] = ((s16 *)a1)[0]; + m.t[1] = ((s16 *)a1)[1]; + m.t[2] = ((s16 *)a1)[2]; + delta.vx = ((s16 *)a2)[0] - ((s16 *)a1)[0]; + delta.vz = ((s16 *)a2)[2] - ((s16 *)a1)[2]; + q = (SV_80182CB8 *)D_801C7560; + c.vz = 0; + c.vy = 0; + c.vx = 0; + i = 1; + do { + b = c; + r = 8; + if (i != 16) { + r = (rand() & 0x1F) + (rand() & 0x1F) + 8; + } + a3 = a3 + 1; + r = r * func_8004787C(a3 << 9) / 4096; + tmp[1].vy = r; + c.vx = delta.vx * i / 16; + c.vy = r; + c.vz = delta.vz * i / 16; + q[0] = b; + q[1] = c; + q[2] = b; + q[3] = c; + q[2].vy -= 10; + q[3].vy -= 10; + func_80017758(q, &m); + q[2].vy += 20; + q[3].vy += 20; + func_80017758(q, &m); + i = i + 1; + } while (i < 17); +} + extern u8 D_801202A0[]; extern s32 D_801C7550[]; diff --git a/src/ov_SC02_005/ov_SC02_005_jr_80181D30.c b/src/ov_SC02_005/ov_SC02_005_jr_80181D30.c index 477f6ad55..0e9db9e21 100644 --- a/src/ov_SC02_005/ov_SC02_005_jr_80181D30.c +++ b/src/ov_SC02_005/ov_SC02_005_jr_80181D30.c @@ -4035,7 +4035,97 @@ void func_80183610(u8 *arg0) { } -INCLUDE_ASM("asm/ov_SC02_005/nonmatchings/ov_SC02_005_jr_80181D30", func_801838A8); +#include "common.h" + +extern u16 D_801E4BBC; +extern s16 D_80126CB4; +extern s32 D_80195AD0[]; +extern s32 D_80195AD2[]; +extern u8 D_80195B2C[]; +extern void (*D_801962F8[])(void *); + +extern s16 func_80185E80(void *a0); +extern void func_80182740(void *a0); +extern void func_801827A8(void *a0); +extern void func_80182810(void *a0); +extern void func_801828D8(); +extern void func_8012AD44(s32 *a0, s16 a1); +extern void func_8012B23C(s32 a0); +extern void func_80186304(); +extern void func_80186F14(void *a0); + +void func_801838A8(u8 *arg0) { + s16 diff; + s16 idx; + + if ((*(s32 *)(arg0 + 0xE8) & 8) == 0 && *(s16 *)(arg0 + 0xFE) != 0) { + *(s16 *)(arg0 + 0xFE) = *(s16 *)(arg0 + 0xFE) - 1; + ((void (*)(void))func_80182810)(); + if (*(s32 *)(arg0 + 0xE8) & 0x2000) { + *(s32 *)(arg0 + 0x1C) = 0x18; + } else { + *(s32 *)(arg0 + 0x1C) = 0x30; + } + func_801828D8(arg0); + *(s32 *)(arg0 + 0xE8) &= ~0x80; + return; + } + + idx = func_80185E80(arg0); + if (idx != 0) { + D_801962F8[idx](arg0); + return; + } + + if (D_801E4BBC == 0) { + diff = *(u16 *)(arg0 + 6) - *(u16 *)&D_80126CB4; + *(s32 *)(arg0 + 0x10) = 0; + if (diff < -0x80 && *(s16 *)(arg0 + 6) < *(s16 *)D_80195AD2) { + func_80182740(arg0); + if (*(s32 *)(arg0 + 0xE8) & 0x2000) { + *(s32 *)(arg0 + 0x1C) = 0x18; + } else { + *(s32 *)(arg0 + 0x1C) = 0x30; + } + func_801828D8(arg0); + return; + } + if (diff >= 0x81 && *(s16 *)(D_80195AD0 + D_801E4BBC) < *(s16 *)(arg0 + 6)) { + func_801827A8(arg0); + if (*(s32 *)(arg0 + 0xE8) & 0x2000) { + *(s32 *)(arg0 + 0x1C) = 0x18; + } else { + *(s32 *)(arg0 + 0x1C) = 0x30; + } + func_801828D8(arg0); + return; + } + } + + if (*(u16 *)(arg0 + 2) == 1) { + if (*(s32 *)(arg0 + 0xE8) & 0x2000) { + *(s32 *)(arg0 + 0x1C) = 0x10; + } else { + *(s32 *)(arg0 + 0x1C) = 0x20; + } + return; + } + + func_8012B23C((s32)arg0); + *(s32 *)(arg0 + 0xE8) |= 1; + func_80186304(arg0, 0, 0); + if (*(s32 *)(arg0 + 0xE8) & 0x2000) { + *(s32 *)(arg0 + 0x1C) = 0x10; + } else { + *(s32 *)(arg0 + 0x1C) = 0x20; + } + *(s32 *)(arg0 + 0x58) = (s32)D_80195B2C | 0x40000000; + *(s16 *)(arg0 + 0x5C) = 0; + *(s16 *)(arg0 + 0xAE) = -1; + func_8012AD44((s32 *)arg0, 1); + func_80186F14((void *)arg0); +} + #include "common.h" @@ -5511,7 +5601,75 @@ void func_80185A04(s32 param_1, s32 param_2, s16 param_3) { INCLUDE_ASM("asm/ov_SC02_005/nonmatchings/ov_SC02_005_jr_80181D30", func_80185A88); -INCLUDE_ASM("asm/ov_SC02_005/nonmatchings/ov_SC02_005_jr_80181D30", func_80185B38); +#include "common.h" + + + + + +extern D_80195AF4_t D_80195AF4[]; +extern D_80195AF6_t D_80195AF6[]; +extern s16 D_80126CB4; +extern s16 D_80126CB8; +extern s16 D_80195ACC; +extern s16 D_801E43A8; +extern s16 D_801E43B0; + +void func_80185B38(s32 a0) +{ + s32 pad[2]; + s16 q; + s16 d; + s16 e; + s16 n6; + s16 nE; + + if (*(s16 *)(a0 + 0xE0) < 0) { + if (*(s16 *)(a0 + 0xDC) != 1) { + if (*(s32 *)(a0 + 0xE8) & 0x800) { + q = ((s16)(D_80126CB4 - *(s16 *)(a0 + 0x6)) + 0x2A) / 0x54; + d = D_80126CB8 - D_80195ACC; + if (q >= 4) { + q = 3; + } else if (q < 0) { + q = 0; + } + *(s16 *)(a0 + 0x6) = *(s16 *)(a0 + 0x6) + q * 0x54; + *(s16 *)(a0 + 0xE) = D_80195ACC; + if (d < -0x2A) { + *(s16 *)(a0 + 0xE) = D_80195ACC - 0x54; + } else if (d > 0x2A) { + *(s16 *)(a0 + 0xE) = D_80195ACC + 0x54; + } + } else { + e = D_80126CB4 + 0x80; + d = D_80126CB8 - *(s16 *)(a0 + 0xE); + *(s16 *)(a0 + 0x6) = -0x80; + if (e < -0x2A) { + *(s16 *)(a0 + 0x6) = -0x80 - 0x54; + } else if (e > 0x2A) { + *(s16 *)(a0 + 0x6) = -0x80 + 0x54; + } + q = (d + 0x2A) / 0x54; + if (q < -3) { + q = -3; + } else if (q > 0) { + q = 0; + } + *(s16 *)(a0 + 0xE) = *(s16 *)(a0 + 0xE) + q * 0x54; + } + } else { + n6 = D_801E43A8; + nE = D_801E43B0; + *(s16 *)(a0 + 0x6) = n6; + *(s16 *)(a0 + 0xE) = nE; + } + } else { + *(s16 *)(a0 + 0x6) = D_80195AF4[*(s16 *)(a0 + 0xE0)].f0; + *(s16 *)(a0 + 0xE) = D_80195AF6[*(s16 *)(a0 + 0xE0)].f0; + } +} + diff --git a/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c b/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c index 3909ec607..89c29f25e 100644 --- a/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c +++ b/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c @@ -10452,7 +10452,86 @@ void func_80186818(s32 *a0) { } -INCLUDE_ASM("asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_80186868); +#include "common.h" + +extern u16 D_80126B5E; +extern u16 D_80126B62; +extern u16 D_80126B66; +extern u16 D_80126B96; +extern s16 D_80126B98; +extern u8 D_80195D30[]; +extern s32 func_800291B4(s32 arg); +extern s32 func_80132EF4(s32 a0, s32 a1); +extern void func_80129374(s32 a0, s32 a1); +extern void func_8002D4C8(s32 a0, s32 a1); +void func_80186AA0(s32 a0); +s32 func_80186B1C(void *a0, void *a1); + +void func_80186868(s32 a0) +{ + register s32 self __asm__("$17") = a0; + s32 flags; + s32 v1; + register s32 v0 __asm__("$2"); + register s32 dx __asm__("$19"); + register s32 dy __asm__("$4"); + register s32 dz __asm__("$18"); + s32 t; + s32 p, q; + s32 sum; + + *(s32 *)(self + 0x1C) = *(s32 *)(self + 0x1C) + 1; + if ((u8)func_800291B4(0xCE) == 1) { + flags = *(s32 *)(self + 0x1C); + if (flags & 0x20) { + func_80186AA0(self); + return; + } + v0 = D_80126B5E; v1 = *(u16 *)(self + 6); v1 = v0 - v1; + v0 = v1 << 16; + dx = v1; if (v0 < 0) { dx = -v1; } + v0 = D_80126B62; v1 = *(u16 *)(self + 0xA); v1 = v0 - v1; + v0 = v1 << 16; + dy = v1; if (v0 < 0) { dy = -v1; } + v0 = D_80126B66; v1 = *(u16 *)(self + 0xE); v1 = v0 - v1; + v0 = v1 << 16; + dz = v1; if (v0 < 0) { dz = -v1; } + v0 = (s16)dx; + if (v0 >= 0x201) { func_80186AA0(self); return; } + v0 = (s16)dy; + if (v0 >= 0x201) { func_80186AA0(self); return; } + v0 = (s16)dz; + if (v0 >= 0x201) { func_80186AA0(self); return; } + if (flags & 1) { + t = func_80132EF4(self, 0x22); + if (t != 0) { + func_80129374(t, self); + *(s16 *)(*(s32 *)(t + 0x20) + 0x18) = 0x5000; + *(s16 *)(*(s32 *)(t + 0x20) + 0x1A) = 0x5000; + } + } + if ((*(s32 *)(self + 0x1C) & 3) == 0) { + v0 = (s16)dx; + p = v0 * v0; + v0 = (s16)dz; + q = v0 * v0; + sum = p + q; + if (sum <= 0x30000) { + func_8002D4C8(0x646, (u16)((((0x30000 - sum) * 127) / 0x30000) | 0x1000)); + *(s16 *)(self + 0xFC) = 1; + } else { + func_80186AA0(self); + } + } + if ((*(s32 *)(self + 0x1C) & 0x1F) >= 8) { + if (func_80186B1C((void *)self, D_80195D30) != 0) { + ((struct { u16 w; } *)&D_80126B96)->w |= 0x4000; + D_80126B98 = 0xC; + } + } + } +} + extern void func_8002D4C8(s32 a0, s32 a1); diff --git a/src/ov_SC02_017/ov_SC02_017_jr_8017DF34.c b/src/ov_SC02_017/ov_SC02_017_jr_8017DF34.c index f5ad0a624..8bd2edd0e 100644 --- a/src/ov_SC02_017/ov_SC02_017_jr_8017DF34.c +++ b/src/ov_SC02_017/ov_SC02_017_jr_8017DF34.c @@ -8775,7 +8775,96 @@ void func_80187178(s32 param_1) { } -INCLUDE_ASM("asm/ov_SC02_017/nonmatchings/ov_SC02_017_jr_8017DF34", func_80187298); +#include "common.h" + +extern void func_8012CBCC(s32 a0); +extern s32 func_80143B6C(s32 a0, s32 a1); +extern s32 func_8012E778(s32 a0, s32 a1); +extern void func_8012B23C(s32 a0); +extern s32 func_80143970(s32 a0); +extern s32 func_8004787C(s32 a0); +extern s32 func_8012BEE8(s32 a0); +extern void func_8012A828(s32 a0, void *a1); +extern void Square0(s32 *a0, s32 *a1); +extern u16 D_80126B5E; +extern u16 D_80126B66; +extern s16 D_801E1264; +extern s16 D_801E1AFC; +extern s16 D_801E11DC; + +typedef struct { + u16 x; + u16 pad0; + u16 z; + u16 pad1; + s32 vx; + s32 vy; + s32 vz; +} D_87298; + +void func_80187298(s32 a0) { + D_87298 d; + s32 t; + s32 v1; + s32 p; + s32 sc; + + switch (*(u16 *)(a0 + 0x34)) { + case 0: + d.x = (u16)D_80126B5E; + d.z = (u16)D_80126B66; + d.vx = *(s16 *)(a0 + 6) - (s32)(s16)D_80126B5E; + d.vy = 0; + d.vz = *(s16 *)(a0 + 0xE) - (s32)(s16)D_80126B66; + Square0(&d.vx, &d.vx); + if (0x10000 < d.vx + d.vz) return; + if (func_8012E778(a0, 0xA000C8) != 0) return; + *(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1; + func_8012B23C(a0); + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) = *(s32 *)(*(s32 *)(a0 + 0x20) + 4) & 0x7FFFFFFF; + func_80143970(a0); + return; + case 1: + if ((((s32 (*)(s32))func_8012CBCC)(a0) & 0x2000) == 0) return; + func_80143B6C(a0, 1); + *(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x2C) = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x2C) | 0x10; + *(s32 *)(a0 + 0x1C) = 0x10; + /* fall through */ + case 2: + t = func_8004787C((*(u32 *)(a0 + 0x1C) << 7) & 0x780); + sc = ((t << 9) >> 12) + 0x1000; + __asm__ __volatile__(""); + p = *(s32 *)(a0 + 0x20); + *(s16 *)(p + 0x1C) = sc; + *(s16 *)(p + 0x18) = sc; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x1A) = 0x1000 - ((t << 10) >> 12); + if (func_8012BEE8(a0) != 0) { + *(u16 *)(a0 + 2) = 3; + if (*(u16 *)(a0 + 0x86) & 2) { + *(u16 *)(a0 + 0x34) = 1; + *(s32 *)(a0 + 0x1C) = 0x28; + if (*(u16 *)(a0 + 0x70) & 0x200) { + func_8012A828(a0, &D_801E1AFC); + } else { + func_8012A828(a0, &D_801E11DC); + } + *(u16 *)(a0 + 0xFE) = 0; + } else { + *(u16 *)(a0 + 0x34) = 0; + func_8012A828(a0, &D_801E1264); + *(s32 *)(a0 + 0x1C) = 0x19; + *(u16 *)(a0 + 0x86) |= 2; + } + v1 = *(s32 *)(a0 + 0x20); + *(u16 *)(v1 + 0x2C) &= 0xFFEF; + } + break; + default: + return; + } +} + /* func_801874E8 (ov_SC02_017) -- fresh crack, mass lane. * diff --git a/src/ov_SC03_028/ov_SC03_028_jr_80183A74.c b/src/ov_SC03_028/ov_SC03_028_jr_80183A74.c index e7bcd56b0..c20d7caf3 100644 --- a/src/ov_SC03_028/ov_SC03_028_jr_80183A74.c +++ b/src/ov_SC03_028/ov_SC03_028_jr_80183A74.c @@ -3332,5 +3332,62 @@ void func_80184568(void *a0) { } -INCLUDE_ASM("asm/ov_SC03_028/nonmatchings/ov_SC03_028_jr_80183A74", func_801845A4); +extern volatile s32 D_801EC44C; +extern s32 func_8012E544(s32 a0); +extern s32 D_80190430[]; + +void func_801845A4(s32 param_1) { + register s32 s1; + s32 base; + s32 lvl; + + if (*(s16 *)(param_1 + 0x12) < 0) { + *(u16 *)(param_1 + 0xFE) += *(s16 *)(param_1 + 0x12); + } else { + *(u16 *)(param_1 + 0xFE) -= *(s16 *)(param_1 + 0x12); + } + if (*(s16 *)(param_1 + 0xFE) > 0) { + *(u16 *)(param_1 + 6) += *(u16 *)(param_1 + 0x12); + } else { + if (*(s16 *)(param_1 + 0xFE) < 0) { + if (*(s16 *)(param_1 + 0x12) < 0) { + *(u16 *)(param_1 + 6) -= *(s16 *)(param_1 + 0xFE); + } else { + *(u16 *)(param_1 + 6) += *(s16 *)(param_1 + 0xFE); + } + } + if ((*(s16 *)(param_1 + 0xFC) != 0) || (*(u16 *)(*(s32 *)(param_1 + 0x64) + 2) == 0x1D)) { + *(s32 *)(param_1 + 0x1C) = 0xA; + } else { + *(s32 *)(param_1 + 0x1C) = 0x3C; + base = D_801EC44C; + lvl = *(s16 *)(base + 0x76); + if (lvl >= 0x51) { + s1 = (s16)*(u16 *)(param_1 + 0x102) % 3; + } else if (lvl >= 0x29) { + s1 = *(s16 *)(param_1 + 0x102) % 4 + 3; + } else { + s1 = (s16)*(u16 *)(param_1 + 0x102) % 5 + 7; + } + *(u16 *)(param_1 + 0x102) = (*(u16 *)(param_1 + 0x102) + 1) & 7; + s1 = D_80190430[s1]; + if (s1 == 4) { + if (func_8012E544(0xCB) == 0) { + *(s16 *)(param_1 + 0x12) >>= 1; + } else { + s1 = 3; + } + } + if (*(s16 *)(param_1 + 0x12) < 0) { + *(s32 *)(param_1 + 0xE4) = s1; + *(s32 *)(param_1 + 0xE8) = s1; + } else { + *(s32 *)(param_1 + 0xDC) = s1; + *(s32 *)(param_1 + 0xE0) = s1; + } + } + *(s16 *)(param_1 + 2) = 1; + } +} + diff --git a/src/ov_SC05_008/ov_SC05_008_jr_8017AE2C.c b/src/ov_SC05_008/ov_SC05_008_jr_8017AE2C.c index 10d9777be..88f4f4d64 100644 --- a/src/ov_SC05_008/ov_SC05_008_jr_8017AE2C.c +++ b/src/ov_SC05_008/ov_SC05_008_jr_8017AE2C.c @@ -4538,7 +4538,87 @@ void func_8017E840(void *a0) { } -INCLUDE_ASM("asm/ov_SC05_008/nonmatchings/ov_SC05_008_jr_8017AE2C", func_8017E850); +void func_8017E850(s32 arg0, s32 arg1) { + extern s32 D_80126B58; + extern u16 D_80126980; + extern s32 D_8012697C; + extern u8 D_80126C01; + extern s32 D_801A12E4; + extern u16 func_80148800(s32 *a0); + extern u8 func_8014880C(s32 *a0); + extern u16 func_80148818(s32 *a0); + extern s32 func_80012DBC(s32 a0, s32 a1, s32 a2, s32 a3); + extern s32 ratan2(s32 a0, s32 a1); + + s32 self = arg0; + s32 *q; + s32 obj; + s16 *rec; + s16 *rec2; + s16 oldx; + s16 oldy; + s32 newx; + s32 newy; + s32 t; + s32 flags = arg1; + + q = &D_80126B58; + obj = *(s32 *)(self + 0x20); + rec = (s16 *)(D_8012697C + (D_80126980 + 8) * 6); + rec2 = rec + 3; + + switch (D_80126C01) { + case 0x41: + flags = ((s32 (*)(s32 *))func_80148800)(q); + break; + case 0x53: + case 0x73: + oldx = *(u16 *)(self + 0xE0); + oldy = *(u16 *)(self + 0xE2); + newx = func_80148818(q) & 0xFF; + *(s16 *)(self + 0xE0) = newx; + newy = *(s16 *)(self + 0xE2) = func_8014880C(q) & 0xFF; + flags = 0; + if (oldx == 0x80) { + t = newx; + if (t != 0x80) { + if (t < 0x80) { + flags |= 0x1000; + } else { + flags |= 0x4000; + } + } + } + if (oldy == 0x80) { + t = newy; + if (t != 0x80) { + if (t < 0x80) { + flags |= 0x8000; + } else { + flags |= 0x2000; + } + } + } + break; + } + + if (flags & 0x8000) { + D_801A12E4++; + } + if (flags & 0x2000) { + D_801A12E4--; + } + if (D_801A12E4 < -2) { + D_801A12E4 = -2; + } + if (D_801A12E4 >= 3) { + D_801A12E4 = 2; + } + *(s16 *)(obj + 0x14) = func_80012DBC(*(s16 *)(obj + 0x14), (s16)(D_801A12E4 * 455), 4, 1); + *(s16 *)(obj + 0x10) = ratan2(rec[1] - rec2[1], rec2[2] - rec[2]); + *(s16 *)(obj + 0x12) = ratan2(rec2[0] - rec[0], rec2[2] - rec[2]); +} + extern u16 D_800B99DA; extern void func_80015978(s32 a0, s32 *a1); diff --git a/src/ov_SC06_016/ov_SC06_016_jr_8017C8D0.c b/src/ov_SC06_016/ov_SC06_016_jr_8017C8D0.c index 507540385..c4cfb0be3 100644 --- a/src/ov_SC06_016/ov_SC06_016_jr_8017C8D0.c +++ b/src/ov_SC06_016/ov_SC06_016_jr_8017C8D0.c @@ -3633,7 +3633,101 @@ void func_8017E1D8(s32 arg0) } -INCLUDE_ASM("asm/ov_SC06_016/nonmatchings/ov_SC06_016_jr_8017C8D0", func_8017E26C); +extern s16 D_8019F6FC; +extern s32 D_8019F700; +extern s16 D_8019F702; +extern s16 D_8019F704; +extern s16 D_80188A22[]; +extern s32 D_80126B58; +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 func_80013328(s32 a0, s32 a1); +extern s32 func_8012BEE8(s32 a0); +extern s32 func_8017EEB4(s32 arg0); +extern void func_8017E4AC(s32 a0); + +void func_8017E26C(s32 arg0) { + volatile s32 pad[2]; + s32 s0; + s32 *ptr; + s32 s1; + s32 v0; + s32 v1; + s32 a0; + s32 a1; + + s0 = arg0; + ptr = &D_80126B58; + + v0 = *(u16 *)(s0 + 0x84); + *(u16 *)(s0 + 0x84) = v0 + 1; + if ((s16)(v0 + 1) == 0x1E) { + func_8002D4C8(0x97F, 0); + } + + v1 = *(u16 *)(s0 + 0x34); + switch (v1) { + case 0: + v0 = *(u16 *)&D_8019F6FC + 1; + D_8019F6FC = v0; + if ((s16)v0 < D_80188A22[0]) { + break; + } + *(u16 *)(s0 + 0x34) = 1; + D_8019F6FC = 0x10; + break; + case 1: + s1 = func_8017EEB4(s0); + a0 = func_80013328(s0 + 4, (s32)(ptr + 1)); + if (a0 < 0) { + a0 = 0x80; + v1 = 0x60000; + } else if (a0 >= 0x181) { + a0 = 0x180; + v1 = 0x60000; + } else { + v1 = 0x60000; + } + v1 = v1 / a0; + a1 = v1 * 1303; + a0 = a1 / 16; + if (s1 != 0) { + a0 = -a0; + } + v0 = D_8019F704; + if (s1 == v0) { + v1 = D_8019F700; + D_8019F6FC = 4; + v0 = v1 + a0; + D_8019F700 = v0; + if (s1 == 0) { + if (a1 < v0) { + D_8019F700 = a1; + } + } else { + v1 = -a1; + if (v0 < v1) { + D_8019F700 = v1; + } + } + } else { + v0 = *(u16 *)&D_8019F6FC - 1; + D_8019F6FC = v0; + if ((s16)v0 <= 0) { + D_8019F704 = (s16)s1; + } + } + a0 = *(s32 *)(s0 + 0x20); + v1 = D_8019F702; + v0 = *(u16 *)(a0 + 0x12); + *(u16 *)(a0 + 0x12) = v0 + v1; + break; + } + + if (func_8012BEE8(s0)) { + func_8017E4AC(s0); + } +} + #include "common.h" diff --git a/src/ov_SC06_025/ov_SC06_025_jr_8017BEBC.c b/src/ov_SC06_025/ov_SC06_025_jr_8017BEBC.c index e6be76242..a49fe3480 100644 --- a/src/ov_SC06_025/ov_SC06_025_jr_8017BEBC.c +++ b/src/ov_SC06_025/ov_SC06_025_jr_8017BEBC.c @@ -3673,7 +3673,61 @@ void func_8017D730(s32 param_1, s16 *param_2) { } -INCLUDE_ASM("asm/ov_SC06_025/nonmatchings/ov_SC06_025_jr_8017BEBC", func_8017D8C8); +// @class: integration / self_decl_tu +// @lever: NOT a codegen problem. The body was already byte-correct; the whole-binary gate +// died on `conflicting types for func_8017D8C8' at the definition site. This TU +// forward-declares the target K&R-style at ov_SC06_025_jr_8017BEBC.c:3526 +// (`extern void func_8017D8C8();`, used by the four call sites in func_8017D4F0), +// so the definition must be compatible with the default argument promotions: +// a `s16 param_3` parameter is promotable and therefore conflicts. Declaring +// param_3 as s32 and sign-extending inside (`s32 ang = (s16)param_3;`) reproduces +// the entry `sll $s1,$a2,16 / sra $s1,$s1,16` pair identically and makes the +// definition promotion-compatible. Verified with recover_integration --probe-only: +// blocker class self_decl_tu -> none, real-TU cc1 MATCH 138 ins. +// @shape: twin of the banked neighbour func_8017D730 in this same TU (same MATRIX(0x20: +// m@0,t@0x14)+SVECTOR stack frame, same source order: m1.t[2] before svec_in.vx/vy so +// the two `sh zero` stores schedule into the t[2] load-delay slot). Differences: this +// one takes the angle as a parameter instead of the literals 4/0x10, and it routes +// 0x48/0x4C/0x50 and 0x3C/0x40/0x44 through func_80012C6C instead of storing directly. +extern s32 func_80012C6C(s32 a0, s32 a1, s32 a2); +extern s32 func_80012ABC(s32 a0, s32 a1, int a2); +extern void func_80049CAC(s32 a0, s32 a1); +extern void func_8012F14C(); + +void func_8017D8C8(s32 param_1, s16 *param_2, s32 param_3) { + s32 ang = (s16)param_3; + struct { short m[3][3]; int t[3]; } m1; + struct { short vx, vy, vz; } svec_in; + struct { short vx, vy, vz; } svec_out; + + *(s32 *)(param_1 + 0x8) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x8), (s32)*(s16 *)(param_1 + 0xC), ang); + *(s32 *)(param_1 + 0x10) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x10), (s32)*(s16 *)(param_1 + 0x14), ang); + *(s16 *)(param_1 + 0x18) = func_80012ABC((s32)*(s16 *)(param_1 + 0x18), (s32)*(s16 *)(param_1 + 0x20), ang); + *(s16 *)(param_1 + 0x1A) = func_80012ABC((s32)*(s16 *)(param_1 + 0x1A), (s32)*(s16 *)(param_1 + 0x22), ang); + *(s16 *)(param_1 + 0x1C) = func_80012ABC((s32)*(s16 *)(param_1 + 0x1C), (s32)*(s16 *)(param_1 + 0x24), ang); + *(s16 *)(param_1 + 0x28) = func_80012C6C((s32)*(s16 *)(param_1 + 0x28), (s32)*(s16 *)(param_1 + 0x2E), ang); + *(s16 *)(param_1 + 0x2A) = func_80012C6C((s32)*(s16 *)(param_1 + 0x2A), (s32)*(s16 *)(param_1 + 0x30), ang); + *(s16 *)(param_1 + 0x2C) = func_80012C6C((s32)*(s16 *)(param_1 + 0x2C), (s32)*(s16 *)(param_1 + 0x32), ang); + + *(s32 *)(param_1 + 0x48) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x48), (s16)(*(s16 *)(param_1 + 0x28) + param_2[0]), ang); + *(s32 *)(param_1 + 0x4C) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x4C), (s16)(*(s16 *)(param_1 + 0x2A) + param_2[1]), ang); + *(s32 *)(param_1 + 0x50) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x50), (s16)(*(s16 *)(param_1 + 0x2C) + param_2[2]), ang); + + func_80049CAC(param_1 + 0x18, (s32)&m1); + + m1.t[0] = *(s16 *)(param_1 + 0x28) + param_2[0]; + m1.t[1] = *(s16 *)(param_1 + 0x2A) + param_2[1]; + m1.t[2] = *(s16 *)(param_1 + 0x2C) + param_2[2]; + svec_in.vx = 0; + svec_in.vy = 0; + svec_in.vz = (s16)*(s32 *)(param_1 + 0x10); + ((void (*)(s32, s32, s32))func_8012F14C)((s32)&m1, (s32)&svec_in, (s32)&svec_out); + + *(s32 *)(param_1 + 0x3C) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x3C), svec_out.vx, ang); + *(s32 *)(param_1 + 0x40) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x40), svec_out.vy, ang); + *(s32 *)(param_1 + 0x44) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x44), svec_out.vz, ang); +} + extern void func_8013B7F4(void *a0, int a1); diff --git a/src/ov_SC06_025/ov_SC06_025_jr_8017EEC4.c b/src/ov_SC06_025/ov_SC06_025_jr_8017EEC4.c index 53c32854e..c9c732f01 100644 --- a/src/ov_SC06_025/ov_SC06_025_jr_8017EEC4.c +++ b/src/ov_SC06_025/ov_SC06_025_jr_8017EEC4.c @@ -3480,7 +3480,76 @@ void func_8017FF4C(s32 arg0, s16 *arg1, s32 arg2) { -INCLUDE_ASM("asm/ov_SC06_025/nonmatchings/ov_SC06_025_jr_8017EEC4", func_80180020); +typedef struct { u8 b[16]; } Blk16A1; + +extern s16 D_801B1B8C; +extern s16 D_801B1B88; +extern s16 D_801B1B82; +extern s16 D_801B1B7A; +extern s16 D_801B1B7C; +extern Blk16A1 D_801B1B78; +extern Blk16A1 D_80188D30; +extern Blk16A1 D_80188D40; + +void func_80180020(void) { + s16 st; + s16 next; + u8 pad8[8]; + + st = D_801B1B8C; + switch (st) { + case 0: + next = D_801B1B88 + 1; + D_801B1B88 = next; + if (next < 0x46) return; + { + s16 v0 = st + 1; + D_801B1B88 = 0; + D_801B1B8C = v0; + } + return; + case 1: + { + s32 a1 = D_801B1B88; + D_801B1B82 = 0x380 - ((a1 * 0x200) / 90); + D_801B1B7A = 0x20 - ((a1 * 96) / 90); + D_801B1B7C = ((a1 * 0x80) / 90) - 0x80; + next = a1 + 1; + } + D_801B1B88 = next; + if (next < 0x5A) return; + { + s16 v1 = st + 1; + D_801B1B88 = 0; + D_801B1B8C = v1; + } + return; + case 2: + next = D_801B1B88 + 1; + D_801B1B88 = next; + if (next < 0x46) return; + { + s16 v2 = st + 1; + D_801B1B78 = D_80188D30; + D_801B1B88 = 0; + D_801B1B8C = v2; + } + return; + case 3: + next = D_801B1B88 + 1; + D_801B1B88 = next; + if (next < 0x46) return; + { + s16 v3; + D_801B1B78 = D_80188D40; + v3 = 2; + D_801B1B88 = 0; + D_801B1B8C = v3; + } + return; + } +} + /* Declarations are BLOCK-scope on purpose (this TU's house style, cf. the * block-scope decl layers at func_80180300 and neighbours in this file). diff --git a/src/ov_SC06_029/ov_SC06_029_jr_8017C954.c b/src/ov_SC06_029/ov_SC06_029_jr_8017C954.c index 7541f5d03..2ce199b06 100644 --- a/src/ov_SC06_029/ov_SC06_029_jr_8017C954.c +++ b/src/ov_SC06_029/ov_SC06_029_jr_8017C954.c @@ -4736,7 +4736,68 @@ void func_80181378(void *a0) } -INCLUDE_ASM("asm/ov_SC06_029/nonmatchings/ov_SC06_029_jr_8017C954", func_801814B0); +#include "common.h" + +extern u8 *func_8012913C(s32 a0); +extern s32 rand(void); +extern void func_8012B0B4(unsigned int *param_1, int param_2, int param_3); + +void func_801814B0(u16 *param_1, s32 param_2) +{ + s32 buf[4]; /* sp+0x10 (16 bytes of locals -> frame -0x38) */ + s32 i; + u8 *ent; + u8 *sub; + s16 sign; + s32 t; + + /* §47 live-length SLIDER, non-barrier form. param_1's pseudo and i's + * pseudo tie EXACTLY in global.c:594 allocno priority (both 7 refs / 120 + * insns => 1166), so the tie-break is creation order and param_1 (the + * lower pseudo) takes $s3. The target wants i in $s3. This zero-byte, + * register-tied ("0") asm is ONE extra insn inside param_1's live range + * but before i's def: 14/121 = 1157 < 14/120 = 1166, splitting the tie + * the right way. It must NOT be `volatile`/colon-less (§194-A): a bare + * `__asm__ __volatile__("")` here fixes the registers but fences sched2 + * out of the prologue and the `addiu $s3,$a1,-1` falls into the guard's + * delay slot (closeness 6). */ + __asm__ ("" : "=r" (param_2) : "0" (param_2)); + + i = param_2 - 1; + if (param_2 != 0) { + do { + ent = func_8012913C(0x23); + if (ent != 0) { + sign = -1; + if (rand() & 1) { + sign = 1; + } + func_8012B0B4((unsigned int *)buf, sign * (rand() % 1024), 0x180); + t = buf[0]; + *(s16 *)(ent + 0x6) = param_1[0] + t; + *(s16 *)(ent + 0xA) = param_1[1] + sign * (rand() % 128); + *(s16 *)(ent + 0xE) = param_1[2] + (t >> 16); + *(s16 *)(ent + 0x34) = + (((rand() % 12287) + 0x5000) & 0x7FF0) | (rand() & 1); + *(u16 *)(*(s32 *)(ent + 0x20) + 0x2C) = 0xC010; + sub = func_8012913C(0x22); + if (sub != 0) { + *(s16 *)(sub + 0x6) = *(u16 *)(ent + 0x6); + *(s16 *)(sub + 0xA) = *(u16 *)(ent + 0xA); + *(s16 *)(sub + 0xE) = *(u16 *)(ent + 0xE); + *(s32 *)(sub + 0x14) = -0x80000 - ((rand() % 9) << 16); + *(s16 *)(sub + 0x34) = + (((rand() % 4) << 12) + 0x2000) | (rand() & 1); + *(u16 *)(*(s32 *)(sub + 0x20) + 0x2C) = + *(u16 *)(*(s32 *)(ent + 0x20) + 0x2C); + *(s32 *)(*(s32 *)(sub + 0x20) + 0x4) |= 0x40000000; + } + } + i--; + } while (i != -1); + } +} + #include "common.h" diff --git a/src/ov_SC07_007/ov_SC07_007_jr_8017BEBC.c b/src/ov_SC07_007/ov_SC07_007_jr_8017BEBC.c index f5bd757ad..bbe8525da 100644 --- a/src/ov_SC07_007/ov_SC07_007_jr_8017BEBC.c +++ b/src/ov_SC07_007/ov_SC07_007_jr_8017BEBC.c @@ -7647,7 +7647,81 @@ s32 func_80181ED4(s32 a0, s32 a1) { } -INCLUDE_ASM("asm/ov_SC07_007/nonmatchings/ov_SC07_007_jr_8017BEBC", func_80181F4C); +#include "common.h" + +/* func_80181F4C — links one 0x18-byte double-buffered sprite packet + (D_801C7874[arg1 & 0xFF][D_800B9A02]) into OT bank D_800A661C[D_800B9A02]. + + Levers that make this byte-exact (all four symbols spelled from the target .s): + + §195-H D_800B9A02 must be the ARRAY spelling + a constant index — that is the + MEM_IN_STRUCT_P (/s) reload dial that produces the 13 per-statement + `lhu 0($t1)` reloads. The scalar spelling collapses them (measured: + 142 -> 115 ins). The TU already declares `extern s16 D_800B9A02;` at + file scope, so the array view is reached through this TU's own + __asm__-alias idiom (cf. `aD800B9A02` @L564) — no C-level conflict. + + §238-ish The +3 store MUST name D_801C7877 (its own symbol, exactly as the .s + spells it). Written as D_801C7874[idx+3] the constant `D_801C7874+3` + becomes cse's related-value ANCHOR: the held base register turns into + sym+3 and every later access pays an extra `addiu` (+22 ins), plus a + stray `addiu $t0,$t0,-3` where the target has a nop. + + §17 `register u8 *p __asm__("$8")` — local_alloc ranks the D_800B9A02 + pointer (14 refs) above the D_801C7874 pointer (13 refs), so without + the pin the two land in $t1/$t0 swapped (26 residual instructions). + + §186b/§226 vars=16 with no saved registers: the dead addressed `pad` array. + The scheduler drops the resulting `addiu $sp,$sp,-0x10` into the + load-delay slot after the 6th `lhu`, exactly as the target does. + + Address shapes: `p4 = p + 4` first (a pointer VALUE) is what yields + `addiu $a2,$t0,4` + `addu` + `sw 0(..)`; every other access is written + `p + idx + K` so K stays in the memory operand (`addu` + `sb K(..)`). + The clut is `(x >> 4) & 0x3F` on x = n*0x100 — combine folds it to + `sll 4; andi 0x3F` only AFTER cse, which is why it does not share the + `sll $v0,$a1,4` of the tpage word (the target emits both). */ + +#define F4C_IDX (aB9A02[0] * 0x18 + n * 0x30) + +void func_80181F4C(s32 arg0, s32 arg1) { + extern u16 aB9A02[1] __asm__("D_800B9A02"); + extern u8 D_801C7874[]; + extern u8 D_801C7877[]; + extern u32 D_800A661C[]; + + s32 n = arg1 & 0xFF; + register u8 *p __asm__("$8") = D_801C7874; + u8 *p4 = p + 4; + u8 *q; + u32 *ot; + s32 pad[4]; + + (void)&pad; + *(u8 *)(D_801C7877 + F4C_IDX) = 5; + *(u32 *)(p4 + F4C_IDX) = ((n * 0x10 + 0x8E) & 0x9FF) | 0xE1000000; + *(u8 *)(p + F4C_IDX + 0xB) = 0x64; + q = p + (n * 0x30 + aB9A02[0] * 0x18); + q[0xA] = arg0; + q[0x9] = arg0; + q[0x8] = arg0; + *(s16 *)(p + F4C_IDX + 0xC) = 0; + *(s16 *)(p + F4C_IDX + 0xE) = -0x70; + *(u8 *)(p + F4C_IDX + 0x10) = 0; + *(u8 *)(p + F4C_IDX + 0x11) = 0; + *(u16 *)(p + F4C_IDX + 0x12) = (((n * 0x100) >> 4) & 0x3F) | 0x7800; + *(s16 *)(p + F4C_IDX + 0x14) = 0x100; + *(s16 *)(p + F4C_IDX + 0x16) = 0xC0; + + *(u32 *)(p + F4C_IDX) = (*(u32 *)(p + F4C_IDX) & 0xFF000000) | + (*(u32 *)((u8 *)D_800A661C + (aB9A02[0] << 14)) & 0xFFFFFF); + + ot = (u32 *)((u8 *)D_800A661C + (aB9A02[0] << 14)); + *ot = (*ot & 0xFF000000) | ((n * 0x30 + (aB9A02[0] * 0x18 + (u32)p)) & 0xFFFFFF); +} + +#undef F4C_IDX + INCLUDE_ASM("asm/ov_SC07_007/nonmatchings/ov_SC07_007_jr_8017BEBC", func_80182184);