feat(phase-26): h_seq family sweep — 43 member-matches banked via remap_hseq

This commit is contained in:
Drew T
2026-08-17 12:25:38 -06:00
parent d73fe15310
commit 45aad382ea
14 changed files with 3240 additions and 57 deletions
+200 -4
View File
@@ -1789,9 +1789,7 @@ extern void func_8016A700(void *a0);
extern s32 func_8016A73C(s32 arg0);
extern s32 func_8016A8FC(s32 a0);
extern void func_8016A890(s32 arg0);
extern u16 D_80126B5E;
extern u16 D_80126B62;
extern u16 D_80126B66;
extern void func_8016AA50(s32 param_1, s32 param_2);
extern void (*D_80189288[])(void);
extern void func_8016AB30(void *a0);
@@ -3474,7 +3472,88 @@ INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017D9D
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017DA5C);
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017DAB8);
typedef struct { u8 b[8]; } Blk8_8017DAB8;
typedef struct {
s32 a; /* 0x00 -> D_801DA750 */
s32 b; /* 0x04 -> D_801DA754 */
} Pair8_8017DDC4_80182244_8017DAB8;
/* Sibling shape in the SAME TU: func_80182244 (already banked, line ~3980)
* uses the identical idiom for the same actor kind: void *a0, raw
* (s32)a0+offset field access, func_8012C1B8 cast-called as (s32(*)(void)),
* func_8012CAE4, func_8001C214, and the 0x70-indexed table lookup + 0x1000000
* OR-flag pattern at (*(s32*)(sub+4)) |= 0x1000000. Adopted as a structural
* hint only (law 1) — none of its per-location symbols are reused here. */
extern void func_8012C1B8(void);
extern void func_8012CAE4(void *a0);
extern s32 func_80029178(s32 a0);
extern void func_8001C214(s32 a0, s32 a1);
extern s32 func_8012AD50(void *a0);
/* idx = *(s16*)(a0+0x70): lhu direct load, 2-byte stride -> u16 table */
/* address-of only in the target (lui/addiu, no load/store through it here) */
void func_8017DAB8(s32 a0)
{
extern u16 D_801A429C[];
extern u8 D_801A428C;
extern u8 D_801A427C;
if ((*(s32 *)(a0 + 0x20) = ((s32 (*)(void))func_8012C1B8)()) == 0) {
func_8012CAE4((void *)a0);
return;
}
if ((func_80029178((s32)D_801A429C[*(s16 *)(a0 + 0x70)]) & 0xFF) != 0) {
register s32 s0 __asm__("$16") = *(s32 *)(a0 + 0xDC);
if (s0 != 0) {
s32 a1 = *(s32 *)(s0 + 0x4);
if (a1 != 0) {
func_8001C214(*(s32 *)(a0 + 0x20), a1);
if (*(s32 *)(s0 + 0xC) != 0) {
s32 v1 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4);
v1 |= 0x1000000;
*(s32 *)(*(s32 *)(a0 + 0x20) + 0x4) = v1;
}
}
}
func_8012AD50((void *)a0);
goto tail;
}
{
register s32 s0 __asm__("$16") = *(s32 *)(a0 + 0xDC);
register s32 flag __asm__("$2") = 1;
if (s0 != 0) {
s32 a1 = *(s32 *)s0;
if (a1 != 0) {
func_8001C214(*(s32 *)(a0 + 0x20), a1);
if (*(s32 *)(s0 + 0xC) != 0) {
s32 v1 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4);
v1 |= 0x1000000;
*(s32 *)(*(s32 *)(a0 + 0x20) + 0x4) = v1;
}
flag = 1;
}
}
*(u8 *)(a0 + 0xC0) = flag;
}
*(s32 *)(a0 + 0xBC) = (s32)&D_801A428C;
*(s32 *)(a0 + 0x58) = (s32)&D_801A427C | 0x40000000;
*(u16 *)(a0 + 0x5C) = 0x8800;
*(s32 *)(a0 + 0xB4) = 0;
*(u8 *)(a0 + 0xC1) = 0;
*(u16 *)(a0 + 0xAE) = 0x7FFF;
*(u8 *)(a0 + 0x75) = 0;
*(s32 *)(a0 + 0xC4) |= 0x2;
tail:
func_8012AD50((void *)a0);
}
// @class: struct
@@ -3638,7 +3717,124 @@ INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017E59
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017E654);
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017E72C);
typedef struct { u8 b[8]; } Blk8_8017E72C;
typedef struct {
u8 c[8];
} Blk8_80186594_8017E72C;
typedef struct {
s32 a; /* 0x00 -> D_801DA750 */
s32 b; /* 0x04 -> D_801DA754 */
} Pair8_8017DDC4_80182244_8017E72C;
/* func_8017E72C -- ov_SC02_027, subseg ov_SC02_027_jr_8017D898 (106 ins).
* Mass-lane fresh crack. Nearest exemplar ov_SC02_026:func_8017E72C is still
* unmatched (INCLUDE_ASM), so no cousin body to adapt -- built straight from
* the target .s.
*
* Symbol provenance:
* func_8012E9C0 NOT declared anywhere in this TU (only inside the
* engine_core.h DEFINE_func_8012E9C0 macro, unexpanded
* here) -> declared fresh, `void (int)`, no conflict.
* func_8002A520 NOT declared in this TU; matches the sibling-TU form
* seen in ov_SC03_006/099 etc's jr_8012ACE0.c: `void (void*)`.
* func_8002A790 same as above, `void (void*)`.
* D_80126B5E TU col-0 decl (this file:1789), adopted verbatim `extern u16`
* D_80126B62 TU local-scope decl (this file:4233/6455/6538),
* adopted verbatim `extern u16`
* D_80126B66 TU col-0 decl (this file:1790), adopted verbatim `extern u16`
* VectorNormalSS TU col-0 decl (this file:1846), adopted verbatim `s32 (void*,void*)`
* func_80131E00 TU local-scope decl (this file:6734/6813/6981),
* adopted verbatim `void (void*, s32)`
* func_8012A828 TU col-0/local decl (this file:4380 et al), adopted
* verbatim `void (s32, s32)`
* D_801A9D90 not declared anywhere in-tree yet; passed as a bare
* lui/addiu address (no load) -> declared as u8[] here.
*
* Residual-class note: field 0x76 is read (u16, for the decrement), stored,
* then read AGAIN (s16, for the <=0 test). A plain second dereference of the
* same `(u8*)a0+0x76` expression lets gcc-2.7.2's cse.c reuse the just-stored
* HImode value and synthesize the sign test via `sll $r,16` instead of a
* genuine `lh` -- confirmed by isolated probes (adds 1 spurious instruction,
* every time another independent load/store shares the block, regardless of
* source statement order or an intervening asm memory-clobber). Fix: (1) an
* `__asm__ __volatile__("" ::: "memory")` between the store and the reload
* to pin ordering, AND (2) drop the named `cnt`/`flags` locals in favor of
* inlining both the 0x5C read-modify-write and the 0x76 compare directly at
* their use sites -- naming the intermediate values reintroduces the same
* cse fold even behind the barrier. Both edits were required together.
*/
extern void func_8012E9C0(int param_1);
extern void func_8002A520(void *a0);
extern void func_8002A790(void *a0);
extern s32 VectorNormalSS(void *a0, void *a1);
extern void func_80131E00(void *a0, s32 a1);
extern void func_8012A828(s32 a0, s32 a1);
void func_8017E72C(void *a0) {
extern u16 D_80126B5E;
extern u16 D_80126B66;
extern u8 D_801A9D90[];
u16 sv[4];
s32 speed;
func_8012E9C0((s32)a0);
if (*(u16 *)((u8 *)a0 + 0x5E) != 0x1D) {
if (*(u8 *)((u8 *)a0 + 0xC8)) {
func_8002A520(a0);
}
if (*(u8 *)((u8 *)a0 + 0xC9)) {
func_8002A790(a0);
}
}
{
s32 base = *(s32 *)((u8 *)a0 + 0x78);
speed = (*(s16 *)((u8 *)a0 + 0x60) * *(s16 *)(base + 0x30)) >> 12;
}
if (speed <= 0) {
speed = 1;
}
*(u16 *)((u8 *)a0 + 0x76) = *(u16 *)((u8 *)a0 + 0x76) - speed;
__asm__ __volatile__("" ::: "memory");
{
*(u16 *)((u8 *)a0 + 0x5C) = *(u16 *)((u8 *)a0 + 0x5C) & 0xFFFE;
if (*(s16 *)((u8 *)a0 + 0x76) <= 0) {
*(u16 *)((u8 *)a0 + 0x5C) = 0;
func_80131E00(a0, 0xE);
} else {
if (speed > 0x10) {
speed = 0x10;
}
sv[0] = *(u16 *)((u8 *)a0 + 6) - D_80126B5E;
sv[1] = *(u16 *)((u8 *)a0 + 0xA) - D_80126B62;
sv[2] = *(u16 *)((u8 *)a0 + 0xE) - D_80126B66;
VectorNormalSS(sv, (u8 *)a0 + 0x102);
speed += 8;
{
s32 p0 = speed * *(s16 *)((u8 *)a0 + 0x102);
s32 p1 = speed * *(s16 *)((u8 *)a0 + 0x104);
s32 p2 = speed * *(s16 *)((u8 *)a0 + 0x106);
*(s32 *)((u8 *)a0 + 0x1C) = 0x10;
*(s16 *)((u8 *)a0 + 0x102) = p0 >> 12;
*(s16 *)((u8 *)a0 + 0x104) = p1 >> 12;
*(s16 *)((u8 *)a0 + 0x106) = p2 >> 12;
}
}
}
*(s16 *)((u8 *)a0 + 6) = *(u16 *)((u8 *)a0 + 0x88);
*(s16 *)((u8 *)a0 + 0xA) = *(u16 *)((u8 *)a0 + 0x8A);
*(s16 *)((u8 *)a0 + 0xE) = *(u16 *)((u8 *)a0 + 0x8C);
func_8012A828((s32)a0, (s32)D_801A9D90);
}
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017E8D4);
+365 -4
View File
@@ -3766,7 +3766,88 @@ void func_8017FF68(void *a0, s32 a1)
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_8017FFC8);
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_80180040);
typedef struct { u8 b[8]; } Blk8_80180040;
typedef struct {
s32 a; /* 0x00 -> D_801DA750 */
s32 b; /* 0x04 -> D_801DA754 */
} Pair8_8017DDC4_80182244_80180040;
/* Sibling shape in the SAME TU: func_80182244 (already banked, line ~3980)
* uses the identical idiom for the same actor kind: void *a0, raw
* (s32)a0+offset field access, func_8012C1B8 cast-called as (s32(*)(void)),
* func_8012CAE4, func_8001C214, and the 0x70-indexed table lookup + 0x1000000
* OR-flag pattern at (*(s32*)(sub+4)) |= 0x1000000. Adopted as a structural
* hint only (law 1) — none of its per-location symbols are reused here. */
extern void func_8012C1B8(void);
extern void func_8012CAE4(void *a0);
extern s32 func_80029178(s32 a0);
extern void func_8001C214(s32 a0, s32 a1);
extern s32 func_8012AD50(void *a0);
/* idx = *(s16*)(a0+0x70): lhu direct load, 2-byte stride -> u16 table */
/* address-of only in the target (lui/addiu, no load/store through it here) */
void func_80180040(s32 a0)
{
extern u16 D_801A4C1C[];
extern u8 D_801A4C0C;
extern u8 D_801A4BFC;
if ((*(s32 *)(a0 + 0x20) = ((s32 (*)(void))func_8012C1B8)()) == 0) {
func_8012CAE4((void *)a0);
return;
}
if ((func_80029178((s32)D_801A4C1C[*(s16 *)(a0 + 0x70)]) & 0xFF) != 0) {
register s32 s0 __asm__("$16") = *(s32 *)(a0 + 0xDC);
if (s0 != 0) {
s32 a1 = *(s32 *)(s0 + 0x4);
if (a1 != 0) {
func_8001C214(*(s32 *)(a0 + 0x20), a1);
if (*(s32 *)(s0 + 0xC) != 0) {
s32 v1 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4);
v1 |= 0x1000000;
*(s32 *)(*(s32 *)(a0 + 0x20) + 0x4) = v1;
}
}
}
func_8012AD50((void *)a0);
goto tail;
}
{
register s32 s0 __asm__("$16") = *(s32 *)(a0 + 0xDC);
register s32 flag __asm__("$2") = 1;
if (s0 != 0) {
s32 a1 = *(s32 *)s0;
if (a1 != 0) {
func_8001C214(*(s32 *)(a0 + 0x20), a1);
if (*(s32 *)(s0 + 0xC) != 0) {
s32 v1 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4);
v1 |= 0x1000000;
*(s32 *)(*(s32 *)(a0 + 0x20) + 0x4) = v1;
}
flag = 1;
}
}
*(u8 *)(a0 + 0xC0) = flag;
}
*(s32 *)(a0 + 0xBC) = (s32)&D_801A4C0C;
*(s32 *)(a0 + 0x58) = (s32)&D_801A4BFC | 0x40000000;
*(u16 *)(a0 + 0x5C) = 0x8800;
*(s32 *)(a0 + 0xB4) = 0;
*(u8 *)(a0 + 0xC1) = 0;
*(u16 *)(a0 + 0xAE) = 0x7FFF;
*(u8 *)(a0 + 0x75) = 0;
*(s32 *)(a0 + 0xC4) |= 0x2;
tail:
func_8012AD50((void *)a0);
}
// @class: struct
@@ -3934,7 +4015,98 @@ INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_801808D
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_80180930);
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_80180970);
typedef struct { u8 b[8]; } Blk8_80180970;
typedef struct {
s32 a; /* 0x00 -> D_801DA750 */
s32 b; /* 0x04 -> D_801DA754 */
} Pair8_8017DDC4_80182244_80180970;
/* stride-8 tables, only the field-0 short of each record is ever read by
* this function; each is a SEPARATE relocation symbol in the target .s
* (D_801A4D0C/672/674/676 are 2/4/6/8 bytes apart but referenced as four
* independently-based arrays, never as one array + constant offset). */
typedef struct { u16 v; u16 pad[3]; } Stride8_u16_80182868_80180970;
typedef struct { s16 v; s16 pad[3]; } Stride8_s16_80182868_80180970;
void func_80180970(void *a0)
{
extern void func_8012C1B8(void);
extern void func_8012CAE4(void *a0);
extern void func_8001C214(s32 a0, s32 a1);
extern s32 func_80029178(s32);
extern void func_80180B4C(void *a0);
extern s32 D_801A6578;
extern s32 D_801A4CFC[];
extern Stride8_u16_80182868_80180970 D_801A4D0C[];
extern Stride8_u16_80182868_80180970 D_801A4D0E[];
extern Stride8_u16_80182868_80180970 D_801A4D10[];
extern Stride8_s16_80182868_80180970 D_801A4D12[];
extern s16 D_801A4CC0[];
s32 v0;
s16 state;
s16 i;
s16 id;
if ((*(s32 *)((s32)a0 + 0x20) = v0 = ((s32 (*)(void))func_8012C1B8)()) == 0) {
func_8012CAE4(a0);
return;
}
/* §67: launder v0 at the statement where the target's `addu a0,v0,zero`
* copy actually lands (the func_8001C214 call site), not right after
* func_8012C1B8 returns -- an unconstrained copy gets hoisted early. */
__asm__ __volatile__("" : "=r"(v0) : "0"(v0));
func_8001C214(v0, (s32)&D_801A6578);
*(u32 *)(*(s32 *)((s32)a0 + 0x20) + 0x28) = 0x2000200;
*(u32 *)((s32)a0 + 0x58) = (s32)D_801A4CFC | 0x10000000;
*(u8 *)((s32)a0 + 0x75) = 0;
if (*(s16 *)((s32)a0 + 0x70) == 1) {
*(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x4) |= 0x80000000;
*(u16 *)((s32)a0 + 0x5C) = 0;
} else {
*(u16 *)((s32)a0 + 0x5C) = 0xCC00;
}
*(s16 *)((s32)a0 + 0x6) = D_801A4D0C[*(s16 *)((s32)a0 + 0x70)].v;
*(s16 *)((s32)a0 + 0xA) = D_801A4D0E[*(s16 *)((s32)a0 + 0x70)].v;
*(s16 *)((s32)a0 + 0xE) = D_801A4D10[*(s16 *)((s32)a0 + 0x70)].v;
func_80180B4C(a0);
if (*(s16 *)((s32)a0 + 0x70) == 3) {
*(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x10) = 0x800;
}
if ((func_80029178(0xAE) & 0xFF) == 0) {
return;
}
if (D_801A4CC0[0] != 0) {
state = *(s16 *)((s32)a0 + 0x70);
i = 0;
for (;;) {
id = D_801A4CC0[i + 1];
if (id == state) {
if (id >= 2) {
if (D_801A4D12[id].v != 0) {
*(s16 *)((s32)a0 + 0x6) -= 0x200;
} else {
*(s16 *)((s32)a0 + 0x6) += 0x200;
}
}
}
i += 2;
if (D_801A4CC0[i] == 0) {
break;
}
}
}
}
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_80180B4C);
@@ -3998,7 +4170,65 @@ INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_801814A
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_80181520);
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_801815F0);
extern void func_8012C1B8(void);
extern void func_8012CAE4(void *a0);
extern void func_8001C810(s32 a0, s32 a1);
extern void func_80178B18(s32, s32);
extern void func_801817B8(void *arg0);
extern void func_80181760(void *arg0);
extern void func_80181A20(void *arg0);
void func_801815F0(void *a0)
{
extern u16 D_801A4DD4[][4];
extern u16 D_801A4DD6[][4];
extern u16 D_801A4DD8[][4];
extern u16 D_801A4DDA[][4];
extern s32 D_801A6958;
extern s32 D_801A4DE4;
extern s32 D_801A4DF4;
s32 v0;
/* §162-style: fold the store AND the test into ONE expression so cc1
* keeps the call's return value live in $v0 for the following call. */
if ((v0 = *(s32 *)((s32)a0 + 0x20) = ((s32 (*)(void))func_8012C1B8)()) == 0) {
func_8012CAE4(a0);
return;
}
func_8001C810(v0, (s32)&D_801A6958);
*(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x4) |= 0x8040;
*(s16 *)(*(s32 *)((s32)a0 + 0x20) + 0x12) =
D_801A4DDA[*(s16 *)((s32)a0 + 0x70)][0];
if (*(s16 *)((s32)a0 + 0x70) < 2) {
*(s32 *)((s32)a0 + 0x58) = (s32)&D_801A4DE4 | 0x40000000;
*(u16 *)((s32)a0 + 0x5C) = 0xC400;
*(u8 *)((s32)a0 + 0x75) = 0;
*(s16 *)((s32)a0 + 0x6) =
D_801A4DD4[*(s16 *)((s32)a0 + 0x70)][0];
*(s16 *)((s32)a0 + 0xA) =
D_801A4DD6[*(s16 *)((s32)a0 + 0x70)][0];
*(s16 *)((s32)a0 + 0xE) =
D_801A4DD8[*(s16 *)((s32)a0 + 0x70)][0];
if (*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0x100) == 0) {
((s32 (*)(s32, s32))func_80178B18)((s32)a0, (s32)&D_801A4DF4);
*(s16 *)((s32)a0 + 0xFE) = 1;
*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0xFE) = 2;
func_80181760(a0);
} else {
*(u16 *)((s32)a0 + 0xA) = *(u16 *)((s32)a0 + 0xA) + 0x280;
func_801817B8(a0);
}
} else {
func_80181A20(a0);
}
}
extern void func_8012AD44(s32 *a0, s16 a1);
void func_80181760(void * arg0) {
@@ -4017,7 +4247,138 @@ extern void func_8012AD44(s32 *a0, s16 a1);
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_801817B8);
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_8017D898", func_80181824);
typedef struct { u8 b[8]; } Blk8_80181824;
typedef struct {
u8 c[8];
} Blk8_80186594_80181824;
typedef struct {
s32 a; /* 0x00 -> D_801DA750 */
s32 b; /* 0x04 -> D_801DA754 */
} Pair8_8017DDC4_80182244_80181824;
/* Declarations copied VERBATIM from the destination TU
* (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c):
* func_8014C088 TU:511 `s32 (s32,s32)`
* func_8002A088 TU:2350 `void (s32)`
* func_8002A2D4 TU:2351 `void (s32)`
* func_8002A544 TU:2352 `void (s32)`
* func_8002A7B4 TU:2353 `void (s32)`
* func_8016AA50 TU:1791 `void (s32,s32)`
* func_80178970 TU:2526 `int (void)`
* func_80178B18 TU:2527 `s32 (s32,s32)`
* func_80178D18 TU:2534 `void (void)`
* func_80029124 TU:500 `void (s32,s32)`
* func_8012BEE8 TU:3912 `s32 (s32)`
* func_801819F0 TU:4178 defined in this TU as `void (s32 *)`
* func_8002D4C8 TU:3708 `void (s32,s32)`
*
* D_801A4DFC / D_801A4DC4 are NOT declared anywhere in this TU yet.
* Declared here in the rawest form the access widths demand (law 4):
* D_801A4DFC is only ever address-of'd (la), never dereferenced by
* this function -> raw scalar is enough.
* D_801A4DC4 is indexed by a signed s16 (sll #1 -> 2-byte stride) and
* read with lhu -> u16 array.
*/
extern s32 func_8014C088(s32 a0, s32 a1);
extern void func_8002A088(s32);
extern void func_8002A2D4(s32);
extern void func_8002A544(s32);
extern void func_8002A7B4(s32);
extern void func_8016AA50(s32 param_1, s32 param_2);
extern int func_80178970(void);
extern void func_80178B18(s32, s32);
extern void func_80178D18(void);
extern void func_80029124(s32 a0, s32 a1);
extern s32 func_8012BEE8(s32 a0);
extern void func_801819F0(void*);
extern void func_8002D4C8(s32 a0, s32 a1);
void func_80181824(void *a0) {
extern void *D_801A4DFC;
extern s32 D_801A4DC4;
u16 sub;
if (*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0xFE) == 2) {
goto L801838C0;
}
sub = *(u16 *)((s32)a0 + 0x34);
switch (sub) {
case 1:
goto L8018384C;
case 0:
goto L8018377C;
case 2:
goto L801838B0;
}
return;
L8018377C:
if (*(s16 *)((s32)a0 + 0x102) != 0) {
goto L801837B0;
}
if (func_8014C088(0, 0xA) != 0) {
*(s16 *)((s32)a0 + 0x102) = 1;
*(u16 *)((s32)a0 + 0x100) = *(u16 *)((s32)a0 + 0x100) + 1;
}
goto L801837DC;
L801837B0:
if (func_8014C088(0, 0xA) != 0) {
goto L801837DC;
}
*(s16 *)((s32)a0 + 0x102) = 0;
if (*(s16 *)((s32)a0 + 0xFC) != *(s16 *)((s32)a0 + 0x106)) {
*(s16 *)((s32)a0 + 0x104) = 1;
}
L801837DC:
if (*(s16 *)((s32)a0 + 0xFC) != 0) {
return;
}
if (*(s16 *)((s32)a0 + 0x104) != 0) {
goto L8018382C;
}
func_8002A088(0x64);
func_8002A2D4(0x64);
func_8002A544(0x64);
func_8002A7B4(0x64);
func_8016AA50((s32)a0, -1);
L8018382C:
*(u16 *)((s32)a0 + 0x34) = *(u16 *)((s32)a0 + 0x34) + 1;
((s32 (*)(s32, s32))func_80178B18)((s32)a0, (s32)&D_801A4DFC);
return;
L8018384C:
/* The TU's file-scope decls are `int func_80178970(void)` / `void
* func_80178D18(void)`, but the target fills BOTH call delay slots with
* `addu $a0,$s0,$zero` -- i.e. the original source passed the object
* pointer. Same resolution already banked in the sibling overlay
* (src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c:4104/4107, func_8017D058):
* keep the TU's declaration and cast AT THE USE (law 4 / §181.4). */
if (((s32 (*)(s32))func_80178970)((s32)a0) == 0) {
return;
}
((void (*)(s32))func_80178D18)((s32)a0);
*(u16 *)((s32)a0 + 0x34) = *(u16 *)((s32)a0 + 0x34) + 1;
*(u16 *)(*(s32 *)((s32)a0 + 0x64) + 0x100) = 1;
func_80029124(((u16 *)&D_801A4DC4)[*(s16 *)(*(s32 *)((s32)a0 + 0x64) + 0x70)], 1);
*(s32 *)((s32)a0 + 0x1C) = 0xA0;
return;
L801838B0:
if (func_8012BEE8((s32)a0) == 0) {
return;
}
L801838C0:
((void (*)(s32 *))func_801819F0)((s32 *)a0);
func_8002D4C8(0x6CA, 0);
}
extern void func_8012AD44(s32 *a0, s16 a1);
void func_801819F0(void *a0) {
+222 -5
View File
@@ -1778,8 +1778,6 @@ extern void func_8016A700(void *a0);
extern s32 func_8016A73C(s32 arg0);
extern s32 func_8016A8FC(s32 a0);
extern void func_8016A890(s32 arg0);
extern u16 D_80126B5E;
extern u16 D_80126B66;
extern void func_8016AA50(s32 param_1, s32 param_2);
extern void (*D_8018E5B0[])(void);
extern void func_8016AB30(void *a0);
@@ -3600,7 +3598,125 @@ INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_80184BD8", func_801865A
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_80184BD8", func_80186668);
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_80184BD8", func_80186740);
typedef struct { u8 b[8]; } Blk8_80186740;
typedef struct {
u8 c[8];
} Blk8_80186594_80186740;
typedef struct {
s32 a; /* 0x00 -> D_801DA750 */
s32 b; /* 0x04 -> D_801DA754 */
} Pair8_8017DDC4_80182244_80186740;
/* func_80186740 -- ov_SC02_027, subseg ov_SC02_027_jr_8017D898 (106 ins).
* Mass-lane fresh crack. Nearest exemplar ov_SC02_026:func_8017E72C is still
* unmatched (INCLUDE_ASM), so no cousin body to adapt -- built straight from
* the target .s.
*
* Symbol provenance:
* func_8012E9C0 NOT declared anywhere in this TU (only inside the
* engine_core.h DEFINE_func_8012E9C0 macro, unexpanded
* here) -> declared fresh, `void (int)`, no conflict.
* func_8002A520 NOT declared in this TU; matches the sibling-TU form
* seen in ov_SC03_006/099 etc's jr_8012ACE0.c: `void (void*)`.
* func_8002A790 same as above, `void (void*)`.
* D_80126B5E TU col-0 decl (this file:1789), adopted verbatim `extern u16`
* D_80126B62 TU local-scope decl (this file:4233/6455/6538),
* adopted verbatim `extern u16`
* D_80126B66 TU col-0 decl (this file:1790), adopted verbatim `extern u16`
* VectorNormalSS TU col-0 decl (this file:1846), adopted verbatim `s32 (void*,void*)`
* func_80131E00 TU local-scope decl (this file:6734/6813/6981),
* adopted verbatim `void (void*, s32)`
* func_8012A828 TU col-0/local decl (this file:4380 et al), adopted
* verbatim `void (s32, s32)`
* D_801AE3A8 not declared anywhere in-tree yet; passed as a bare
* lui/addiu address (no load) -> declared as u8[] here.
*
* Residual-class note: field 0x76 is read (u16, for the decrement), stored,
* then read AGAIN (s16, for the <=0 test). A plain second dereference of the
* same `(u8*)a0+0x76` expression lets gcc-2.7.2's cse.c reuse the just-stored
* HImode value and synthesize the sign test via `sll $r,16` instead of a
* genuine `lh` -- confirmed by isolated probes (adds 1 spurious instruction,
* every time another independent load/store shares the block, regardless of
* source statement order or an intervening asm memory-clobber). Fix: (1) an
* `__asm__ __volatile__("" ::: "memory")` between the store and the reload
* to pin ordering, AND (2) drop the named `cnt`/`flags` locals in favor of
* inlining both the 0x5C read-modify-write and the 0x76 compare directly at
* their use sites -- naming the intermediate values reintroduces the same
* cse fold even behind the barrier. Both edits were required together.
*/
extern void func_8012E9C0(int param_1);
extern void func_8002A520(void *a0);
extern void func_8002A790(void *a0);
extern s32 VectorNormalSS(void *a0, void *a1);
extern void func_80131E00(void *a0, s32 a1);
extern void func_8012A828(s32 a0, s32 a1);
void func_80186740(void *a0) {
extern u16 D_80126B5E;
extern u16 D_80126B66;
extern u8 D_801AE3A8[];
extern u16 D_80126B62;
u16 sv[4];
s32 speed;
func_8012E9C0((s32)a0);
if (*(u16 *)((u8 *)a0 + 0x5E) != 0x1D) {
if (*(u8 *)((u8 *)a0 + 0xC8)) {
func_8002A520(a0);
}
if (*(u8 *)((u8 *)a0 + 0xC9)) {
func_8002A790(a0);
}
}
{
s32 base = *(s32 *)((u8 *)a0 + 0x78);
speed = (*(s16 *)((u8 *)a0 + 0x60) * *(s16 *)(base + 0x30)) >> 12;
}
if (speed <= 0) {
speed = 1;
}
*(u16 *)((u8 *)a0 + 0x76) = *(u16 *)((u8 *)a0 + 0x76) - speed;
__asm__ __volatile__("" ::: "memory");
{
*(u16 *)((u8 *)a0 + 0x5C) = *(u16 *)((u8 *)a0 + 0x5C) & 0xFFFE;
if (*(s16 *)((u8 *)a0 + 0x76) <= 0) {
*(u16 *)((u8 *)a0 + 0x5C) = 0;
func_80131E00(a0, 0xE);
} else {
if (speed > 0x10) {
speed = 0x10;
}
sv[0] = *(u16 *)((u8 *)a0 + 6) - D_80126B5E;
sv[1] = *(u16 *)((u8 *)a0 + 0xA) - D_80126B62;
sv[2] = *(u16 *)((u8 *)a0 + 0xE) - D_80126B66;
VectorNormalSS(sv, (u8 *)a0 + 0x102);
speed += 8;
{
s32 p0 = speed * *(s16 *)((u8 *)a0 + 0x102);
s32 p1 = speed * *(s16 *)((u8 *)a0 + 0x104);
s32 p2 = speed * *(s16 *)((u8 *)a0 + 0x106);
*(s32 *)((u8 *)a0 + 0x1C) = 0x10;
*(s16 *)((u8 *)a0 + 0x102) = p0 >> 12;
*(s16 *)((u8 *)a0 + 0x104) = p1 >> 12;
*(s16 *)((u8 *)a0 + 0x106) = p2 >> 12;
}
}
}
*(s16 *)((u8 *)a0 + 6) = *(u16 *)((u8 *)a0 + 0x88);
*(s16 *)((u8 *)a0 + 0xA) = *(u16 *)((u8 *)a0 + 0x8A);
*(s16 *)((u8 *)a0 + 0xE) = *(u16 *)((u8 *)a0 + 0x8C);
func_8012A828((s32)a0, (s32)D_801AE3A8);
}
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_80184BD8", func_801868E8);
@@ -3964,9 +4080,110 @@ s32 func_80187780(s16 *a0, s32 a1, s32 a2, s32 a3) {
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_80184BD8", func_801879E8);
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_80184BD8", func_80187AD4);
INCLUDE_ASM("asm/ov_SC02_028/nonmatchings/ov_SC02_028_jr_80184BD8", func_80187C6C);
extern s32 func_8012C354(s32 a0, s32 a1);
extern void func_8012A828(s32 a0, s32 a1);
extern void func_80143970(void *a0);
extern void func_8012B23C(void *a0);
void func_80187AD4(s32 a0) {
extern u8 D_801AE418[];
extern u8 D_801AF438[];
extern u8 D_801AE44C[];
extern u16 D_801AE3B8[];
extern u16 D_801AE3BA[];
extern u16 D_801AE3BC[];
s32 v1;
s16 idx;
if (func_8012C354(a0, (s32)D_801AE418) != 0) {
*(u8 *)(a0 + 0xC0) = 1;
*(s32 *)(a0 + 0xB4) = -0x201;
*(s32 *)(a0 + 0xBC) = (s32)D_801AE44C;
func_8012A828(a0, (s32)D_801AF438);
*(s16 *)(a0 + 0x2) = 1;
func_80143970((void *)a0);
func_8012B23C((void *)a0);
*(s16 *)(a0 + 0xFE) = (rand() & 0x1F) + 0x20;
*(s16 *)(a0 + 0x100) = (rand() & 0x1F) + 0x20;
v1 = *(s32 *)(a0 + 0x64);
if (*(s16 *)(*(s32 *)(v1 + 0x20) + 0x12) != 0) {
idx = *(s16 *)(a0 + 0x70);
*(s16 *)(a0 + 0x6) = *(u16 *)(a0 + 0x6) -
*(u16 *)((u8 *)D_801AE3B8 + idx * 8);
idx = *(s16 *)(a0 + 0x70);
*(s16 *)(a0 + 0xA) = *(u16 *)(a0 + 0xA) +
*(u16 *)((u8 *)D_801AE3BA + idx * 8);
idx = *(s16 *)(a0 + 0x70);
*(s16 *)(a0 + 0xE) = *(u16 *)(a0 + 0xE) -
*(u16 *)((u8 *)D_801AE3BC + idx * 8);
} else {
idx = *(s16 *)(a0 + 0x70);
*(s16 *)(a0 + 0x6) = *(u16 *)(a0 + 0x6) +
*(u16 *)((u8 *)D_801AE3B8 + idx * 8);
idx = *(s16 *)(a0 + 0x70);
*(s16 *)(a0 + 0xA) = *(u16 *)(a0 + 0xA) +
*(u16 *)((u8 *)D_801AE3BA + idx * 8);
idx = *(s16 *)(a0 + 0x70);
*(s16 *)(a0 + 0xE) = *(u16 *)(a0 + 0xE) +
*(u16 *)((u8 *)D_801AE3BC + idx * 8);
}
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) =
*(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12);
}
}
extern s32 func_80047948(s32 a0);
void func_80187C6C(void *arg0) {
extern u16 D_801AE3B8[];
extern u16 D_801AE3BA[];
extern u16 D_801AE3BC[];
s32 s0 = (s32)arg0;
s32 v1 = *(s32 *)(s0 + 0x64);
s16 a0v;
if (*(s16 *)(*(s32 *)(v1 + 0x20) + 0x12) != 0) {
*(s16 *)(s0 + 0x6) = *(u16 *)(v1 + 0x6) -
*(u16 *)((u8 *)D_801AE3B8 + *(s16 *)(s0 + 0x70) * 8);
*(s16 *)(s0 + 0xA) = *(u16 *)(*(s32 *)(s0 + 0x64) + 0xA) +
*(u16 *)((u8 *)D_801AE3BA + *(s16 *)(s0 + 0x70) * 8);
*(s16 *)(s0 + 0xE) = *(u16 *)(*(s32 *)(s0 + 0x64) + 0xE) -
*(u16 *)((u8 *)D_801AE3BC + *(s16 *)(s0 + 0x70) * 8);
} else {
*(s16 *)(s0 + 0x6) = *(u16 *)(v1 + 0x6) +
*(u16 *)((u8 *)D_801AE3B8 + *(s16 *)(s0 + 0x70) * 8);
*(s16 *)(s0 + 0xA) = *(u16 *)(*(s32 *)(s0 + 0x64) + 0xA) +
*(u16 *)((u8 *)D_801AE3BA + *(s16 *)(s0 + 0x70) * 8);
*(s16 *)(s0 + 0xE) = *(u16 *)(*(s32 *)(s0 + 0x64) + 0xE) +
*(u16 *)((u8 *)D_801AE3BC + *(s16 *)(s0 + 0x70) * 8);
}
a0v = (*(u16 *)(s0 + 0x102) + *(u16 *)(s0 + 0xFE)) & 0xFFF;
*(u16 *)(s0 + 0x102) = a0v;
*(s16 *)(*(s32 *)(s0 + 0x20) + 0x10) = func_80047948(a0v) >> 5;
a0v = (*(u16 *)(s0 + 0x104) + *(u16 *)(s0 + 0x100)) & 0xFFF;
*(u16 *)(s0 + 0x104) = a0v;
*(s16 *)(*(s32 *)(s0 + 0x20) + 0x14) = func_80047948(a0v) >> 5;
}
typedef struct { u8 b[8]; } Blk8_80187DE4;
typedef struct {
+578 -13
View File
@@ -80,7 +80,6 @@ extern s32 *D_80126B78;
extern u8 D_80078EC1;
extern s32 D_80078EC8;
extern s32 D_80126B9C;
extern s32 D_8011F730;
extern u16 D_801152B8;
extern u16 D_8012693A;
extern u8 D_80126BE0[];
@@ -321,7 +320,6 @@ extern s32 func_80012B04(s32 a0, s32 a1, s32 a2);
extern void func_801490F8(s32 a0, s32 a1);
extern s32 func_801491C4(s32 a0);
extern s32 func_80149184(s32 a0);
extern s32 D_801151D4;
extern void func_80149204(s32 *a0);
extern void func_80149210(s32 a0, s32 a1);
extern s32 func_80149284(s32 *a0, s32 a1);
@@ -3187,7 +3185,101 @@ void func_8017CDF4(s32 a0) {
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8017CE3C);
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8017CEF4);
typedef struct { short a, b, c; } SV3_80181D44_8017CEF4; /* == the TU's own `SV3` (engine_types.h:612); renamed only because
typedef struct { s16 vx, vy, vz, pad; } SV_8017D7C0_8017F19C_8017CEF4; /* 8 bytes, align 2 */
/* Callee externs — spellings copied from src/ov_SC04_002/ov_SC04_002_jr_8017BEBC.c
* (law 2). func_8017D098 is DEFINED later in that same TU as `void func_8017D098(void)`
* (a trivial wrapper around func_80151664()); our call site sets $a0 before the jal but
* the real body ignores it, so we declare it unprototyped (K&R style) to accept the
* dead argument without a conflicting-prototype error against the later definition. */
extern void func_80149020(s32 *a0);
extern void func_80147A84(s32 arg0);
extern void func_801473EC(s32 *a0);
extern void func_80148038(s32 a0, s32 a1);
extern void func_80147460(s32 a0);
extern s32 func_801535F4(void *arg0);
extern void func_8017D098();
extern void func_80159B3C(void *a0);
extern void func_8015BF48(s32 *a0);
extern s32 func_80146E98(s32 a0);
extern s32 func_80146A6C(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5, s32 a6);
extern void func_80165718(s32 a0);
/* 16-byte-stride table at D_801887C0, indexed by the actor's 0xF2 animation/state id
* (signed s16); only the table row's first word (offset 0) is read. */
typedef struct {
s32 f0;
u8 pad[12];
} Tbl16_8018BDE4_8017CEF4;
void func_8017CEF4(s32 a0) {
extern Tbl16_8018BDE4_8017CEF4 D_801887C0[];
s32 s0;
s16 s1;
s32 ret;
s0 = *(s32 *)(a0 + 0x20);
func_80149020((s32 *)a0);
s1 = *(s16 *)(s0 + 0x12);
*(s16 *)(s0 + 0x12) = *(u16 *)(a0 + 0x244);
func_80147A84(a0);
func_801473EC((s32 *)a0);
func_80148038(a0, D_801887C0[*(s16 *)(a0 + 0xF2)].f0);
func_80147460(a0);
*(s16 *)(s0 + 0x12) = s1;
if (*(s32 *)(a0 + 0x234) == 0) {
if (*(s32 *)(a0 + 0x34) >= 0) {
if ((*(u16 *)(a0 + 0xB8) & 0x8000) != 0) {
__asm__ __volatile__("" ::: "memory");
*(u16 *)(a0 + 0xB8) = *(u16 *)(a0 + 0xBA);
*(s32 *)(a0 + 0x234) = *(s32 *)(a0 + 0x234) + 1;
}
}
}
ret = func_801535F4((void *)a0);
if (ret == 1) {
goto L_case1;
}
if (ret < 2) {
goto L_default;
}
if (ret == 2) {
goto L_case2;
}
goto L_default;
L_case1:
func_8017D098(a0);
func_80159B3C((void *)a0);
func_80146A6C(2, (void *)a0, 0, 0, 0, 1, 0);
func_80165718(a0);
return;
L_case2:
func_8017D098(a0);
func_8015BF48((s32 *)a0);
func_80146A6C(2, (void *)a0, 0, 0, 0, 1, 0);
func_80165718(a0);
return;
L_default:
if (func_80146E98(a0) == 0) {
return;
}
func_8017D098(a0);
func_80159B3C((void *)a0);
func_80146A6C(2, (void *)a0, 0, 0, 0, 1, 0);
func_80165718(a0);
}
extern void func_80151664(void);
void func_8017D098(void) {
@@ -4821,7 +4913,47 @@ void func_8017F314(int a, s16 *b, SVECTOR_8017E6D8 *c, SVECTOR_8017E6D8 *d,
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8017F690);
typedef struct { s16 m[3][3]; s32 t[3]; } MTX_8017D7C0_8017F19C_8017F690; /* 0x20 bytes, align 4 */
typedef struct { u16 x, y, z, w; } V8_80181368_8017F690;
extern s32 func_8004787C(s32 a0);
extern s32 func_80047948(s32 a0);
extern s32 func_80133784(s32 a0, void *a1, s32 a2);
s32 func_8017F690(s32 a0, s32 a1) {
V8_80181368_8017F690 sp10;
V8_80181368_8017F690 sp18;
s32 t;
s32 r;
sp10.x = *(u16 *)(a0 + 0x6);
sp10.y = *(u16 *)(a0 + 0xA) - 0x20;
sp10.z = *(u16 *)(a0 + 0xE);
t = func_8004787C(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF);
r = (s16)a1;
sp18.y = sp10.y;
sp18.x = sp10.x - ((t * r) >> 12);
t = func_80047948(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF);
sp18.z = sp10.z - ((t * r) >> 12);
if ((func_80133784(1, &sp10, (s32)&sp18) & 0x8000) == 0) {
t = func_8004787C(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF);
sp10.x = *(u16 *)(a0 + 0x6) - ((t * 8) >> 12);
sp10.y = *(u16 *)(a0 + 0xA) - 0x10;
t = func_80047948(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF);
sp10.z = *(u16 *)(a0 + 0xE) - ((t * 8) >> 12);
sp18.x = sp10.x;
sp18.y = sp10.y + 0x20;
sp18.z = sp10.z;
if (func_80133784(1, &sp10, (s32)&sp18) & 0x6000) {
return 0;
}
}
*(s32 *)(a0 + 0x4) = *(s32 *)(a0 + 0x38);
*(s32 *)(a0 + 0xC) = *(s32 *)(a0 + 0x40);
return 1;
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8017F81C);
@@ -4847,10 +4979,13 @@ INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8017FF4
// @class: plumbing
// @stuck: none — MATCH (18 ins): if((b&1) && p!=&sym) call(param,&sym); $a0 live, $a1=&sym fall out
extern void func_8012A828(s32 a0, void *a1);
extern void D_801AB8A8;
void func_8017FFB8(s32 arg0)
{
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
LATER function in this TU, which blocks a byte-true decl of a different type.
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
extern void D_801AB8A8;
if ((M2C_FIELD(arg0, u8 *, 0xC3) & 1) && (M2C_FIELD(arg0, void **, 0x90) != &D_801AB8A8)) {
func_8012A828(arg0, &D_801AB8A8);
}
@@ -4873,9 +5008,12 @@ void func_8018008C(s32 a0) {
#include "common.h"
extern void func_8012A828(s32 a0, void *a1);
extern void D_801AB8A8;
void func_801800CC(s32 a0) {
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
LATER function in this TU, which blocks a byte-true decl of a different type.
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
extern void D_801AB8A8;
*(s16 *)(a0 + 0x2) = 3;
func_8012A828(a0, &D_801AB8A8);
*(u16 *)(a0 + 0x5C) = 0xAA10;
@@ -4940,11 +5078,160 @@ void func_80180228(s32 *a0) {
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8018023C);
typedef struct { s16 f0, f2, f4, f6, f8, fA, fC, fE; s32 f10; } St_80182784_80185DA8_8018023C;
typedef struct { s16 vx, vy, vz, pad; } SV_8017D7C0_8017F19C_8018023C; /* 8 bytes, align 2 */
typedef struct {
s32 f0;
u8 pad[12];
} Tbl16_8018BDE4_8018023C;
typedef struct {
SVECTOR_8016E7C8 v[4]; /* 0x00 */
s32 f0, f1, f2, f3, f4, f5; /* 0x20..0x37 */
u8 f6; /* 0x38 */
u8 pad[7]; /* -> 0x40 */
} Prim_8016E7C8_8018023C;
extern s32 func_8012D5E4(s32 a0, s32 a1, s32 a2, s32 a3);
extern void func_8012EC04(s32 param_1, s32 param_2, s32 *param_3);
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
extern s32 func_8012C51C(void *a0, s32 a1);
extern void func_8012EFB8(s32 a0);
extern void func_8002D4C8(s32 a0, s32 a1);
extern s32 func_8012BEE8(s32 a0);
extern void func_8012A828(s32 a0, void *a1);
void func_8018023C(void *a0) {
extern void D_801AB8A8;
if (*(s32 *)((char *)a0 + 0x1C) == 9) {
extern u8 D_801A3DAC[];
extern u8 D_801A3DBC[];
func_8012D5E4((s32)a0, (s32)D_801A3DAC, (s32)(D_801A3DAC + 8), 0x10);
if (*(s16 *)((char *)a0 + 0x70) & 0x8000) {
u16 out[4];
struct { s16 f0, f2, f4, f6, f8, fA, fC, fE; s32 f10; } s;
s32 buf[8];
func_8012EC04((s32)a0, 0, buf);
((void (*)(s32 *, u8 *, u16 *))func_8012F14C)(buf, D_801A3DBC, out);
s.f6 = 0x23E;
s.f0 = out[0];
s.f2 = out[1];
s.f4 = out[2];
s.fA = 0;
s.fC = 0x7FFF;
s.fE = *(u16 *)(*(s32 *)((char *)a0 + 0x20) + 0x12);
func_8012C51C(&s, (s32)a0);
s.fE = *(u16 *)(*(s32 *)((char *)a0 + 0x20) + 0x12) + 0x100;
func_8012C51C(&s, (s32)a0);
s.fE = *(u16 *)(*(s32 *)((char *)a0 + 0x20) + 0x12) - 0x100;
func_8012C51C(&s, (s32)a0);
}
{
u16 in3[3];
s16 out2[2];
s32 v;
in3[0] = *(u16 *)((char *)a0 + 0x6);
in3[1] = *(u16 *)((char *)a0 + 0xA);
in3[2] = *(u16 *)((char *)a0 + 0xE);
((u32 (*)(u16 *, s16 *))func_8012EFB8)(in3, out2);
v = out2[0];
if (v < 0) {
v = -v;
}
if (v < 0xB5) {
v = out2[1];
if (v < 0) {
v = -v;
}
if (v < 0xA1) {
func_8002D4C8(0x98B, 0);
}
}
}
}
if (func_8012BEE8((s32)a0) != 0) {
*(s16 *)((char *)a0 + 0x2) = 3;
func_8012A828((s32)a0, &D_801AB8A8);
*(u16 *)((char *)a0 + 0x5C) = 0xAA10;
*(s16 *)((char *)a0 + 0x5E) = 0;
*(s16 *)((char *)a0 + 0xDC) = 0;
*(s32 *)((char *)a0 + 0x1C) = 0x2D;
}
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_801803F0);
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_80180438);
/* Fresh mass-lane crack (Phase-31 wave T). No banked twin was found for this
* skeleton (grepped D_801B9548 / D_801A3D6C / D_801A3D8C / D_801A3DC4 / the
* jal callees across src/ -- only extern decls / INCLUDE_ASM stubs turned up,
* all for unrelated overlay-local reuses of the same address). The dispatch
* head (D_801A3DC4[*(u16*)(a0+2)]();) mirrors the ALREADY-BANKED
* func_8017EC70 in THIS SAME TU (D_8018C074[*(u16*)((s32)a0+2)]();) -- same
* idiom, used as a hint per law 1 (never copied its symbols). */
extern s32 func_8012C044(s32 a0);
extern void func_8002A04C(s32 a0);
extern void func_8012C098(void);
extern void func_8012E8A8(u8 *a0);
extern void func_800183E0(s32 a0);
void func_80180438(void *a0) {
extern void (*D_801A3DC4[])(void);
extern u16 D_800B99DA;
extern u16 D_801A3D6C[];
extern u16 D_801B9548[];
extern u8 D_801A3D8C[];
void *s0 = a0;
D_801A3DC4[*(u16 *)((u8 *)s0 + 0x2)]();
if (func_8012C044((s32)s0)) {
*(s16 *)((u8 *)s0 + 0x100) = 1;
__asm__ __volatile__("" ::: "memory");
*(s16 *)((u8 *)s0 + 0x76) = 0;
if (*(s16 *)((u8 *)s0 + 0x100) == 0) {
func_8002A04C((s32)s0);
}
if (*(s16 *)((u8 *)s0 + 0xFE) == 0) {
((void (*)(void *))func_8012C098)(s0);
} else {
*(s16 *)((u8 *)s0 + 0x2) = 6;
func_8012E8A8((u8 *)s0);
*(s16 *)((u8 *)s0 + 0x5C) = 0;
*(u8 *)((u8 *)s0 + 0xC1) = 0;
}
}
if (*(s16 *)((u8 *)s0 + 0xFE) != 0) {
u16 *src = D_801A3D6C;
s32 shift = D_800B99DA & 0xF;
u16 *dst = &D_801B9548[shift];
s32 i;
for (i = 0; i < 0xF - shift; i++) {
*dst++ = *src++;
}
dst = D_801B9548;
for (i = 0; i < shift; i++) {
*dst++ = *src++;
}
func_800183E0((s32)D_801A3D8C);
}
}
extern void (*D_801A3DE8[])(void);
@@ -5054,7 +5341,53 @@ void func_80180A5C(int param_1)
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_80180ACC);
typedef struct { s16 a, b, c; } SV3x_80180ACC; /* 6-byte, align-2 triple of s16 */
typedef struct { s16 a, b, c, d; } SV4x_80180ACC; /* 8-byte, align-2 quad of s16 */
extern void func_8012C218(void *a0);
extern void func_8012F214(s32 a0, s32 a1, s32 a2);
void func_80180ACC(void *a0) {
extern s32 D_801ABE80;
extern s32 D_801A3DE0;
s32 s0 = (s32)a0;
s32 s1;
SV3x_80180ACC out;
s1 = *(s32 *)(s0 + 0x64);
if (*(s16 *)(s0 + 0xFE) == 0x7FFF) {
*(s16 *)(s0 + 0xFE) = *(u16 *)(*(s32 *)(s0 + 0x20) + 0x12);
}
if (*(s16 *)(s0 + 0xFC) != *(s16 *)(s1 + 0x36)) {
func_8012C218((void *)s0);
return;
}
*(SV4x_80180ACC *)(*(s32 *)(s0 + 0x20) + 0x10) = *(SV4x_80180ACC *)(*(s32 *)(s1 + 0x20) + 0x10);
if (*(s32 *)(s1 + 0x90) != (s32)&D_801ABE80) {
*(s16 *)(*(s32 *)(s0 + 0x20) + 0x12) = *(s16 *)(s0 + 0xFE);
*(s32 *)(s0 + 0x4) = *(s32 *)(s1 + 0x4);
*(s32 *)(s0 + 0x8) = *(s32 *)(s1 + 0x8);
*(s32 *)(s0 + 0xC) = *(s32 *)(s1 + 0xC);
} else {
func_8012F214(s1, (s32)&D_801A3DE0, (s32)&out);
*(s16 *)(s0 + 0x6) = out.a;
*(s16 *)(s0 + 0xA) = out.b;
*(s16 *)(s0 + 0xE) = out.c;
}
*(SV4x_80180ACC *)(*(s32 *)(s0 + 0x20) + 0x18) = *(SV4x_80180ACC *)(*(s32 *)(s1 + 0x20) + 0x18);
*(s16 *)(*(s32 *)(s0 + 0x20) + 0x2C) = *(s16 *)(*(s32 *)(s1 + 0x20) + 0x2C);
*(s32 *)(*(s32 *)(s0 + 0x20) + 0x4) = *(s32 *)(*(s32 *)(s1 + 0x20) + 0x4);
}
#include "common.h"
@@ -5734,7 +6067,6 @@ typedef struct { u16 x, y, z, w; } V8_80182044;
extern s32 D_80126B58;
extern s32 D_80126B84;
extern s32 D_8011F730;
extern void func_8012A828(s32 a0, void *a1);
extern void func_8012A8E8(void);
@@ -5744,6 +6076,10 @@ extern s32 func_80182F20(s32 a0);
extern s32 func_80133784(s32 a0, void *a1, s32 a2);
void func_80182044(s32 a0) {
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
LATER function in this TU, which blocks a byte-true decl of a different type.
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
extern s32 D_8011F730;
extern u8 D_801B5D9C[];
extern u8 D_801B61D4[];
@@ -5807,7 +6143,79 @@ void func_8018227C(s32 a0) {
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_801822C0);
extern void func_80182D80(s32 a0);
extern s32 func_80029DB4(void);
extern s32 func_80029E30(void);
extern s32 func_80182BAC(s32 a0, s32 a1, s32 a2, s32 a3);
extern void func_8012A828(s32 a0, void *a1);
extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2);
extern void func_8012CBCC(s32 a0);
void func_801822C0(s32 a0) {
extern s32 D_8011F730;
extern u8 D_801B61D4[];
extern s32 D_801B5E24;
extern s32 D_801B5E8C;
extern s32 D_801B6074;
extern u8 D_801AD1B8[];
extern u8 D_801AD1D8[];
s32 state;
s32 g;
s32 v0;
s32 arg0, arg1;
func_80182D80(a0);
state = *(u16 *)(a0 + 0x34);
switch (state) {
case 0:
g = D_8011F730;
if (g == 2) {
*(u16 *)(a0 + 0x34) = 3;
func_8012A828(a0, D_801B61D4);
return;
} else if (g == 3) {
*(u16 *)(a0 + 0x34) = 1;
func_8012A828(a0, &D_801B5E24);
return;
} else if (g == 4) {
*(u16 *)(a0 + 0x34) = 2;
func_8012A828(a0, &D_801B5E8C);
return;
}
goto tail_short;
case 1:
v0 = func_80029DB4();
func_80182BAC(a0, (s32)D_801AD1B8, 7, v0);
arg0 = 0x1EB;
arg1 = 0;
break;
case 2:
v0 = func_80029E30();
func_80182BAC(a0, (s32)D_801AD1D8, 6, v0);
arg0 = 0x1EB;
arg1 = 1;
break;
case 3:
goto tail_short;
default:
return;
}
func_8012C658(arg0, arg1, a0);
if (*(u16 *)(a0 + 0x72) & 0x4000) {
func_8012A828(a0, &D_801B6074);
}
tail_short:
if (((s32 (*)(s32))func_8012CBCC)(a0) & 0x2000) {
*(u16 *)(a0 + 0x2) = 1;
}
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_80182444);
@@ -6195,7 +6603,88 @@ INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_80182F2
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_80183014);
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8018317C);
extern s32 func_80132EF4(s32 a0, s32 a1);
typedef struct { short a, b, c; } SV3_80181D44_8018317C; /* == the TU's own `SV3` (engine_types.h:612); renamed only because
extern s32 func_80132EF4(s32 a0, s32 a1);
extern s32 rand(void);
/* func_801832F8 is the NEXT stub in this same TU (INCLUDE_ASM at the line below
* func_8018317C's). Its own .s takes TWO args ($a0 = entity-owner, $a1 = id):
* do NOT adopt the 1-arg `void f(void*)` spelling that the *unrelated* overlay
* ov_SC03_001 uses for its own different function at the same address. */
extern void func_801832F8(s32 a0, s32 a1);
/* Spawn a 0x4F entity for `a0`, then jitter its three s16 fields at +0x6/+0xA/+0xE
* by a random amount (mod 28 / 32 / 28, sign picked by a second rand()), flip the
* substruct at *(s32*)(entity+0x20) fields 0x18/0x1A/0x1C to +/-0x2000, and notify. */
s32 func_8018317C(s32 a0) {
s32 s2;
s2 = func_80132EF4(a0, 0x4F);
if (s2 == 0) {
return 0;
}
*(s16 *)(s2 + 0xA) = *(u16 *)(s2 + 0xA) - 0x28;
/* NOTE (this is the whole match, do not "tidy" it): each block MUST own its
* own r/val/base locals. With one shared `r` across all three blocks, the
* /32 block's remainder pseudo conflicts with the rand()-result pseudo, so
* global.c's expand_preferences() cannot merge their preferences (it needs
* a non-conflicting REG_DEAD copy). The result pseudo then has NO hard-reg
* preference of its own, prune_preferences() puts $v1 into its
* regs_someone_prefers set, and find_reg's pass 0 skips $v1 and lands the
* value in $a0 instead of the target's $v1 (4 wrong instructions). */
{
s32 r, val, base;
r = rand() % 28;
base = *(s16 *)(s2 + 0x6);
val = (rand() & 1) ? (base + r) : (base - r);
*(s16 *)(s2 + 0x6) = val;
}
{
s32 r, val, base;
r = rand() % 32;
base = *(s16 *)(s2 + 0xA);
val = (rand() & 1) ? (base + r) : (base - r);
*(s16 *)(s2 + 0xA) = val;
}
{
s32 r, val, base;
r = rand() % 28;
base = *(s16 *)(s2 + 0xE);
val = (rand() & 1) ? (base + r) : (base - r);
*(s16 *)(s2 + 0xE) = val;
}
{
s32 v0, v1;
if (rand() & 1) {
v1 = *(s32 *)(s2 + 0x20);
v0 = -0x2000;
*(s16 *)(v1 + 0x1C) = v0;
} else {
v1 = *(s32 *)(s2 + 0x20);
v0 = 0x2000;
*(s16 *)(v1 + 0x1C) = v0;
}
*(s16 *)(v1 + 0x1A) = v0;
*(s16 *)(v1 + 0x18) = v0;
}
/* Zero-byte scheduling fence (§190-C). Without it BOTH sched1 and sched2
* independently hoist the call's `move $a0,$s3` + `li $a1,0x7F3` above the
* two trailing `sh` stores (they feed the jal, so they carry the higher
* INSN_PRIORITY), and reorg then fills the delay slot with `sh 0x18`
* instead of the target's `addiu $a1`. -fno-schedule-insns{,2} alone does
* not reproduce the target order -- only both together do, hence a real
* barrier rather than a statement reorder. */
__asm__ __volatile__("" ::: "memory");
func_801832F8(a0, 0x7F3);
return s2;
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_801832F8);
@@ -6915,7 +7404,83 @@ void func_80183FE0(s32 a0, s32 a1, s32 a2)
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8018428C);
typedef struct { s16 vx, vy, vz, pad; } SV_8017D7C0_8017F19C_8018428C; /* 8 bytes, align 2 */
/* func_8018428C (ov_SC04_002, ov_SC04_002_jr_8017BEBC, 83 ins)
*
* Sibling family (skeleton group, remapped mechanically once this banks):
* ov_SC02_041:func_8018428C, ov_SC04_005:func_80186C80, ov_SC04_007:func_801832EC
*
* Two conflicting local extern decls exist for this function in the TU
* (func_8018739C uses `void *a1, MATRIX *a3`; func_80187604 uses `s32 a1,
* void *a3`) -- neither is dereferenced structurally inside this function's
* own body (a3 is only ever forwarded as an opaque pointer argument), so the
* definition-side signature below (s32 a1, void *a3) is chosen freely and is
* compatible with both call sites' own local prototypes.
*/
void func_8018428C(s32 a0, s32 a1, s32 a2, void *a3)
{
extern s32 D_801151D4;
extern void func_8012EC04(s32 param_1, s32 param_2, s32 *param_3);
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
extern void func_800D20C0(void *a0, void *a1, s32 a2);
extern void func_80017E68(void *a0, void *a1);
extern void func_800D23D0(void *a0);
extern void ApplyMatrixSV(void *a0, void *a1, void *a2);
extern void RotMatrixYXZ(void *a0, void *a1);
extern void ApplyTransposeMatrixLV(void *a0, void *a1, void *a2);
extern s32 ratan2(s32 a0, s32 a1);
s32 mtx1[8]; /* sp+0x10, 0x20 bytes: scratch MATRIX */
s16 buf2[4]; /* sp+0x30, 8 bytes: vx,vy,vz,pad */
s16 vec[4]; /* sp+0x38, 8 bytes: vx,vy,vz,pad */
s32 diff[3]; /* sp+0x40 */
s32 base;
s32 v0;
s32 v1;
base = D_801151D4;
func_8012EC04(a0, a2, (s32 *)mtx1);
func_8012F14C((s32)mtx1, a1 + 0x18, (s32)buf2);
func_800D20C0((void *)buf2, (void *)vec, 8);
func_80017E68((void *)buf2, a3);
v0 = *(u16 *)(a1 + 0x8);
v1 = *(u16 *)(a1 + 0x10);
v0 = v0 - v1;
vec[0] = v0;
v0 = *(u16 *)(a1 + 0xA);
v1 = *(u16 *)(a1 + 0x12);
v0 = v0 - v1;
vec[1] = v0;
v0 = *(u16 *)(a1 + 0xC);
v1 = *(u16 *)(a1 + 0x14);
v0 = v0 - v1;
vec[2] = v0;
ApplyMatrixSV((void *)mtx1, (void *)vec, (void *)vec);
func_800D23D0((void *)vec);
RotMatrixYXZ((void *)vec, a3);
diff[0] = *(s32 *)(base + 0x5C) - buf2[0];
diff[1] = *(s32 *)(base + 0x60) - buf2[1];
diff[2] = *(s32 *)(base + 0x64) - buf2[2];
ApplyTransposeMatrixLV(a3, (void *)diff, (void *)diff);
v0 = ratan2(diff[0], diff[1]);
vec[2] = -v0;
RotMatrixYXZ((void *)vec, a3);
}
#include "common.h"
+242 -4
View File
@@ -43,7 +43,6 @@ extern void func_80162120(void);
extern void func_80029124(s32, s32);
extern s32 func_80165A50(s32);
extern void func_80029514(s32);
extern u8 D_800AF630[];
extern u8 D_80078EC0;
extern s32 D_80126B58;
extern s32 func_80028FBC(void);
@@ -2823,7 +2822,115 @@ void func_80185144(void *a0) {
INCLUDE_ASM("asm/ov_SC03_015/nonmatchings/ov_SC03_015_jr_801848E4", func_80185180);
INCLUDE_ASM("asm/ov_SC03_015/nonmatchings/ov_SC03_015_jr_801848E4", func_80185380);
typedef struct {
s16 m[3][3];
s16 pad;
s32 t[3];
} MtxLocal_80185380;
typedef struct {
SVECTOR_8016E7C8 v[4]; /* 0x00 */
s32 f0, f1, f2, f3, f4, f5; /* 0x20..0x37 */
u8 f6; /* 0x38 */
u8 pad[7]; /* -> 0x40 */
} Prim_8016E7C8_80185380;
extern void func_8012C218(void *a0);
extern s32 func_8012B8A4(s16 *a0);
extern s32 func_8004787C(s32 a0);
extern s32 func_80047948(s32 a0);
extern s32 func_80178B18(s32 param_1, s32 param_2);
extern s32 func_801789AC(s32 arg0);
extern void func_80178D18(void);
extern void func_80029514(s32);
extern void func_8012A568(void (*a0)(void));
extern void func_80183980(void);
void func_80185380(s32 param_1) {
extern u16 D_80126B5E;
extern u16 D_80126B62;
extern u16 D_80126B66;
extern u16 D_80190048;
extern u16 D_8019004A;
extern u16 D_8019004C;
extern u16 D_8019005A;
extern u16 D_8019005C;
extern s32 D_80190344;
u16 state;
s32 obj;
state = *(u16 *)(param_1 + 0x34);
switch (state) {
case 0:
obj = *(s32 *)(param_1 + 0x6C);
if (*(s16 *)(obj + 0x76) > 0) {
return;
}
*(u16 *)(param_1 + 0x34) = state + 1;
func_8012C218((void *)*(s32 *)(param_1 + 0xCC));
func_8012C218((void *)*(s32 *)(param_1 + 0xD0));
{
register s32 o __asm__("$2");
u16 v6;
register u16 *p10 __asm__("$3");
o = *(s32 *)(param_1 + 0x6C);
v6 = *(u16 *)(o + 0x6);
__asm__ __volatile__("" : "=r"(v6) : "0"(v6) : "memory");
p10 = &D_80190048;
__asm__ __volatile__("" : "=r"(p10) : "0"(p10) : "memory");
*p10 = v6;
o = *(s32 *)(param_1 + 0x6C);
D_8019004A = *(u16 *)(o + 0xA) - 0x40;
o = *(s32 *)(param_1 + 0x6C);
{
u16 g5e = D_80126B5E;
D_8019004C = *(u16 *)(o + 0xE);
*(u16 *)((u8 *)p10 + 0x10) = g5e;
}
}
D_8019005A = D_80126B62 - 0x40;
D_8019005C = D_80126B66;
{
s32 v;
s32 a1val;
s32 sinv;
s32 angleDelta;
s32 tmp;
s32 *p;
v = func_8012B8A4((s16 *)param_1);
a1val = func_8004787C(v);
p = &D_80190344;
angleDelta = (*(s16 *)(param_1 + 0x6) - (((a1val * 3) << 5) >> 12)) & 0xFFFF;
*p = angleDelta;
sinv = func_80047948(v);
tmp = (*(s32 *)(param_1 + 0xC) - ((sinv * 3) << 9)) & 0xFFFF0000;
*p = *p | tmp;
func_80178B18(param_1, (s32)((u8 *)p - 0x4C));
}
break;
case 1:
if (func_801789AC(param_1) != 0) {
((void (*)(void *))func_80178D18)((void *)param_1);
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
*(u16 *)(*(s32 *)(param_1 + 0xD8) + 0x34) = 1;
func_80029514(0x2DA);
func_8012A568(func_80183980);
}
break;
}
}
DEFINE_func_8018553C() /* dedup: shared engine-core @0x8018553C (src/shared) */
@@ -3230,13 +3337,144 @@ void func_80185EF8(s32 a0) {
}
INCLUDE_ASM("asm/ov_SC03_015/nonmatchings/ov_SC03_015_jr_801848E4", func_801863B8);
typedef struct { s32 a; s32 b[4]; } Ot_8018B23C_801863B8;
/* Declarations adopted verbatim from src/ov_SC03_014/ov_SC03_014_jr_801848E4.c
* (law 2). D_801E2CE8 and D_80190538 are first uses in this TU, declared in
* the raw form matching how their addresses are consumed here (never
* dereferenced in this function; passed on as a pointer arg only). */
extern s32 func_8012CBCC(s32 a0);
extern s32 func_8012BA10(s32 a0, s32 a1);
extern void func_8012A828(s32 a0, void *a1);
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2);
extern void func_8002D4C8(s32 a0, s32 a1);
void func_801863B8(s32 a0) {
extern u8 D_801E2CE8[];
extern u8 D_80190538[];
s32 obj;
s32 s1;
s32 msg;
u16 sp[3];
func_8012CBCC(a0);
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += func_8012BA10(a0, 4);
switch (*(u16 *)(a0 + 0x34)) {
case 0:
if (!(*(u16 *)(a0 + 0x72) & 0x4000)) {
break;
}
*(u16 *)(a0 + 0x34) = 1;
func_8012A828(a0, D_801E2CE8);
msg = 0xA7E;
goto tail;
case 1:
if (*(s32 *)(a0 + 0x94) != 0xF) {
break;
}
*(u16 *)(a0 + 0x34) = 2;
func_8012F14C(*(s32 *)(a0 + 0x20) + 0x34, (s32)D_80190538, (s32)sp);
for (s1 = -0x200; s1 < 0x300; s1 += 0x200) {
obj = func_8012C658(0x265, 1, a0);
if (obj != 0) {
*(u16 *)(obj + 0xFE) =
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + s1;
*(u16 *)(*(s32 *)(obj + 0x20) + 0x14) =
*(u16 *)(obj + 0xFC) + 0x200;
*(u16 *)(obj + 0x6) = sp[0];
*(u16 *)(obj + 0xA) = sp[1];
*(u16 *)(obj + 0xE) = sp[2];
}
}
msg = 0xA35;
tail:
func_8002D4C8(msg, 0);
break;
case 2:
if (!(*(u16 *)(a0 + 0x72) & 0x4000)) {
break;
}
*(u16 *)(a0 + 0x2) = 1;
func_8012A828(a0, D_801E2170);
break;
}
}
DEFINE_func_8018655C() /* dedup: shared engine-core @0x8018655C (src/shared) */
DEFINE_func_801867F8() /* dedup: shared engine-core @0x801867F8 (src/shared) */
INCLUDE_ASM("asm/ov_SC03_015/nonmatchings/ov_SC03_015_jr_801848E4", func_80186A74);
/* Declarations matched verbatim to src/ov_SC03_014/ov_SC03_014_jr_801848E4.c
* where that TU already declares the symbol (law 2/1b). Fresh raw-form decls
* (u8[]) for the two data symbols the TU does not yet mention. */
extern s32 func_8012CBCC(s32 a0);
extern s32 func_8012BA10(s32 a0, s32 a1);
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2);
extern void func_8012A828(s32 a0, void *a1);
extern s32 func_8004787C(s32 a0);
extern s32 func_80047948(s32 a0);
extern void func_8002D4C8(s32 a0, s32 a1);
void func_80186A74(s32 a0) {
extern u8 D_801E2B50[];
extern u8 D_80190540[];
s16 sp10[3];
s32 s0;
func_8012CBCC(a0);
switch (*(u16 *)(a0 + 0x34)) {
case 0:
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += func_8012BA10(a0, 4);
if (*(u16 *)(a0 + 0x72) & 0x4000) {
*(u16 *)(a0 + 0x34) = 1;
func_8012A828(a0, D_801E2B50);
func_8002D4C8(0xA81, 0);
}
break;
case 1:
if (*(s32 *)(a0 + 0x94) == 0xF) {
*(u16 *)(a0 + 0x34) = 2;
func_8012F14C(*(s32 *)(a0 + 0x20) + 0x34, (s32)D_80190540, (s32)sp10);
s0 = func_8012C658(0x265, 3, a0);
if (s0 != 0) {
*(u16 *)(*(s32 *)(s0 + 0x20) + 0x14) =
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12);
*(s32 *)(s0 + 0x10) =
-(func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) << 8);
*(s32 *)(s0 + 0x18) =
-(func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) << 8);
*(u16 *)(s0 + 0x6) = sp10[0];
*(u16 *)(s0 + 0xA) = sp10[1];
*(u16 *)(s0 + 0xE) = sp10[2];
}
func_8002D4C8(0xA36, 0);
}
break;
case 2:
if (*(u16 *)(a0 + 0x72) & 0x4000) {
*(u16 *)(a0 + 0xFC) = 0x1E;
*(u16 *)(a0 + 0x2) = 9;
func_8012A828(a0, D_801E2170);
*(u16 *)(a0 + 0xAE) = 0x2900;
}
break;
}
func_8012C658(0x3DE, 0, a0);
}
/* func_80186C4C — ov_SC03_014 / ov_SC03_014_jr_801848E4. MATCH 273/273.
+48 -1
View File
@@ -4927,7 +4927,54 @@ void func_80181D74(void *a0) {
INCLUDE_ASM("asm/ov_SC03_024/nonmatchings/ov_SC03_024_jr_8017DF84", func_80181DB0);
INCLUDE_ASM("asm/ov_SC03_024/nonmatchings/ov_SC03_024_jr_8017DF84", func_80181F7C);
extern void func_8013CABC(void);
extern void func_8018282C(s32*);
extern s32 func_8012BEE8(s32 a0);
extern void func_801821D4(s32 a0);
extern void func_80182108(s32 a0);
extern void func_80181070(void);
extern int func_80178970(void);
void func_80181F7C(s32 a0) {
extern s32 D_801C1358;
s32 self;
self = a0;
if (*(s32 *)(self + 0x1C) == 0x30) {
func_8013CABC();
} else if (*(s32 *)(self + 0x1C) == 0x10) {
((void (*)(void *))func_8018282C)((void *)*(s32 *)(self + 0xD0));
}
if (*(u16 *)(self + 0x84) & 1) {
*(u16 *)(*(s32 *)(self + 0x64) + 6) = *(u16 *)(*(s32 *)(self + 0x64) + 6) - 3;
*(u16 *)(*(s32 *)(*(s32 *)(self + 0x64) + 0x20) + 8) =
*(u16 *)(*(s32 *)(*(s32 *)(self + 0x64) + 0x20) + 8) - 3;
*(u16 *)(self + 6) = *(u16 *)(self + 6) - 3;
} else {
*(u16 *)(*(s32 *)(self + 0x64) + 6) = *(u16 *)(*(s32 *)(self + 0x64) + 6) + 3;
*(u16 *)(*(s32 *)(*(s32 *)(self + 0x64) + 0x20) + 8) =
*(u16 *)(*(s32 *)(*(s32 *)(self + 0x64) + 0x20) + 8) + 3;
*(u16 *)(self + 6) = *(u16 *)(self + 6) + 3;
}
{
s32 t;
t = D_801C1358;
*(u16 *)(self + 0x84) = *(u16 *)(self + 0x84) + 1;
if (t == 0) {
D_801C1358 = ((s32 (*)(void))func_80181070)();
}
}
if (func_8012BEE8(self) && D_801C1358) {
func_801821D4(self);
} else {
if (*(s32 *)(self + 0x1C) < 0x48) {
if ((*(u16 *)(self + 0x84) & 3) == 0) {
func_80182108(self);
}
}
}
((void (*)(s32))func_80178970)(self);
}
INCLUDE_ASM("asm/ov_SC03_024/nonmatchings/ov_SC03_024_jr_8017DF84", func_80182108);
+82 -1
View File
@@ -5162,7 +5162,88 @@ INCLUDE_ASM("asm/ov_SC03_092/nonmatchings/ov_SC03_092_jr_8017AE2C", func_80180B2
void func_80180BF4(void) {
}
INCLUDE_ASM("asm/ov_SC03_092/nonmatchings/ov_SC03_092_jr_8017AE2C", func_80180BFC);
typedef struct { u8 b[8]; } Blk8_80180BFC;
typedef struct {
s32 a; /* 0x00 -> D_801DA750 */
s32 b; /* 0x04 -> D_801DA754 */
} Pair8_8017DDC4_80182244_80180BFC;
/* Sibling shape in the SAME TU: func_80182244 (already banked, line ~3980)
* uses the identical idiom for the same actor kind: void *a0, raw
* (s32)a0+offset field access, func_8012C1B8 cast-called as (s32(*)(void)),
* func_8012CAE4, func_8001C214, and the 0x70-indexed table lookup + 0x1000000
* OR-flag pattern at (*(s32*)(sub+4)) |= 0x1000000. Adopted as a structural
* hint only (law 1) — none of its per-location symbols are reused here. */
extern void func_8012C1B8(void);
extern void func_8012CAE4(void *a0);
extern s32 func_80029178(s32 a0);
extern void func_8001C214(s32 a0, s32 a1);
extern s32 func_8012AD50(void *a0);
/* idx = *(s16*)(a0+0x70): lhu direct load, 2-byte stride -> u16 table */
/* address-of only in the target (lui/addiu, no load/store through it here) */
void func_80180BFC(s32 a0)
{
extern u16 D_801AC610[];
extern u8 D_801AC600;
extern u8 D_801AC5F0;
if ((*(s32 *)(a0 + 0x20) = ((s32 (*)(void))func_8012C1B8)()) == 0) {
func_8012CAE4((void *)a0);
return;
}
if ((func_80029178((s32)D_801AC610[*(s16 *)(a0 + 0x70)]) & 0xFF) != 0) {
register s32 s0 __asm__("$16") = *(s32 *)(a0 + 0xDC);
if (s0 != 0) {
s32 a1 = *(s32 *)(s0 + 0x4);
if (a1 != 0) {
func_8001C214(*(s32 *)(a0 + 0x20), a1);
if (*(s32 *)(s0 + 0xC) != 0) {
s32 v1 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4);
v1 |= 0x1000000;
*(s32 *)(*(s32 *)(a0 + 0x20) + 0x4) = v1;
}
}
}
func_8012AD50((void *)a0);
goto tail;
}
{
register s32 s0 __asm__("$16") = *(s32 *)(a0 + 0xDC);
register s32 flag __asm__("$2") = 1;
if (s0 != 0) {
s32 a1 = *(s32 *)s0;
if (a1 != 0) {
func_8001C214(*(s32 *)(a0 + 0x20), a1);
if (*(s32 *)(s0 + 0xC) != 0) {
s32 v1 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4);
v1 |= 0x1000000;
*(s32 *)(*(s32 *)(a0 + 0x20) + 0x4) = v1;
}
flag = 1;
}
}
*(u8 *)(a0 + 0xC0) = flag;
}
*(s32 *)(a0 + 0xBC) = (s32)&D_801AC600;
*(s32 *)(a0 + 0x58) = (s32)&D_801AC5F0 | 0x40000000;
*(u16 *)(a0 + 0x5C) = 0x8800;
*(s32 *)(a0 + 0xB4) = 0;
*(u8 *)(a0 + 0xC1) = 0;
*(u16 *)(a0 + 0xAE) = 0x7FFF;
*(u8 *)(a0 + 0x75) = 0;
*(s32 *)(a0 + 0xC4) |= 0x2;
tail:
func_8012AD50((void *)a0);
}
// @class: struct
+139 -2
View File
@@ -3829,7 +3829,78 @@ L_end:
}
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017F140);
/* Sibling pattern for the func_8012C354(a0, &D_xxx) gate + s0+0xC0/s0+0x2 flag
* writes is func_8017F3F4 in this same TU (ov_SC03_112_jr_8017C294.c, ~L3892):
* it declares the target-only data symbol as `extern M2C_UNK D_xxx;` and passes
* `(s32)&D_xxx` as the gate's second arg. Followed here for D_8019E640.
*
* func_8012C354(s32,s32)->s32 : TU decl at L3911 (verbatim, adopted).
* func_8001CD9C(int,void*) : TU decl at L1818 (verbatim, adopted); defined
* void at src/800.c:5936 as (s32,s32) -- the TU's
* own extern spelling wins per law 2/8.
* func_8012C194(void)->s32, func_80143994(s32,s32)->s32, func_8012E8A8(u8*)->void
* : not declared in this TU; typed by the majority project-wide spelling.
*/
extern s32 func_8012C354(s32 a0, s32 a1);
extern void func_8001CD9C(int, void *);
extern s32 func_8012C194(void);
extern s32 func_80143994(s32 a0, s32 a1);
extern void func_8012E8A8(u8 *a0);
void func_8017F140(s32 a0) {
extern M2C_UNK D_8019E640;
extern M2C_UNK D_8019E674;
extern M2C_UNK D_8019E6BC;
extern M2C_UNK D_8019E70C;
s32 s0;
s32 v1;
u16 v0;
if (func_8012C354(a0, (s32)&D_8019E640)) {
v1 = *(s32 *)(a0 + 0x20);
*(u16 *)(v1 + 0x2C) |= 0x30;
v1 = *(s32 *)(a0 + 0x20);
*(void **)(v1 + 0x80) = &D_8019E674;
*(s32 *)(a0 + 0xE8) = 0x40;
s0 = func_8012C194();
if (s0 != 0) {
*(s32 *)(a0 + 0xD0) = s0;
func_8001CD9C((int)s0, (void *)&D_8019E6BC);
*(s16 *)(s0 + 0x18) = 0x555;
*(s16 *)(s0 + 0x1A) = 0x555;
*(s32 *)(s0 + 0x4) |= 0x50000000;
}
v0 = *(u16 *)(a0 + 0x70);
if (v0 & 0x2) {
*(u16 *)(a0 + 0x2) = 0x8;
*(u8 *)(a0 + 0xC0) = 1;
*(void **)(a0 + 0xBC) = &D_8019E70C;
*(s32 *)(a0 + 0xB4) = -0x249D;
*(s32 *)(a0 + 0xC4) |= 0x2;
func_8012E8A8((u8 *)a0);
return;
}
if (v0 & 0x1) {
*(u16 *)(a0 + 0x2) = 6;
*(u16 *)(a0 + 0x5C) &= 0x5FFF;
} else {
*(u8 *)(a0 + 0xC0) = 1;
*(void **)(a0 + 0xBC) = &D_8019E70C;
*(s32 *)(a0 + 0xB4) = -0x249D;
*(u16 *)(a0 + 0x2) = 1;
*(s32 *)(a0 + 0xC4) |= 0x2;
}
*(s32 *)(a0 + 0xCC) = func_80143994(a0, 0x1000);
}
}
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017F29C);
@@ -4006,6 +4077,72 @@ TAIL_5DC:
}
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017F640);
typedef struct {
SVECTOR_8016E7C8 v[4]; /* 0x00 */
s32 f0, f1, f2, f3, f4, f5; /* 0x20..0x37 */
u8 f6; /* 0x38 */
u8 pad[7]; /* -> 0x40 */
} Prim_8016E7C8_8017F640;
extern s32 func_8012BCCC(s32 a0);
extern s32 func_8004787C(s32 a0);
extern s32 func_8012B8E4(s32 a0, s32 a1);
void func_8017F640(s32 param_1)
{
extern void func_801808B4(s32 a0);
extern s32 func_8012BDBC(s32 a0, s32 a1);
extern void func_8012B178(s32 a0, s32 a1);
extern s32 func_8012CBA4(s32 a0);
extern void func_8012ADE4(u8 *a0);
s32 dist;
s32 angle;
s32 iVar1;
s32 a1;
if (*(s16 *)(param_1 + 0xa) >= 0x10) {
func_801808B4(param_1);
goto end;
}
dist = func_8012BCCC(param_1);
if (func_8012BDBC(param_1, 0x400) == 0) {
*(s16 *)(param_1 + 2) = 1;
goto end;
}
if (dist > 0x24000) {
*(s16 *)(param_1 + 2) = 1;
goto end;
}
if (dist < 0x4001) {
*(s16 *)(param_1 + 2) = 4;
goto end;
}
angle = func_8004787C((*(s32 *)(param_1 + 0xe4) << 7) & 0x780);
*(s16 *)(*(s32 *)(param_1 + 0x20) + 0x1a) = (angle >> 1) + 0x800;
iVar1 = func_8012B8E4(param_1, 0xa);
{
s32 ptr = *(s32 *)(param_1 + 0x20);
s32 v = *(u16 *)(ptr + 0x12) + iVar1;
*(u16 *)(ptr + 0x12) = v;
if (0x1000 - angle >= 0) {
a1 = 0xFFFF0000 - ((0x1000 - angle) << 7);
} else {
a1 = 0xFFFF0000 - ((angle - 0x1000) << 7);
}
}
func_8012B178(param_1, a1);
iVar1 = func_8012CBA4(param_1);
if ((iVar1 & 0x6000) == 0) {
func_8012ADE4((u8 *)param_1);
}
*(s32 *)(param_1 + 0xe4) += 1;
end:
return;
}
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017F788);
+139 -2
View File
@@ -3421,7 +3421,78 @@ L_end:
}
INCLUDE_ASM("asm/ov_SC03_110/nonmatchings/ov_SC03_110_jr_8017D898", func_8017F4CC);
/* Sibling pattern for the func_8012C354(a0, &D_xxx) gate + s0+0xC0/s0+0x2 flag
* writes is func_8017F3F4 in this same TU (ov_SC03_112_jr_8017C294.c, ~L3892):
* it declares the target-only data symbol as `extern M2C_UNK D_xxx;` and passes
* `(s32)&D_xxx` as the gate's second arg. Followed here for D_8019BF40.
*
* func_8012C354(s32,s32)->s32 : TU decl at L3911 (verbatim, adopted).
* func_8001CD9C(int,void*) : TU decl at L1818 (verbatim, adopted); defined
* void at src/800.c:5936 as (s32,s32) -- the TU's
* own extern spelling wins per law 2/8.
* func_8012C194(void)->s32, func_80143994(s32,s32)->s32, func_8012E8A8(u8*)->void
* : not declared in this TU; typed by the majority project-wide spelling.
*/
extern s32 func_8012C354(s32 a0, s32 a1);
extern void func_8001CD9C(int, void *);
extern s32 func_8012C194(void);
extern s32 func_80143994(s32 a0, s32 a1);
extern void func_8012E8A8(u8 *a0);
void func_8017F4CC(s32 a0) {
extern M2C_UNK D_8019BF40;
extern M2C_UNK D_8019BF74;
extern M2C_UNK D_8019BFBC;
extern M2C_UNK D_8019C00C;
s32 s0;
s32 v1;
u16 v0;
if (func_8012C354(a0, (s32)&D_8019BF40)) {
v1 = *(s32 *)(a0 + 0x20);
*(u16 *)(v1 + 0x2C) |= 0x30;
v1 = *(s32 *)(a0 + 0x20);
*(void **)(v1 + 0x80) = &D_8019BF74;
*(s32 *)(a0 + 0xE8) = 0x40;
s0 = func_8012C194();
if (s0 != 0) {
*(s32 *)(a0 + 0xD0) = s0;
func_8001CD9C((int)s0, (void *)&D_8019BFBC);
*(s16 *)(s0 + 0x18) = 0x555;
*(s16 *)(s0 + 0x1A) = 0x555;
*(s32 *)(s0 + 0x4) |= 0x50000000;
}
v0 = *(u16 *)(a0 + 0x70);
if (v0 & 0x2) {
*(u16 *)(a0 + 0x2) = 0x8;
*(u8 *)(a0 + 0xC0) = 1;
*(void **)(a0 + 0xBC) = &D_8019C00C;
*(s32 *)(a0 + 0xB4) = -0x249D;
*(s32 *)(a0 + 0xC4) |= 0x2;
func_8012E8A8((u8 *)a0);
return;
}
if (v0 & 0x1) {
*(u16 *)(a0 + 0x2) = 6;
*(u16 *)(a0 + 0x5C) &= 0x5FFF;
} else {
*(u8 *)(a0 + 0xC0) = 1;
*(void **)(a0 + 0xBC) = &D_8019C00C;
*(s32 *)(a0 + 0xB4) = -0x249D;
*(u16 *)(a0 + 0x2) = 1;
*(s32 *)(a0 + 0xC4) |= 0x2;
}
*(s32 *)(a0 + 0xCC) = func_80143994(a0, 0x1000);
}
}
INCLUDE_ASM("asm/ov_SC03_110/nonmatchings/ov_SC03_110_jr_8017D898", func_8017F628);
@@ -3600,6 +3671,72 @@ TAIL_5DC:
}
INCLUDE_ASM("asm/ov_SC03_110/nonmatchings/ov_SC03_110_jr_8017D898", func_8017F9CC);
typedef struct {
SVECTOR_8016E7C8 v[4]; /* 0x00 */
s32 f0, f1, f2, f3, f4, f5; /* 0x20..0x37 */
u8 f6; /* 0x38 */
u8 pad[7]; /* -> 0x40 */
} Prim_8016E7C8_8017F9CC;
extern s32 func_8012BCCC(s32 a0);
extern s32 func_8004787C(s32 a0);
extern s32 func_8012B8E4(s32 a0, s32 a1);
void func_8017F9CC(s32 param_1)
{
extern void func_80180C40(s32 a0);
extern s32 func_8012BDBC(s32 a0, s32 a1);
extern void func_8012B178(s32 a0, s32 a1);
extern s32 func_8012CBA4(s32 a0);
extern void func_8012ADE4(u8 *a0);
s32 dist;
s32 angle;
s32 iVar1;
s32 a1;
if (*(s16 *)(param_1 + 0xa) >= 0x10) {
func_80180C40(param_1);
goto end;
}
dist = func_8012BCCC(param_1);
if (func_8012BDBC(param_1, 0x400) == 0) {
*(s16 *)(param_1 + 2) = 1;
goto end;
}
if (dist > 0x24000) {
*(s16 *)(param_1 + 2) = 1;
goto end;
}
if (dist < 0x4001) {
*(s16 *)(param_1 + 2) = 4;
goto end;
}
angle = func_8004787C((*(s32 *)(param_1 + 0xe4) << 7) & 0x780);
*(s16 *)(*(s32 *)(param_1 + 0x20) + 0x1a) = (angle >> 1) + 0x800;
iVar1 = func_8012B8E4(param_1, 0xa);
{
s32 ptr = *(s32 *)(param_1 + 0x20);
s32 v = *(u16 *)(ptr + 0x12) + iVar1;
*(u16 *)(ptr + 0x12) = v;
if (0x1000 - angle >= 0) {
a1 = 0xFFFF0000 - ((0x1000 - angle) << 7);
} else {
a1 = 0xFFFF0000 - ((angle - 0x1000) << 7);
}
}
func_8012B178(param_1, a1);
iVar1 = func_8012CBA4(param_1);
if ((iVar1 & 0x6000) == 0) {
func_8012ADE4((u8 *)param_1);
}
*(s32 *)(param_1 + 0xe4) += 1;
end:
return;
}
INCLUDE_ASM("asm/ov_SC03_110/nonmatchings/ov_SC03_110_jr_8017D898", func_8017FB14);
+202 -4
View File
@@ -6326,10 +6326,13 @@ INCLUDE_ASM("asm/ov_SC04_004/nonmatchings/ov_SC04_004_jr_8017AE2C", func_801832A
// @class: plumbing
// @stuck: none — MATCH (18 ins): if((b&1) && p!=&sym) call(param,&sym); $a0 live, $a1=&sym fall out
extern void func_8012A828(s32 a0, void *a1);
extern void D_801B0750;
void func_80183318(s32 arg0)
{
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
LATER function in this TU, which blocks a byte-true decl of a different type.
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
extern void D_801B0750;
if ((M2C_FIELD(arg0, u8 *, 0xC3) & 1) && (M2C_FIELD(arg0, void **, 0x90) != &D_801B0750)) {
func_8012A828(arg0, &D_801B0750);
}
@@ -6406,11 +6409,160 @@ void func_80183588(void *a0) {
}
INCLUDE_ASM("asm/ov_SC04_004/nonmatchings/ov_SC04_004_jr_8017AE2C", func_8018359C);
typedef struct { s16 f0, f2, f4, f6, f8, fA, fC, fE; s32 f10; } St_80182784_80185DA8_8018359C;
typedef struct { s16 vx, vy, vz, pad; } SV_8017D7C0_8017F19C_8018359C; /* 8 bytes, align 2 */
typedef struct {
s32 f0;
u8 pad[12];
} Tbl16_8018BDE4_8018359C;
typedef struct {
SVECTOR_8016E7C8 v[4]; /* 0x00 */
s32 f0, f1, f2, f3, f4, f5; /* 0x20..0x37 */
u8 f6; /* 0x38 */
u8 pad[7]; /* -> 0x40 */
} Prim_8016E7C8_8018359C;
extern s32 func_8012D5E4(s32 a0, s32 a1, s32 a2, s32 a3);
extern void func_8012EC04(s32 param_1, s32 param_2, s32 *param_3);
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
extern s32 func_8012C51C(void *a0, s32 a1);
extern void func_8012EFB8(s32 a0);
extern void func_8002D4C8(s32 a0, s32 a1);
extern s32 func_8012BEE8(s32 a0);
extern void func_8012A828(s32 a0, void *a1);
void func_8018359C(void *a0) {
extern void D_801B0750;
if (*(s32 *)((char *)a0 + 0x1C) == 9) {
extern u8 D_801A8C54[];
extern u8 D_801A8C64[];
func_8012D5E4((s32)a0, (s32)D_801A8C54, (s32)(D_801A8C54 + 8), 0x10);
if (*(s16 *)((char *)a0 + 0x70) & 0x8000) {
u16 out[4];
struct { s16 f0, f2, f4, f6, f8, fA, fC, fE; s32 f10; } s;
s32 buf[8];
func_8012EC04((s32)a0, 0, buf);
((void (*)(s32 *, u8 *, u16 *))func_8012F14C)(buf, D_801A8C64, out);
s.f6 = 0x23E;
s.f0 = out[0];
s.f2 = out[1];
s.f4 = out[2];
s.fA = 0;
s.fC = 0x7FFF;
s.fE = *(u16 *)(*(s32 *)((char *)a0 + 0x20) + 0x12);
func_8012C51C(&s, (s32)a0);
s.fE = *(u16 *)(*(s32 *)((char *)a0 + 0x20) + 0x12) + 0x100;
func_8012C51C(&s, (s32)a0);
s.fE = *(u16 *)(*(s32 *)((char *)a0 + 0x20) + 0x12) - 0x100;
func_8012C51C(&s, (s32)a0);
}
{
u16 in3[3];
s16 out2[2];
s32 v;
in3[0] = *(u16 *)((char *)a0 + 0x6);
in3[1] = *(u16 *)((char *)a0 + 0xA);
in3[2] = *(u16 *)((char *)a0 + 0xE);
((u32 (*)(u16 *, s16 *))func_8012EFB8)(in3, out2);
v = out2[0];
if (v < 0) {
v = -v;
}
if (v < 0xB5) {
v = out2[1];
if (v < 0) {
v = -v;
}
if (v < 0xA1) {
func_8002D4C8(0x98B, 0);
}
}
}
}
if (func_8012BEE8((s32)a0) != 0) {
*(s16 *)((char *)a0 + 0x2) = 3;
func_8012A828((s32)a0, &D_801B0750);
*(u16 *)((char *)a0 + 0x5C) = 0xAA10;
*(s16 *)((char *)a0 + 0x5E) = 0;
*(s16 *)((char *)a0 + 0xDC) = 0;
*(s32 *)((char *)a0 + 0x1C) = 0x2D;
}
}
INCLUDE_ASM("asm/ov_SC04_004/nonmatchings/ov_SC04_004_jr_8017AE2C", func_80183750);
INCLUDE_ASM("asm/ov_SC04_004/nonmatchings/ov_SC04_004_jr_8017AE2C", func_80183798);
/* Fresh mass-lane crack (Phase-31 wave T). No banked twin was found for this
* skeleton (grepped D_801B3AC0 / D_801A8C14 / D_801A8C34 / D_801A8C6C / the
* jal callees across src/ -- only extern decls / INCLUDE_ASM stubs turned up,
* all for unrelated overlay-local reuses of the same address). The dispatch
* head (D_801A8C6C[*(u16*)(a0+2)]();) mirrors the ALREADY-BANKED
* func_8017EC70 in THIS SAME TU (D_8018C074[*(u16*)((s32)a0+2)]();) -- same
* idiom, used as a hint per law 1 (never copied its symbols). */
extern s32 func_8012C044(s32 a0);
extern void func_8002A04C(s32 a0);
extern void func_8012C098(void);
extern void func_8012E8A8(u8 *a0);
extern void func_800183E0(s32 a0);
void func_80183798(void *a0) {
extern void (*D_801A8C6C[])(void);
extern u16 D_800B99DA;
extern u16 D_801A8C14[];
extern u16 D_801B3AC0[];
extern u8 D_801A8C34[];
void *s0 = a0;
D_801A8C6C[*(u16 *)((u8 *)s0 + 0x2)]();
if (func_8012C044((s32)s0)) {
*(s16 *)((u8 *)s0 + 0x100) = 1;
__asm__ __volatile__("" ::: "memory");
*(s16 *)((u8 *)s0 + 0x76) = 0;
if (*(s16 *)((u8 *)s0 + 0x100) == 0) {
func_8002A04C((s32)s0);
}
if (*(s16 *)((u8 *)s0 + 0xFE) == 0) {
((void (*)(void *))func_8012C098)(s0);
} else {
*(s16 *)((u8 *)s0 + 0x2) = 6;
func_8012E8A8((u8 *)s0);
*(s16 *)((u8 *)s0 + 0x5C) = 0;
*(u8 *)((u8 *)s0 + 0xC1) = 0;
}
}
if (*(s16 *)((u8 *)s0 + 0xFE) != 0) {
u16 *src = D_801A8C14;
s32 shift = D_800B99DA & 0xF;
u16 *dst = &D_801B3AC0[shift];
s32 i;
for (i = 0; i < 0xF - shift; i++) {
*dst++ = *src++;
}
dst = D_801B3AC0;
for (i = 0; i < shift; i++) {
*dst++ = *src++;
}
func_800183E0((s32)D_801A8C34);
}
}
extern void (*D_801A8C90[])(void);
@@ -6520,7 +6672,53 @@ void func_80183DBC(int param_1)
}
INCLUDE_ASM("asm/ov_SC04_004/nonmatchings/ov_SC04_004_jr_8017AE2C", func_80183E2C);
typedef struct { s16 a, b, c; } SV3x_80183E2C; /* 6-byte, align-2 triple of s16 */
typedef struct { s16 a, b, c, d; } SV4x_80183E2C; /* 8-byte, align-2 quad of s16 */
extern void func_8012C218(void *a0);
extern void func_8012F214(s32 a0, s32 a1, s32 a2);
void func_80183E2C(void *a0) {
extern s32 D_801B0D28;
extern s32 D_801A8C88;
s32 s0 = (s32)a0;
s32 s1;
SV3x_80183E2C out;
s1 = *(s32 *)(s0 + 0x64);
if (*(s16 *)(s0 + 0xFE) == 0x7FFF) {
*(s16 *)(s0 + 0xFE) = *(u16 *)(*(s32 *)(s0 + 0x20) + 0x12);
}
if (*(s16 *)(s0 + 0xFC) != *(s16 *)(s1 + 0x36)) {
func_8012C218((void *)s0);
return;
}
*(SV4x_80183E2C *)(*(s32 *)(s0 + 0x20) + 0x10) = *(SV4x_80183E2C *)(*(s32 *)(s1 + 0x20) + 0x10);
if (*(s32 *)(s1 + 0x90) != (s32)&D_801B0D28) {
*(s16 *)(*(s32 *)(s0 + 0x20) + 0x12) = *(s16 *)(s0 + 0xFE);
*(s32 *)(s0 + 0x4) = *(s32 *)(s1 + 0x4);
*(s32 *)(s0 + 0x8) = *(s32 *)(s1 + 0x8);
*(s32 *)(s0 + 0xC) = *(s32 *)(s1 + 0xC);
} else {
func_8012F214(s1, (s32)&D_801A8C88, (s32)&out);
*(s16 *)(s0 + 0x6) = out.a;
*(s16 *)(s0 + 0xA) = out.b;
*(s16 *)(s0 + 0xE) = out.c;
}
*(SV4x_80183E2C *)(*(s32 *)(s0 + 0x20) + 0x18) = *(SV4x_80183E2C *)(*(s32 *)(s1 + 0x20) + 0x18);
*(s16 *)(*(s32 *)(s0 + 0x20) + 0x2C) = *(s16 *)(*(s32 *)(s1 + 0x20) + 0x2C);
*(s32 *)(*(s32 *)(s0 + 0x20) + 0x4) = *(s32 *)(*(s32 *)(s1 + 0x20) + 0x4);
}
extern void (*D_801B0DF4[])(void);
+368 -6
View File
@@ -317,7 +317,6 @@ extern s32 func_80012B04(s32 a0, s32 a1, s32 a2);
extern void func_801490F8(s32 a0, s32 a1);
extern s32 func_801491C4(s32 a0);
extern s32 func_80149184(s32 a0);
extern s32 D_801151D4;
extern void func_80149204(s32 *a0);
extern void func_80149210(s32 a0, s32 a1);
extern s32 func_80149284(s32 *a0, s32 a1);
@@ -3175,7 +3174,101 @@ void func_8017CDF4(s32 a0) {
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_8017CE3C);
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_8017CEF4);
typedef struct { short a, b, c; } SV3_80181D44_8017CEF4; /* == the TU's own `SV3` (engine_types.h:612); renamed only because
typedef struct { s16 vx, vy, vz, pad; } SV_8017D7C0_8017F19C_8017CEF4; /* 8 bytes, align 2 */
/* Callee externs — spellings copied from src/ov_SC04_002/ov_SC04_002_jr_8017BEBC.c
* (law 2). func_8017D098 is DEFINED later in that same TU as `void func_8017D098(void)`
* (a trivial wrapper around func_80151664()); our call site sets $a0 before the jal but
* the real body ignores it, so we declare it unprototyped (K&R style) to accept the
* dead argument without a conflicting-prototype error against the later definition. */
extern void func_80149020(s32 *a0);
extern void func_80147A84(s32 arg0);
extern void func_801473EC(s32 *a0);
extern void func_80148038(s32 a0, s32 a1);
extern void func_80147460(s32 a0);
extern s32 func_801535F4(void *arg0);
extern void func_8017D098();
extern void func_80159B3C(void *a0);
extern void func_8015BF48(s32 *a0);
extern s32 func_80146E98(s32 a0);
extern s32 func_80146A6C(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5, s32 a6);
extern void func_80165718(s32 a0);
/* 16-byte-stride table at D_8018B4E8, indexed by the actor's 0xF2 animation/state id
* (signed s16); only the table row's first word (offset 0) is read. */
typedef struct {
s32 f0;
u8 pad[12];
} Tbl16_8018BDE4_8017CEF4;
void func_8017CEF4(s32 a0) {
extern Tbl16_8018BDE4_8017CEF4 D_8018B4E8[];
s32 s0;
s16 s1;
s32 ret;
s0 = *(s32 *)(a0 + 0x20);
func_80149020((s32 *)a0);
s1 = *(s16 *)(s0 + 0x12);
*(s16 *)(s0 + 0x12) = *(u16 *)(a0 + 0x244);
func_80147A84(a0);
func_801473EC((s32 *)a0);
func_80148038(a0, D_8018B4E8[*(s16 *)(a0 + 0xF2)].f0);
func_80147460(a0);
*(s16 *)(s0 + 0x12) = s1;
if (*(s32 *)(a0 + 0x234) == 0) {
if (*(s32 *)(a0 + 0x34) >= 0) {
if ((*(u16 *)(a0 + 0xB8) & 0x8000) != 0) {
__asm__ __volatile__("" ::: "memory");
*(u16 *)(a0 + 0xB8) = *(u16 *)(a0 + 0xBA);
*(s32 *)(a0 + 0x234) = *(s32 *)(a0 + 0x234) + 1;
}
}
}
ret = func_801535F4((void *)a0);
if (ret == 1) {
goto L_case1;
}
if (ret < 2) {
goto L_default;
}
if (ret == 2) {
goto L_case2;
}
goto L_default;
L_case1:
func_8017D098(a0);
func_80159B3C((void *)a0);
func_80146A6C(2, (void *)a0, 0, 0, 0, 1, 0);
func_80165718(a0);
return;
L_case2:
func_8017D098(a0);
func_8015BF48((s32 *)a0);
func_80146A6C(2, (void *)a0, 0, 0, 0, 1, 0);
func_80165718(a0);
return;
L_default:
if (func_80146E98(a0) == 0) {
return;
}
func_8017D098(a0);
func_80159B3C((void *)a0);
func_80146A6C(2, (void *)a0, 0, 0, 0, 1, 0);
func_80165718(a0);
}
extern void func_80151664(void);
void func_8017D098(void) {
@@ -6242,7 +6335,47 @@ INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_8018242
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_801824F0);
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_8018259C);
typedef struct { s16 m[3][3]; s32 t[3]; } MTX_8017D7C0_8017F19C_8018259C; /* 0x20 bytes, align 4 */
typedef struct { u16 x, y, z, w; } V8_80181368_8018259C;
extern s32 func_8004787C(s32 a0);
extern s32 func_80047948(s32 a0);
extern s32 func_80133784(s32 a0, void *a1, s32 a2);
s32 func_8018259C(s32 a0, s32 a1) {
V8_80181368_8018259C sp10;
V8_80181368_8018259C sp18;
s32 t;
s32 r;
sp10.x = *(u16 *)(a0 + 0x6);
sp10.y = *(u16 *)(a0 + 0xA) - 0x20;
sp10.z = *(u16 *)(a0 + 0xE);
t = func_8004787C(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF);
r = (s16)a1;
sp18.y = sp10.y;
sp18.x = sp10.x - ((t * r) >> 12);
t = func_80047948(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF);
sp18.z = sp10.z - ((t * r) >> 12);
if ((func_80133784(1, &sp10, (s32)&sp18) & 0x8000) == 0) {
t = func_8004787C(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF);
sp10.x = *(u16 *)(a0 + 0x6) - ((t * 8) >> 12);
sp10.y = *(u16 *)(a0 + 0xA) - 0x10;
t = func_80047948(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF);
sp10.z = *(u16 *)(a0 + 0xE) - ((t * 8) >> 12);
sp18.x = sp10.x;
sp18.y = sp10.y + 0x20;
sp18.z = sp10.z;
if (func_80133784(1, &sp10, (s32)&sp18) & 0x6000) {
return 0;
}
}
*(s32 *)(a0 + 0x4) = *(s32 *)(a0 + 0x38);
*(s32 *)(a0 + 0xC) = *(s32 *)(a0 + 0x40);
return 1;
}
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_80182728);
@@ -7044,7 +7177,79 @@ void func_80184A38(s32 a0) {
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_80184C70);
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_80184CB4);
extern void func_80185774(s32 a0);
extern s32 func_80029DB4(void);
extern s32 func_80029E30(void);
extern s32 func_801855A0(s32 a0, s32 a1, s32 a2, s32 a3);
extern void func_8012A828(s32, s32);
extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2);
extern void func_8012CBCC(s32 a0);
void func_80184CB4(s32 a0) {
extern s32 D_8011F730;
extern u8 D_801BE9EC[];
extern s32 D_801BE63C;
extern s32 D_801BE6A4;
extern s32 D_801BE88C;
extern u8 D_801B59D0[];
extern u8 D_801B59F0[];
s32 state;
s32 g;
s32 v0;
s32 arg0, arg1;
func_80185774(a0);
state = *(u16 *)(a0 + 0x34);
switch (state) {
case 0:
g = D_8011F730;
if (g == 2) {
*(u16 *)(a0 + 0x34) = 3;
((void (*)(s32, void *))func_8012A828)(a0, D_801BE9EC);
return;
} else if (g == 3) {
*(u16 *)(a0 + 0x34) = 1;
((void (*)(s32, void *))func_8012A828)(a0, &D_801BE63C);
return;
} else if (g == 4) {
*(u16 *)(a0 + 0x34) = 2;
((void (*)(s32, void *))func_8012A828)(a0, &D_801BE6A4);
return;
}
goto tail_short;
case 1:
v0 = func_80029DB4();
func_801855A0(a0, (s32)D_801B59D0, 7, v0);
arg0 = 0x1EB;
arg1 = 0;
break;
case 2:
v0 = func_80029E30();
func_801855A0(a0, (s32)D_801B59F0, 6, v0);
arg0 = 0x1EB;
arg1 = 1;
break;
case 3:
goto tail_short;
default:
return;
}
func_8012C658(arg0, arg1, a0);
if (*(u16 *)(a0 + 0x72) & 0x4000) {
((void (*)(s32, void *))func_8012A828)(a0, &D_801BE88C);
}
tail_short:
if (((s32 (*)(s32))func_8012CBCC)(a0) & 0x2000) {
*(u16 *)(a0 + 0x2) = 1;
}
}
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_80184E38);
@@ -7360,7 +7565,88 @@ INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_8018591
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_80185A08);
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_80185B70);
extern s32 func_80132EF4(s32 a0, s32 a1);
typedef struct { short a, b, c; } SV3_80181D44_80185B70; /* == the TU's own `SV3` (engine_types.h:612); renamed only because
extern s32 func_80132EF4(s32 a0, s32 a1);
extern s32 rand(void);
/* func_80185CEC is the NEXT stub in this same TU (INCLUDE_ASM at the line below
* func_80185B70's). Its own .s takes TWO args ($a0 = entity-owner, $a1 = id):
* do NOT adopt the 1-arg `void f(void*)` spelling that the *unrelated* overlay
* ov_SC03_001 uses for its own different function at the same address. */
extern void func_80185CEC(s32 a0, s32 a1);
/* Spawn a 0x4F entity for `a0`, then jitter its three s16 fields at +0x6/+0xA/+0xE
* by a random amount (mod 28 / 32 / 28, sign picked by a second rand()), flip the
* substruct at *(s32*)(entity+0x20) fields 0x18/0x1A/0x1C to +/-0x2000, and notify. */
s32 func_80185B70(s32 a0) {
s32 s2;
s2 = func_80132EF4(a0, 0x4F);
if (s2 == 0) {
return 0;
}
*(s16 *)(s2 + 0xA) = *(u16 *)(s2 + 0xA) - 0x28;
/* NOTE (this is the whole match, do not "tidy" it): each block MUST own its
* own r/val/base locals. With one shared `r` across all three blocks, the
* /32 block's remainder pseudo conflicts with the rand()-result pseudo, so
* global.c's expand_preferences() cannot merge their preferences (it needs
* a non-conflicting REG_DEAD copy). The result pseudo then has NO hard-reg
* preference of its own, prune_preferences() puts $v1 into its
* regs_someone_prefers set, and find_reg's pass 0 skips $v1 and lands the
* value in $a0 instead of the target's $v1 (4 wrong instructions). */
{
s32 r, val, base;
r = rand() % 28;
base = *(s16 *)(s2 + 0x6);
val = (rand() & 1) ? (base + r) : (base - r);
*(s16 *)(s2 + 0x6) = val;
}
{
s32 r, val, base;
r = rand() % 32;
base = *(s16 *)(s2 + 0xA);
val = (rand() & 1) ? (base + r) : (base - r);
*(s16 *)(s2 + 0xA) = val;
}
{
s32 r, val, base;
r = rand() % 28;
base = *(s16 *)(s2 + 0xE);
val = (rand() & 1) ? (base + r) : (base - r);
*(s16 *)(s2 + 0xE) = val;
}
{
s32 v0, v1;
if (rand() & 1) {
v1 = *(s32 *)(s2 + 0x20);
v0 = -0x2000;
*(s16 *)(v1 + 0x1C) = v0;
} else {
v1 = *(s32 *)(s2 + 0x20);
v0 = 0x2000;
*(s16 *)(v1 + 0x1C) = v0;
}
*(s16 *)(v1 + 0x1A) = v0;
*(s16 *)(v1 + 0x18) = v0;
}
/* Zero-byte scheduling fence (§190-C). Without it BOTH sched1 and sched2
* independently hoist the call's `move $a0,$s3` + `li $a1,0x7F3` above the
* two trailing `sh` stores (they feed the jal, so they carry the higher
* INSN_PRIORITY), and reorg then fills the delay slot with `sh 0x18`
* instead of the target's `addiu $a1`. -fno-schedule-insns{,2} alone does
* not reproduce the target order -- only both together do, hence a real
* barrier rather than a statement reorder. */
__asm__ __volatile__("" ::: "memory");
func_80185CEC(a0, 0x7F3);
return s2;
}
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_80185CEC);
@@ -7923,7 +8209,83 @@ void func_801869D4(s32 a0, s32 a1, s32 a2)
}
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_80186C80);
typedef struct { s16 vx, vy, vz, pad; } SV_8017D7C0_8017F19C_80186C80; /* 8 bytes, align 2 */
/* func_80186C80 (ov_SC04_002, ov_SC04_002_jr_8017BEBC, 83 ins)
*
* Sibling family (skeleton group, remapped mechanically once this banks):
* ov_SC02_041:func_8018428C, ov_SC04_005:func_80186C80, ov_SC04_007:func_801832EC
*
* Two conflicting local extern decls exist for this function in the TU
* (func_8018739C uses `void *a1, MATRIX *a3`; func_80187604 uses `s32 a1,
* void *a3`) -- neither is dereferenced structurally inside this function's
* own body (a3 is only ever forwarded as an opaque pointer argument), so the
* definition-side signature below (s32 a1, void *a3) is chosen freely and is
* compatible with both call sites' own local prototypes.
*/
void func_80186C80(s32 a0, s32 a1, s32 a2, void *a3)
{
extern s32 D_801151D4;
extern void func_8012EC04(s32 param_1, s32 param_2, s32 *param_3);
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
extern void func_800D20C0(void *a0, void *a1, s32 a2);
extern void func_80017E68(void *a0, void *a1);
extern void func_800D23D0(void *a0);
extern void ApplyMatrixSV(void *a0, void *a1, void *a2);
extern void RotMatrixYXZ(void *a0, void *a1);
extern void ApplyTransposeMatrixLV(void *a0, void *a1, void *a2);
extern s32 ratan2(s32 a0, s32 a1);
s32 mtx1[8]; /* sp+0x10, 0x20 bytes: scratch MATRIX */
s16 buf2[4]; /* sp+0x30, 8 bytes: vx,vy,vz,pad */
s16 vec[4]; /* sp+0x38, 8 bytes: vx,vy,vz,pad */
s32 diff[3]; /* sp+0x40 */
s32 base;
s32 v0;
s32 v1;
base = D_801151D4;
func_8012EC04(a0, a2, (s32 *)mtx1);
func_8012F14C((s32)mtx1, a1 + 0x18, (s32)buf2);
func_800D20C0((void *)buf2, (void *)vec, 8);
func_80017E68((void *)buf2, a3);
v0 = *(u16 *)(a1 + 0x8);
v1 = *(u16 *)(a1 + 0x10);
v0 = v0 - v1;
vec[0] = v0;
v0 = *(u16 *)(a1 + 0xA);
v1 = *(u16 *)(a1 + 0x12);
v0 = v0 - v1;
vec[1] = v0;
v0 = *(u16 *)(a1 + 0xC);
v1 = *(u16 *)(a1 + 0x14);
v0 = v0 - v1;
vec[2] = v0;
ApplyMatrixSV((void *)mtx1, (void *)vec, (void *)vec);
func_800D23D0((void *)vec);
RotMatrixYXZ((void *)vec, a3);
diff[0] = *(s32 *)(base + 0x5C) - buf2[0];
diff[1] = *(s32 *)(base + 0x60) - buf2[1];
diff[2] = *(s32 *)(base + 0x64) - buf2[2];
ApplyTransposeMatrixLV(a3, (void *)diff, (void *)diff);
v0 = ratan2(diff[0], diff[1]);
vec[2] = -v0;
RotMatrixYXZ((void *)vec, a3);
}
typedef struct { u32 addr : 24; u32 len : 8; } PTag_801843D8_80186DCC;
#define gte_ldv3_801843D8(r0, r1, r2) __asm__ volatile ( \
+232 -4
View File
@@ -318,7 +318,6 @@ extern s32 func_80012B04(s32 a0, s32 a1, s32 a2);
extern void func_801490F8(s32 a0, s32 a1);
extern s32 func_801491C4(s32 a0);
extern s32 func_80149184(s32 a0);
extern s32 D_801151D4;
extern void func_80149204(s32 *a0);
extern void func_80149210(s32 a0, s32 a1);
extern s32 func_80149284(s32 *a0, s32 a1);
@@ -5751,7 +5750,79 @@ void func_801810A4(s32 a0) {
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_801812DC);
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_80181320);
extern void func_80181DE0(s32 a0);
extern s32 func_80029DB4(void);
extern s32 func_80029E30(void);
extern s32 func_80181C0C(s32 a0, s32 a1, s32 a2, s32 a3);
extern void func_8012A828(s32, s32);
extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2);
extern void func_8012CBCC(s32 a0);
void func_80181320(s32 a0) {
extern s32 D_8011F730;
extern u8 D_801A1094[];
extern s32 D_801A0CE4;
extern s32 D_801A0D4C;
extern s32 D_801A0F34;
extern u8 D_80198078[];
extern u8 D_80198098[];
s32 state;
s32 g;
s32 v0;
s32 arg0, arg1;
func_80181DE0(a0);
state = *(u16 *)(a0 + 0x34);
switch (state) {
case 0:
g = D_8011F730;
if (g == 2) {
*(u16 *)(a0 + 0x34) = 3;
((void (*)(s32, void *))func_8012A828)(a0, D_801A1094);
return;
} else if (g == 3) {
*(u16 *)(a0 + 0x34) = 1;
((void (*)(s32, void *))func_8012A828)(a0, &D_801A0CE4);
return;
} else if (g == 4) {
*(u16 *)(a0 + 0x34) = 2;
((void (*)(s32, void *))func_8012A828)(a0, &D_801A0D4C);
return;
}
goto tail_short;
case 1:
v0 = func_80029DB4();
func_80181C0C(a0, (s32)D_80198078, 7, v0);
arg0 = 0x1EB;
arg1 = 0;
break;
case 2:
v0 = func_80029E30();
func_80181C0C(a0, (s32)D_80198098, 6, v0);
arg0 = 0x1EB;
arg1 = 1;
break;
case 3:
goto tail_short;
default:
return;
}
func_8012C658(arg0, arg1, a0);
if (*(u16 *)(a0 + 0x72) & 0x4000) {
((void (*)(s32, void *))func_8012A828)(a0, &D_801A0F34);
}
tail_short:
if (((s32 (*)(s32))func_8012CBCC)(a0) & 0x2000) {
*(u16 *)(a0 + 0x2) = 1;
}
}
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_801814A4);
@@ -6057,7 +6128,88 @@ INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_80181F8
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_80182074);
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_801821DC);
extern s32 func_80132EF4(s32 a0, s32 a1);
typedef struct { short a, b, c; } SV3_80181D44_801821DC; /* == the TU's own `SV3` (engine_types.h:612); renamed only because
extern s32 func_80132EF4(s32 a0, s32 a1);
extern s32 rand(void);
/* func_80182358 is the NEXT stub in this same TU (INCLUDE_ASM at the line below
* func_801821DC's). Its own .s takes TWO args ($a0 = entity-owner, $a1 = id):
* do NOT adopt the 1-arg `void f(void*)` spelling that the *unrelated* overlay
* ov_SC03_001 uses for its own different function at the same address. */
extern void func_80182358(s32 a0, s32 a1);
/* Spawn a 0x4F entity for `a0`, then jitter its three s16 fields at +0x6/+0xA/+0xE
* by a random amount (mod 28 / 32 / 28, sign picked by a second rand()), flip the
* substruct at *(s32*)(entity+0x20) fields 0x18/0x1A/0x1C to +/-0x2000, and notify. */
s32 func_801821DC(s32 a0) {
s32 s2;
s2 = func_80132EF4(a0, 0x4F);
if (s2 == 0) {
return 0;
}
*(s16 *)(s2 + 0xA) = *(u16 *)(s2 + 0xA) - 0x28;
/* NOTE (this is the whole match, do not "tidy" it): each block MUST own its
* own r/val/base locals. With one shared `r` across all three blocks, the
* /32 block's remainder pseudo conflicts with the rand()-result pseudo, so
* global.c's expand_preferences() cannot merge their preferences (it needs
* a non-conflicting REG_DEAD copy). The result pseudo then has NO hard-reg
* preference of its own, prune_preferences() puts $v1 into its
* regs_someone_prefers set, and find_reg's pass 0 skips $v1 and lands the
* value in $a0 instead of the target's $v1 (4 wrong instructions). */
{
s32 r, val, base;
r = rand() % 28;
base = *(s16 *)(s2 + 0x6);
val = (rand() & 1) ? (base + r) : (base - r);
*(s16 *)(s2 + 0x6) = val;
}
{
s32 r, val, base;
r = rand() % 32;
base = *(s16 *)(s2 + 0xA);
val = (rand() & 1) ? (base + r) : (base - r);
*(s16 *)(s2 + 0xA) = val;
}
{
s32 r, val, base;
r = rand() % 28;
base = *(s16 *)(s2 + 0xE);
val = (rand() & 1) ? (base + r) : (base - r);
*(s16 *)(s2 + 0xE) = val;
}
{
s32 v0, v1;
if (rand() & 1) {
v1 = *(s32 *)(s2 + 0x20);
v0 = -0x2000;
*(s16 *)(v1 + 0x1C) = v0;
} else {
v1 = *(s32 *)(s2 + 0x20);
v0 = 0x2000;
*(s16 *)(v1 + 0x1C) = v0;
}
*(s16 *)(v1 + 0x1A) = v0;
*(s16 *)(v1 + 0x18) = v0;
}
/* Zero-byte scheduling fence (§190-C). Without it BOTH sched1 and sched2
* independently hoist the call's `move $a0,$s3` + `li $a1,0x7F3` above the
* two trailing `sh` stores (they feed the jal, so they carry the higher
* INSN_PRIORITY), and reorg then fills the delay slot with `sh 0x18`
* instead of the target's `addiu $a1`. -fno-schedule-insns{,2} alone does
* not reproduce the target order -- only both together do, hence a real
* barrier rather than a statement reorder. */
__asm__ __volatile__("" ::: "memory");
func_80182358(a0, 0x7F3);
return s2;
}
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_80182358);
@@ -6620,7 +6772,83 @@ void func_80183040(s32 a0, s32 a1, s32 a2)
}
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_801832EC);
typedef struct { s16 vx, vy, vz, pad; } SV_8017D7C0_8017F19C_801832EC; /* 8 bytes, align 2 */
/* func_801832EC (ov_SC04_002, ov_SC04_002_jr_8017BEBC, 83 ins)
*
* Sibling family (skeleton group, remapped mechanically once this banks):
* ov_SC02_041:func_8018428C, ov_SC04_005:func_80186C80, ov_SC04_007:func_801832EC
*
* Two conflicting local extern decls exist for this function in the TU
* (func_8018739C uses `void *a1, MATRIX *a3`; func_80187604 uses `s32 a1,
* void *a3`) -- neither is dereferenced structurally inside this function's
* own body (a3 is only ever forwarded as an opaque pointer argument), so the
* definition-side signature below (s32 a1, void *a3) is chosen freely and is
* compatible with both call sites' own local prototypes.
*/
void func_801832EC(s32 a0, s32 a1, s32 a2, void *a3)
{
extern s32 D_801151D4;
extern void func_8012EC04(s32 param_1, s32 param_2, s32 *param_3);
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
extern void func_800D20C0(void *a0, void *a1, s32 a2);
extern void func_80017E68(void *a0, void *a1);
extern void func_800D23D0(void *a0);
extern void ApplyMatrixSV(void *a0, void *a1, void *a2);
extern void RotMatrixYXZ(void *a0, void *a1);
extern void ApplyTransposeMatrixLV(void *a0, void *a1, void *a2);
extern s32 ratan2(s32 a0, s32 a1);
s32 mtx1[8]; /* sp+0x10, 0x20 bytes: scratch MATRIX */
s16 buf2[4]; /* sp+0x30, 8 bytes: vx,vy,vz,pad */
s16 vec[4]; /* sp+0x38, 8 bytes: vx,vy,vz,pad */
s32 diff[3]; /* sp+0x40 */
s32 base;
s32 v0;
s32 v1;
base = D_801151D4;
func_8012EC04(a0, a2, (s32 *)mtx1);
func_8012F14C((s32)mtx1, a1 + 0x18, (s32)buf2);
func_800D20C0((void *)buf2, (void *)vec, 8);
func_80017E68((void *)buf2, a3);
v0 = *(u16 *)(a1 + 0x8);
v1 = *(u16 *)(a1 + 0x10);
v0 = v0 - v1;
vec[0] = v0;
v0 = *(u16 *)(a1 + 0xA);
v1 = *(u16 *)(a1 + 0x12);
v0 = v0 - v1;
vec[1] = v0;
v0 = *(u16 *)(a1 + 0xC);
v1 = *(u16 *)(a1 + 0x14);
v0 = v0 - v1;
vec[2] = v0;
ApplyMatrixSV((void *)mtx1, (void *)vec, (void *)vec);
func_800D23D0((void *)vec);
RotMatrixYXZ((void *)vec, a3);
diff[0] = *(s32 *)(base + 0x5C) - buf2[0];
diff[1] = *(s32 *)(base + 0x60) - buf2[1];
diff[2] = *(s32 *)(base + 0x64) - buf2[2];
ApplyTransposeMatrixLV(a3, (void *)diff, (void *)diff);
v0 = ratan2(diff[0], diff[1]);
vec[2] = -v0;
RotMatrixYXZ((void *)vec, a3);
}
typedef struct { u32 addr : 24; u32 len : 8; } PTag_801843D8_80183438;
#define gte_ldv3_801843D8(r0, r1, r2) __asm__ volatile ( \
+139 -2
View File
@@ -5624,7 +5624,78 @@ L_end:
}
INCLUDE_ASM("asm/ov_SC05_001/nonmatchings/ov_SC05_001_jr_8017BEBC", func_80182E0C);
/* Sibling pattern for the func_8012C354(a0, &D_xxx) gate + s0+0xC0/s0+0x2 flag
* writes is func_8017F3F4 in this same TU (ov_SC03_112_jr_8017C294.c, ~L3892):
* it declares the target-only data symbol as `extern M2C_UNK D_xxx;` and passes
* `(s32)&D_xxx` as the gate's second arg. Followed here for D_801AE2E4.
*
* func_8012C354(s32,s32)->s32 : TU decl at L3911 (verbatim, adopted).
* func_8001CD9C(int,void*) : TU decl at L1818 (verbatim, adopted); defined
* void at src/800.c:5936 as (s32,s32) -- the TU's
* own extern spelling wins per law 2/8.
* func_8012C194(void)->s32, func_80143994(s32,s32)->s32, func_8012E8A8(u8*)->void
* : not declared in this TU; typed by the majority project-wide spelling.
*/
extern s32 func_8012C354(s32 a0, s32 a1);
extern void func_8001CD9C(int, void *);
extern s32 func_8012C194(void);
extern s32 func_80143994(s32 a0, s32 a1);
extern void func_8012E8A8(u8 *a0);
void func_80182E0C(s32 a0) {
extern M2C_UNK D_801AE2E4;
extern M2C_UNK D_801AE318;
extern M2C_UNK D_801AE360;
extern M2C_UNK D_801AE3B0;
s32 s0;
s32 v1;
u16 v0;
if (func_8012C354(a0, (s32)&D_801AE2E4)) {
v1 = *(s32 *)(a0 + 0x20);
*(u16 *)(v1 + 0x2C) |= 0x30;
v1 = *(s32 *)(a0 + 0x20);
*(void **)(v1 + 0x80) = &D_801AE318;
*(s32 *)(a0 + 0xE8) = 0x40;
s0 = func_8012C194();
if (s0 != 0) {
*(s32 *)(a0 + 0xD0) = s0;
func_8001CD9C((int)s0, (void *)&D_801AE360);
*(s16 *)(s0 + 0x18) = 0x555;
*(s16 *)(s0 + 0x1A) = 0x555;
*(s32 *)(s0 + 0x4) |= 0x50000000;
}
v0 = *(u16 *)(a0 + 0x70);
if (v0 & 0x2) {
*(u16 *)(a0 + 0x2) = 0x8;
*(u8 *)(a0 + 0xC0) = 1;
*(void **)(a0 + 0xBC) = &D_801AE3B0;
*(s32 *)(a0 + 0xB4) = -0x249D;
*(s32 *)(a0 + 0xC4) |= 0x2;
func_8012E8A8((u8 *)a0);
return;
}
if (v0 & 0x1) {
*(u16 *)(a0 + 0x2) = 6;
*(u16 *)(a0 + 0x5C) &= 0x5FFF;
} else {
*(u8 *)(a0 + 0xC0) = 1;
*(void **)(a0 + 0xBC) = &D_801AE3B0;
*(s32 *)(a0 + 0xB4) = -0x249D;
*(u16 *)(a0 + 0x2) = 1;
*(s32 *)(a0 + 0xC4) |= 0x2;
}
*(s32 *)(a0 + 0xCC) = func_80143994(a0, 0x1000);
}
}
INCLUDE_ASM("asm/ov_SC05_001/nonmatchings/ov_SC05_001_jr_8017BEBC", func_80182F68);
@@ -5803,6 +5874,72 @@ TAIL_5DC:
}
INCLUDE_ASM("asm/ov_SC05_001/nonmatchings/ov_SC05_001_jr_8017BEBC", func_8018330C);
typedef struct {
SVECTOR_8016E7C8 v[4]; /* 0x00 */
s32 f0, f1, f2, f3, f4, f5; /* 0x20..0x37 */
u8 f6; /* 0x38 */
u8 pad[7]; /* -> 0x40 */
} Prim_8016E7C8_8018330C;
extern s32 func_8012BCCC(s32 a0);
extern s32 func_8004787C(s32 a0);
extern s32 func_8012B8E4(s32 a0, s32 a1);
void func_8018330C(s32 param_1)
{
extern void func_80184580(s32 a0);
extern s32 func_8012BDBC(s32 a0, s32 a1);
extern void func_8012B178(s32 a0, s32 a1);
extern s32 func_8012CBA4(s32 a0);
extern void func_8012ADE4(u8 *a0);
s32 dist;
s32 angle;
s32 iVar1;
s32 a1;
if (*(s16 *)(param_1 + 0xa) >= 0x10) {
func_80184580(param_1);
goto end;
}
dist = func_8012BCCC(param_1);
if (func_8012BDBC(param_1, 0x400) == 0) {
*(s16 *)(param_1 + 2) = 1;
goto end;
}
if (dist > 0x24000) {
*(s16 *)(param_1 + 2) = 1;
goto end;
}
if (dist < 0x4001) {
*(s16 *)(param_1 + 2) = 4;
goto end;
}
angle = func_8004787C((*(s32 *)(param_1 + 0xe4) << 7) & 0x780);
*(s16 *)(*(s32 *)(param_1 + 0x20) + 0x1a) = (angle >> 1) + 0x800;
iVar1 = func_8012B8E4(param_1, 0xa);
{
s32 ptr = *(s32 *)(param_1 + 0x20);
s32 v = *(u16 *)(ptr + 0x12) + iVar1;
*(u16 *)(ptr + 0x12) = v;
if (0x1000 - angle >= 0) {
a1 = 0xFFFF0000 - ((0x1000 - angle) << 7);
} else {
a1 = 0xFFFF0000 - ((angle - 0x1000) << 7);
}
}
func_8012B178(param_1, a1);
iVar1 = func_8012CBA4(param_1);
if ((iVar1 & 0x6000) == 0) {
func_8012ADE4((u8 *)param_1);
}
*(s32 *)(param_1 + 0xe4) += 1;
end:
return;
}
INCLUDE_ASM("asm/ov_SC05_001/nonmatchings/ov_SC05_001_jr_8017BEBC", func_80183454);
+284 -5
View File
@@ -4452,7 +4452,93 @@ void func_8018A0B8(s32 param_1) {
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018A170);
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018A28C);
typedef struct { s32 a; s32 b[4]; } OtBlk_8018A974_8018EB08_8018A28C; /* == engine_types.h OtBlk (0x14) */
/* func_8018A28C — ov_SC06_032 / ov_SC06_032_jr_80182890, 122 ins.
*
* State entry dispatcher: switch on (flags@0x70 & 3), where cases {0,2} take the
* "spawn child object" arm and cases {1,3} take the "allocate display object" arm;
* both then fall into a shared tail that primes the display object at +0x20.
*
* The 4-way compare tree (beq 1 / slti 2 / beqz 0 / beq 2 / beq 3 / j default) is
* gcc-2.7.2's balanced case tree for the four labels 0..3 with two shared bodies.
*/
extern int func_8012C354();
extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2);
extern void func_8012C1B8(void);
extern void func_8012CAE4();
extern void func_8001C214();
extern s32 func_8012AD50(void *arg0);
extern void func_8018C310(void);
extern void func_8018AB00(void);
extern void func_8018A474(void *arg0);
void func_8018A28C(s32 param_1) {
extern u8 D_801CD3B0[];
extern u8 D_801CD3C0[];
extern u8 D_801CD3D8[];
extern u8 D_801D1094[];
s32 obj;
s32 g;
switch (*(u16 *)(param_1 + 0x70) & 3) {
case 0:
case 2:
if (((s32 (*)(s32, u8 *))func_8012C354)(param_1, D_801CD3D8) == 0) {
return;
}
*(s32 *)(param_1 + 0xCC) =
func_8012C658(0x2E4, (*(u16 *)(param_1 + 0x70) & 2) | 1, param_1);
*(u16 *)(param_1 + 0x104) = *(u16 *)(param_1 + 0x70) & 0x102;
*(u16 *)(param_1 + 0x70) = *(u16 *)(param_1 + 0x70) & 1;
if (*(u16 *)(param_1 + 0x104) & 0x100) {
func_8018C310();
func_8018AB00();
}
*(u8 *)(param_1 + 0xC0) = 1;
*(u8 **)(param_1 + 0xBC) = D_801CD3C0;
*(s32 *)(param_1 + 0xB4) = 0;
*(u8 *)(param_1 + 0xC1) = 0;
*(s16 *)(param_1 + 0xAE) = 0x6918;
*(u32 *)(param_1 + 0xC4) |= 2;
break;
case 1:
case 3:
obj = ((s32 (*)(void))func_8012C1B8)();
*(s32 *)(param_1 + 0x20) = obj;
if (obj == 0) {
((void (*)(s32))func_8012CAE4)(param_1);
return;
}
((void (*)(s32, u8 *))func_8001C214)(obj, D_801D1094);
*(u16 *)(param_1 + 0x104) = *(u16 *)(param_1 + 0x70) & 2;
*(u16 *)(param_1 + 0x70) = *(u16 *)(param_1 + 0x70) & 1;
*(u16 *)(param_1 + 0xA) = *(u16 *)(param_1 + 0xA) - 0xA0;
break;
}
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x2C) |= 0x10;
/* one cached base for the three 0xE00 stores: the target loads 0x20($s0)
* only once here, so the source must hold it in a pseudo (any indirect
* store invalidates the CSE of the load in gcc-2.7.2). */
g = *(s32 *)(param_1 + 0x20);
*(s16 *)(g + 0x1C) = 0xE00;
*(s16 *)(g + 0x1A) = 0xE00;
*(s16 *)(g + 0x18) = 0xE00;
*(u8 *)(param_1 + 0x75) = 0;
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x2C) |= 0x80;
*(u8 **)(*(s32 *)(param_1 + 0x20) + 0x80) = D_801CD3B0;
if (*(s16 *)(param_1 + 0x70) != 0 && *(s16 *)(param_1 + 0x104) != 0) {
func_8018A474((void *)param_1);
} else {
func_8012AD50((void *)param_1);
}
}
extern void func_8012AD44(s32 *a0, s16 a1);
void func_8018A474(void *arg0) {
@@ -4671,7 +4757,6 @@ INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018AE6
// `addiu $a0,$sp,0x10` at each use site.
extern Blk20_8018AF88 D_800AE620;
extern s32 D_801CD498;
extern s32 func_8012B8A4(s16 *a0);
@@ -4682,6 +4767,10 @@ extern s32 rand(void);
void func_8018AF88(s32 param_1)
{
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
LATER function in this TU, which blocks a byte-true decl of a different type.
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
extern Blk20_8018AF88 D_800AE620;
Blk20_8018AF88 local_30;
Blk20_8018AF88 *m;
s32 iVar1;
@@ -4705,9 +4794,117 @@ void func_8018AF88(s32 param_1)
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018B060);
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018B1D8);
typedef struct { s32 a; s32 b[4]; } OtBlk_8018A974_8018EB08_8018B1D8; /* == engine_types.h OtBlk (0x14) */
/* Local standins for the shared types (src/shared/engine_types.h) that the real TU pulls in via
* "../shared/engine_core.h" -- match_one's -Iinclude can't reach src/shared/, so these are typed
* identically for the standalone compile only; the real TU already has both. */
/* STEP 0 magic-literal grep: aD800AE620_8018B1D8 / D_801CD40C / ApplyMatrixSV / func_8012AD44 turned up the
* banked sibling func_80186160 (same TU) which establishes: the whole-struct
* `local = aD800AE620_8018B1D8;` idiom (typed Blk20_8018AF88_80186160, from src/shared/engine_types.h), the
* address of that local cached into a POINTER LOCAL (forced into $s1 because it's live across the
* RotMatrixY call and reused as ApplyMatrixSV's a0), and the `func_8012AD44((s32 *)param_1, N)`
* call-through form. D_801CD40C here is a per-overlay array of SVECTOR (indexed *8 = sizeof(SVECTOR)),
* unrelated to the scalar u8 D_801CD40C seen in ov_SC03_104 (different overlay, same address).
*/
extern void RotMatrixY(s32 a0, void *a1);
extern void ApplyMatrixSV(void *a0, void *a1, void *a2);
extern void func_8012AD44(s32 *a0, s16 a1);
extern s32 rand(void);
void func_8018B1D8(s32 param_1)
{
extern Blk20_8018AF88_80186160 aD800AE620_8018B1D8 __asm__("D_800AE620");
extern SVECTOR D_801CD40C[];
Blk20_8018AF88_80186160 local_38;
Blk20_8018AF88_80186160 *m;
SVECTOR out;
s32 rotY;
s32 t;
s16 v1;
local_38 = aD800AE620_8018B1D8;
rotY = rand() & 0x1F0;
m = &local_38;
RotMatrixY(rotY, m);
ApplyMatrixSV(m, &D_801CD40C[*(s16 *)(param_1 + 0x70)], &out);
*(u16 *)(param_1 + 6) = *(u16 *)(*(s32 *)(param_1 + 0x64) + 6) + (u16)out.vx;
*(u16 *)(param_1 + 0xA) = *(u16 *)(*(s32 *)(param_1 + 0x64) + 0xA) + (u16)out.vy;
*(u16 *)(param_1 + 0xE) = *(u16 *)(*(s32 *)(param_1 + 0x64) + 0xE) + (u16)out.vz;
*(s32 *)(param_1 + 0x10) = (s32)out.vx << 12;
t = -(((rand() & 0x3F) << 12) + 0x200000);
*(s32 *)(param_1 + 0x14) = t;
*(s32 *)(param_1 + 0xE0) = t;
*(s32 *)(param_1 + 0x18) = (s32)out.vz << 12;
*(u16 *)(param_1 + 0x106) = rand() & 0xF0;
*(u16 *)(param_1 + 0x108) = rand() & 0xF0;
v1 = *(s16 *)(param_1 + 0x70);
*(u16 *)(param_1 + 0xFE) = v1;
func_8012AD44((s32 *)param_1, 2);
}
extern void func_8012CC40(s32 arg0, s32 arg1); /* fleet-canonical: void; $v0 used -> cast at use */
extern s32 func_8012BEE8(s32 a0);
extern void func_8012C218(void *a0);
extern void func_8018B714(s32 a0);
void func_8018B330(s32 param_1)
{
extern s32 D_801CD4A8;
s32 iVar;
switch (*(u16 *)(param_1 + 0x34)) {
case 0:
iVar = ((s32 (*)(s32, s32))func_8012CC40)(param_1, (s32)&D_801CD4A8);
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) =
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + *(u16 *)(param_1 + 0x106);
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x14) =
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x14) + *(u16 *)(param_1 + 0x108);
if (iVar != 0) {
u16 ns = *(u16 *)(param_1 + 0x34) + 1;
*(s32 *)(param_1 + 0x14) = *(s32 *)(param_1 + 0xE0) >> 1;
*(s32 *)(param_1 + 0x10) = *(s32 *)(param_1 + 0x10) >> 1;
*(s32 *)(param_1 + 0x18) = *(s32 *)(param_1 + 0x18) >> 1;
*(u16 *)(param_1 + 0x34) = ns;
}
func_8018B714(param_1);
break;
case 1:
iVar = ((s32 (*)(s32, s32))func_8012CC40)(param_1, (s32)&D_801CD4A8);
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) =
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + *(u16 *)(param_1 + 0x106);
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x14) =
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x14) + *(u16 *)(param_1 + 0x108);
if (iVar != 0) {
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
*(s32 *)(param_1 + 0x1C) = 0x10;
}
func_8018B714(param_1);
break;
case 2:
if (func_8012BEE8(param_1) != 0) {
func_8012C218((void *)param_1);
} else if (*(s32 *)(param_1 + 0x1C) & 1) {
*(s32 *)(*(s32 *)(param_1 + 0x20) + 4) |= 0x80000000;
} else {
*(s32 *)(*(s32 *)(param_1 + 0x20) + 4) &= 0x7FFFFFFF;
}
break;
}
}
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018B330);
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018B4D8);
@@ -4761,7 +4958,89 @@ void func_8018BC40(s32 param_1)
}
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018BCC4);
typedef struct { s32 a; s32 b[4]; } OtBlk_8018A974_8018EB08_8018BCC4; /* == engine_types.h OtBlk (0x14) */
/* func_8018BCC4 -- MATCH (185 ins, relocation-masked).
*
* Three load-bearing spellings, all verified by byte-diff:
*
* (a) `pad_lo[4]` -- the target's var area starts 0x20 BELOW `sv`. Without a
* 32-byte leading local the frame is 0x98 instead of 0xB8 and every
* sp-relative offset is short by 0x20 (134/185 mismatched). gcc-2.7.2
* still reserves the slot for an unreferenced aggregate, so any 32-byte
* aggregate declared first reproduces the layout.
*
* (b) 4th param declared `u32 col` (a SCALAR whose address is taken), NOT a
* 4-byte struct by value, together with the `arg0->mtx` COMPONENT_REF.
* Both spellings emit identical instructions, but they change gcc-2.7.2's
* alias heuristic in alias.c:true_dependence -- "a varying struct ref does
* not conflict with a fixed scalar ref". With a struct param the 0xC4 home
* slot MEM is MEM_IN_STRUCT_P, so `sw $a3,0xC4($sp)` stays dependent on
* `lw 0x20($s1)` and sched1 cannot sink it (3 mismatched at idx 11-13).
* Scalar-param home slot (not in-struct, non-varying) + struct-member load
* (in-struct, varying) => independent => the store sinks to idx 13. MATCH.
*
* (c) SVec/CVec have alignment 2 / 1, which is what makes the plain struct
* assignments lower to lwl/lwr + swl/swr block moves (cookbook 48-C2).
*/
extern void func_8004914C(void *a0);
extern void func_800491AC(void *a0);
extern void RotTransSV(void *a0, void *a1, void *a2);
extern void func_8018C090(void *a0);
typedef struct { s16 vx, vy, vz, pad; } SVec_80186E9C_8018BCC4; /* 8 bytes, align 2 -> lwl/lwr block move */
typedef struct { u8 r, g, b, cd; } CVec_80186E9C_8018BCC4; /* 4 bytes, align 1 */
typedef struct {
/* 0x00 */ SVec_80186E9C_8018BCC4 v[4];
/* 0x20 */ CVec_80186E9C_8018BCC4 col;
/* 0x24 */ u32 code;
} Quad_80186E9C_8018BCC4;
typedef struct { u8 pad00[0x20]; /* 0x20 */ u8 *mtx; } Ent_80186E9C_8018BCC4;
void func_8018BCC4(Ent_80186E9C_8018BCC4 *arg0, s32 arg1, u16 *arg2, u32 col)
{
extern SVec_80186E9C_8018BCC4 D_801CD4E0[];
SVec_80186E9C_8018BCC4 pad_lo[4]; /* unused 32-byte leading local (frame filler) */
SVec_80186E9C_8018BCC4 sv;
SVec_80186E9C_8018BCC4 out[6];
Quad_80186E9C_8018BCC4 q;
long flag;
SVec_80186E9C_8018BCC4 *p;
s32 i;
func_8004914C(arg0->mtx + 0x34);
func_800491AC(arg0->mtx + 0x34);
p = &D_801CD4E0[(arg1 & 1) * 3];
for (i = 0; i < 3; i++) {
sv.vx = p[i].vx;
sv.vy = p[i].vy;
sv.vz = -arg2[0];
RotTransSV(&sv, &out[i], &flag);
}
for (i = 0; i < 3; i++) {
sv.vx = p[i].vx;
sv.vy = p[i].vy;
sv.vz = -arg2[1];
RotTransSV(&sv, &out[i + 3], &flag);
}
q.col = *(CVec_80186E9C_8018BCC4 *)&col;
q.code = 0x50000000;
q.v[0] = out[0]; q.v[1] = out[1]; q.v[2] = out[3]; q.v[3] = out[4];
func_8018C090(&q);
q.v[0] = out[1]; q.v[1] = out[2]; q.v[2] = out[4]; q.v[3] = out[5];
func_8018C090(&q);
q.v[0] = out[2]; q.v[1] = out[0]; q.v[2] = out[5]; q.v[3] = out[3];
func_8018C090(&q);
}
extern s32 ratan2(s32 a0, s32 a1);