From 124d5198ef768d9f7e679543684098c07f896d4d Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Tue, 11 Aug 2026 20:59:47 -0600 Subject: [PATCH] feat(phase-30 S48-T6): propagate func_8018DE60 to its zero-crack siblings --- src/ov_SC06_018/ov_SC06_018_jr_80187AEC.c | 78 ++++++++++- src/ov_SC06_032/ov_SC06_032_jr_80182890.c | 160 +++++++++++++++++++++- src/ov_SC06_033/ov_SC06_033_jr_80186574.c | 160 +++++++++++++++++++++- 3 files changed, 393 insertions(+), 5 deletions(-) diff --git a/src/ov_SC06_018/ov_SC06_018_jr_80187AEC.c b/src/ov_SC06_018/ov_SC06_018_jr_80187AEC.c index 59af0255de..53b7a7d67f 100644 --- a/src/ov_SC06_018/ov_SC06_018_jr_80187AEC.c +++ b/src/ov_SC06_018/ov_SC06_018_jr_80187AEC.c @@ -5152,7 +5152,83 @@ void func_8018DE60(void *arg) { } -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018DFF4); + + +// func_8018DFF4 -- ov_SC06_018 / ov_SC06_018_jr_80187AEC +// +// Structural sibling of func_8018E188 (SAME TU, banked MATCH, this file: func_8018E188). +// Shares VERBATIM: the 0x60 gate + 0x1D snapshot block, the 0x78/0x60 decrement block +// (AND form -- see E188's @stuck note), the 0x82&1 finisher, and the C8/C9 pokes. +// Diverges after that: instead of E188's 0x76<0 spawn-loop / CC-D0-D4 reseed, this +// function's 0x76<0 arm sets a distinct "state 2" field group (offsets 2/0x5C/0x34/ +// 0xC1/0xF4 + clears bit 0x80 of *(p+0x20)->0x2C), and its else arm plays a different +// sound (func_8002D4C8(0xAD8,0) vs E188's 0xAE0) then tail-calls func_8018D654 (still +// INCLUDE_ASM in this TU -- no other TU references it, so this call site sets its own +// convention: void func_8018D654(void *)). +// +// @class: regalloc-order +// @stuck: none -- see match_one output. + +extern void func_8016AA50(s32, s32); +extern s32 func_8016B428(s32); +extern void func_80019064(void *); +extern void func_8002A520(int); +extern void func_8002A790(int); +extern void func_8002D4C8(s32, s32); +extern void func_8018D654(void *); + +void func_8018DFF4(void *arg) { + u8 *p = (u8 *)arg; + s32 e = *(u8 *)(p + 0x5E); + + if (*(s16 *)(p + 0x60) != 0) { + if (e == 0x1D) { + *(u16 *)(p + 0x82) = 0; + *(u16 *)(p + 0x7C) = *(u16 *)(p + 0x06); + *(u16 *)(p + 0x7E) = *(u16 *)(p + 0x0A); + *(u16 *)(p + 0x80) = *(u16 *)(p + 0x0E); + } + { + s32 dec; + s32 q = *(s32 *)(p + 0x78); + if (q != 0 && *(s16 *)(p + 0x60) != 0) { + dec = ((s32)*(s16 *)(p + 0x60) * (s32)*(s16 *)(q + 0x30)) >> 12; + if (dec < 1) dec = 1; + } else { + dec = *(s16 *)(p + 0x60); + } + *(u16 *)(p + 0x76) = *(u16 *)(p + 0x76) - dec; + ((void (*)(void *, s32))func_8016AA50)(p, dec); + } + if (*(u16 *)(p + 0x82) & 1) { + ((void (*)(void *))func_8016B428)(p); + func_80019064(&D_801D1210); + } + } + + if (e != 0x1D) { + if (*(u8 *)(p + 0xC8)) func_8002A520(p); + if (*(u8 *)(p + 0xC9)) func_8002A790(p); + } + + if (*(s16 *)(p + 0x76) < 0) { + s32 q = *(s32 *)(p + 0x20); + *(s16 *)(p + 0x02) = 0xB; + *(u16 *)(p + 0x5C) = 0x800; + *(u16 *)(p + 0x34) = 0; + *(u8 *)(p + 0xC1) = 0; + *(s32 *)(p + 0xF4) = 1; + *(u16 *)(q + 0x2C) &= 0xFF7F; + } else { + func_8002D4C8(0xAD8, 0); + *(u16 *)(p + 0x5C) = 0x8800; + *(u16 *)(p + 0x60) = 0; + *(u8 *)(p + 0xC1) = 0; + *(u8 *)(p + 0xC2) = 0x10; + func_8018D654(p); + } +} + // @class: regalloc-order // @stuck: none — MATCH (277 ins). p pinned $s1; e/spawn-ptr coalesce $s0; counter $s2; const2 hoisted $s3. diff --git a/src/ov_SC06_032/ov_SC06_032_jr_80182890.c b/src/ov_SC06_032/ov_SC06_032_jr_80182890.c index 709e734582..771f456537 100644 --- a/src/ov_SC06_032/ov_SC06_032_jr_80182890.c +++ b/src/ov_SC06_032/ov_SC06_032_jr_80182890.c @@ -7099,9 +7099,165 @@ void func_8018D5C0(void *arg) { } -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_80182890", func_8018DBB0); -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_80182890", func_8018DD44); + +// func_8018DBB0 -- ov_SC06_018 / ov_SC06_018_jr_80187AEC +// +// Structural sibling of func_8018E188 (SAME TU, banked MATCH, this file: func_8018E188). +// Shares VERBATIM: the 0x60 gate + 0x1D snapshot block, the 0x78/0x60 decrement block +// (AND form -- see E188's @stuck note), the 0x82&1 finisher, and the C8/C9 pokes. +// Diverges after that: instead of E188's 0x76<0 spawn-loop / CC-D0-D4 reseed, this +// function's 0x76<0 arm sets a distinct "state 2" field group (offsets 2/0x5C/0x34/ +// 0xC1/0xF4 + clears bit 0x80 of *(p+0x20)->0x2C), and its else arm plays a different +// sound (func_8002D4C8(0xAD8,0) vs E188's 0xAE0) then tail-calls func_8018D3A4 (still +// INCLUDE_ASM in this TU -- no other TU references it, so this call site sets its own +// convention: void func_8018D3A4(void *)). +// +// @class: regalloc-order +// @stuck: none -- see match_one output. + +extern void func_8016AA50(s32, s32); +extern s32 func_8016B428(s32); +extern void func_80019064(void *); +extern void func_8002A520(int); +extern void func_8002A790(int); +extern void func_8002D4C8(s32, s32); +extern void func_8018D3A4(void *); + +void func_8018DBB0(void *arg) { + + extern u8 D_801CC7E4; + u8 *p = (u8 *)arg; + s32 e = *(u8 *)(p + 0x5E); + + if (*(s16 *)(p + 0x60) != 0) { + if (e == 0x1D) { + *(u16 *)(p + 0x82) = 0; + *(u16 *)(p + 0x7C) = *(u16 *)(p + 0x06); + *(u16 *)(p + 0x7E) = *(u16 *)(p + 0x0A); + *(u16 *)(p + 0x80) = *(u16 *)(p + 0x0E); + } + { + s32 dec; + s32 q = *(s32 *)(p + 0x78); + if (q != 0 && *(s16 *)(p + 0x60) != 0) { + dec = ((s32)*(s16 *)(p + 0x60) * (s32)*(s16 *)(q + 0x30)) >> 12; + if (dec < 1) dec = 1; + } else { + dec = *(s16 *)(p + 0x60); + } + *(u16 *)(p + 0x76) = *(u16 *)(p + 0x76) - dec; + ((void (*)(void *, s32))func_8016AA50)(p, dec); + } + if (*(u16 *)(p + 0x82) & 1) { + ((void (*)(void *))func_8016B428)(p); + func_80019064(&D_801CC7E4); + } + } + + if (e != 0x1D) { + if (*(u8 *)(p + 0xC8)) func_8002A520(p); + if (*(u8 *)(p + 0xC9)) func_8002A790(p); + } + + if (*(s16 *)(p + 0x76) < 0) { + s32 q = *(s32 *)(p + 0x20); + *(s16 *)(p + 0x02) = 0xA; + *(u16 *)(p + 0x5C) = 0x800; + *(u16 *)(p + 0x34) = 0; + *(u8 *)(p + 0xC1) = 0; + *(s32 *)(p + 0xF4) = 1; + *(u16 *)(q + 0x2C) &= 0xFF7F; + } else { + func_8002D4C8(0xAD8, 0); + *(u16 *)(p + 0x5C) = 0x8800; + *(u16 *)(p + 0x60) = 0; + *(u8 *)(p + 0xC1) = 0; + *(u8 *)(p + 0xC2) = 0x10; + func_8018D3A4(p); + } +} + + + + +// func_8018DD44 -- ov_SC06_018 / ov_SC06_018_jr_80187AEC +// +// Structural sibling of func_8018E188 (SAME TU, banked MATCH, this file: func_8018E188). +// Shares VERBATIM: the 0x60 gate + 0x1D snapshot block, the 0x78/0x60 decrement block +// (AND form -- see E188's @stuck note), the 0x82&1 finisher, and the C8/C9 pokes. +// Diverges after that: instead of E188's 0x76<0 spawn-loop / CC-D0-D4 reseed, this +// function's 0x76<0 arm sets a distinct "state 2" field group (offsets 2/0x5C/0x34/ +// 0xC1/0xF4 + clears bit 0x80 of *(p+0x20)->0x2C), and its else arm plays a different +// sound (func_8002D4C8(0xAD8,0) vs E188's 0xAE0) then tail-calls func_8018D3A4 (still +// INCLUDE_ASM in this TU -- no other TU references it, so this call site sets its own +// convention: void func_8018D3A4(void *)). +// +// @class: regalloc-order +// @stuck: none -- see match_one output. + +extern void func_8016AA50(s32, s32); +extern s32 func_8016B428(s32); +extern void func_80019064(void *); +extern void func_8002A520(int); +extern void func_8002A790(int); +extern void func_8002D4C8(s32, s32); +extern void func_8018D3A4(void *); + +void func_8018DD44(void *arg) { + + extern u8 D_801CC7E4; + u8 *p = (u8 *)arg; + s32 e = *(u8 *)(p + 0x5E); + + if (*(s16 *)(p + 0x60) != 0) { + if (e == 0x1D) { + *(u16 *)(p + 0x82) = 0; + *(u16 *)(p + 0x7C) = *(u16 *)(p + 0x06); + *(u16 *)(p + 0x7E) = *(u16 *)(p + 0x0A); + *(u16 *)(p + 0x80) = *(u16 *)(p + 0x0E); + } + { + s32 dec; + s32 q = *(s32 *)(p + 0x78); + if (q != 0 && *(s16 *)(p + 0x60) != 0) { + dec = ((s32)*(s16 *)(p + 0x60) * (s32)*(s16 *)(q + 0x30)) >> 12; + if (dec < 1) dec = 1; + } else { + dec = *(s16 *)(p + 0x60); + } + *(u16 *)(p + 0x76) = *(u16 *)(p + 0x76) - dec; + ((void (*)(void *, s32))func_8016AA50)(p, dec); + } + if (*(u16 *)(p + 0x82) & 1) { + ((void (*)(void *))func_8016B428)(p); + func_80019064(&D_801CC7E4); + } + } + + if (e != 0x1D) { + if (*(u8 *)(p + 0xC8)) func_8002A520(p); + if (*(u8 *)(p + 0xC9)) func_8002A790(p); + } + + if (*(s16 *)(p + 0x76) < 0) { + s32 q = *(s32 *)(p + 0x20); + *(s16 *)(p + 0x02) = 0xB; + *(u16 *)(p + 0x5C) = 0x800; + *(u16 *)(p + 0x34) = 0; + *(u8 *)(p + 0xC1) = 0; + *(s32 *)(p + 0xF4) = 1; + *(u16 *)(q + 0x2C) &= 0xFF7F; + } else { + func_8002D4C8(0xAD8, 0); + *(u16 *)(p + 0x5C) = 0x8800; + *(u16 *)(p + 0x60) = 0; + *(u8 *)(p + 0xC1) = 0; + *(u8 *)(p + 0xC2) = 0x10; + func_8018D3A4(p); + } +} + // @class: regalloc-order diff --git a/src/ov_SC06_033/ov_SC06_033_jr_80186574.c b/src/ov_SC06_033/ov_SC06_033_jr_80186574.c index 4d1b97007a..b956d4675f 100644 --- a/src/ov_SC06_033/ov_SC06_033_jr_80186574.c +++ b/src/ov_SC06_033/ov_SC06_033_jr_80186574.c @@ -4468,9 +4468,165 @@ void func_801895AC(void *arg) { } -INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_80186574", func_80189B9C); -INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_80186574", func_80189D30); + +// func_80189B9C -- ov_SC06_018 / ov_SC06_018_jr_80187AEC +// +// Structural sibling of func_8018E188 (SAME TU, banked MATCH, this file: func_8018E188). +// Shares VERBATIM: the 0x60 gate + 0x1D snapshot block, the 0x78/0x60 decrement block +// (AND form -- see E188's @stuck note), the 0x82&1 finisher, and the C8/C9 pokes. +// Diverges after that: instead of E188's 0x76<0 spawn-loop / CC-D0-D4 reseed, this +// function's 0x76<0 arm sets a distinct "state 2" field group (offsets 2/0x5C/0x34/ +// 0xC1/0xF4 + clears bit 0x80 of *(p+0x20)->0x2C), and its else arm plays a different +// sound (func_8002D4C8(0xAD8,0) vs E188's 0xAE0) then tail-calls func_80189390 (still +// INCLUDE_ASM in this TU -- no other TU references it, so this call site sets its own +// convention: void func_80189390(void *)). +// +// @class: regalloc-order +// @stuck: none -- see match_one output. + +extern void func_8016AA50(s32, s32); +extern s32 func_8016B428(s32); +extern void func_80019064(void *); +extern void func_8002A520(int); +extern void func_8002A790(int); +extern void func_8002D4C8(s32, s32); +extern void func_80189390(void *); + +void func_80189B9C(void *arg) { + + extern u8 D_801C835C; + u8 *p = (u8 *)arg; + s32 e = *(u8 *)(p + 0x5E); + + if (*(s16 *)(p + 0x60) != 0) { + if (e == 0x1D) { + *(u16 *)(p + 0x82) = 0; + *(u16 *)(p + 0x7C) = *(u16 *)(p + 0x06); + *(u16 *)(p + 0x7E) = *(u16 *)(p + 0x0A); + *(u16 *)(p + 0x80) = *(u16 *)(p + 0x0E); + } + { + s32 dec; + s32 q = *(s32 *)(p + 0x78); + if (q != 0 && *(s16 *)(p + 0x60) != 0) { + dec = ((s32)*(s16 *)(p + 0x60) * (s32)*(s16 *)(q + 0x30)) >> 12; + if (dec < 1) dec = 1; + } else { + dec = *(s16 *)(p + 0x60); + } + *(u16 *)(p + 0x76) = *(u16 *)(p + 0x76) - dec; + ((void (*)(void *, s32))func_8016AA50)(p, dec); + } + if (*(u16 *)(p + 0x82) & 1) { + ((void (*)(void *))func_8016B428)(p); + func_80019064(&D_801C835C); + } + } + + if (e != 0x1D) { + if (*(u8 *)(p + 0xC8)) func_8002A520(p); + if (*(u8 *)(p + 0xC9)) func_8002A790(p); + } + + if (*(s16 *)(p + 0x76) < 0) { + s32 q = *(s32 *)(p + 0x20); + *(s16 *)(p + 0x02) = 0xA; + *(u16 *)(p + 0x5C) = 0x800; + *(u16 *)(p + 0x34) = 0; + *(u8 *)(p + 0xC1) = 0; + *(s32 *)(p + 0xF4) = 1; + *(u16 *)(q + 0x2C) &= 0xFF7F; + } else { + func_8002D4C8(0xAD8, 0); + *(u16 *)(p + 0x5C) = 0x8800; + *(u16 *)(p + 0x60) = 0; + *(u8 *)(p + 0xC1) = 0; + *(u8 *)(p + 0xC2) = 0x10; + func_80189390(p); + } +} + + + + +// func_80189D30 -- ov_SC06_018 / ov_SC06_018_jr_80187AEC +// +// Structural sibling of func_8018E188 (SAME TU, banked MATCH, this file: func_8018E188). +// Shares VERBATIM: the 0x60 gate + 0x1D snapshot block, the 0x78/0x60 decrement block +// (AND form -- see E188's @stuck note), the 0x82&1 finisher, and the C8/C9 pokes. +// Diverges after that: instead of E188's 0x76<0 spawn-loop / CC-D0-D4 reseed, this +// function's 0x76<0 arm sets a distinct "state 2" field group (offsets 2/0x5C/0x34/ +// 0xC1/0xF4 + clears bit 0x80 of *(p+0x20)->0x2C), and its else arm plays a different +// sound (func_8002D4C8(0xAD8,0) vs E188's 0xAE0) then tail-calls func_80189390 (still +// INCLUDE_ASM in this TU -- no other TU references it, so this call site sets its own +// convention: void func_80189390(void *)). +// +// @class: regalloc-order +// @stuck: none -- see match_one output. + +extern void func_8016AA50(s32, s32); +extern s32 func_8016B428(s32); +extern void func_80019064(void *); +extern void func_8002A520(int); +extern void func_8002A790(int); +extern void func_8002D4C8(s32, s32); +extern void func_80189390(void *); + +void func_80189D30(void *arg) { + + extern u8 D_801C835C; + u8 *p = (u8 *)arg; + s32 e = *(u8 *)(p + 0x5E); + + if (*(s16 *)(p + 0x60) != 0) { + if (e == 0x1D) { + *(u16 *)(p + 0x82) = 0; + *(u16 *)(p + 0x7C) = *(u16 *)(p + 0x06); + *(u16 *)(p + 0x7E) = *(u16 *)(p + 0x0A); + *(u16 *)(p + 0x80) = *(u16 *)(p + 0x0E); + } + { + s32 dec; + s32 q = *(s32 *)(p + 0x78); + if (q != 0 && *(s16 *)(p + 0x60) != 0) { + dec = ((s32)*(s16 *)(p + 0x60) * (s32)*(s16 *)(q + 0x30)) >> 12; + if (dec < 1) dec = 1; + } else { + dec = *(s16 *)(p + 0x60); + } + *(u16 *)(p + 0x76) = *(u16 *)(p + 0x76) - dec; + ((void (*)(void *, s32))func_8016AA50)(p, dec); + } + if (*(u16 *)(p + 0x82) & 1) { + ((void (*)(void *))func_8016B428)(p); + func_80019064(&D_801C835C); + } + } + + if (e != 0x1D) { + if (*(u8 *)(p + 0xC8)) func_8002A520(p); + if (*(u8 *)(p + 0xC9)) func_8002A790(p); + } + + if (*(s16 *)(p + 0x76) < 0) { + s32 q = *(s32 *)(p + 0x20); + *(s16 *)(p + 0x02) = 0xB; + *(u16 *)(p + 0x5C) = 0x800; + *(u16 *)(p + 0x34) = 0; + *(u8 *)(p + 0xC1) = 0; + *(s32 *)(p + 0xF4) = 1; + *(u16 *)(q + 0x2C) &= 0xFF7F; + } else { + func_8002D4C8(0xAD8, 0); + *(u16 *)(p + 0x5C) = 0x8800; + *(u16 *)(p + 0x60) = 0; + *(u8 *)(p + 0xC1) = 0; + *(u8 *)(p + 0xC2) = 0x10; + func_80189390(p); + } +} + // @class: regalloc-order