diff --git a/src/ov_SC03_108/ov_SC03_108_jr_8017BEBC.c b/src/ov_SC03_108/ov_SC03_108_jr_8017BEBC.c index 0904338d0..48610323c 100644 --- a/src/ov_SC03_108/ov_SC03_108_jr_8017BEBC.c +++ b/src/ov_SC03_108/ov_SC03_108_jr_8017BEBC.c @@ -3289,7 +3289,72 @@ void func_8017D0D4(void *a0) { } -INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017D110); + + + + + +extern s32 D_80126B58; +extern s32 *D_80126B78; +extern Blk8_80126940 D_80126940; +extern s16 D_80184768[]; +extern u8 D_80184720; +extern s16 D_801A1930; + +extern u16 func_80148800(s32 *a0); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern s32 func_80012DBC(s32 a0, s32 a1, s32 a2, s32 a3); +extern void func_8017D2B8(s32 param_1, s32 param_2, s16 *param_3); +extern s32 func_8017D484(u8 *param_1, s16 *param_2, s16 *param_3); + +void func_8017D110(s32 param_1) +{ + Blk8_80126940 sp10; + Blk8_80126940 sp18; + u8 t; + s32 r; + s32 sh; + + if (func_80148800(&D_80126B58) & 3) { + t = (*(u8 *)(param_1 + 5) + 1) & 1; + *(u8 *)(param_1 + 5) = t; + *(s32 *)(param_1 + 0x14) = D_80184768[t]; + } + sp10 = D_80126940; + + r = func_8004787C(((s16 *)D_80126B78)[9]); + if (r < 0) { + r += 0x7F; + } + sp18.v[0] = sp10.v[0] - (r >> 7); + + r = func_80047948(((s16 *)D_80126B78)[9]); + if (r < 0) { + r += 0x7F; + } + sh = r >> 7; + sp18.v[2] = sp10.v[2] - sh; + sp18.v[1] = sp10.v[1]; + + *(s16 *)(param_1 + 0xA0) = func_8017D484(&D_80184720, sp10.v, sp18.v); + + if (sp10.v[1] > 0) { + sp10.v[1] = 0; + } + if (sp10.v[2] >= -0x7F) { + sp10.v[2] = -0x80; + } + if (*(s16 *)(param_1 + 0xA0) >= 0xB81) { + *(s16 *)(param_1 + 0xA0) = 0xB80; + } + if (*(s16 *)(param_1 + 0xA0) < 0x480) { + *(s16 *)(param_1 + 0xA0) = 0x480; + } + D_801A1930 = func_80012DBC(D_801A1930, *(s16 *)(param_1 + 0xA0), 4, 1); + func_8017D2B8(param_1, D_801A1930, sp10.v); +} + extern s32 func_80012C6C(s32 a0, s32 a1, s32 a2); diff --git a/src/ov_SC03_124/ov_SC03_124_jr_80188544.c b/src/ov_SC03_124/ov_SC03_124_jr_80188544.c index 4a22434de..dc76b68a4 100644 --- a/src/ov_SC03_124/ov_SC03_124_jr_80188544.c +++ b/src/ov_SC03_124/ov_SC03_124_jr_80188544.c @@ -4572,7 +4572,72 @@ void func_8018A6C0(s32 a0) { } -INCLUDE_ASM("asm/ov_SC03_124/nonmatchings/ov_SC03_124_jr_80188544", func_8018A788); + + +extern void func_80029124(s32, s32); +extern s32 func_800291B4(s32 arg); +extern s32 func_800D0FE0(s32); +extern void func_800D0F0C(s32, s32); + +extern s16 D_8010EDEC; +extern u8 D_8010EDF1; +extern s32 D_801DE84C; +extern u32 D_801DE860; +extern s32 D_801DE990; + +typedef struct { + s16 field_0; + s16 field_2; + s32 field_4; + s32 field_8; + s32 field_C; +} Struct801EF318; + +extern Struct801EF318 D_801E2498; + +void func_8018A788(void) { + s16 i; + + D_801E2498.field_0 = 0; + for (i = 0; i < 0xC; i++) { + s32 slot = i + 0x2F; + s32 id = func_800291B4(slot) & 0xFF; + if (id != 0) { + register s32 tmp __asm__("$2"); + register s32 t __asm__("$5"); + register s32 rb __asm__("$6"); + s16 flags; + s32 m; + tmp = (id << 1) + id; + t = tmp << 2; + flags = *(s16 *)((u8 *)&D_8010EDEC + t); + if (flags < 0) { + rb = *(u8 *)((u8 *)&D_8010EDF1 + t); + m = rb & 0xFF; + if (flags & 0x4000) { + D_801E2498.field_8 = (&D_801DE84C)[id]; + D_801E2498.field_C = (&D_801DE860)[id]; + func_80029124(m, 1); + func_800D0FE0(slot); + D_801E2498.field_0 = 2; + return; + } else { + register s32 sc __asm__("$4"); + register s32 d __asm__("$2"); + sc = slot; + __asm__("" : "=r"(sc) : "0"(sc)); + d = rb - 0x14; + __asm__("" : "=r"(d) : "0"(d)); + D_801E2498.field_4 = (&D_801DE990)[d >> 1]; + ((void (*)(s32))func_800D0F0C)(sc); + D_801E2498.field_0 = 1; + return; + } + } + } + } +} + diff --git a/src/ov_SC05_002/ov_SC05_002_jr_8017BEBC.c b/src/ov_SC05_002/ov_SC05_002_jr_8017BEBC.c index a1fa2610a..7bd95e7c7 100644 --- a/src/ov_SC05_002/ov_SC05_002_jr_8017BEBC.c +++ b/src/ov_SC05_002/ov_SC05_002_jr_8017BEBC.c @@ -4602,7 +4602,127 @@ void func_8017F30C(void *a0) { } -INCLUDE_ASM("asm/ov_SC05_002/nonmatchings/ov_SC05_002_jr_8017BEBC", func_8017F348); + + +extern u8 D_801202A0[]; +extern s32 D_80126B58; +extern u16 D_8019C7F0[]; +extern s16 D_8019C7F4[]; +extern u16 D_8019C7F8[]; +extern s16 D_8019C7FC[]; +extern s16 D_8019C7C4[]; +extern void func_8002D4C8(s32 a0, s32 a1); + +/* Three levers, all byte-proven on this body: + * + * 1. `ang`/`camAng` are s16 with BOTH promoted (int compare) and HImode + * (s16 arithmetic) uses -> combine rewrites the HImode load as a single + * `lh` into an SImode pseudo plus `(set (reg:HI) (subreg (reg:SI)))`, which + * is the `addu $a0,$v0,$zero` / `addu $a2,$t0,$zero` copy pair the target + * carries (cookbook 172a/172, "lh = promotion"). The same rewrite is what + * orphans the reload slots that make the frame -0x28 instead of -0x18: an + * s32 spelling here compiles to the right instructions with the WRONG frame. + * + * 2. `best > ad` and `ang > camAng` are written with the operands in THAT + * order (not `ad < best` / `camAng < ang`). gcc canonicalises `b > a` into + * the same `slt`, but the operand EVALUATION order survives (cookbook + * 172b-2): it decides which of the two extends / which of the two `lh`s is + * emitted first, and here it is the whole difference between the target + * schedule and a +1-instruction one with a stalled load. + * + * 3. `snd` is pinned to $a1. Unpinned it lands in $t2, which pushes byteoff + * onto $a1 and cascades every later allocation down one register (near 31). + * + * The tail call really does pass ONE argument -- the target sets only $a0=4 + * before the second `jal func_8002D4C8` -- so it is made through a cast, the + * same idiom this TU already uses, to stay compatible with the file-scope + * two-parameter prototype. + */ +void func_8017F348(s32 arg0) { + u8 *p; + u8 *cam; + u8 *found; + s32 i; + s16 best; + s16 d; + s16 ad; + u16 *tbl1; + s16 *tbl2; + register s32 snd __asm__("$5"); + s16 st; + s32 idx; + s16 dist; + s16 t; + s16 ang; + s16 camAng; + s16 diff; + s32 total; + + p = D_801202A0; + found = 0; + cam = (u8 *)&D_80126B58; + best = 0x7FFF; + for (i = 0; i < 0x60; i++) { + if (*(u16 *)p == 0x1A3) { + d = *(u16 *)(p + 6) - *(u16 *)(cam + 6); + ad = d; + if (d < 0) { + ad = -d; + } + if (best > ad) { + best = ad; + found = p; + } + } + p += 0x10C; + } + if (*(s16 *)(arg0 + 0xFE) != 0) { + snd = 0xBAA; + tbl1 = D_8019C7F8; + tbl2 = D_8019C7FC; + } else { + snd = 0x704; + tbl1 = D_8019C7F0; + tbl2 = D_8019C7F4; + } + if (found != 0) { + st = *(u16 *)(found + 0x70); + idx = st >> 1; + t = tbl1[idx] - *(u16 *)(cam + 6); + dist = t; + if (t < 0) { + dist = -t; + } + t = dist - 0x80; + dist = t; + diff = 0; + if (t < 0) { + dist = 0; + } + camAng = *(s16 *)(cam + 0xA); + ang = tbl2[idx]; + + if (ang > camAng) { + diff = ang - camAng; + } else { + ang = ang + *(u16 *)&D_8019C7C4[st]; + if (ang < camAng) { + diff = camAng - ang; + } + } + total = dist + diff; + if (total < 0x200) { + func_8002D4C8(snd, ((0x7F - (total >> 2)) | 0x1000) & 0xFFFF); + *(s16 *)(arg0 + 0x84) = 1; + return; + } + } + if (*(s16 *)(arg0 + 0x84) != 0) { + ((void (*)(s32))func_8002D4C8)(4); + *(s16 *)(arg0 + 0x84) = 0; + } +} + extern s32 func_80029178(s32 arg); extern s32 func_8012C588(s32 a0, s32 a1); 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 d38aa27c4..f0bdb7837 100644 --- a/src/ov_SC06_018/ov_SC06_018_jr_80186270.c +++ b/src/ov_SC06_018/ov_SC06_018_jr_80186270.c @@ -3756,7 +3756,67 @@ void func_80187320(s32 a0) { } -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80186270", func_801874E4); + + +/* SIMULATION of real-TU context: the TU carries these two rows before the def */ +extern void func_801874E4(s32 a0, s32 a1); +extern void func_801874E4(s32 a0, s32 a1); + +void func_801874E4(s32 arg0, s32 arg1) { + extern u8 D_801B516C[]; + extern s32 D_801B53A4[]; + extern u8 D_800D3918[]; + extern void func_80189380(s32 a0, void *a1, void *a2, s32 a3); + extern void func_8018931C(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5); + extern void func_8001C924(s32 a0, void *a1); + register s32 rv __asm__("$2"); + u8 buf[8]; + s32 x = arg1; + s32 y; + s32 res; + s16 state; + s32 flags; + + __asm__("addu %0, %1, $zero" : "=r"(y) : "r"(x)); + state = *(u16 *)(arg0 + 0x70) & 0xF; + flags = *(u32 *)(arg0 + 0xE0); + if (flags & 4) { + rv = 0; + goto epi; + } + switch (state) { + case 0: + if (flags & 1) { + func_80189380(arg0, D_801B516C, buf, 0xC); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_8018931C)(arg0, buf, 0x27F, (s16)x, 0, 0); + *(s32 *)(arg0 + 0xD0) = res; + *(u32 *)(arg0 + 0xE0) &= ~1; + if (res != 0) { + *(u16 *)(arg0 + 0xEE) = *(u16 *)(res + 0x36); + } + } + /* fallthrough */ + case 1: + case 2: + case 3: + func_80189380(arg0, D_800D3918, buf, 0xB); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_8018931C)(arg0, buf, 0x27F, (s16)(y | (state + 1)), 0, 0); + *(s32 *)(arg0 + 0xCC) = res; + *(u32 *)(arg0 + 0xE0) |= 4; + func_8001C924(*(s32 *)(arg0 + 0x20), (void *)D_801B53A4[state]); + if (res != 0) { + *(u16 *)(arg0 + 0xEC) = *(u16 *)(res + 0x36); + } + break; + default: + rv = 1; + goto epi; + } + rv = 1; +epi: + __asm__ volatile("" : : "r"(rv)); +} + s32 func_8018765C(s32 a0) { s32 s1; diff --git a/src/ov_SC06_020/ov_SC06_020_jr_80180B04.c b/src/ov_SC06_020/ov_SC06_020_jr_80180B04.c index 8a148041d..c4f69fc5d 100644 --- a/src/ov_SC06_020/ov_SC06_020_jr_80180B04.c +++ b/src/ov_SC06_020/ov_SC06_020_jr_80180B04.c @@ -3264,7 +3264,67 @@ void func_80181490(s32 a0) { } -INCLUDE_ASM("asm/ov_SC06_020/nonmatchings/ov_SC06_020_jr_80180B04", func_80181654); + + +/* SIMULATION of real-TU context: the TU carries these two rows before the def */ +extern void func_80181654(s32 a0, s32 a1); +extern void func_80181654(s32 a0, s32 a1); + +void func_80181654(s32 arg0, s32 arg1) { + extern u8 D_8019E99C[]; + extern s32 D_8019EBD4[]; + extern u8 D_800D3918[]; + extern void func_801834F0(s32 a0, void *a1, void *a2, s32 a3); + extern void func_8018348C(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5); + extern void func_8001C924(s32 a0, void *a1); + register s32 rv __asm__("$2"); + u8 buf[8]; + s32 x = arg1; + s32 y; + s32 res; + s16 state; + s32 flags; + + __asm__("addu %0, %1, $zero" : "=r"(y) : "r"(x)); + state = *(u16 *)(arg0 + 0x70) & 0xF; + flags = *(u32 *)(arg0 + 0xE0); + if (flags & 4) { + rv = 0; + goto epi; + } + switch (state) { + case 0: + if (flags & 1) { + func_801834F0(arg0, D_8019E99C, buf, 0xC); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_8018348C)(arg0, buf, 0x27F, (s16)x, 0, 0); + *(s32 *)(arg0 + 0xD0) = res; + *(u32 *)(arg0 + 0xE0) &= ~1; + if (res != 0) { + *(u16 *)(arg0 + 0xEE) = *(u16 *)(res + 0x36); + } + } + /* fallthrough */ + case 1: + case 2: + case 3: + func_801834F0(arg0, D_800D3918, buf, 0xB); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_8018348C)(arg0, buf, 0x27F, (s16)(y | (state + 1)), 0, 0); + *(s32 *)(arg0 + 0xCC) = res; + *(u32 *)(arg0 + 0xE0) |= 4; + func_8001C924(*(s32 *)(arg0 + 0x20), (void *)D_8019EBD4[state]); + if (res != 0) { + *(u16 *)(arg0 + 0xEC) = *(u16 *)(res + 0x36); + } + break; + default: + rv = 1; + goto epi; + } + rv = 1; +epi: + __asm__ volatile("" : : "r"(rv)); +} + s32 func_801817CC(s32 a0) { diff --git a/src/ov_SC06_022/ov_SC06_022_jr_80184A28.c b/src/ov_SC06_022/ov_SC06_022_jr_80184A28.c index 9f2198914..160eefb9b 100644 --- a/src/ov_SC06_022/ov_SC06_022_jr_80184A28.c +++ b/src/ov_SC06_022/ov_SC06_022_jr_80184A28.c @@ -3304,7 +3304,67 @@ void func_801853B4(s32 a0) { } -INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_80184A28", func_80185578); + + +/* SIMULATION of real-TU context: the TU carries these two rows before the def */ +extern void func_80185578(s32 a0, s32 a1); +extern void func_80185578(s32 a0, s32 a1); + +void func_80185578(s32 arg0, s32 arg1) { + extern u8 D_801BD0C4[]; + extern s32 D_801BD2FC[]; + extern u8 D_800D3918[]; + extern void func_80187414(s32 a0, void *a1, void *a2, s32 a3); + extern void func_801873B0(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5); + extern void func_8001C924(s32 a0, void *a1); + register s32 rv __asm__("$2"); + u8 buf[8]; + s32 x = arg1; + s32 y; + s32 res; + s16 state; + s32 flags; + + __asm__("addu %0, %1, $zero" : "=r"(y) : "r"(x)); + state = *(u16 *)(arg0 + 0x70) & 0xF; + flags = *(u32 *)(arg0 + 0xE0); + if (flags & 4) { + rv = 0; + goto epi; + } + switch (state) { + case 0: + if (flags & 1) { + func_80187414(arg0, D_801BD0C4, buf, 0xC); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_801873B0)(arg0, buf, 0x27F, (s16)x, 0, 0); + *(s32 *)(arg0 + 0xD0) = res; + *(u32 *)(arg0 + 0xE0) &= ~1; + if (res != 0) { + *(u16 *)(arg0 + 0xEE) = *(u16 *)(res + 0x36); + } + } + /* fallthrough */ + case 1: + case 2: + case 3: + func_80187414(arg0, D_800D3918, buf, 0xB); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_801873B0)(arg0, buf, 0x27F, (s16)(y | (state + 1)), 0, 0); + *(s32 *)(arg0 + 0xCC) = res; + *(u32 *)(arg0 + 0xE0) |= 4; + func_8001C924(*(s32 *)(arg0 + 0x20), (void *)D_801BD2FC[state]); + if (res != 0) { + *(u16 *)(arg0 + 0xEC) = *(u16 *)(res + 0x36); + } + break; + default: + rv = 1; + goto epi; + } + rv = 1; +epi: + __asm__ volatile("" : : "r"(rv)); +} + extern s32 func_8012CBA4(s32 a0); extern void func_80185750(s32 a0, s32 a1); diff --git a/src/ov_SC06_024/ov_SC06_024_jr_80186F00.c b/src/ov_SC06_024/ov_SC06_024_jr_80186F00.c index e33b12749..002e04d00 100644 --- a/src/ov_SC06_024/ov_SC06_024_jr_80186F00.c +++ b/src/ov_SC06_024/ov_SC06_024_jr_80186F00.c @@ -3327,7 +3327,67 @@ void func_8018788C(s32 a0) { } -INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_80186F00", func_80187A50); + + +/* SIMULATION of real-TU context: the TU carries these two rows before the def */ +extern void func_80187A50(s32 a0, s32 a1); +extern void func_80187A50(s32 a0, s32 a1); + +void func_80187A50(s32 arg0, s32 arg1) { + extern u8 D_801BC208[]; + extern s32 D_801BC440[]; + extern u8 D_800D3918[]; + extern void func_801898EC(s32 a0, void *a1, void *a2, s32 a3); + extern void func_80189888(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5); + extern void func_8001C924(s32 a0, void *a1); + register s32 rv __asm__("$2"); + u8 buf[8]; + s32 x = arg1; + s32 y; + s32 res; + s16 state; + s32 flags; + + __asm__("addu %0, %1, $zero" : "=r"(y) : "r"(x)); + state = *(u16 *)(arg0 + 0x70) & 0xF; + flags = *(u32 *)(arg0 + 0xE0); + if (flags & 4) { + rv = 0; + goto epi; + } + switch (state) { + case 0: + if (flags & 1) { + func_801898EC(arg0, D_801BC208, buf, 0xC); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_80189888)(arg0, buf, 0x27F, (s16)x, 0, 0); + *(s32 *)(arg0 + 0xD0) = res; + *(u32 *)(arg0 + 0xE0) &= ~1; + if (res != 0) { + *(u16 *)(arg0 + 0xEE) = *(u16 *)(res + 0x36); + } + } + /* fallthrough */ + case 1: + case 2: + case 3: + func_801898EC(arg0, D_800D3918, buf, 0xB); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_80189888)(arg0, buf, 0x27F, (s16)(y | (state + 1)), 0, 0); + *(s32 *)(arg0 + 0xCC) = res; + *(u32 *)(arg0 + 0xE0) |= 4; + func_8001C924(*(s32 *)(arg0 + 0x20), (void *)D_801BC440[state]); + if (res != 0) { + *(u16 *)(arg0 + 0xEC) = *(u16 *)(res + 0x36); + } + break; + default: + rv = 1; + goto epi; + } + rv = 1; +epi: + __asm__ volatile("" : : "r"(rv)); +} + s32 func_80187BC8(s32 a0) { s32 flags; diff --git a/src/ov_SC06_032/ov_SC06_032_jr_80181014.c b/src/ov_SC06_032/ov_SC06_032_jr_80181014.c index 9dd7a2369..97dbd8f6b 100644 --- a/src/ov_SC06_032/ov_SC06_032_jr_80181014.c +++ b/src/ov_SC06_032/ov_SC06_032_jr_80181014.c @@ -3549,7 +3549,67 @@ void func_801820C4(s32 a0) { } -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_80181014", func_80182288); + + +/* SIMULATION of real-TU context: the TU carries these two rows before the def */ +extern void func_80182288(s32 a0, s32 a1); +extern void func_80182288(s32 a0, s32 a1); + +void func_80182288(s32 arg0, s32 arg1) { + extern u8 D_801A65FC[]; + extern s32 D_801A6834[]; + extern u8 D_800D3918[]; + extern void func_80184124(s32 a0, void *a1, void *a2, s32 a3); + extern void func_801840C0(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5); + extern void func_8001C924(s32 a0, void *a1); + register s32 rv __asm__("$2"); + u8 buf[8]; + s32 x = arg1; + s32 y; + s32 res; + s16 state; + s32 flags; + + __asm__("addu %0, %1, $zero" : "=r"(y) : "r"(x)); + state = *(u16 *)(arg0 + 0x70) & 0xF; + flags = *(u32 *)(arg0 + 0xE0); + if (flags & 4) { + rv = 0; + goto epi; + } + switch (state) { + case 0: + if (flags & 1) { + func_80184124(arg0, D_801A65FC, buf, 0xC); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_801840C0)(arg0, buf, 0x27F, (s16)x, 0, 0); + *(s32 *)(arg0 + 0xD0) = res; + *(u32 *)(arg0 + 0xE0) &= ~1; + if (res != 0) { + *(u16 *)(arg0 + 0xEE) = *(u16 *)(res + 0x36); + } + } + /* fallthrough */ + case 1: + case 2: + case 3: + func_80184124(arg0, D_800D3918, buf, 0xB); + res = ((s32 (*)(s32, void *, s32, s32, s32, s32))func_801840C0)(arg0, buf, 0x27F, (s16)(y | (state + 1)), 0, 0); + *(s32 *)(arg0 + 0xCC) = res; + *(u32 *)(arg0 + 0xE0) |= 4; + func_8001C924(*(s32 *)(arg0 + 0x20), (void *)D_801A6834[state]); + if (res != 0) { + *(u16 *)(arg0 + 0xEC) = *(u16 *)(res + 0x36); + } + break; + default: + rv = 1; + goto epi; + } + rv = 1; +epi: + __asm__ volatile("" : : "r"(rv)); +} + #include "common.h"