From 2844e0def1f30ca340f0a1ccfc510eb09963a832 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:27:08 -0800 Subject: [PATCH 01/19] gr: Match grIceMt_801F85C4 and grIceMt_801F87FC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Match Icicle Mountain stage functions: - grIceMt_801F85C4 (100%) - Stage update calling animation/state functions - grIceMt_801F87FC (94.8%) - Loop over 5 GObj pointers calling grMaterial_801C8CDC Note: grIceMt_801F87FC uses raw pointer math for array access at offset 0xF8. This could be improved with proper struct field definitions if the array purpose is understood. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 416141ff84..6c4db536f0 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -628,8 +628,12 @@ bool grIceMt_801F85BC(Ground_GObj* param1) return false; } -/// #grIceMt_801F85C4 - +void grIceMt_801F85C4(Ground_GObj* gobj) +{ + grIceMt_801F929C((HSD_GObj*)((u8*)gobj->user_data + 0x108)); + grIceMt_801F98A8(gobj); + Ground_801C2FE0(gobj); +} /// #grIceMt_801F8608 void grIceMt_801F8608(Ground_GObj* arg0) { @@ -683,7 +687,17 @@ void grIceMt_801F87C8(Ground_GObj* param1) return; } -/// #grIceMt_801F87FC +void grIceMt_801F87FC(Ground_GObj* gobj) +{ + int i; + Ground* gp = GET_GROUND(gobj); + for (i = 0; i < 5; i++) { + HSD_GObj* temp = *(HSD_GObj**)((u8*)gp + 0xF8 + i * 4); + if (temp != NULL) { + grMaterial_801C8CDC(temp); + } + } +} /// #grIceMt_801F8850 void grIceMt_801F8850(Ground_GObj* arg0) From af46903c743c7fc19c4df332a4da88a7ae55a919 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Tue, 30 Dec 2025 12:24:45 -0800 Subject: [PATCH 02/19] docs(gr): fix pointer arithmetic in grIceMt_801F87FC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace raw pointer math `(u8*)gp + 0xF8 + i * 4` with proper struct field access `gp->gv.icemt.xF4[i + 1]`. Also document the xF4 field's mixed-type usage: - xF4[0] stores IceMountainParams* - xF4[1-5] store HSD_GObj* for material updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 4 +++- src/melee/gr/types.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 6c4db536f0..49bd7249c3 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -687,12 +687,14 @@ void grIceMt_801F87C8(Ground_GObj* param1) return; } +/// @brief Update material GObjs for Icicle Mountain stage. +/// Iterates over xF4[1..5] calling grMaterial update on each. void grIceMt_801F87FC(Ground_GObj* gobj) { int i; Ground* gp = GET_GROUND(gobj); for (i = 0; i < 5; i++) { - HSD_GObj* temp = *(HSD_GObj**)((u8*)gp + 0xF8 + i * 4); + HSD_GObj* temp = gp->gv.icemt.xF4[i + 1]; if (temp != NULL) { grMaterial_801C8CDC(temp); } diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index 3df90c1de7..b2fca1937d 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -353,6 +353,7 @@ struct grIceMt_GroundVars { /* +0 gp+D8 */ s16 xDE; /* +0 gp+D8 */ s16 xE0; /* +0 gp+D8 */ f32 xE4; + /// @brief Mixed pointer array: xF4[0] = IceMountainParams*, xF4[1-5] = HSD_GObj*. /* +0 gp+D8 */ void* xF4[6]; }; struct grIceMt_GroundVars2 { From c94b9a54b130f74fd45a7479bcec932229f38ea7 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Tue, 30 Dec 2025 12:32:42 -0800 Subject: [PATCH 03/19] docs(gr): fix pointer arithmetic in grIceMt_801F87FC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace raw pointer math `(u8*)gp + 0xF8 + i * 4` with proper struct field access `gp->gv.icemt.xF4[i + 1]`. Document xF4 field's mixed-type usage: - xF4[0] stores IceMountainParams* - xF4[1-5] store Item_GObj* for grMaterial cleanup Add @todo for future renaming once row 5's purpose is understood. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 4 ++-- tools/decomp.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 49bd7249c3..a2971a8c6d 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -687,8 +687,8 @@ void grIceMt_801F87C8(Ground_GObj* param1) return; } -/// @brief Update material GObjs for Icicle Mountain stage. -/// Iterates over xF4[1..5] calling grMaterial update on each. +/// @todo Rename: This is callback3 (destroy) for row 5 in grIm_803E4718. +/// Destroys Item_GObj* stored in icemt.xF4[1-5]. void grIceMt_801F87FC(Ground_GObj* gobj) { int i; diff --git a/tools/decomp.py b/tools/decomp.py index 37c8b892a2..6c5ffc287a 100755 --- a/tools/decomp.py +++ b/tools/decomp.py @@ -151,7 +151,7 @@ def main() -> None: "-m", "m2c.main", *args.m2c_args, - "--knr", "--pointer", "left", + "--knr", "--pointer", "left", "--valid-syntax", "--target", "ppc-mwcc-c", "--context", From b52b7a7eb6c20854164f9ecbb5edb7080131850d Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Tue, 30 Dec 2025 13:03:32 -0800 Subject: [PATCH 04/19] Revert unintended --valid-syntax flag addition to decomp.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This flag was inadvertently included in the grIceMt commit. The upstream melee repo doesn't want this change - the --valid-syntax flag should only be used in the local decomp.me instance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- tools/decomp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/decomp.py b/tools/decomp.py index 6c5ffc287a..37c8b892a2 100755 --- a/tools/decomp.py +++ b/tools/decomp.py @@ -151,7 +151,7 @@ def main() -> None: "-m", "m2c.main", *args.m2c_args, - "--knr", "--pointer", "left", "--valid-syntax", + "--knr", "--pointer", "left", "--target", "ppc-mwcc-c", "--context", From 7d6eb20ee60bf48693569e1b75fee562fcbc8732 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Thu, 1 Jan 2026 18:50:55 -0800 Subject: [PATCH 05/19] Use struct access in grIceMt functions per PR feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses r-burns feedback on PR #2027: - Add padding fields xE8 and xEC to grIceMt_GroundVars for correct offset - Use gp->gv.icemt.xF4[] struct access instead of pointer arithmetic - grIceMt_801F85C4: 99.1% (register allocation diff only) - grIceMt_801F87FC: 99.7% (uses inline assignment for better codegen) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 12 +++++++----- src/melee/gr/types.h | 4 +++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index a2971a8c6d..704f641760 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -628,9 +628,11 @@ bool grIceMt_801F85BC(Ground_GObj* param1) return false; } +/// #grIceMt_801F85C4 void grIceMt_801F85C4(Ground_GObj* gobj) { - grIceMt_801F929C((HSD_GObj*)((u8*)gobj->user_data + 0x108)); + Ground* gp = gobj->user_data; + grIceMt_801F929C((HSD_GObj*)&gp->gv.icemt.xF4[5]); grIceMt_801F98A8(gobj); Ground_801C2FE0(gobj); } @@ -688,14 +690,14 @@ void grIceMt_801F87C8(Ground_GObj* param1) } /// @todo Rename: This is callback3 (destroy) for row 5 in grIm_803E4718. -/// Destroys Item_GObj* stored in icemt.xF4[1-5]. +/// Destroys HSD_GObj* stored in icemt.xF4[1-5]. void grIceMt_801F87FC(Ground_GObj* gobj) { + Ground* gp = gobj->user_data; int i; - Ground* gp = GET_GROUND(gobj); for (i = 0; i < 5; i++) { - HSD_GObj* temp = gp->gv.icemt.xF4[i + 1]; - if (temp != NULL) { + HSD_GObj* temp; + if ((temp = gp->gv.icemt.xF4[i + 1]) != NULL) { grMaterial_801C8CDC(temp); } } diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index b2fca1937d..35eb5ca0a7 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -353,7 +353,9 @@ struct grIceMt_GroundVars { /* +0 gp+D8 */ s16 xDE; /* +0 gp+D8 */ s16 xE0; /* +0 gp+D8 */ f32 xE4; - /// @brief Mixed pointer array: xF4[0] = IceMountainParams*, xF4[1-5] = HSD_GObj*. + /* +0 gp+D8 */ u32 xE8; + /* +0 gp+D8 */ u32 xEC; + /// @brief xF4[0] = IceMountainParams*, xF4[1-5] = HSD_GObj*. /* +0 gp+D8 */ void* xF4[6]; }; struct grIceMt_GroundVars2 { From c2df1681ecc1101774a8657b100e6ee9fc6224ea Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Thu, 1 Jan 2026 19:27:51 -0800 Subject: [PATCH 06/19] refactor(gr): split grIceMt_GroundVars xF4 into separate fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address review feedback: Split void* xF4[6] into IceMountainParams* xF4 and HSD_GObj* xF8[5] for clearer type semantics. Update accessor code in grIceMt_801F85C4, grIceMt_801F87FC, and grIceMt_801F75FC accordingly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 15 ++++++++------- src/melee/gr/types.h | 6 ++++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 704f641760..eb89caeffd 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -348,17 +348,18 @@ void grIceMt_801F75FC(Ground_GObj* arg0) { u32 iVar1; Ground* gp = GET_GROUND(arg0); + void** ptrs = (void**)&gp->gv.icemt.xF4; memzero(&gp->gv.icemt.xDC, 0x18); memzero(&gp->gv.icemt.xF4, 0x14); do { iVar1 = HSD_Randi(6); - } while (gp->gv.icemt.xF4[iVar1] != 0); - gp->gv.icemt.xF4[iVar1] = grIm_804D69F4; + } while (ptrs[iVar1] != 0); + ptrs[iVar1] = grIm_804D69F4; gp->gv.icemt.xC4 = grIm_803E4068[iVar1]; do { iVar1 = HSD_Randi(6); - } while (gp->gv.icemt.xF4[iVar1] != 0); - gp->gv.icemt.xF4[iVar1] = grIm_804D69F4; + } while (ptrs[iVar1] != 0); + ptrs[iVar1] = grIm_804D69F4; // Ground_801C10B8(arg0,fn_801F75EC(arg0));grIm_803E4068 gp->gv.icemt.xC6 = grIm_803E4068[iVar1]; grIceMt_801FA0BC(gp->gv.icemt2.xC4); @@ -632,7 +633,7 @@ bool grIceMt_801F85BC(Ground_GObj* param1) void grIceMt_801F85C4(Ground_GObj* gobj) { Ground* gp = gobj->user_data; - grIceMt_801F929C((HSD_GObj*)&gp->gv.icemt.xF4[5]); + grIceMt_801F929C((HSD_GObj*)&gp->gv.icemt.xF8[4]); grIceMt_801F98A8(gobj); Ground_801C2FE0(gobj); } @@ -690,14 +691,14 @@ void grIceMt_801F87C8(Ground_GObj* param1) } /// @todo Rename: This is callback3 (destroy) for row 5 in grIm_803E4718. -/// Destroys HSD_GObj* stored in icemt.xF4[1-5]. +/// Destroys HSD_GObj* stored in icemt.xF8[0-4]. void grIceMt_801F87FC(Ground_GObj* gobj) { Ground* gp = gobj->user_data; int i; for (i = 0; i < 5; i++) { HSD_GObj* temp; - if ((temp = gp->gv.icemt.xF4[i + 1]) != NULL) { + if ((temp = gp->gv.icemt.xF8[i]) != NULL) { grMaterial_801C8CDC(temp); } } diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index 35eb5ca0a7..0bc43c9ab4 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -12,6 +12,8 @@ #include #include +typedef struct IceMountainParams IceMountainParams; + #include #include @@ -355,8 +357,8 @@ struct grIceMt_GroundVars { /* +0 gp+D8 */ f32 xE4; /* +0 gp+D8 */ u32 xE8; /* +0 gp+D8 */ u32 xEC; - /// @brief xF4[0] = IceMountainParams*, xF4[1-5] = HSD_GObj*. - /* +0 gp+D8 */ void* xF4[6]; + /* +0 gp+D8 */ IceMountainParams* xF4; + /* +0 gp+D8 */ HSD_GObj* xF8[5]; }; struct grIceMt_GroundVars2 { /* +0 gp+C4 */ f32 xC4; From 4e1ab96beff6cb86c7a63284d77987ac5f27d913 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Thu, 1 Jan 2026 20:20:16 -0800 Subject: [PATCH 07/19] fix(gr): correct grIceMt types and add grIceMt_801F75FC improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix xC4/xC6 types from HSD_GObj* to s16 (assembly shows sth/lha) - Add xF0 padding field to align xF4 to correct offset - Define IceMtRowData struct for grIm_803E4068 (12-byte elements) - Improve grIceMt_801F75FC match using s16 pointer arithmetic (75.6%) The xF4 memory area is interpreted as s16 indices during initialization but later treated as pointers by other functions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 41 ++++++++++++++++++++++++++--------------- src/melee/gr/types.h | 5 +++-- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index eb89caeffd..5b30ef3c19 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -64,7 +64,15 @@ HSD_GObj* grIm_804D69EC; HSD_GObj* grIm_804D69F0; IceMountainParams* grIm_804D69F4; -HSD_GObj* grIm_803E4068[6]; // This likely contains the ground segments +/// @brief Ice Mountain row data - 12 bytes each. +/// First field is used both as pointer comparison and as s16 index. +typedef struct IceMtRowData { + HSD_GObj* gobj; // Also sign-extended to s16 when stored to xC4/xC6 + u32 x4; + u32 x8; +} IceMtRowData; + +IceMtRowData grIm_803E4068[6]; S16Vec3 grIm_803E40B0[] = { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 }, { 2, 0, 0 } @@ -137,17 +145,17 @@ void grIceMt_801F686C(void) //} // uVar4 = 0; - if (grIm_804D69F4->xAC == grIm_803E4068[0]) { + if (grIm_804D69F4->xAC == grIm_803E4068[0].gobj) { uVar4 = 1; - if (grIm_804D69F4->xAC == grIm_803E4068[1]) { + if (grIm_804D69F4->xAC == grIm_803E4068[1].gobj) { uVar4 = 2; - if (grIm_804D69F4->xAC == grIm_803E4068[2]) { + if (grIm_804D69F4->xAC == grIm_803E4068[2].gobj) { uVar4 = 3; - if (grIm_804D69F4->xAC == grIm_803E4068[3]) { + if (grIm_804D69F4->xAC == grIm_803E4068[3].gobj) { uVar4 = 4; - if (grIm_804D69F4->xAC == grIm_803E4068[4]) { + if (grIm_804D69F4->xAC == grIm_803E4068[4].gobj) { uVar4 = 5; - if (grIm_804D69F4->xAC == grIm_803E4068[5]) { + if (grIm_804D69F4->xAC == grIm_803E4068[5].gobj) { uVar4 = 6; } } @@ -344,24 +352,27 @@ void fn_801F75EC(HSD_GObj* arg0) } /// #grIceMt_801F75FC +/// @note This function treats xF4 area as s16 indices during initialization. +/// The same memory is later interpreted as pointers by other functions. void grIceMt_801F75FC(Ground_GObj* arg0) { u32 iVar1; + s16 val; Ground* gp = GET_GROUND(arg0); - void** ptrs = (void**)&gp->gv.icemt.xF4; memzero(&gp->gv.icemt.xDC, 0x18); memzero(&gp->gv.icemt.xF4, 0x14); do { iVar1 = HSD_Randi(6); - } while (ptrs[iVar1] != 0); - ptrs[iVar1] = grIm_804D69F4; - gp->gv.icemt.xC4 = grIm_803E4068[iVar1]; + val = *(s16*)((u8*)gp + 0xF4 + iVar1 * 2); + } while (val != 0); + *(s16*)((u8*)gp + 0xF4 + iVar1 * 2) = *(s16*)grIm_804D69F4; + gp->gv.icemt.xC4 = (s16)(s32)grIm_803E4068[iVar1].gobj; do { iVar1 = HSD_Randi(6); - } while (ptrs[iVar1] != 0); - ptrs[iVar1] = grIm_804D69F4; - // Ground_801C10B8(arg0,fn_801F75EC(arg0));grIm_803E4068 - gp->gv.icemt.xC6 = grIm_803E4068[iVar1]; + val = *(s16*)((u8*)gp + 0xF4 + iVar1 * 2); + } while (val != 0); + *(s16*)((u8*)gp + 0xF4 + iVar1 * 2) = *(s16*)grIm_804D69F4; + gp->gv.icemt.xC6 = (s16)(s32)grIm_803E4068[iVar1].gobj; grIceMt_801FA0BC(gp->gv.icemt2.xC4); gp->gv.icemt.xDA = 0; gp->gv.icemt.xC8 = 0; diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index 0bc43c9ab4..fda27f4405 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -340,8 +340,8 @@ struct grGreatBay_GroundVars { }; struct grIceMt_GroundVars { - /* +0 gp+C4 */ HSD_GObj* xC4; - /* +0 gp+C4 */ HSD_GObj* xC6; + /* +0 gp+C4 */ s16 xC4; + /* +0 gp+C4 */ s16 xC6; /* +0 gp+C4 */ s16 xC8; /* +0 gp+C4 */ s16 xCA; /* +0 gp+C4 */ s16 xCC; @@ -357,6 +357,7 @@ struct grIceMt_GroundVars { /* +0 gp+D8 */ f32 xE4; /* +0 gp+D8 */ u32 xE8; /* +0 gp+D8 */ u32 xEC; + /* +0 gp+D8 */ u32 xF0; // padding /* +0 gp+D8 */ IceMountainParams* xF4; /* +0 gp+D8 */ HSD_GObj* xF8[5]; }; From e32bf85d3ee8517d57e2157685426ca77fa831ca Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Thu, 1 Jan 2026 20:25:37 -0800 Subject: [PATCH 08/19] match(gr): improve grIceMt_801F98A8 to 87.6% MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add proper bitfield check at start of function - checks and clears bit 6 of icemt2.xC4 (interpreted as byte flags) before doing cleanup. Uses pointer array for sequential HSD_JObj access. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 5b30ef3c19..5b88a5f503 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -941,28 +941,28 @@ float grIceMt_801F96E0(float y) } /// #grIceMt_801F98A8 -int grIceMt_801F98A8(HSD_GObj* param1) +/// @note Checks bit 6 of icemt2.xC4 (as byte) - clears it and does cleanup. +int grIceMt_801F98A8(Ground_GObj* param1) { - Ground* gp = GET_GROUND(param1); - // gp->x8_callback = NULL; - // gp->xC_callback = NULL; - if (gp->gv.icemt2.xC8) { - Ground_801C2D0C(0, gp->gv.icemt2.xC8); - } - if (gp->gv.icemt2.xCC) { - Ground_801C2D0C(1, gp->gv.icemt2.xCC); - } - if (gp->gv.icemt2.xD0) { - Ground_801C2D0C(2, gp->gv.icemt2.xD0); - } - if (gp->gv.icemt2.xD4) { - Ground_801C2D0C(3, gp->gv.icemt2.xD4); + Ground* gp = param1->user_data; + u8 flags = *(u8*)&gp->gv.icemt2.xC4; + HSD_JObj** ptrs = &gp->gv.icemt2.xC8; + + if (flags & 0x40) { + *(u8*)&gp->gv.icemt2.xC4 = flags & ~0x40; + if (ptrs[0]) { + Ground_801C2D0C(0, ptrs[0]); + } + if (ptrs[1]) { + Ground_801C2D0C(1, ptrs[1]); + } + if (ptrs[2]) { + Ground_801C2D0C(2, ptrs[2]); + } + if (ptrs[3]) { + Ground_801C2D0C(3, ptrs[3]); + } } - - // Ground_801C2D0C(1); - // Ground_801C2D0C(2); - // Ground_801C2D0C(3); - // int bruh = Ground_801C2D0C(1, param1); return 0; } From cd31c30841b8ec43c5b75935178c82a00a6a2d29 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Thu, 1 Jan 2026 20:32:50 -0800 Subject: [PATCH 09/19] fix(gr): move IceMountainParams forward decl to forward.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes typedef-redefinition error by moving the forward declaration to gr/forward.h where other forward declarations live, avoiding conflict with the full definition in gricemt.h. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/forward.h | 1 + src/melee/gr/types.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/melee/gr/forward.h b/src/melee/gr/forward.h index 41cb2f58f7..228fb3cb0e 100644 --- a/src/melee/gr/forward.h +++ b/src/melee/gr/forward.h @@ -7,6 +7,7 @@ struct grCorneria_GroundVars; typedef struct grDynamicAttr_UnkStruct grDynamicAttr_UnkStruct; typedef struct Ground Ground; +typedef struct IceMountainParams IceMountainParams; typedef struct StageInfo StageInfo; typedef struct UnkArchiveStruct UnkArchiveStruct; typedef struct UnkBgmStruct UnkBgmStruct; diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index fda27f4405..ccef6e11d0 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -12,8 +12,6 @@ #include #include -typedef struct IceMountainParams IceMountainParams; - #include #include From 457bb65edb01da80a425e9d1efecc308f810643b Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Thu, 1 Jan 2026 20:39:56 -0800 Subject: [PATCH 10/19] fix(gr): remove typedef from IceMountainParams struct definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The typedef is already in forward.h, so we only need the struct definition here. Having both causes a "typedef redefinition" error in C90/C99 mode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/melee/gr/gricemt.h b/src/melee/gr/gricemt.h index 7b6e2dc652..458bc36854 100644 --- a/src/melee/gr/gricemt.h +++ b/src/melee/gr/gricemt.h @@ -11,7 +11,7 @@ #include -typedef struct IceMountainParams { +struct IceMountainParams { float x0; int x4; float x8; @@ -65,7 +65,7 @@ typedef struct IceMountainParams { float xC4; float xC8; float xCC; -} IceMountainParams; +}; /* 1F6868 */ void grIceMt_801F6868(bool id); /* 1F686C */ void grIceMt_801F686C(void); From b3d393ab15fbfa777bfde0dd4b6de11ff3a844ed Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Fri, 2 Jan 2026 09:47:16 -0800 Subject: [PATCH 11/19] match(gr): match grIceMt_801F8CDC and fix header signatures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Match grIceMt_801F8CDC to 93.4% (material item creation for Ice Mountain) - Fix header signature mismatches for void-returning functions - Define const floats locally instead of extern declarations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 65 ++++++++++++++++++++++++++++++++++++++++-- src/melee/gr/gricemt.h | 29 ++++++++++--------- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 5b88a5f503..6be4d11c97 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -8,6 +8,7 @@ #include "baselib/random.h" #include "cm/camera.h" #include "ef/efsync.h" +#include "gr/grdatfiles.h" #include "gr/grdisplay.h" #include "gr/grlib.h" #include "gr/grmaterial.h" @@ -22,6 +23,7 @@ #include "lb/lb_00B0.h" #include "mp/mplib.h" +#include #include #include @@ -116,7 +118,10 @@ StageData grIm_803E4800 = { 3, }; -const float grIm_804DB574 = 0.0; +const float grIm_804DB574 = 0.0F; +const float grIm_804DB5B0 = -1.0F; +const float grIm_804DB5B4 = 1.0F; +const float grIm_804DB5B8 = 6.0F; void grIceMt_801F6868(bool id) {} @@ -813,7 +818,63 @@ void fn_801F8C64(Item_GObj* gobj, Ground* u1, Vec3* u2, HSD_GObj* u3, f32 u4) Camera_80030E44(2, &pos); } -/// #grIceMt_801F8CDC +/// @brief Creates material items and attaches them to Entity05 platform JObjs. +/// @param gobj The Entity05 Ground_GObj +/// @param joint_indices Array of joint indices to get parent JObjs from +/// @param count Number of items to create (max 20) +/// @param output_array Array to store created Item_GObj pointers +void grIceMt_801F8CDC(Ground_GObj* gobj, s16* joint_indices, int count, + HSD_GObj** output_array) +{ + Ground* gp = gobj->user_data; + UnkArchiveStruct* archive; + void* jobj_desc; + HSD_JObj* parent_jobjs[20]; + HSD_JObj* parent_jobj; + HSD_JObj* child_jobj; + Item_GObj* item; + int i; + u8 unused[24]; + + archive = grDatFiles_801C6324(); + jobj_desc = M2C_FIELD(archive->unk4->unk8, void**, 0x16C); + + if (count > 20) { + __assert((char*) grIm_803E4068 + 0x690, 0x7D4, + (char*) grIm_803E4068 + 0x7F0); + } + + for (i = 0; i < count; i++) { + parent_jobjs[i] = Ground_801C3FA4(gobj, joint_indices[i]); + } + + for (i = 0; i < count; i++) { + parent_jobj = parent_jobjs[i]; + if (parent_jobj == NULL) { + __assert((char*) grIm_803E4068 + 0x690, 0x7E3, + (char*) grIm_803E4068 + 0x810); + } + + child_jobj = HSD_JObjLoadJoint(jobj_desc); + if (child_jobj == NULL) { + __assert((char*) grIm_803E4068 + 0x690, 0x7E6, + (char*) grIm_803E4068 + 0x81C); + } + + HSD_JObjAddChild(parent_jobj, child_jobj); + + item = grMaterial_801C8CFC(8, 0, gp, parent_jobj, NULL, fn_801F8C64, + NULL); + if (item != NULL) { + grMaterial_801C8DE0(item, grIm_804DB574, grIm_804DB5B0, + grIm_804DB574, grIm_804DB574, grIm_804DB5B4, + grIm_804DB574, grIm_804DB5B8); + grMaterial_801C8E08(item); + grMaterial_801C8E68(item, 0); + } + output_array[i] = item; + } +} /// #fn_801F8E58 diff --git a/src/melee/gr/gricemt.h b/src/melee/gr/gricemt.h index 458bc36854..73a29d868b 100644 --- a/src/melee/gr/gricemt.h +++ b/src/melee/gr/gricemt.h @@ -116,34 +116,35 @@ struct IceMountainParams { /* 1F8B10 */ void grIceMt_801F8B10(Ground_GObj*); /* 1F8C60 */ void grIceMt_801F8C60(Ground_GObj*); /* 1F8C64 */ // void fn_801F8C64(Item_GObj*, Ground*, Vec3*, HSD_GObj*, f32); -/* 1F8CDC */ UNK_RET grIceMt_801F8CDC(Ground_GObj*); +/* 1F8CDC */ void grIceMt_801F8CDC(Ground_GObj*, s16* joint_indices, int count, + HSD_GObj** output_array); /* 1F8E58 */ UNK_RET fn_801F8E58(Ground_GObj*); /* 1F9038 */ UNK_RET fn_801F9038(Ground_GObj*); /* 1F9150 */ IceMountainParams* fn_801F9150(HSD_GObj*); -/* 1F91A4 */ void fn_801F91A4(UNK_PARAMS); +/* 1F91A4 */ void fn_801F91A4(void); /* 1F91A8 */ HSD_GObj* fn_801F91A8(HSD_GObj*); /* 1F91EC */ UNK_RET grIceMt_801F91EC(HSD_GObj*); -/* 1F929C */ UNK_RET grIceMt_801F929C(HSD_GObj* arg0); -/* 1F9338 */ UNK_RET fn_801F9338(Ground*, int, CollData*, s32, - mpLib_GroundEnum, float); -/* 1F9448 */ UNK_RET fn_801F9448(Ground*, int, CollData*, s32, - mpLib_GroundEnum, float); -/* 1F9558 */ UNK_RET fn_801F9558(Ground*, int, CollData*, s32, - mpLib_GroundEnum, float); +/* 1F929C */ void grIceMt_801F929C(HSD_GObj* arg0); +/* 1F9338 */ void fn_801F9338(Ground*, int, CollData*, s32, mpLib_GroundEnum, + float); +/* 1F9448 */ void fn_801F9448(Ground*, int, CollData*, s32, mpLib_GroundEnum, + float); +/* 1F9558 */ void fn_801F9558(Ground*, int, CollData*, s32, mpLib_GroundEnum, + float); /* 1F9668 */ void grIceMt_801F9668(float); /* 1F96E0 */ float grIceMt_801F96E0(float); /* 1F98A8 */ bool grIceMt_801F98A8(HSD_GObj* param1); /* 1F993C */ UNK_RET grIceMt_801F993C(UNK_PARAMS); -/* 1F9ACC */ UNK_RET grIceMt_801F9ACC(float); +/* 1F9ACC */ void grIceMt_801F9ACC(float); /* 1FA0BC */ UNK_RET grIceMt_801FA0BC(int); /* 1FA364 */ void grIceMt_801FA364(UNK_T, float*, HSD_GObjEvent, Ground_GObj*); /* 1FA4CC */ int fn_801FA4CC(int num); /* 1FA500 */ int grIceMt_801FA500(HSD_GObj*); -/* 1FA6D8 */ UNK_RET grIceMt_801FA6D8(Ground_GObj*); +/* 1FA6D8 */ void grIceMt_801FA6D8(HSD_GObj*); /* 1FA728 */ void grIceMt_801FA728(Vec3*); -/* 1FA7F0 */ UNK_RET grIceMt_801FA7F0(Ground*, s32, CollData*, s32, - mpLib_GroundEnum, float); -/* 1FA854 */ UNK_RET grIceMt_801FA854(void); +/* 1FA7F0 */ void grIceMt_801FA7F0(Ground*, s32, CollData*, s32, + mpLib_GroundEnum, float); +/* 1FA854 */ void grIceMt_801FA854(void); /* 1FA8F8 */ DynamicsDesc* grIceMt_801FA8F8(enum_t id); /* 1FA900 */ bool grIceMt_801FA900(Vec3* a, int id, HSD_JObj* jobj); From 6b6d088a32ce4f666b89d5633a73546222e1416c Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Thu, 1 Jan 2026 18:44:40 -0800 Subject: [PATCH 12/19] Match grIceMt_801F85C4 and grIceMt_801F87FC with struct access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add padding fields xE8 and xEC to grIceMt_GroundVars to fix struct offset - Use proper struct access gp->gv.icemt.xF4[] instead of pointer arithmetic - grIceMt_801F85C4: 99.1% (register allocation diff only) - grIceMt_801F87FC: 99.7% (uses inline assignment for better codegen) Addresses r-burns feedback on PR #2027. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 6 +++--- src/melee/gr/types.h | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 6be4d11c97..eef7b3945f 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -649,7 +649,7 @@ bool grIceMt_801F85BC(Ground_GObj* param1) void grIceMt_801F85C4(Ground_GObj* gobj) { Ground* gp = gobj->user_data; - grIceMt_801F929C((HSD_GObj*)&gp->gv.icemt.xF8[4]); + grIceMt_801F929C((HSD_GObj*)&gp->gv.icemt.xF4[5]); grIceMt_801F98A8(gobj); Ground_801C2FE0(gobj); } @@ -707,14 +707,14 @@ void grIceMt_801F87C8(Ground_GObj* param1) } /// @todo Rename: This is callback3 (destroy) for row 5 in grIm_803E4718. -/// Destroys HSD_GObj* stored in icemt.xF8[0-4]. +/// Destroys HSD_GObj* stored in icemt.xF4[1-5]. void grIceMt_801F87FC(Ground_GObj* gobj) { Ground* gp = gobj->user_data; int i; for (i = 0; i < 5; i++) { HSD_GObj* temp; - if ((temp = gp->gv.icemt.xF8[i]) != NULL) { + if ((temp = gp->gv.icemt.xF4[i + 1]) != NULL) { grMaterial_801C8CDC(temp); } } diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index 107d8fb791..38ef370f15 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -367,9 +367,8 @@ struct grIceMt_GroundVars { /* +0 gp+D8 */ f32 xE4; /* +0 gp+D8 */ u32 xE8; /* +0 gp+D8 */ u32 xEC; - /* +0 gp+D8 */ u32 xF0; // padding - /* +0 gp+D8 */ IceMountainParams* xF4; - /* +0 gp+D8 */ HSD_GObj* xF8[5]; + /// @brief xF4[0] = IceMountainParams*, xF4[1-5] = HSD_GObj*. + /* +0 gp+D8 */ void* xF4[6]; }; struct grIceMt_GroundVars2 { /* +0 gp+C4 */ f32 xC4; From 030165078194a7d6bf678a92661985e4390111b9 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Fri, 2 Jan 2026 11:00:29 -0800 Subject: [PATCH 13/19] fix(gr): restore correct grIceMt_GroundVars struct layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cherry-pick of 401daef57 inadvertently reverted the struct changes from 4e1ab96be. Restore the correct layout: - Add u32 xF0 padding field - Split void* xF4[6] into IceMountainParams* xF4 + HSD_GObj* xF8[5] Update function code to use xF8[i] instead of xF4[i+1]. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 6 +++--- src/melee/gr/types.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index eef7b3945f..aed6e93cd7 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -649,7 +649,7 @@ bool grIceMt_801F85BC(Ground_GObj* param1) void grIceMt_801F85C4(Ground_GObj* gobj) { Ground* gp = gobj->user_data; - grIceMt_801F929C((HSD_GObj*)&gp->gv.icemt.xF4[5]); + grIceMt_801F929C((HSD_GObj*) &gp->gv.icemt.xF8[4]); grIceMt_801F98A8(gobj); Ground_801C2FE0(gobj); } @@ -707,14 +707,14 @@ void grIceMt_801F87C8(Ground_GObj* param1) } /// @todo Rename: This is callback3 (destroy) for row 5 in grIm_803E4718. -/// Destroys HSD_GObj* stored in icemt.xF4[1-5]. +/// Destroys HSD_GObj* stored in icemt.xF8[0-4]. void grIceMt_801F87FC(Ground_GObj* gobj) { Ground* gp = gobj->user_data; int i; for (i = 0; i < 5; i++) { HSD_GObj* temp; - if ((temp = gp->gv.icemt.xF4[i + 1]) != NULL) { + if ((temp = gp->gv.icemt.xF8[i]) != NULL) { grMaterial_801C8CDC(temp); } } diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index 38ef370f15..107d8fb791 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -367,8 +367,9 @@ struct grIceMt_GroundVars { /* +0 gp+D8 */ f32 xE4; /* +0 gp+D8 */ u32 xE8; /* +0 gp+D8 */ u32 xEC; - /// @brief xF4[0] = IceMountainParams*, xF4[1-5] = HSD_GObj*. - /* +0 gp+D8 */ void* xF4[6]; + /* +0 gp+D8 */ u32 xF0; // padding + /* +0 gp+D8 */ IceMountainParams* xF4; + /* +0 gp+D8 */ HSD_GObj* xF8[5]; }; struct grIceMt_GroundVars2 { /* +0 gp+C4 */ f32 xC4; From 5925780ba4ab23776c8abe2e2e8b00e91676e181 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Fri, 2 Jan 2026 11:10:35 -0800 Subject: [PATCH 14/19] match(gr): improve grIceMt_801F785C to 99.8% and fix grIceMt_801FA0BC calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Implement grIceMt_801F785C using struct access where possible - Use M2C_FIELD macro for xAC offset access - Fix grIceMt_801FA0BC calls to pass address instead of value - Both grIceMt_801F75FC and grIceMt_801F785C now use (int)&gp->gv.icemt.xC4 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 34 +++++++++++++++++++++++++--------- src/melee/gr/types.h | 2 +- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index aed6e93cd7..e76b90cbb5 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -378,7 +378,7 @@ void grIceMt_801F75FC(Ground_GObj* arg0) } while (val != 0); *(s16*)((u8*)gp + 0xF4 + iVar1 * 2) = *(s16*)grIm_804D69F4; gp->gv.icemt.xC6 = (s16)(s32)grIm_803E4068[iVar1].gobj; - grIceMt_801FA0BC(gp->gv.icemt2.xC4); + grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); gp->gv.icemt.xDA = 0; gp->gv.icemt.xC8 = 0; gp->gv.icemt.xCE = 0; @@ -419,24 +419,40 @@ void fn_801F77B0(HSD_GObj* arg0) mpJointSetCb1(4, gp, grIceMt_801FA7F0); } -void grIceMt_801F785C(Ground_GObj* arg0) +/// #grIceMt_801F785C +void grIceMt_801F785C(Ground_GObj* gobj) { - Ground* gp = GET_GROUND(arg0); + Ground* gp = GET_GROUND(gobj); + + // Index into grIm_803E4068 using s16 values from grIm_804D69F4->xAC + gp->gv.icemt.xC4 = + (s16) (s32) grIm_803E4068[M2C_FIELD(grIm_804D69F4->xAC, s16*, 2)].gobj; + gp->gv.icemt.xC6 = + (s16) (s32) grIm_803E4068[M2C_FIELD(grIm_804D69F4->xAC, s16*, 0)].gobj; + + grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); + gp->gv.icemt.xDC = 0; - // gp->gv.icemt.xE0 = 2; + gp->gv.icemt.xE0 = 2; gp->gv.icemt.xDE = 0; - gp->gv.icemt.xDA = 0; - gp->gv.icemt.xE4 = 0.0; + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b1 = 0; + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b2 = 0; + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b3 = 0; + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b4 = 0; + gp->gv.icemt.xDA = 0; + gp->gv.icemt.xE4 = grIm_804DB574; gp->gv.icemt.xC8 = 0; gp->gv.icemt.xCE = 0; gp->gv.icemt.xCA = 0; gp->gv.icemt.xCC = 0; - gp->gv.icemt.xD0 = NULL; + gp->gv.icemt.xD0 = -1; gp->gv.icemt.xD4 = grIm_804DB574; - // gp->gv.icemt.xD8 = 1; - Ground_801C10B8(arg0, fn_801F77B0); + + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b7 = 1; + + Ground_801C10B8(gobj, fn_801F77B0); } /// #grIceMt_801F796C gricemt.c diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index 107d8fb791..fe100e4bf5 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -367,7 +367,7 @@ struct grIceMt_GroundVars { /* +0 gp+D8 */ f32 xE4; /* +0 gp+D8 */ u32 xE8; /* +0 gp+D8 */ u32 xEC; - /* +0 gp+D8 */ u32 xF0; // padding + /* +0 gp+D8 */ u32 xF0; // padding /* +0 gp+D8 */ IceMountainParams* xF4; /* +0 gp+D8 */ HSD_GObj* xF8[5]; }; From c6aff573e4e1a92166b40e7bd914c4e4dacd5e5a Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Fri, 2 Jan 2026 11:22:50 -0800 Subject: [PATCH 15/19] fix(gr): correct types for IceMountainParams.xAC and IceMtRowData MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on assembly analysis: - Change IceMountainParams.xAC from HSD_GObj* to s16* (array of row indices) - Change IceMtRowData.gobj to IceMtRowData.id (s32 identifier) - Update grIceMt_801F785C to use xAC[0]/xAC[1] array access - Fix fn_801F91A8 to properly read xAC[gp->xE0] (80% match, was 10.6%) - Remove M2C_FIELD usage now that types are correct 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 40 ++++++++++++++++++++-------------------- src/melee/gr/gricemt.h | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index e76b90cbb5..cccb599bae 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -67,9 +67,8 @@ HSD_GObj* grIm_804D69F0; IceMountainParams* grIm_804D69F4; /// @brief Ice Mountain row data - 12 bytes each. -/// First field is used both as pointer comparison and as s16 index. typedef struct IceMtRowData { - HSD_GObj* gobj; // Also sign-extended to s16 when stored to xC4/xC6 + s32 id; // Row identifier, compared with xAC[i] values u32 x4; u32 x8; } IceMtRowData; @@ -149,18 +148,18 @@ void grIceMt_801F686C(void) // grIm_803E4068[uVar4]); uVar4++) { //} - // uVar4 = 0; - if (grIm_804D69F4->xAC == grIm_803E4068[0].gobj) { + // TODO: Assembly shows checking both xAC[0] and xAC[1] against each id + if (grIm_804D69F4->xAC[0] == grIm_803E4068[0].id) { uVar4 = 1; - if (grIm_804D69F4->xAC == grIm_803E4068[1].gobj) { + if (grIm_804D69F4->xAC[0] == grIm_803E4068[1].id) { uVar4 = 2; - if (grIm_804D69F4->xAC == grIm_803E4068[2].gobj) { + if (grIm_804D69F4->xAC[0] == grIm_803E4068[2].id) { uVar4 = 3; - if (grIm_804D69F4->xAC == grIm_803E4068[3].gobj) { + if (grIm_804D69F4->xAC[0] == grIm_803E4068[3].id) { uVar4 = 4; - if (grIm_804D69F4->xAC == grIm_803E4068[4].gobj) { + if (grIm_804D69F4->xAC[0] == grIm_803E4068[4].id) { uVar4 = 5; - if (grIm_804D69F4->xAC == grIm_803E4068[5].gobj) { + if (grIm_804D69F4->xAC[0] == grIm_803E4068[5].id) { uVar4 = 6; } } @@ -371,13 +370,13 @@ void grIceMt_801F75FC(Ground_GObj* arg0) val = *(s16*)((u8*)gp + 0xF4 + iVar1 * 2); } while (val != 0); *(s16*)((u8*)gp + 0xF4 + iVar1 * 2) = *(s16*)grIm_804D69F4; - gp->gv.icemt.xC4 = (s16)(s32)grIm_803E4068[iVar1].gobj; + gp->gv.icemt.xC4 = (s16)grIm_803E4068[iVar1].id; do { iVar1 = HSD_Randi(6); val = *(s16*)((u8*)gp + 0xF4 + iVar1 * 2); } while (val != 0); *(s16*)((u8*)gp + 0xF4 + iVar1 * 2) = *(s16*)grIm_804D69F4; - gp->gv.icemt.xC6 = (s16)(s32)grIm_803E4068[iVar1].gobj; + gp->gv.icemt.xC6 = (s16)grIm_803E4068[iVar1].id; grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); gp->gv.icemt.xDA = 0; gp->gv.icemt.xC8 = 0; @@ -424,11 +423,9 @@ void grIceMt_801F785C(Ground_GObj* gobj) { Ground* gp = GET_GROUND(gobj); - // Index into grIm_803E4068 using s16 values from grIm_804D69F4->xAC - gp->gv.icemt.xC4 = - (s16) (s32) grIm_803E4068[M2C_FIELD(grIm_804D69F4->xAC, s16*, 2)].gobj; - gp->gv.icemt.xC6 = - (s16) (s32) grIm_803E4068[M2C_FIELD(grIm_804D69F4->xAC, s16*, 0)].gobj; + // Index into grIm_803E4068 using row indices from grIm_804D69F4->xAC + gp->gv.icemt.xC4 = (s16)grIm_803E4068[grIm_804D69F4->xAC[1]].id; + gp->gv.icemt.xC6 = (s16)grIm_803E4068[grIm_804D69F4->xAC[0]].id; grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); @@ -905,12 +902,15 @@ IceMountainParams* fn_801F9150(HSD_GObj* arg0) void fn_801F91A4(void) {} /// #fn_801F91A8 grIm_804D69F4 +/// @todo This function reads xAC[gp->xE0] and returns grIm_803E4068[index].id HSD_GObj* fn_801F91A8(HSD_GObj* arg0) { - HSD_GObj* iVar2 = grIm_804D69F4->xAC; - // if (iVar2 != -1) { - return iVar2; - //} + Ground* gp = GET_GROUND(arg0); + s16 index = grIm_804D69F4->xAC[gp->gv.icemt.xE0]; + if (index == -1) { + return (HSD_GObj*)index; + } + return (HSD_GObj*)grIm_803E4068[index].id; } /// #grIceMt_801F91EC diff --git a/src/melee/gr/gricemt.h b/src/melee/gr/gricemt.h index 73a29d868b..615bdfd4fe 100644 --- a/src/melee/gr/gricemt.h +++ b/src/melee/gr/gricemt.h @@ -56,7 +56,7 @@ struct IceMountainParams { float xA0; float xA4; float xA8; - HSD_GObj* xAC; + s16* xAC; float xB0; float xB4; s16 xB8; From 823dc2bd528ba1224e432f21d1af8952df21b3e4 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Fri, 2 Jan 2026 14:24:22 -0800 Subject: [PATCH 16/19] match(gr): improve grIceMt_801F686C to 94.98% MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add missing 4th call to grIceMt_801F993C using field28 - Fix y_pos accumulation pattern to match target - Update grIceMt_801F993C signature from UNK_PARAMS to (s32, s32) -> f32 - Remove volatile/void workaround for field28 since it's now used - Move grIm_804DB570 extern to header 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 174 ++++++++++++++++++++++++++++++----------- src/melee/gr/gricemt.h | 4 +- 2 files changed, 131 insertions(+), 47 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index cccb599bae..57b07d049c 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -68,7 +68,7 @@ IceMountainParams* grIm_804D69F4; /// @brief Ice Mountain row data - 12 bytes each. typedef struct IceMtRowData { - s32 id; // Row identifier, compared with xAC[i] values + s32 id; // Row identifier, compared with xAC[i] values u32 x4; u32 x8; } IceMtRowData; @@ -124,13 +124,24 @@ const float grIm_804DB5B8 = 6.0F; void grIceMt_801F6868(bool id) {} +#define ICEMT_FIELD_MAX 6 + /// #grIceMt_801F686C void grIceMt_801F686C(void) { - int iVar3; - u32 uVar4; - f32 dVar6; - f32 dVar7; + s32 field30; + s32 field29; + s32 field28; + u32 row_idx; + s16* xAC; + s32 id; + f32 y_pos; + f32 y_pos2; + f32 y_pos3; + f32 y_pos4; + HSD_GObj* gobj; + HSD_JObj* jobj; + grIm_804D69F4 = Ground_801C49F8(); stage_info.unk8C.b4 = true; stage_info.unk8C.b5 = false; @@ -142,47 +153,117 @@ void grIceMt_801F686C(void) Ground_801C3260(4); Ground_801C3260(5); Ground_801C3260(6); - iVar3 = Stage_80225194(); - if (iVar3 == 76) { // adventure mode - // foreach (uVar4 = 0; (uVar4 < 7) && (grIm_804D69F4->xAC == - // grIm_803E4068[uVar4]); uVar4++) { - //} - // TODO: Assembly shows checking both xAC[0] and xAC[1] against each id - if (grIm_804D69F4->xAC[0] == grIm_803E4068[0].id) { - uVar4 = 1; - if (grIm_804D69F4->xAC[0] == grIm_803E4068[1].id) { - uVar4 = 2; - if (grIm_804D69F4->xAC[0] == grIm_803E4068[2].id) { - uVar4 = 3; - if (grIm_804D69F4->xAC[0] == grIm_803E4068[3].id) { - uVar4 = 4; - if (grIm_804D69F4->xAC[0] == grIm_803E4068[4].id) { - uVar4 = 5; - if (grIm_804D69F4->xAC[0] == grIm_803E4068[5].id) { - uVar4 = 6; - } - } - } - } + if (Stage_80225194() == 76) { + // First loop: find row where neither xAC[0] nor xAC[1] matches + for (row_idx = 0; row_idx < ICEMT_FIELD_MAX; row_idx++) { + xAC = grIm_804D69F4->xAC; + id = grIm_803E4068[row_idx].id; + if (xAC[0] == id) { + continue; + } + if (xAC[1] == id) { + continue; + } + field30 = grIm_803E4068[row_idx].id; + break; + } + if (row_idx >= ICEMT_FIELD_MAX) { + __assert("gricemt.c", 0x258, ""); + } + + // Second loop: find row where xAC[0], xAC[1], and field30 don't match + for (row_idx = 0; row_idx < ICEMT_FIELD_MAX; row_idx++) { + xAC = grIm_804D69F4->xAC; + id = grIm_803E4068[row_idx].id; + if (xAC[0] == id) { + continue; + } + if (xAC[1] == id) { + continue; } + if (field30 == id) { + continue; + } + field29 = grIm_803E4068[row_idx].id; + break; + } + if (row_idx >= ICEMT_FIELD_MAX) { + __assert("gricemt.c", 0x261, ""); } - if (5 < uVar4) { - __assert("gricemt.c", 600, ""); + + // Third loop: find row where xAC[0], xAC[1], field30, and field29 + // don't match + for (row_idx = 0; row_idx < ICEMT_FIELD_MAX; row_idx++) { + xAC = grIm_804D69F4->xAC; + id = grIm_803E4068[row_idx].id; + if (xAC[0] == id) { + continue; + } + if (xAC[1] == id) { + continue; + } + if (field30 == id) { + continue; + } + if (field29 == id) { + continue; + } + field28 = grIm_803E4068[row_idx].id; + break; } - uVar4 = 0; - if (5 < uVar4) { + if (row_idx >= ICEMT_FIELD_MAX) { __assert("gricemt.c", 0x26B, ""); } - __assert("gricemt.c", 0xA37, "bg_gobj"); - __assert("gricemt.c", 0xA37, "bg_gobj"); - __assert("gricemt.c", 0xA37, "bg_gobj"); - __assert("gricemt.c", 0xA37, "bg_gobj"); - __assert("gricemt.c", 0xA37, "bg_gobj"); - dVar6 = Ground_801C0498(); - dVar7 = -20.0 * dVar6; - // dVar6 = grIceMt_801F993C(); - } else { // melee mode + + // Calculate Y positions for the 3 topi platforms + y_pos = Ground_801C0498(); + xAC = grIm_804D69F4->xAC; + y_pos = grIm_804DB570 * y_pos; + y_pos = y_pos + grIceMt_801F993C(grIm_803E4068[xAC[0]].id, + grIm_803E4068[xAC[1]].id); + y_pos2 = y_pos + grIceMt_801F993C(grIm_803E4068[xAC[1]].id, field30); + y_pos3 = y_pos2 + grIceMt_801F993C(field30, field29); + y_pos4 = y_pos3 + grIceMt_801F993C(field29, field28); + + // Set up first topi (grIm_804D69E8) + gobj = grIceMt_801F71E8(grIm_803E4068[xAC[2]].id); + if (gobj == NULL) { + __assert("gricemt.c", 0x27C, "bg_gobj"); + } + jobj = gobj->hsd_obj; + if (jobj == NULL) { + __assert("gricemt.c", 0x27D, "jobj"); + } + HSD_JObjSetTranslateY(jobj, y_pos2); + grIm_804D69E8 = gobj; + + // Set up second topi (grIm_804D69EC) + gobj = grIceMt_801F71E8(grIm_803E4068[xAC[3]].id); + if (gobj == NULL) { + __assert("gricemt.c", 0x281, "bg_gobj"); + } + jobj = gobj->hsd_obj; + if (jobj == NULL) { + __assert("gricemt.c", 0x282, "jobj"); + } + HSD_JObjSetTranslateY(jobj, y_pos3); + grIm_804D69EC = gobj; + + // Set up third topi (grIm_804D69F0) + gobj = grIceMt_801F71E8(grIm_803E4068[xAC[4]].id); + if (gobj == NULL) { + __assert("gricemt.c", 0x286, "bg_gobj"); + } + jobj = gobj->hsd_obj; + if (jobj == NULL) { + __assert("gricemt.c", 0x287, "jobj"); + } + HSD_JObjSetTranslateY(jobj, y_pos4); + grIm_804D69F0 = gobj; + + grIceMt_801F71E8(0xA); + } else { grIceMt_801F71E8(9); grIm_804D69E8 = NULL; grIm_804D69EC = NULL; @@ -191,6 +272,7 @@ void grIceMt_801F686C(void) Ground_801C39C0(); Ground_801C3BB4(); } + void grIceMt_801F7080(void) { // Ground_801C2BA4(5); @@ -370,13 +452,13 @@ void grIceMt_801F75FC(Ground_GObj* arg0) val = *(s16*)((u8*)gp + 0xF4 + iVar1 * 2); } while (val != 0); *(s16*)((u8*)gp + 0xF4 + iVar1 * 2) = *(s16*)grIm_804D69F4; - gp->gv.icemt.xC4 = (s16)grIm_803E4068[iVar1].id; + gp->gv.icemt.xC4 = (s16) grIm_803E4068[iVar1].id; do { iVar1 = HSD_Randi(6); val = *(s16*)((u8*)gp + 0xF4 + iVar1 * 2); } while (val != 0); *(s16*)((u8*)gp + 0xF4 + iVar1 * 2) = *(s16*)grIm_804D69F4; - gp->gv.icemt.xC6 = (s16)grIm_803E4068[iVar1].id; + gp->gv.icemt.xC6 = (s16) grIm_803E4068[iVar1].id; grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); gp->gv.icemt.xDA = 0; gp->gv.icemt.xC8 = 0; @@ -424,8 +506,8 @@ void grIceMt_801F785C(Ground_GObj* gobj) Ground* gp = GET_GROUND(gobj); // Index into grIm_803E4068 using row indices from grIm_804D69F4->xAC - gp->gv.icemt.xC4 = (s16)grIm_803E4068[grIm_804D69F4->xAC[1]].id; - gp->gv.icemt.xC6 = (s16)grIm_803E4068[grIm_804D69F4->xAC[0]].id; + gp->gv.icemt.xC4 = (s16) grIm_803E4068[grIm_804D69F4->xAC[1]].id; + gp->gv.icemt.xC6 = (s16) grIm_803E4068[grIm_804D69F4->xAC[0]].id; grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); @@ -908,9 +990,9 @@ HSD_GObj* fn_801F91A8(HSD_GObj* arg0) Ground* gp = GET_GROUND(arg0); s16 index = grIm_804D69F4->xAC[gp->gv.icemt.xE0]; if (index == -1) { - return (HSD_GObj*)index; + return (HSD_GObj*) index; } - return (HSD_GObj*)grIm_803E4068[index].id; + return (HSD_GObj*) grIm_803E4068[index].id; } /// #grIceMt_801F91EC diff --git a/src/melee/gr/gricemt.h b/src/melee/gr/gricemt.h index 615bdfd4fe..481cf0f721 100644 --- a/src/melee/gr/gricemt.h +++ b/src/melee/gr/gricemt.h @@ -67,6 +67,8 @@ struct IceMountainParams { float xCC; }; +extern f32 grIm_804DB570; + /* 1F6868 */ void grIceMt_801F6868(bool id); /* 1F686C */ void grIceMt_801F686C(void); /* 1F7080 */ void grIceMt_801F7080(void); @@ -134,7 +136,7 @@ struct IceMountainParams { /* 1F9668 */ void grIceMt_801F9668(float); /* 1F96E0 */ float grIceMt_801F96E0(float); /* 1F98A8 */ bool grIceMt_801F98A8(HSD_GObj* param1); -/* 1F993C */ UNK_RET grIceMt_801F993C(UNK_PARAMS); +/* 1F993C */ f32 grIceMt_801F993C(s32, s32); /* 1F9ACC */ void grIceMt_801F9ACC(float); /* 1FA0BC */ UNK_RET grIceMt_801FA0BC(int); /* 1FA364 */ void grIceMt_801FA364(UNK_T, float*, HSD_GObjEvent, Ground_GObj*); From 1e4bd56dbaaf91ecdb2762bcd166de48b967fbb8 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Fri, 2 Jan 2026 15:45:28 -0800 Subject: [PATCH 17/19] fix(gr): correct xF4 type from pointer to s16 array in grIceMt_GroundVars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The xF4 field was incorrectly typed as IceMountainParams* but is never dereferenced as a pointer. Analysis shows it's used as an s16 array for slot initialization, with indices 0-5 overflowing into adjacent xF8. Changes: - types.h: IceMountainParams* xF4 -> s16 xF4[2] - gricemt.c: Replace pointer arithmetic with clean array access grIceMt_801F75FC now matches at 99.9% (was 89.2% with pointer arithmetic). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 8 ++++---- src/melee/gr/types.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 57b07d049c..9dfd8efe70 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -449,15 +449,15 @@ void grIceMt_801F75FC(Ground_GObj* arg0) memzero(&gp->gv.icemt.xF4, 0x14); do { iVar1 = HSD_Randi(6); - val = *(s16*)((u8*)gp + 0xF4 + iVar1 * 2); + val = gp->gv.icemt.xF4[iVar1]; } while (val != 0); - *(s16*)((u8*)gp + 0xF4 + iVar1 * 2) = *(s16*)grIm_804D69F4; + gp->gv.icemt.xF4[iVar1] = *(s16*)grIm_804D69F4; gp->gv.icemt.xC4 = (s16) grIm_803E4068[iVar1].id; do { iVar1 = HSD_Randi(6); - val = *(s16*)((u8*)gp + 0xF4 + iVar1 * 2); + val = gp->gv.icemt.xF4[iVar1]; } while (val != 0); - *(s16*)((u8*)gp + 0xF4 + iVar1 * 2) = *(s16*)grIm_804D69F4; + gp->gv.icemt.xF4[iVar1] = *(s16*)grIm_804D69F4; gp->gv.icemt.xC6 = (s16) grIm_803E4068[iVar1].id; grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); gp->gv.icemt.xDA = 0; diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index fe100e4bf5..857c36898f 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -368,7 +368,7 @@ struct grIceMt_GroundVars { /* +0 gp+D8 */ u32 xE8; /* +0 gp+D8 */ u32 xEC; /* +0 gp+D8 */ u32 xF0; // padding - /* +0 gp+D8 */ IceMountainParams* xF4; + /* +0 gp+D8 */ s16 xF4[2]; /* +0 gp+D8 */ HSD_GObj* xF8[5]; }; struct grIceMt_GroundVars2 { From a095474a4d49e5cecc650eeac5b3ceacda961a27 Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Fri, 2 Jan 2026 15:54:06 -0800 Subject: [PATCH 18/19] fix(gr): cast s16 through s32 to avoid int-to-pointer-cast warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function returns -1 as a sentinel pointer value. Cast through s32 (same size as pointer) to avoid -Wint-to-pointer-cast warning while preserving the correct return value. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 9dfd8efe70..cb8d65acf2 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -451,13 +451,13 @@ void grIceMt_801F75FC(Ground_GObj* arg0) iVar1 = HSD_Randi(6); val = gp->gv.icemt.xF4[iVar1]; } while (val != 0); - gp->gv.icemt.xF4[iVar1] = *(s16*)grIm_804D69F4; + gp->gv.icemt.xF4[iVar1] = *(s16*) grIm_804D69F4; gp->gv.icemt.xC4 = (s16) grIm_803E4068[iVar1].id; do { iVar1 = HSD_Randi(6); val = gp->gv.icemt.xF4[iVar1]; } while (val != 0); - gp->gv.icemt.xF4[iVar1] = *(s16*)grIm_804D69F4; + gp->gv.icemt.xF4[iVar1] = *(s16*) grIm_804D69F4; gp->gv.icemt.xC6 = (s16) grIm_803E4068[iVar1].id; grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); gp->gv.icemt.xDA = 0; @@ -990,7 +990,7 @@ HSD_GObj* fn_801F91A8(HSD_GObj* arg0) Ground* gp = GET_GROUND(arg0); s16 index = grIm_804D69F4->xAC[gp->gv.icemt.xE0]; if (index == -1) { - return (HSD_GObj*) index; + return (HSD_GObj*) (s32) index; } return (HSD_GObj*) grIm_803E4068[index].id; } From a30e5e442d7fa602cade0d7351120b9b7653db4e Mon Sep 17 00:00:00 2001 From: itsgrimetime <990274+itsgrimetime@users.noreply.github.com> Date: Fri, 2 Jan 2026 17:29:51 -0800 Subject: [PATCH 19/19] fix(gricemt): remove pointer arithmetic from grIceMt_801F8CDC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace M2C_FIELD offset access with proper struct array indexing: - archive->unk4->unk8[7].unk0 instead of M2C_FIELD(..., 0x16C) - Use string literals for __assert instead of char pointer math Match improved from 93.08% to 99.45%. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/melee/gr/gricemt.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index cb8d65acf2..33d06db44c 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -932,11 +932,10 @@ void grIceMt_801F8CDC(Ground_GObj* gobj, s16* joint_indices, int count, u8 unused[24]; archive = grDatFiles_801C6324(); - jobj_desc = M2C_FIELD(archive->unk4->unk8, void**, 0x16C); + jobj_desc = archive->unk4->unk8[7].unk0; if (count > 20) { - __assert((char*) grIm_803E4068 + 0x690, 0x7D4, - (char*) grIm_803E4068 + 0x7F0); + __assert("gricemt.c", 0x7D4, "count <= 20"); } for (i = 0; i < count; i++) { @@ -946,14 +945,12 @@ void grIceMt_801F8CDC(Ground_GObj* gobj, s16* joint_indices, int count, for (i = 0; i < count; i++) { parent_jobj = parent_jobjs[i]; if (parent_jobj == NULL) { - __assert((char*) grIm_803E4068 + 0x690, 0x7E3, - (char*) grIm_803E4068 + 0x810); + __assert("gricemt.c", 0x7E3, "parent_jobj"); } child_jobj = HSD_JObjLoadJoint(jobj_desc); if (child_jobj == NULL) { - __assert((char*) grIm_803E4068 + 0x690, 0x7E6, - (char*) grIm_803E4068 + 0x81C); + __assert("gricemt.c", 0x7E6, "child_jobj"); } HSD_JObjAddChild(parent_jobj, child_jobj);