From b4b120a159bc81b8410d3d06d91cc787e2779972 Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Sun, 24 May 2026 15:29:06 +0000 Subject: [PATCH 01/16] Match grBigBlueRoute_8020BF38 (98%) Co-Authored-By: Claude Opus 4.7 (1M context) --- src/melee/gr/grbigblueroute.c | 13 ++++++------- src/melee/gr/types.h | 16 ++++++++++++++++ target_funcs.txt | 9 +++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 target_funcs.txt diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 84801f8c18..d78e423e63 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -349,10 +349,9 @@ bool grBigBlueRoute_8020BF30(Ground_GObj* arg) extern f32 grBb_Route_804DB948; extern f32 grBb_Route_804DB94C; -extern s16 grBb_Route_804D49EC; -/// @todo Currently 95.33% match - address caching in counter section, -/// minor register allocation in loop jobj load +/// @todo Currently 98.29% match - register allocation only (extra mr through +/// r0 for first loop jobj load and idx computation) void grBigBlueRoute_8020BF38(Ground_GObj* gobj) { Ground* gp = GET_GROUND(gobj); @@ -388,17 +387,17 @@ void grBigBlueRoute_8020BF38(Ground_GObj* gobj) } { - s32 idx = *(s16*) ((u8*) gp + 0xC8) + 5; + s32 idx = gp->gv.bigblueroute2.xC8 + 5; if (idx <= 7) { if (Ground_801C2D24(idx, &checkpoint) != 0) { if (fighter_pos.x > checkpoint.x) { - *(s16*) ((u8*) gp + 0xC8) = - *(s16*) ((u8*) gp + 0xC8) + 1; + gp->gv.bigblueroute2.xC8 = + gp->gv.bigblueroute2.xC8 + 1; } } } } - grBb_Route_804D49EC = *(s16*) ((u8*) gp + 0xC8); + stage_info.x6DC = gp->gv.bigblueroute2.xC8; } lb_800115F4(); diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index f67d308481..80a00d7cf1 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -1268,6 +1268,21 @@ struct grBigBlueRoute_GroundVars { /* +46 gp+10A */ s16 x10A; }; +struct grBigBlueRoute_GroundVars2 { + /* +00 gp+C4 */ u8 pad_C4[0xC8 - 0xC4]; + /* +04 gp+C8 */ s16 xC8; + /* +06 gp+CA */ u8 pad_CA[0xCC - 0xCA]; + /* +08 gp+CC */ Vec3 xCC; + /* +14 gp+D8 */ Vec3 xD8; + /* +20 gp+E4 */ HSD_JObj* xE4; + /* +24 gp+E8 */ Vec3 xE8; + /* +30 gp+F4 */ HSD_JObj* xF4; + /* +34 gp+F8 */ Vec3 xF8; + /* +40 gp+104 */ HSD_JObj* x104; + /* +44 gp+108 */ Vec3 x108; + /* +50 gp+114 */ HSD_JObj* x114; +}; + struct grCastle_GroundVars { /* +0 gp+C4 */ u32 xC4; /* +0 gp+C8 */ s16 xC8; @@ -1606,6 +1621,7 @@ struct Ground { struct grArwing_GroundVars arwing; struct grBigBlue_GroundVars bigblue; struct grBigBlueRoute_GroundVars bigblueroute; + struct grBigBlueRoute_GroundVars2 bigblueroute2; struct grCastle_GroundVars castle; struct grCastle_GroundVars2 castle2; struct grCastle_GroundVars3 castle3; diff --git a/target_funcs.txt b/target_funcs.txt new file mode 100644 index 0000000000..deb7702891 --- /dev/null +++ b/target_funcs.txt @@ -0,0 +1,9 @@ +File: src/melee/gr/grbigblueroute.c +Funcs: +- [x] grBigBlueRoute_8020DD64 +- [x] grBigBlueRoute_8020BF38 +- [ ] grBigBlueRoute_8020DAB4 +- [ ] grBigBlueRoute_8020BC68 +- [ ] grBigBlueRoute_8020C530 +- [ ] grBigBlueRoute_8020C85C +- [ ] grBigBlueRoute_8020CD20 From 8ebef23aa4d500a6e0f96cdff896c1779255d405 Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Sun, 24 May 2026 15:34:40 +0000 Subject: [PATCH 02/16] Match grBigBlueRoute_8020DAB4 (98%) Pool __FILE__ into the file string literal so asserts reference the shared grBb_Route_803E61D4 pool, fixing the data-offset mismatch across the unit's HSD_ASSERT calls. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/melee/gr/grbigblueroute.c | 6 ++---- target_funcs.txt | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index d78e423e63..977d8618e2 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -111,8 +111,6 @@ static struct { "%s:%d: couldn t get gobj(id=%d)\n", }; -char grBb_Route_803E61D4[] = "grbigblueroute.c"; - static struct { int x0; f32 x4; @@ -214,7 +212,7 @@ HSD_GObj* grBigBlueRoute_8020B9D4(int gobj_id) } } else { - OSReport(grBb_Route_803E617C.fmt, grBb_Route_803E61D4, 0x117, gobj_id); + OSReport(grBb_Route_803E617C.fmt, __FILE__, 0x117, gobj_id); } return gobj; @@ -680,7 +678,7 @@ int grBigBlueRoute_8020DA9C(struct grBigBlueRoute_8020DA9C_t* desc) return desc->x8; } -/// @todo Currently 97.71% match - needs register allocation fix (r27/r30 swap +/// @todo Currently 97.73% match - needs register allocation fix (r27/r30 swap /// for arr/jobj) void grBigBlueRoute_8020DAB4(HSD_JObj** jobjs, f32 scale, int count) { diff --git a/target_funcs.txt b/target_funcs.txt index deb7702891..ba555aff0d 100644 --- a/target_funcs.txt +++ b/target_funcs.txt @@ -2,7 +2,7 @@ File: src/melee/gr/grbigblueroute.c Funcs: - [x] grBigBlueRoute_8020DD64 - [x] grBigBlueRoute_8020BF38 -- [ ] grBigBlueRoute_8020DAB4 +- [x] grBigBlueRoute_8020DAB4 - [ ] grBigBlueRoute_8020BC68 - [ ] grBigBlueRoute_8020C530 - [ ] grBigBlueRoute_8020C85C From cc86b1364f06a43b811ca99ff18c9544b7a91a9e Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Sun, 24 May 2026 15:37:30 +0000 Subject: [PATCH 03/16] Match grBigBlueRoute_8020BC68 (99%) Use the bigblueroute2 struct view so the jobj caches and translation vectors use displacement addressing instead of cached pointers. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/melee/gr/grbigblueroute.c | 48 +++++++++++++++++------------------ target_funcs.txt | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 977d8618e2..6c794ff98b 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -281,8 +281,8 @@ void grBigBlueRoute_8020BC34(Ground_GObj* gobj) gp->gv.bigblueroute.xC4 = grBigBlueRoute_8020B9D4(4); } -/// @todo Currently 90.72% match - HSD_JObjGetTranslation inline hoists dest -/// pointer to r27 (target uses r0 for addic. + r30+offset for stores) +/// @todo Currently 99.83% match - remaining diffs are anonymous string-pool +/// symbols (translate/reb0_jobj) vs the target's single grBb_Route_803E61D4 void grBigBlueRoute_8020BC68(Ground_GObj* gobj) { Vec3 origin; @@ -293,50 +293,50 @@ void grBigBlueRoute_8020BC68(Ground_GObj* gobj) gp->x8_callback = NULL; gp->xC_callback = NULL; gp->x10_flags.b5 = 1; - *(s16*) ((u8*) gp + 0xC8) = 0; + gp->gv.bigblueroute2.xC8 = 0; if (Ground_801C2D24(148, &origin)) { jobj = Ground_801C2CF4(127); - *(HSD_JObj**) ((u8*) gp + 0xE4) = jobj; + gp->gv.bigblueroute2.xE4 = jobj; if (jobj != NULL) { - jobj = *(HSD_JObj**) ((u8*) gp + 0xE4); - HSD_JObjGetTranslation(jobj, (Vec3*) ((u8*) gp + 0xD8)); - lbVector_Sub((Vec3*) ((u8*) gp + 0xD8), &origin); + jobj = gp->gv.bigblueroute2.xE4; + HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.xD8); + lbVector_Sub(&gp->gv.bigblueroute2.xD8, &origin); } jobj = Ground_801C2CF4(128); - *(HSD_JObj**) ((u8*) gp + 0xF4) = jobj; + gp->gv.bigblueroute2.xF4 = jobj; if (jobj != NULL) { - jobj = *(HSD_JObj**) ((u8*) gp + 0xF4); - HSD_JObjGetTranslation(jobj, (Vec3*) ((u8*) gp + 0xE8)); - lbVector_Sub((Vec3*) ((u8*) gp + 0xE8), &origin); + jobj = gp->gv.bigblueroute2.xF4; + HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.xE8); + lbVector_Sub(&gp->gv.bigblueroute2.xE8, &origin); } jobj = Ground_801C2CF4(129); - *(HSD_JObj**) ((u8*) gp + 0x104) = jobj; + gp->gv.bigblueroute2.x104 = jobj; if (jobj != NULL) { - jobj = *(HSD_JObj**) ((u8*) gp + 0x104); - HSD_JObjGetTranslation(jobj, (Vec3*) ((u8*) gp + 0xF8)); - lbVector_Sub((Vec3*) ((u8*) gp + 0xF8), &origin); + jobj = gp->gv.bigblueroute2.x104; + HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.xF8); + lbVector_Sub(&gp->gv.bigblueroute2.xF8, &origin); } jobj = Ground_801C2CF4(130); - *(HSD_JObj**) ((u8*) gp + 0x114) = jobj; + gp->gv.bigblueroute2.x114 = jobj; if (jobj != NULL) { - jobj = *(HSD_JObj**) ((u8*) gp + 0x114); - HSD_JObjGetTranslation(jobj, (Vec3*) ((u8*) gp + 0x108)); - lbVector_Sub((Vec3*) ((u8*) gp + 0x108), &origin); + jobj = gp->gv.bigblueroute2.x114; + HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.x108); + lbVector_Sub(&gp->gv.bigblueroute2.x108, &origin); } } else { - *(HSD_JObj**) ((u8*) gp + 0xE4) = NULL; - *(HSD_JObj**) ((u8*) gp + 0xF4) = NULL; - *(HSD_JObj**) ((u8*) gp + 0x104) = NULL; - *(HSD_JObj**) ((u8*) gp + 0x114) = NULL; + gp->gv.bigblueroute2.xE4 = NULL; + gp->gv.bigblueroute2.xF4 = NULL; + gp->gv.bigblueroute2.x104 = NULL; + gp->gv.bigblueroute2.x114 = NULL; } jobj = Ground_801C2CF4(4); HSD_ASSERT(452, jobj != NULL); - HSD_JObjGetTranslation(jobj, (Vec3*) ((u8*) gp + 0xCC)); + HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.xCC); Ground_801C10B8(gobj, grBigBlueRoute_8020BC34); } diff --git a/target_funcs.txt b/target_funcs.txt index ba555aff0d..6d98643b7f 100644 --- a/target_funcs.txt +++ b/target_funcs.txt @@ -3,7 +3,7 @@ Funcs: - [x] grBigBlueRoute_8020DD64 - [x] grBigBlueRoute_8020BF38 - [x] grBigBlueRoute_8020DAB4 -- [ ] grBigBlueRoute_8020BC68 +- [x] grBigBlueRoute_8020BC68 - [ ] grBigBlueRoute_8020C530 - [ ] grBigBlueRoute_8020C85C - [ ] grBigBlueRoute_8020CD20 From 98045a86812295237fffa71a623b71de0f34d6f3 Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Sun, 24 May 2026 15:38:49 +0000 Subject: [PATCH 04/16] Match grBigBlueRoute_8020C530 (100%) Co-Authored-By: Claude Opus 4.7 (1M context) --- src/melee/gr/grbigblueroute.c | 7 +++---- target_funcs.txt | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 6c794ff98b..d7bbaef9b0 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -504,7 +504,6 @@ s32 grBigBlueRoute_8020C530(Ground_GObj* arg0) { Ground* gp = arg0->user_data; s32 count; - s32 idx; s32 i; count = 0; @@ -524,10 +523,10 @@ s32 grBigBlueRoute_8020C530(Ground_GObj* arg0) count = 0; } - for (idx = 0; idx < 30; idx++) { - if (!(*((u8*) gp->gv.bigblueroute.xC8 + idx * 0x2C) >> 7 & 1)) { + for (i = 0; i < 30; i++) { + if (!(*((u8*) gp->gv.bigblueroute.xC8 + i * 0x2C) >> 7 & 1)) { if (--count < 0) { - return idx; + return i; } } } diff --git a/target_funcs.txt b/target_funcs.txt index 6d98643b7f..b6ddc74740 100644 --- a/target_funcs.txt +++ b/target_funcs.txt @@ -4,6 +4,6 @@ Funcs: - [x] grBigBlueRoute_8020BF38 - [x] grBigBlueRoute_8020DAB4 - [x] grBigBlueRoute_8020BC68 -- [ ] grBigBlueRoute_8020C530 +- [x] grBigBlueRoute_8020C530 - [ ] grBigBlueRoute_8020C85C - [ ] grBigBlueRoute_8020CD20 From 5bb6290eb85a2046ee95246418dd60cb921cff63 Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Sun, 24 May 2026 15:44:33 +0000 Subject: [PATCH 05/16] Use float literals in grBigBlueRoute_8020BF38 to fix sdata2 pool order Referencing 30/4000 as extern symbols left them out of the unit's .sdata2 literal pool, shifting every later constant. Emitting them as literals aligns the pool with the target and improves 8020DD64. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/melee/gr/grbigblueroute.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index d7bbaef9b0..263e22130d 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -345,9 +345,6 @@ bool grBigBlueRoute_8020BF30(Ground_GObj* arg) return false; } -extern f32 grBb_Route_804DB948; -extern f32 grBb_Route_804DB94C; - /// @todo Currently 98.29% match - register allocation only (extra mr through /// r0 for first loop jobj load and idx computation) void grBigBlueRoute_8020BF38(Ground_GObj* gobj) @@ -361,7 +358,7 @@ void grBigBlueRoute_8020BF38(Ground_GObj* gobj) HSD_JObj* jobj; fighter = Ground_801C57A4(); - Ground_801C3D44(0, grBb_Route_804DB948, grBb_Route_804DB94C); + Ground_801C3D44(0, 30.0f, 4000.0f); if (fighter != NULL) { ftLib_80086644(fighter, &fighter_pos); From 74e2fed7b56a2f86d9a182fcdf8d751e947328dd Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Sun, 24 May 2026 15:54:25 +0000 Subject: [PATCH 06/16] Match grBigBlueRoute_8020C85C (92%) Fix the route-entry angle randomization to use 5.2359877/2.6179938 instead of 2.0/1.0, which also corrects the unit's sdata2 pool order. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/melee/gr/grbigblueroute.c | 354 +++++++++++++++++++++++++++++++++- target_funcs.txt | 2 +- 2 files changed, 352 insertions(+), 4 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 263e22130d..db233d17dd 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -530,7 +530,7 @@ s32 grBigBlueRoute_8020C530(Ground_GObj* arg0) __assert(__FILE__, 0x2E5, "0"); } -/// @todo Currently 91.77% match - register allocation (gp in r30 vs r31) +/// @todo Currently 91.71% match - register allocation (gp in r30 vs r31) /// and cror+beq vs bge for float >= comparison. void grBigBlueRoute_8020C85C(Ground_GObj* gobj) { @@ -612,7 +612,7 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) { f32 rand = HSD_Randf(); re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - re->x20 = 2.0F * rand - 1.0F; + re->x20 = 5.2359877f * rand - 2.6179938f; } if (!((RouteEntryFlags*) ((u8*) gp->gv.bigblueroute.xC8 + offset))->b1) @@ -664,7 +664,355 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) gp->gv.bigblueroute.x108++; } -/// #grBigBlueRoute_8020CD20 +static const Vec3 grBb_Route_803B83E0 = { 0.0f, 1.0f, 0.0f }; + +void grBigBlueRoute_8020CD20(Ground_GObj* gobj) +{ + Ground* gp = gobj->user_data; + HSD_JObj* root_jobj = gobj->hsd_obj; + HSD_GObj* fighter; + Vec3 fighter_pos; + HSD_JObj* jobj; + int i; + int offset; + RouteEntry* re; + Vec3 pos; + Vec3 rot; + + fighter = Ground_801C57A4(); + if (fighter == NULL) { + return; + } + ftLib_80086644(fighter, &fighter_pos); + + if (root_jobj == NULL) { + return; + } + jobj = HSD_JObjGetChild(root_jobj); + if (jobj == NULL) { + return; + } + + i = 0; + offset = 0; + do { + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->flags.b0) { + re->x4 += re->x8; + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->x4 > 1.0f) { + re->x4 = 1.0f; + } + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re->x14 += re->x18; + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->x14 > 1.0f) { + re->x14 = 1.0f; + } + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + switch (re->flags.b2_5) { + case 0: { + f32 t = re->x4; + f32 frac; + Vec3 p0; + Vec3 p1; + Vec3 tangent; + + if (re->xC < re->x10) { + re->xC += 0.01f; + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->xC > re->x10) { + re->xC = re->x10; + } + } else if (re->xC > re->x10) { + re->xC -= 0.01f; + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->xC < re->x10) { + re->xC = re->x10; + } + } + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + t = re->x4; + frac = re->xC; + splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, t); + splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, t); + lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xD0, t); + lbVector_Diff(&p1, &p0, &pos); + pos.x *= frac; + pos.y *= frac; + pos.z *= frac; + lbVector_Add(&pos, &p0); + rot.x = -atan2f(tangent.y, tangent.x); + rot.y = 1.5707964f; + rot.z = 0.0f; + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->x4 > 0.966f) { + re->flags.b2_5 = 2; + re->x14 = 0.0f; + re->x1C = 0.0f; + re->x20 = 5.2359877f * HSD_Randf() - 2.6179938f; + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re->x24 = re->x4; + } + break; + } + case 1: { + f32 t; + f32 angle; + Vec3 up; + Vec3 tangent; + Vec3 side; + Vec3 orient; + + if (re->x1C < re->x20) { + re->x1C += 0.017453292f; + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->x1C > re->x20) { + re->x1C = re->x20; + } + } else if (re->x1C > re->x20) { + re->x1C -= 0.017453292f; + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->x1C < re->x20) { + re->x1C = re->x20; + } + } + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + t = re->x14; + angle = re->x1C; + up = grBb_Route_803B83E0; + splGetSplinePoint(&pos, gp->gv.bigblueroute.xCC, t); + lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, t); + grBigBlueRoute_8020DD64(&tangent); + PSVECCrossProduct(&up, &tangent, &side); + lbVector_RotateAboutUnitAxis(&side, &tangent, angle); + grBigBlueRoute_8020DD64(&side); + PSVECCrossProduct(&tangent, &side, &up); + grBigBlueRoute_8020DD64(&up); + Ground_801C5AEC(&orient, &tangent, &side, &up); + rot.x = orient.x; + rot.y = orient.y; + rot.z = orient.z; + { + f32 s = 45.0f * Ground_801C0498(); + up.x *= s; + up.y *= s; + up.z *= s; + } + lbVector_Add(&pos, &up); + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->x14 > 0.967f) { + re->flags.b2_5 = 3; + re->x4 = 0.0f; + re->xC = 0.5f; + re->x10 = HSD_Randf(); + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re->x24 = re->x14; + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re->flags.b6 = 0; + if (re->flags.b1) { + gp->gv.bigblue.x0 &= ~0x40; + } + } + break; + } + case 2: { + f32 prog; + f32 frac; + f32 t; + f32 angle; + Vec3 road; + Vec3 road_tan; + Vec3 p0; + Vec3 p1; + Vec3 up; + Vec3 air; + Vec3 tangent; + Vec3 side; + Vec3 orient; + + prog = (re->x4 - re->x24) / (1.0f - re->x24); + frac = ((1.0f - prog) * (re->xC - 0.5f)) + 0.5f; + splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, re->x4); + splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, re->x4); + lbShadow_8000E9F0(&road_tan, gp->gv.bigblueroute.xD0, re->x4); + lbVector_Diff(&p1, &p0, &road); + road.x *= frac; + road.y *= frac; + road.z *= frac; + lbVector_Add(&road, &p0); + rot.x = -atan2f(road_tan.y, road_tan.x); + rot.y = 1.5707964f; + rot.z = 0.0f; + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + t = re->x14; + angle = re->x1C; + up = grBb_Route_803B83E0; + splGetSplinePoint(&air, gp->gv.bigblueroute.xCC, t); + lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, t); + grBigBlueRoute_8020DD64(&tangent); + PSVECCrossProduct(&up, &tangent, &side); + lbVector_RotateAboutUnitAxis(&side, &tangent, angle); + grBigBlueRoute_8020DD64(&side); + PSVECCrossProduct(&tangent, &side, &up); + grBigBlueRoute_8020DD64(&up); + Ground_801C5AEC(&orient, &tangent, &side, &up); + { + f32 s = 45.0f * Ground_801C0498(); + up.x *= s; + up.y *= s; + up.z *= s; + } + lbVector_Add(&air, &up); + lbVector_Diff(&air, &road, &pos); + pos.x *= prog; + pos.y *= prog; + pos.z *= prog; + lbVector_Add(&pos, &road); + rot.x = -atan2f(road_tan.y, road_tan.x); + rot.y = 1.5707964f; + rot.z = 0.0f; + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->x4 == 1.0f) { + re->flags.b2_5 = 1; + } + break; + } + case 3: { + f32 prog; + f32 angle; + f32 t; + f32 frac; + Vec3 up; + Vec3 air; + Vec3 tangent; + Vec3 side; + Vec3 orient; + Vec3 p0; + Vec3 p1; + Vec3 road_tan; + Vec3 road; + + prog = (re->x14 - re->x24) / (1.0f - re->x24); + up = grBb_Route_803B83E0; + angle = (1.0f - prog) * re->x1C; + splGetSplinePoint(&air, gp->gv.bigblueroute.xCC, re->x14); + lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, re->x14); + grBigBlueRoute_8020DD64(&tangent); + PSVECCrossProduct(&up, &tangent, &side); + lbVector_RotateAboutUnitAxis(&side, &tangent, angle); + grBigBlueRoute_8020DD64(&side); + PSVECCrossProduct(&tangent, &side, &up); + grBigBlueRoute_8020DD64(&up); + Ground_801C5AEC(&orient, &tangent, &side, &up); + rot.x = orient.x; + rot.y = orient.y; + rot.z = orient.z; + { + f32 s = 45.0f * Ground_801C0498(); + up.x *= s; + up.y *= s; + up.z *= s; + } + lbVector_Add(&air, &up); + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + t = re->x4; + frac = re->xC; + splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, t); + splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, t); + lbShadow_8000E9F0(&road_tan, gp->gv.bigblueroute.xD0, t); + lbVector_Diff(&p1, &p0, &road); + road.x *= frac; + road.y *= frac; + road.z *= frac; + lbVector_Add(&road, &p0); + atan2f(road_tan.y, road_tan.x); + lbVector_Diff(&road, &air, &pos); + pos.x *= prog; + pos.y *= prog; + pos.z *= prog; + lbVector_Add(&pos, &air); + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (re->x14 == 1.0f) { + re->flags.b2_5 = 0; + } + break; + } + } + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (!re->flags.b1) { + HSD_JObjSetTranslate(jobj, &pos); + HSD_JObjSetRotationX(jobj, rot.x); + HSD_JObjSetRotationY(jobj, rot.y); + HSD_JObjSetRotationZ(jobj, rot.z); + } + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (pos.x - 260.0f < fighter_pos.x && + fighter_pos.x < 260.0f + pos.x && + pos.z - 260.0f < fighter_pos.z && + fighter_pos.z < 260.0f + pos.z && !re->flags.b1) { + if (!((gp->gv.bigblue.x0 >> 6) & 1)) { + gp->gv.bigblue.x0 |= 0x40; + Ground_801C53EC(0x77A16); + } + } + + re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + if (pos.x - 100.0f < fighter_pos.x && + fighter_pos.x < 100.0f + pos.x && + pos.z - 100.0f < fighter_pos.z && + fighter_pos.z < 100.0f + pos.z) { + if (re->flags.b1) { + if (!((gp->gv.bigblue.x0 >> 7) & 1)) { + un_802FD604((s32) grBb_Route_804D6A68->x4C); + Ground_801C53EC(0x77A11); + gp->gv.bigblue.x0 |= 0x80; + } + } else { + Camera_80030E44(1, NULL); + if (!re->flags.b6) { + re->flags.b6 = 1; + if (HSD_Randi(100) < 40) { + switch (HSD_Randi(3)) { + case 0: + Ground_801C53EC(0x77A15); + break; + case 1: + Ground_801C53EC(0x77A14); + break; + case 2: + Ground_801C53EC(0x77A13); + break; + } + } + } + } + } else if (re->flags.b1) { + if ((gp->gv.bigblue.x0 >> 7) & 1) { + gp->gv.bigblue.x0 &= ~0x80; + } + } + } + + offset += 0x2C; + i++; + jobj = (jobj != NULL) + ? (HSD_JObj*) grBigBlueRoute_8020DA9C( + (struct grBigBlueRoute_8020DA9C_t*) jobj) + : NULL; + } while (i < 31); +} int grBigBlueRoute_8020DA9C(struct grBigBlueRoute_8020DA9C_t* desc) { diff --git a/target_funcs.txt b/target_funcs.txt index b6ddc74740..97014b3aee 100644 --- a/target_funcs.txt +++ b/target_funcs.txt @@ -5,5 +5,5 @@ Funcs: - [x] grBigBlueRoute_8020DAB4 - [x] grBigBlueRoute_8020BC68 - [x] grBigBlueRoute_8020C530 -- [ ] grBigBlueRoute_8020C85C +- [x] grBigBlueRoute_8020C85C - [ ] grBigBlueRoute_8020CD20 From d6b30c18721748632ef5ebfab14950c8e11caa2a Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Sun, 24 May 2026 15:58:19 +0000 Subject: [PATCH 07/16] Implement grBigBlueRoute_8020CD20 (86%) Implement the route state-machine update from scratch (was a stub): 4-state per-entry animation, spline positioning, jobj transforms and proximity sound/camera triggers. Include trigf.h so atan2f returns f32. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/melee/gr/grbigblueroute.c | 5 +++++ src/melee/gr/grbigblueroute.h | 4 ++-- target_funcs.txt | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index db233d17dd..1dc603a87e 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -21,6 +21,8 @@ #include "mp/mpcoll.h" #include "mp/mplib.h" +#include + #include #include #include @@ -666,6 +668,9 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) static const Vec3 grBb_Route_803B83E0 = { 0.0f, 1.0f, 0.0f }; +/// @todo Currently 85.77% match - SYSTEMIC: MWCC caches the RouteEntry pointer +/// (target reloads gp->...xC8 per access), plus float-constant hoisting order +/// and stack layout differ. void grBigBlueRoute_8020CD20(Ground_GObj* gobj) { Ground* gp = gobj->user_data; diff --git a/src/melee/gr/grbigblueroute.h b/src/melee/gr/grbigblueroute.h index 2f5e76fa52..8bcfac47eb 100644 --- a/src/melee/gr/grbigblueroute.h +++ b/src/melee/gr/grbigblueroute.h @@ -33,7 +33,7 @@ typedef struct { f32 x18; f32 x1C; f32 x20; - u8 pad_24[4]; + f32 x24; void* x28; } RouteEntry; @@ -67,7 +67,7 @@ typedef struct { /* 20C238 */ void grBigBlueRoute_8020C238(Ground_GObj*); /* 20C530 */ s32 grBigBlueRoute_8020C530(Ground_GObj*); /* 20C85C */ void grBigBlueRoute_8020C85C(Ground_GObj*); -/* 20CD20 */ UNK_RET grBigBlueRoute_8020CD20(Ground_GObj*); +/* 20CD20 */ void grBigBlueRoute_8020CD20(Ground_GObj*); /* 20DA9C */ int grBigBlueRoute_8020DA9C(struct grBigBlueRoute_8020DA9C_t*); /* 20DAB4 */ void grBigBlueRoute_8020DAB4(HSD_JObj**, float, int); /* 20DD64 */ void grBigBlueRoute_8020DD64(Vec3*); diff --git a/target_funcs.txt b/target_funcs.txt index 97014b3aee..1fe48ca113 100644 --- a/target_funcs.txt +++ b/target_funcs.txt @@ -6,4 +6,4 @@ Funcs: - [x] grBigBlueRoute_8020BC68 - [x] grBigBlueRoute_8020C530 - [x] grBigBlueRoute_8020C85C -- [ ] grBigBlueRoute_8020CD20 +- [x] grBigBlueRoute_8020CD20 From e0c8279243313869479f65b5d16caa57ccfccf88 Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Sun, 24 May 2026 15:59:36 +0000 Subject: [PATCH 08/16] Improve grBigBlueRoute_8020C85C to 92% Express the early-out as !(x108 < limit) so the float compare emits bge instead of cror+beq, matching the target. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/melee/gr/grbigblueroute.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 1dc603a87e..01c585ac38 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -532,15 +532,15 @@ s32 grBigBlueRoute_8020C530(Ground_GObj* arg0) __assert(__FILE__, 0x2E5, "0"); } -/// @todo Currently 91.71% match - register allocation (gp in r30 vs r31) -/// and cror+beq vs bge for float >= comparison. +/// @todo Currently 92.06% match - register allocation (gp in r30 vs r31) +/// and addressing-mode choices for RouteEntry stores. void grBigBlueRoute_8020C85C(Ground_GObj* gobj) { Ground* gp = GET_GROUND(gobj); s32 route_idx; PAD_STACK(8); - if ((f32) gp->gv.bigblueroute.x108 >= 1.0f + grBb_Route_804D6A68->x40) { + if (!((f32) gp->gv.bigblueroute.x108 < 1.0f + grBb_Route_804D6A68->x40)) { return; } From 1359a4bb8e8740e1ed86cdfb833093535aee28a6 Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Sun, 24 May 2026 16:00:51 +0000 Subject: [PATCH 09/16] Improve grBigBlueRoute_8020CD20 to 89% Reload the RouteEntry base per field access (via macro) to match the target's addressing instead of caching the pointer in a saved register. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/melee/gr/grbigblueroute.c | 163 +++++++++++++++------------------- 1 file changed, 70 insertions(+), 93 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 01c585ac38..328bd5734d 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -668,9 +668,9 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) static const Vec3 grBb_Route_803B83E0 = { 0.0f, 1.0f, 0.0f }; -/// @todo Currently 85.77% match - SYSTEMIC: MWCC caches the RouteEntry pointer -/// (target reloads gp->...xC8 per access), plus float-constant hoisting order -/// and stack layout differ. +/// @todo Currently 89.41% match - SYSTEMIC: float-constant hoisting order and +/// register pressure differ (target spills rot to stack; we keep it in FPRs). +#define RE_ENTRY ((RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset)) void grBigBlueRoute_8020CD20(Ground_GObj* gobj) { Ground* gp = gobj->user_data; @@ -680,7 +680,6 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) HSD_JObj* jobj; int i; int offset; - RouteEntry* re; Vec3 pos; Vec3 rot; @@ -701,46 +700,38 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) i = 0; offset = 0; do { - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->flags.b0) { - re->x4 += re->x8; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->x4 > 1.0f) { - re->x4 = 1.0f; + if (RE_ENTRY->flags.b0) { + RE_ENTRY->x4 += RE_ENTRY->x8; + if (RE_ENTRY->x4 > 1.0f) { + RE_ENTRY->x4 = 1.0f; } - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - re->x14 += re->x18; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->x14 > 1.0f) { - re->x14 = 1.0f; + RE_ENTRY->x14 += RE_ENTRY->x18; + if (RE_ENTRY->x14 > 1.0f) { + RE_ENTRY->x14 = 1.0f; } - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - switch (re->flags.b2_5) { + switch (RE_ENTRY->flags.b2_5) { case 0: { - f32 t = re->x4; + f32 t = RE_ENTRY->x4; f32 frac; Vec3 p0; Vec3 p1; Vec3 tangent; - if (re->xC < re->x10) { - re->xC += 0.01f; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->xC > re->x10) { - re->xC = re->x10; + if (RE_ENTRY->xC < RE_ENTRY->x10) { + RE_ENTRY->xC += 0.01f; + if (RE_ENTRY->xC > RE_ENTRY->x10) { + RE_ENTRY->xC = RE_ENTRY->x10; } - } else if (re->xC > re->x10) { - re->xC -= 0.01f; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->xC < re->x10) { - re->xC = re->x10; + } else if (RE_ENTRY->xC > RE_ENTRY->x10) { + RE_ENTRY->xC -= 0.01f; + if (RE_ENTRY->xC < RE_ENTRY->x10) { + RE_ENTRY->xC = RE_ENTRY->x10; } } - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - t = re->x4; - frac = re->xC; + t = RE_ENTRY->x4; + frac = RE_ENTRY->xC; splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, t); splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, t); lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xD0, t); @@ -753,14 +744,12 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) rot.y = 1.5707964f; rot.z = 0.0f; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->x4 > 0.966f) { - re->flags.b2_5 = 2; - re->x14 = 0.0f; - re->x1C = 0.0f; - re->x20 = 5.2359877f * HSD_Randf() - 2.6179938f; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - re->x24 = re->x4; + if (RE_ENTRY->x4 > 0.966f) { + RE_ENTRY->flags.b2_5 = 2; + RE_ENTRY->x14 = 0.0f; + RE_ENTRY->x1C = 0.0f; + RE_ENTRY->x20 = 5.2359877f * HSD_Randf() - 2.6179938f; + RE_ENTRY->x24 = RE_ENTRY->x4; } break; } @@ -772,23 +761,20 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) Vec3 side; Vec3 orient; - if (re->x1C < re->x20) { - re->x1C += 0.017453292f; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->x1C > re->x20) { - re->x1C = re->x20; + if (RE_ENTRY->x1C < RE_ENTRY->x20) { + RE_ENTRY->x1C += 0.017453292f; + if (RE_ENTRY->x1C > RE_ENTRY->x20) { + RE_ENTRY->x1C = RE_ENTRY->x20; } - } else if (re->x1C > re->x20) { - re->x1C -= 0.017453292f; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->x1C < re->x20) { - re->x1C = re->x20; + } else if (RE_ENTRY->x1C > RE_ENTRY->x20) { + RE_ENTRY->x1C -= 0.017453292f; + if (RE_ENTRY->x1C < RE_ENTRY->x20) { + RE_ENTRY->x1C = RE_ENTRY->x20; } } - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - t = re->x14; - angle = re->x1C; + t = RE_ENTRY->x14; + angle = RE_ENTRY->x1C; up = grBb_Route_803B83E0; splGetSplinePoint(&pos, gp->gv.bigblueroute.xCC, t); lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, t); @@ -810,17 +796,14 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) } lbVector_Add(&pos, &up); - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->x14 > 0.967f) { - re->flags.b2_5 = 3; - re->x4 = 0.0f; - re->xC = 0.5f; - re->x10 = HSD_Randf(); - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - re->x24 = re->x14; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - re->flags.b6 = 0; - if (re->flags.b1) { + if (RE_ENTRY->x14 > 0.967f) { + RE_ENTRY->flags.b2_5 = 3; + RE_ENTRY->x4 = 0.0f; + RE_ENTRY->xC = 0.5f; + RE_ENTRY->x10 = HSD_Randf(); + RE_ENTRY->x24 = RE_ENTRY->x14; + RE_ENTRY->flags.b6 = 0; + if (RE_ENTRY->flags.b1) { gp->gv.bigblue.x0 &= ~0x40; } } @@ -841,11 +824,11 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) Vec3 side; Vec3 orient; - prog = (re->x4 - re->x24) / (1.0f - re->x24); - frac = ((1.0f - prog) * (re->xC - 0.5f)) + 0.5f; - splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, re->x4); - splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, re->x4); - lbShadow_8000E9F0(&road_tan, gp->gv.bigblueroute.xD0, re->x4); + prog = (RE_ENTRY->x4 - RE_ENTRY->x24) / (1.0f - RE_ENTRY->x24); + frac = ((1.0f - prog) * (RE_ENTRY->xC - 0.5f)) + 0.5f; + splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, RE_ENTRY->x4); + splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, RE_ENTRY->x4); + lbShadow_8000E9F0(&road_tan, gp->gv.bigblueroute.xD0, RE_ENTRY->x4); lbVector_Diff(&p1, &p0, &road); road.x *= frac; road.y *= frac; @@ -855,9 +838,8 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) rot.y = 1.5707964f; rot.z = 0.0f; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - t = re->x14; - angle = re->x1C; + t = RE_ENTRY->x14; + angle = RE_ENTRY->x1C; up = grBb_Route_803B83E0; splGetSplinePoint(&air, gp->gv.bigblueroute.xCC, t); lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, t); @@ -884,9 +866,8 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) rot.y = 1.5707964f; rot.z = 0.0f; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->x4 == 1.0f) { - re->flags.b2_5 = 1; + if (RE_ENTRY->x4 == 1.0f) { + RE_ENTRY->flags.b2_5 = 1; } break; } @@ -905,11 +886,11 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) Vec3 road_tan; Vec3 road; - prog = (re->x14 - re->x24) / (1.0f - re->x24); + prog = (RE_ENTRY->x14 - RE_ENTRY->x24) / (1.0f - RE_ENTRY->x24); up = grBb_Route_803B83E0; - angle = (1.0f - prog) * re->x1C; - splGetSplinePoint(&air, gp->gv.bigblueroute.xCC, re->x14); - lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, re->x14); + angle = (1.0f - prog) * RE_ENTRY->x1C; + splGetSplinePoint(&air, gp->gv.bigblueroute.xCC, RE_ENTRY->x14); + lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, RE_ENTRY->x14); grBigBlueRoute_8020DD64(&tangent); PSVECCrossProduct(&up, &tangent, &side); lbVector_RotateAboutUnitAxis(&side, &tangent, angle); @@ -928,9 +909,8 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) } lbVector_Add(&air, &up); - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - t = re->x4; - frac = re->xC; + t = RE_ENTRY->x4; + frac = RE_ENTRY->xC; splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, t); splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, t); lbShadow_8000E9F0(&road_tan, gp->gv.bigblueroute.xD0, t); @@ -946,39 +926,35 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) pos.z *= prog; lbVector_Add(&pos, &air); - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (re->x14 == 1.0f) { - re->flags.b2_5 = 0; + if (RE_ENTRY->x14 == 1.0f) { + RE_ENTRY->flags.b2_5 = 0; } break; } } - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); - if (!re->flags.b1) { + if (!RE_ENTRY->flags.b1) { HSD_JObjSetTranslate(jobj, &pos); HSD_JObjSetRotationX(jobj, rot.x); HSD_JObjSetRotationY(jobj, rot.y); HSD_JObjSetRotationZ(jobj, rot.z); } - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); if (pos.x - 260.0f < fighter_pos.x && fighter_pos.x < 260.0f + pos.x && pos.z - 260.0f < fighter_pos.z && - fighter_pos.z < 260.0f + pos.z && !re->flags.b1) { + fighter_pos.z < 260.0f + pos.z && !RE_ENTRY->flags.b1) { if (!((gp->gv.bigblue.x0 >> 6) & 1)) { gp->gv.bigblue.x0 |= 0x40; Ground_801C53EC(0x77A16); } } - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); if (pos.x - 100.0f < fighter_pos.x && fighter_pos.x < 100.0f + pos.x && pos.z - 100.0f < fighter_pos.z && fighter_pos.z < 100.0f + pos.z) { - if (re->flags.b1) { + if (RE_ENTRY->flags.b1) { if (!((gp->gv.bigblue.x0 >> 7) & 1)) { un_802FD604((s32) grBb_Route_804D6A68->x4C); Ground_801C53EC(0x77A11); @@ -986,8 +962,8 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) } } else { Camera_80030E44(1, NULL); - if (!re->flags.b6) { - re->flags.b6 = 1; + if (!RE_ENTRY->flags.b6) { + RE_ENTRY->flags.b6 = 1; if (HSD_Randi(100) < 40) { switch (HSD_Randi(3)) { case 0: @@ -1003,7 +979,7 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) } } } - } else if (re->flags.b1) { + } else if (RE_ENTRY->flags.b1) { if ((gp->gv.bigblue.x0 >> 7) & 1) { gp->gv.bigblue.x0 &= ~0x80; } @@ -1018,6 +994,7 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) : NULL; } while (i < 31); } +#undef RE_ENTRY int grBigBlueRoute_8020DA9C(struct grBigBlueRoute_8020DA9C_t* desc) { From 1e56a326ab28d61682b0e80c76e1daa7dd265167 Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Mon, 25 May 2026 13:54:12 +0000 Subject: [PATCH 10/16] grbigblueroute: inline float consts as literals (drop extern-const trick) --- src/melee/gr/grbigblueroute.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 328bd5734d..c14094956a 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -1108,9 +1108,6 @@ void fn_8020DEAC(void) Ground_801C53EC(0x77A12); } -extern f32 grBb_Route_804DB994; -extern f32 grBb_Route_804DB998; -extern f32 grBb_Route_804DB99C; /* Clamp camera position to stage bounds */ void grBigBlueRoute_8020DED4(Vec3* pos) @@ -1118,14 +1115,14 @@ void grBigBlueRoute_8020DED4(Vec3* pos) f32 x = pos->x; f32 y = pos->y; - if (x < grBb_Route_804DB994 * Ground_801C0498()) { - x = grBb_Route_804DB994 * Ground_801C0498(); + if (x < 20.0f * Ground_801C0498()) { + x = 20.0f * Ground_801C0498(); } - if (y < grBb_Route_804DB998 * Ground_801C0498()) { - y = grBb_Route_804DB998 * Ground_801C0498(); - } else if (y > grBb_Route_804DB99C * Ground_801C0498()) { - y = grBb_Route_804DB99C * Ground_801C0498(); + if (y < 250.0f * Ground_801C0498()) { + y = 250.0f * Ground_801C0498(); + } else if (y > -3.0f * Ground_801C0498()) { + y = -3.0f * Ground_801C0498(); } Ground_801C38BC(x, y); From 58de0c5511db7aa2a7c843b2739f212a54102ec4 Mon Sep 17 00:00:00 2001 From: Jurre Groenendijk Date: Mon, 25 May 2026 14:19:24 +0000 Subject: [PATCH 11/16] grbigblueroute: include lb/lbshadow.h (fix implicit decl of lbShadow_8000E9F0) --- src/melee/gr/grbigblueroute.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index c14094956a..84660859f5 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -17,6 +17,7 @@ #include "if/ifhazard.h" #include "lb/lb_00B0.h" #include "lb/lb_00F9.h" +#include "lb/lbshadow.h" #include "lb/lbvector.h" #include "mp/mpcoll.h" #include "mp/mplib.h" From 193ceb02b6f7338c4ddf6006da002836536fedcb Mon Sep 17 00:00:00 2001 From: JurreJelle Date: Sun, 31 May 2026 08:25:16 +0000 Subject: [PATCH 12/16] Fix pointer math --- src/melee/gr/grbigblueroute.c | 114 ++++++++++++++++------------------ src/melee/gr/types.h | 14 ++--- 2 files changed, 59 insertions(+), 69 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 84660859f5..fb590926ca 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -300,41 +300,41 @@ void grBigBlueRoute_8020BC68(Ground_GObj* gobj) if (Ground_801C2D24(148, &origin)) { jobj = Ground_801C2CF4(127); - gp->gv.bigblueroute2.xE4 = jobj; + gp->gv.bigblueroute2.tracks[0].jobj = jobj; if (jobj != NULL) { - jobj = gp->gv.bigblueroute2.xE4; - HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.xD8); - lbVector_Sub(&gp->gv.bigblueroute2.xD8, &origin); + jobj = gp->gv.bigblueroute2.tracks[0].jobj; + HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.tracks[0].offset); + lbVector_Sub(&gp->gv.bigblueroute2.tracks[0].offset, &origin); } jobj = Ground_801C2CF4(128); - gp->gv.bigblueroute2.xF4 = jobj; + gp->gv.bigblueroute2.tracks[1].jobj = jobj; if (jobj != NULL) { - jobj = gp->gv.bigblueroute2.xF4; - HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.xE8); - lbVector_Sub(&gp->gv.bigblueroute2.xE8, &origin); + jobj = gp->gv.bigblueroute2.tracks[1].jobj; + HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.tracks[1].offset); + lbVector_Sub(&gp->gv.bigblueroute2.tracks[1].offset, &origin); } jobj = Ground_801C2CF4(129); - gp->gv.bigblueroute2.x104 = jobj; + gp->gv.bigblueroute2.tracks[2].jobj = jobj; if (jobj != NULL) { - jobj = gp->gv.bigblueroute2.x104; - HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.xF8); - lbVector_Sub(&gp->gv.bigblueroute2.xF8, &origin); + jobj = gp->gv.bigblueroute2.tracks[2].jobj; + HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.tracks[2].offset); + lbVector_Sub(&gp->gv.bigblueroute2.tracks[2].offset, &origin); } jobj = Ground_801C2CF4(130); - gp->gv.bigblueroute2.x114 = jobj; + gp->gv.bigblueroute2.tracks[3].jobj = jobj; if (jobj != NULL) { - jobj = gp->gv.bigblueroute2.x114; - HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.x108); - lbVector_Sub(&gp->gv.bigblueroute2.x108, &origin); + jobj = gp->gv.bigblueroute2.tracks[3].jobj; + HSD_JObjGetTranslation(jobj, &gp->gv.bigblueroute2.tracks[3].offset); + lbVector_Sub(&gp->gv.bigblueroute2.tracks[3].offset, &origin); } } else { - gp->gv.bigblueroute2.xE4 = NULL; - gp->gv.bigblueroute2.xF4 = NULL; - gp->gv.bigblueroute2.x104 = NULL; - gp->gv.bigblueroute2.x114 = NULL; + gp->gv.bigblueroute2.tracks[0].jobj = NULL; + gp->gv.bigblueroute2.tracks[1].jobj = NULL; + gp->gv.bigblueroute2.tracks[2].jobj = NULL; + gp->gv.bigblueroute2.tracks[3].jobj = NULL; } jobj = Ground_801C2CF4(4); @@ -357,7 +357,6 @@ void grBigBlueRoute_8020BF38(Ground_GObj* gobj) Vec3 checkpoint; Vec3 fighter_pos; int i; - u8* car; HSD_JObj* jobj; fighter = Ground_801C57A4(); @@ -369,15 +368,17 @@ void grBigBlueRoute_8020BF38(Ground_GObj* gobj) if (ftLib_80086EC0(fighter) == 0) { grBigBlueRoute_8020DED4(&fighter_pos); - for (i = 0, car = (u8*) gp; i < 3; i++, car += 0x10) { - jobj = *(HSD_JObj**) (car + 0xE4); + for (i = 0; i < 3; i++) { + jobj = gp->gv.bigblueroute2.tracks[i].jobj; if (jobj != NULL) { - HSD_JObjSetTranslateX(jobj, *(f32*) (car + 0xD8) + - fighter_pos.x); - - jobj = *(HSD_JObj**) (car + 0xE4); - HSD_JObjSetTranslateY(jobj, *(f32*) (car + 0xDC) + - fighter_pos.y); + HSD_JObjSetTranslateX(jobj, + gp->gv.bigblueroute2.tracks[i].offset.x + + fighter_pos.x); + + jobj = gp->gv.bigblueroute2.tracks[i].jobj; + HSD_JObjSetTranslateY(jobj, + gp->gv.bigblueroute2.tracks[i].offset.y + + fighter_pos.y); } } @@ -410,11 +411,11 @@ void grBigBlueRoute_8020C140(Ground_GObj* gobj) Ground* gp = gobj->user_data; grFZeroCar_801CAFBC(gobj, grBb_Route_803E6200, 30, 0); - *(s32*) ((u8*) gp + 0xCC) = (s32) Ground_801C247C(33, 1); - *(s32*) ((u8*) gp + 0xD0) = (s32) Ground_801C247C(33, 0); - *(s32*) ((u8*) gp + 0xD4) = (s32) Ground_801C247C(33, 2); + gp->gv.bigblueroute.xCC = (HSD_Spline*) Ground_801C247C(33, 1); + gp->gv.bigblueroute.xD0 = (HSD_Spline*) Ground_801C247C(33, 0); + gp->gv.bigblueroute.xD4 = (HSD_Spline*) Ground_801C247C(33, 2); grBigBlueRoute_8020C238(gobj); - ((UnkFlagStruct*) ((u8*) gp + 0xC4))->b0 = 0; + ((UnkFlagStruct*) &gp->gv.bigblueroute.xC4)->b0 = 0; } bool grBigBlueRoute_8020C1D4(Ground_GObj* arg) @@ -508,7 +509,7 @@ s32 grBigBlueRoute_8020C530(Ground_GObj* arg0) count = 0; for (i = 0; i < 30; i++) { - if (!(*((u8*) gp->gv.bigblueroute.xC8 + i * 0x2C) >> 7 & 1)) { + if (!((RouteEntry*) gp->gv.bigblueroute.xC8)[i].flags.b0) { count++; } } @@ -524,7 +525,7 @@ s32 grBigBlueRoute_8020C530(Ground_GObj* arg0) } for (i = 0; i < 30; i++) { - if (!(*((u8*) gp->gv.bigblueroute.xC8 + i * 0x2C) >> 7 & 1)) { + if (!((RouteEntry*) gp->gv.bigblueroute.xC8)[i].flags.b0) { if (--count < 0) { return i; } @@ -551,8 +552,7 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) if (gp->gv.bigblueroute.x108 == 0) { route_idx = 30; - /* RouteEntry array at xC8, each entry 44 bytes */ - ((RouteEntryFlags*) ((u8*) gp->gv.bigblueroute.xC8 + 30 * 44))->b1 = 1; + ((RouteEntry*) gp->gv.bigblueroute.xC8)[30].flags.b1 = 1; gp->gv.bigblueroute.x10A = grBb_Route_804D6A68->x4C; } else { s32 min_val; @@ -561,8 +561,7 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) route_idx = grBigBlueRoute_8020C530(gobj); - ((RouteEntryFlags*) ((u8*) gp->gv.bigblueroute.xC8 + route_idx * 44)) - ->b1 = 0; + ((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx].flags.b1 = 0; min_val = (s32) grBb_Route_804D6A68->x44; max_val = (s32) grBb_Route_804D6A68->x48; @@ -580,46 +579,43 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) } if (route_idx != -1) { - s32 offset = route_idx * 44; - RouteEntry* re; + RouteEntry* re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; - ((RouteEntryFlags*) ((u8*) gp->gv.bigblueroute.xC8 + offset))->b0 = 1; - ((RouteEntryFlags*) ((u8*) gp->gv.bigblueroute.xC8 + offset))->b6 = 0; - ((RouteEntryFlags*) ((u8*) gp->gv.bigblueroute.xC8 + offset))->b2_5 = - 1; + re->flags.b0 = 1; + re->flags.b6 = 0; + re->flags.b2_5 = 1; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->x4 = 0.0F; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->x8 = grBb_Route_804D6A68->x20; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->xC = 0.0F; { f32 rand = HSD_Randf(); - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->x10 = rand; } - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->x14 = 0.0F; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->x18 = grBb_Route_804D6A68->x3C; - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->x1C = 0.0F; { f32 rand = HSD_Randf(); - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset); + re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->x20 = 5.2359877f * rand - 2.6179938f; } - if (!((RouteEntryFlags*) ((u8*) gp->gv.bigblueroute.xC8 + offset))->b1) - { + if (!((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx].flags.b1) { HSD_JObj* root = gobj->hsd_obj; if (root != NULL) { HSD_JObj* jobj; @@ -652,8 +648,7 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) 0, 1, gp, jobj, (void (*)(Item_GObj*, Ground*)) fn_8020DEAC, NULL, NULL); - re = (RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + - offset); + re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->x28 = (void*) item; if (item != NULL) { grMaterial_801C8E28((HSD_GObj*) item); @@ -671,7 +666,7 @@ static const Vec3 grBb_Route_803B83E0 = { 0.0f, 1.0f, 0.0f }; /// @todo Currently 89.41% match - SYSTEMIC: float-constant hoisting order and /// register pressure differ (target spills rot to stack; we keep it in FPRs). -#define RE_ENTRY ((RouteEntry*) ((u8*) gp->gv.bigblueroute.xC8 + offset)) +#define RE_ENTRY (&((RouteEntry*) gp->gv.bigblueroute.xC8)[i]) void grBigBlueRoute_8020CD20(Ground_GObj* gobj) { Ground* gp = gobj->user_data; @@ -680,7 +675,6 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) Vec3 fighter_pos; HSD_JObj* jobj; int i; - int offset; Vec3 pos; Vec3 rot; @@ -699,7 +693,6 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) } i = 0; - offset = 0; do { if (RE_ENTRY->flags.b0) { RE_ENTRY->x4 += RE_ENTRY->x8; @@ -987,7 +980,6 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) } } - offset += 0x2C; i++; jobj = (jobj != NULL) ? (HSD_JObj*) grBigBlueRoute_8020DA9C( diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index 80a00d7cf1..2de0bf4bab 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -1268,19 +1268,17 @@ struct grBigBlueRoute_GroundVars { /* +46 gp+10A */ s16 x10A; }; +struct grBigBlueRoute_Track { + Vec3 offset; + HSD_JObj* jobj; +}; + struct grBigBlueRoute_GroundVars2 { /* +00 gp+C4 */ u8 pad_C4[0xC8 - 0xC4]; /* +04 gp+C8 */ s16 xC8; /* +06 gp+CA */ u8 pad_CA[0xCC - 0xCA]; /* +08 gp+CC */ Vec3 xCC; - /* +14 gp+D8 */ Vec3 xD8; - /* +20 gp+E4 */ HSD_JObj* xE4; - /* +24 gp+E8 */ Vec3 xE8; - /* +30 gp+F4 */ HSD_JObj* xF4; - /* +34 gp+F8 */ Vec3 xF8; - /* +40 gp+104 */ HSD_JObj* x104; - /* +44 gp+108 */ Vec3 x108; - /* +50 gp+114 */ HSD_JObj* x114; + /* +14 gp+D8 */ struct grBigBlueRoute_Track tracks[4]; }; struct grCastle_GroundVars { From 4799f8114cc5e2a0f02ffff4fd2b72a1d55e7232 Mon Sep 17 00:00:00 2001 From: JurreJelle Date: Sun, 31 May 2026 08:36:23 +0000 Subject: [PATCH 13/16] match grBigBlueRoute_8020DAB4 --- src/melee/gr/grbigblueroute.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index fb590926ca..5c9bd7b4df 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -1001,9 +1001,9 @@ int grBigBlueRoute_8020DA9C(struct grBigBlueRoute_8020DA9C_t* desc) /// for arr/jobj) void grBigBlueRoute_8020DAB4(HSD_JObj** jobjs, f32 scale, int count) { + HSD_JObj** arr; int i; int countdown = 30; - HSD_JObj** arr; HSD_JObj* jobj; HSD_GObj* gobj; @@ -1022,12 +1022,12 @@ void grBigBlueRoute_8020DAB4(HSD_JObj** jobjs, f32 scale, int count) int random_idx; if (*arr == NULL) { - continue; + break; } random_idx = (countdown != 0) ? HSD_Randi(countdown) : 0; - jobj = gobj->hsd_obj; + jobj = HSD_GObjGetHSDObj(gobj); HSD_ASSERT(1434, jobj); jobj = HSD_JObjGetChild(jobj); From 8816af30fa4519ded0d9c8b60d2c630e5defbc29 Mon Sep 17 00:00:00 2001 From: JurreJelle Date: Sun, 31 May 2026 08:51:40 +0000 Subject: [PATCH 14/16] improvement on grBigBlueRoute_8020C85C --- src/melee/gr/grbigblueroute.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 5c9bd7b4df..0d19d7217f 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -579,11 +579,12 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) } if (route_idx != -1) { + // probably an inline of some sort RouteEntry* re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; - re->flags.b0 = 1; - re->flags.b6 = 0; - re->flags.b2_5 = 1; + (&((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx])->flags.b0 = 1; + (&((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx])->flags.b6 = 0; + (&((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx])->flags.b2_5 = 1; re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; re->x4 = 0.0F; From 8f414dab6b902082eaeb1a8bbb20bf416a83196b Mon Sep 17 00:00:00 2001 From: jellejurre Date: Sun, 31 May 2026 11:53:07 +0200 Subject: [PATCH 15/16] Match grBigBlueRoute_8020BF38 --- src/melee/gr/grbigblueroute.c | 6 +++--- target_funcs.txt | 9 --------- 2 files changed, 3 insertions(+), 12 deletions(-) delete mode 100644 target_funcs.txt diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 0d19d7217f..3378332290 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -369,8 +369,8 @@ void grBigBlueRoute_8020BF38(Ground_GObj* gobj) grBigBlueRoute_8020DED4(&fighter_pos); for (i = 0; i < 3; i++) { - jobj = gp->gv.bigblueroute2.tracks[i].jobj; - if (jobj != NULL) { + if (gp->gv.bigblueroute2.tracks[i].jobj != NULL) { + jobj = gp->gv.bigblueroute2.tracks[i].jobj; HSD_JObjSetTranslateX(jobj, gp->gv.bigblueroute2.tracks[i].offset.x + fighter_pos.x); @@ -387,7 +387,7 @@ void grBigBlueRoute_8020BF38(Ground_GObj* gobj) { s32 idx = gp->gv.bigblueroute2.xC8 + 5; - if (idx <= 7) { + if (gp->gv.bigblueroute2.xC8 + 5 <= 7) { if (Ground_801C2D24(idx, &checkpoint) != 0) { if (fighter_pos.x > checkpoint.x) { gp->gv.bigblueroute2.xC8 = diff --git a/target_funcs.txt b/target_funcs.txt deleted file mode 100644 index 1fe48ca113..0000000000 --- a/target_funcs.txt +++ /dev/null @@ -1,9 +0,0 @@ -File: src/melee/gr/grbigblueroute.c -Funcs: -- [x] grBigBlueRoute_8020DD64 -- [x] grBigBlueRoute_8020BF38 -- [x] grBigBlueRoute_8020DAB4 -- [x] grBigBlueRoute_8020BC68 -- [x] grBigBlueRoute_8020C530 -- [x] grBigBlueRoute_8020C85C -- [x] grBigBlueRoute_8020CD20 From 59176ba3404c5830d5b15cd3021035bfdc6dafd3 Mon Sep 17 00:00:00 2001 From: jellejurre Date: Sun, 31 May 2026 11:56:32 +0200 Subject: [PATCH 16/16] Fix asserts --- src/melee/gr/grbigblueroute.c | 136 +++++++++++++++++----------------- src/melee/gr/types.h | 4 +- 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/src/melee/gr/grbigblueroute.c b/src/melee/gr/grbigblueroute.c index 3378332290..5cb9a44e63 100644 --- a/src/melee/gr/grbigblueroute.c +++ b/src/melee/gr/grbigblueroute.c @@ -2,6 +2,7 @@ #include +#include "baselib/debug.h" #include "baselib/memory.h" #include "cm/camera.h" #include "ft/ftlib.h" @@ -23,7 +24,6 @@ #include "mp/mplib.h" #include - #include #include #include @@ -281,7 +281,7 @@ void grBigBlueRoute_8020BC30(Ground_GObj* arg) {} void grBigBlueRoute_8020BC34(Ground_GObj* gobj) { Ground* gp = GET_GROUND(gobj); - gp->gv.bigblueroute.xC4 = grBigBlueRoute_8020B9D4(4); + gp->u.car.xC4 = grBigBlueRoute_8020B9D4(4); } /// @todo Currently 99.83% match - remaining diffs are anonymous string-pool @@ -411,11 +411,11 @@ void grBigBlueRoute_8020C140(Ground_GObj* gobj) Ground* gp = gobj->user_data; grFZeroCar_801CAFBC(gobj, grBb_Route_803E6200, 30, 0); - gp->gv.bigblueroute.xCC = (HSD_Spline*) Ground_801C247C(33, 1); - gp->gv.bigblueroute.xD0 = (HSD_Spline*) Ground_801C247C(33, 0); - gp->gv.bigblueroute.xD4 = (HSD_Spline*) Ground_801C247C(33, 2); + gp->u.car.xCC = (HSD_Spline*) Ground_801C247C(33, 1); + gp->u.car.xD0 = (HSD_Spline*) Ground_801C247C(33, 0); + gp->u.car.xD4 = (HSD_Spline*) Ground_801C247C(33, 2); grBigBlueRoute_8020C238(gobj); - ((UnkFlagStruct*) &gp->gv.bigblueroute.xC4)->b0 = 0; + ((UnkFlagStruct*) &gp->u.car.xC4)->b0 = 0; } bool grBigBlueRoute_8020C1D4(Ground_GObj* arg) @@ -432,7 +432,7 @@ void grBigBlueRoute_8020C1DC(Ground_GObj* gobj) void grBigBlueRoute_8020C210(Ground_GObj* gobj) { Ground* gp = GET_GROUND(gobj); - HSD_Free((void*) gp->gv.bigblueroute.xC8); + HSD_Free((void*) gp->u.car.car_info); } void grBigBlueRoute_8020C238(Ground_GObj* gobj) @@ -472,33 +472,31 @@ void grBigBlueRoute_8020C238(Ground_GObj* gobj) } } - gp->gv.bigblueroute.xC8 = HSD_MemAlloc(0x554); - ((gp->gv.bigblueroute.xC8) - ? ((void) 0) - : __assert(__FILE__, 674, "gp->u.car.car_info")); - memzero(gp->gv.bigblueroute.xC8, 0x554); + gp->u.car.car_info = HSD_MemAlloc(0x554); + HSD_ASSERT(0x2A2, gp->u.car.car_info); + memzero(gp->u.car.car_info, 0x554); - gp->gv.bigblueroute.x10A = 0; - gp->gv.bigblueroute.x108 = 0; + gp->u.car.x10A = 0; + gp->u.car.x108 = 0; - splGetSplinePoint(&gp->gv.bigblueroute.xD8, gp->gv.bigblueroute.xCC, 0.0F); - splGetSplinePoint(&gp->gv.bigblueroute.xE4, gp->gv.bigblueroute.xCC, 1.0F); + splGetSplinePoint(&gp->u.car.xD8, gp->u.car.xCC, 0.0F); + splGetSplinePoint(&gp->u.car.xE4, gp->u.car.xCC, 1.0F); - splGetSplinePoint(&gp->gv.bigblueroute.xF0, gp->gv.bigblueroute.xD0, 0.0F); - splGetSplinePoint(&spline_pt, gp->gv.bigblueroute.xD4, 0.0F); - lbVector_Add(&gp->gv.bigblueroute.xF0, &spline_pt); + splGetSplinePoint(&gp->u.car.xF0, gp->u.car.xD0, 0.0F); + splGetSplinePoint(&spline_pt, gp->u.car.xD4, 0.0F); + lbVector_Add(&gp->u.car.xF0, &spline_pt); - gp->gv.bigblueroute.xF0.x *= 0.5F; - gp->gv.bigblueroute.xF0.y *= 0.5F; - gp->gv.bigblueroute.xF0.z *= 0.5F; + gp->u.car.xF0.x *= 0.5F; + gp->u.car.xF0.y *= 0.5F; + gp->u.car.xF0.z *= 0.5F; - splGetSplinePoint(&gp->gv.bigblueroute.xFC, gp->gv.bigblueroute.xD0, 1.0F); - splGetSplinePoint(&spline_pt, gp->gv.bigblueroute.xD4, 1.0F); - lbVector_Add(&gp->gv.bigblueroute.xFC, &spline_pt); + splGetSplinePoint(&gp->u.car.xFC, gp->u.car.xD0, 1.0F); + splGetSplinePoint(&spline_pt, gp->u.car.xD4, 1.0F); + lbVector_Add(&gp->u.car.xFC, &spline_pt); - gp->gv.bigblueroute.xFC.x *= 0.5F; - gp->gv.bigblueroute.xFC.y *= 0.5F; - gp->gv.bigblueroute.xFC.z *= 0.5F; + gp->u.car.xFC.x *= 0.5F; + gp->u.car.xFC.y *= 0.5F; + gp->u.car.xFC.z *= 0.5F; } s32 grBigBlueRoute_8020C530(Ground_GObj* arg0) @@ -509,7 +507,7 @@ s32 grBigBlueRoute_8020C530(Ground_GObj* arg0) count = 0; for (i = 0; i < 30; i++) { - if (!((RouteEntry*) gp->gv.bigblueroute.xC8)[i].flags.b0) { + if (!((RouteEntry*) gp->u.car.car_info)[i].flags.b0) { count++; } } @@ -525,13 +523,13 @@ s32 grBigBlueRoute_8020C530(Ground_GObj* arg0) } for (i = 0; i < 30; i++) { - if (!((RouteEntry*) gp->gv.bigblueroute.xC8)[i].flags.b0) { + if (!((RouteEntry*) gp->u.car.car_info)[i].flags.b0) { if (--count < 0) { return i; } } } - __assert(__FILE__, 0x2E5, "0"); + HSD_ASSERT(0X2E5, NULL); } /// @todo Currently 92.06% match - register allocation (gp in r30 vs r31) @@ -542,18 +540,18 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) s32 route_idx; PAD_STACK(8); - if (!((f32) gp->gv.bigblueroute.x108 < 1.0f + grBb_Route_804D6A68->x40)) { + if (!((f32) gp->u.car.x108 < 1.0f + grBb_Route_804D6A68->x40)) { return; } - if (gp->gv.bigblueroute.x10A-- >= 0) { + if (gp->u.car.x10A-- >= 0) { return; } - if (gp->gv.bigblueroute.x108 == 0) { + if (gp->u.car.x108 == 0) { route_idx = 30; - ((RouteEntry*) gp->gv.bigblueroute.xC8)[30].flags.b1 = 1; - gp->gv.bigblueroute.x10A = grBb_Route_804D6A68->x4C; + ((RouteEntry*) gp->u.car.car_info)[30].flags.b1 = 1; + gp->u.car.x10A = grBb_Route_804D6A68->x4C; } else { s32 min_val; s32 max_val; @@ -561,7 +559,7 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) route_idx = grBigBlueRoute_8020C530(gobj); - ((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx].flags.b1 = 0; + ((RouteEntry*) gp->u.car.car_info)[route_idx].flags.b1 = 0; min_val = (s32) grBb_Route_804D6A68->x44; max_val = (s32) grBb_Route_804D6A68->x48; @@ -575,48 +573,48 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) } else { new_timer = max_val; } - gp->gv.bigblueroute.x10A = (s16) new_timer; + gp->u.car.x10A = (s16) new_timer; } if (route_idx != -1) { // probably an inline of some sort - RouteEntry* re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + RouteEntry* re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; - (&((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx])->flags.b0 = 1; - (&((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx])->flags.b6 = 0; - (&((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx])->flags.b2_5 = 1; + (&((RouteEntry*) gp->u.car.car_info)[route_idx])->flags.b0 = 1; + (&((RouteEntry*) gp->u.car.car_info)[route_idx])->flags.b6 = 0; + (&((RouteEntry*) gp->u.car.car_info)[route_idx])->flags.b2_5 = 1; - re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; re->x4 = 0.0F; - re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; re->x8 = grBb_Route_804D6A68->x20; - re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; re->xC = 0.0F; { f32 rand = HSD_Randf(); - re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; re->x10 = rand; } - re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; re->x14 = 0.0F; - re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; re->x18 = grBb_Route_804D6A68->x3C; - re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; re->x1C = 0.0F; { f32 rand = HSD_Randf(); - re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; re->x20 = 5.2359877f * rand - 2.6179938f; } - if (!((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx].flags.b1) { + if (!((RouteEntry*) gp->u.car.car_info)[route_idx].flags.b1) { HSD_JObj* root = gobj->hsd_obj; if (root != NULL) { HSD_JObj* jobj; @@ -649,7 +647,7 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) 0, 1, gp, jobj, (void (*)(Item_GObj*, Ground*)) fn_8020DEAC, NULL, NULL); - re = &((RouteEntry*) gp->gv.bigblueroute.xC8)[route_idx]; + re = &((RouteEntry*) gp->u.car.car_info)[route_idx]; re->x28 = (void*) item; if (item != NULL) { grMaterial_801C8E28((HSD_GObj*) item); @@ -660,14 +658,14 @@ void grBigBlueRoute_8020C85C(Ground_GObj* gobj) } } - gp->gv.bigblueroute.x108++; + gp->u.car.x108++; } static const Vec3 grBb_Route_803B83E0 = { 0.0f, 1.0f, 0.0f }; /// @todo Currently 89.41% match - SYSTEMIC: float-constant hoisting order and /// register pressure differ (target spills rot to stack; we keep it in FPRs). -#define RE_ENTRY (&((RouteEntry*) gp->gv.bigblueroute.xC8)[i]) +#define RE_ENTRY (&((RouteEntry*) gp->u.car.car_info)[i]) void grBigBlueRoute_8020CD20(Ground_GObj* gobj) { Ground* gp = gobj->user_data; @@ -727,9 +725,9 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) t = RE_ENTRY->x4; frac = RE_ENTRY->xC; - splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, t); - splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, t); - lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xD0, t); + splGetSplinePoint(&p0, gp->u.car.xD0, t); + splGetSplinePoint(&p1, gp->u.car.xD4, t); + lbShadow_8000E9F0(&tangent, gp->u.car.xD0, t); lbVector_Diff(&p1, &p0, &pos); pos.x *= frac; pos.y *= frac; @@ -771,8 +769,8 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) t = RE_ENTRY->x14; angle = RE_ENTRY->x1C; up = grBb_Route_803B83E0; - splGetSplinePoint(&pos, gp->gv.bigblueroute.xCC, t); - lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, t); + splGetSplinePoint(&pos, gp->u.car.xCC, t); + lbShadow_8000E9F0(&tangent, gp->u.car.xCC, t); grBigBlueRoute_8020DD64(&tangent); PSVECCrossProduct(&up, &tangent, &side); lbVector_RotateAboutUnitAxis(&side, &tangent, angle); @@ -821,9 +819,9 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) prog = (RE_ENTRY->x4 - RE_ENTRY->x24) / (1.0f - RE_ENTRY->x24); frac = ((1.0f - prog) * (RE_ENTRY->xC - 0.5f)) + 0.5f; - splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, RE_ENTRY->x4); - splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, RE_ENTRY->x4); - lbShadow_8000E9F0(&road_tan, gp->gv.bigblueroute.xD0, RE_ENTRY->x4); + splGetSplinePoint(&p0, gp->u.car.xD0, RE_ENTRY->x4); + splGetSplinePoint(&p1, gp->u.car.xD4, RE_ENTRY->x4); + lbShadow_8000E9F0(&road_tan, gp->u.car.xD0, RE_ENTRY->x4); lbVector_Diff(&p1, &p0, &road); road.x *= frac; road.y *= frac; @@ -836,8 +834,8 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) t = RE_ENTRY->x14; angle = RE_ENTRY->x1C; up = grBb_Route_803B83E0; - splGetSplinePoint(&air, gp->gv.bigblueroute.xCC, t); - lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, t); + splGetSplinePoint(&air, gp->u.car.xCC, t); + lbShadow_8000E9F0(&tangent, gp->u.car.xCC, t); grBigBlueRoute_8020DD64(&tangent); PSVECCrossProduct(&up, &tangent, &side); lbVector_RotateAboutUnitAxis(&side, &tangent, angle); @@ -884,8 +882,8 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) prog = (RE_ENTRY->x14 - RE_ENTRY->x24) / (1.0f - RE_ENTRY->x24); up = grBb_Route_803B83E0; angle = (1.0f - prog) * RE_ENTRY->x1C; - splGetSplinePoint(&air, gp->gv.bigblueroute.xCC, RE_ENTRY->x14); - lbShadow_8000E9F0(&tangent, gp->gv.bigblueroute.xCC, RE_ENTRY->x14); + splGetSplinePoint(&air, gp->u.car.xCC, RE_ENTRY->x14); + lbShadow_8000E9F0(&tangent, gp->u.car.xCC, RE_ENTRY->x14); grBigBlueRoute_8020DD64(&tangent); PSVECCrossProduct(&up, &tangent, &side); lbVector_RotateAboutUnitAxis(&side, &tangent, angle); @@ -906,9 +904,9 @@ void grBigBlueRoute_8020CD20(Ground_GObj* gobj) t = RE_ENTRY->x4; frac = RE_ENTRY->xC; - splGetSplinePoint(&p0, gp->gv.bigblueroute.xD0, t); - splGetSplinePoint(&p1, gp->gv.bigblueroute.xD4, t); - lbShadow_8000E9F0(&road_tan, gp->gv.bigblueroute.xD0, t); + splGetSplinePoint(&p0, gp->u.car.xD0, t); + splGetSplinePoint(&p1, gp->u.car.xD4, t); + lbShadow_8000E9F0(&road_tan, gp->u.car.xD0, t); lbVector_Diff(&p1, &p0, &road); road.x *= frac; road.y *= frac; diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index 2de0bf4bab..6870420200 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -1256,7 +1256,7 @@ struct grBigBlue_GroundVars { struct grBigBlueRoute_GroundVars { /* +0 gp+C4 */ HSD_GObj* xC4; - /* +4 gp+C8 */ void* xC8; + /* +4 gp+C8 */ void* car_info; /* +8 gp+CC */ HSD_Spline* xCC; /* +C gp+D0 */ HSD_Spline* xD0; /* +10 gp+D4 */ HSD_Spline* xD4; @@ -1618,7 +1618,6 @@ struct Ground { char pad_0[0x204 - 0xC4]; struct grArwing_GroundVars arwing; struct grBigBlue_GroundVars bigblue; - struct grBigBlueRoute_GroundVars bigblueroute; struct grBigBlueRoute_GroundVars2 bigblueroute2; struct grCastle_GroundVars castle; struct grCastle_GroundVars2 castle2; @@ -1735,6 +1734,7 @@ struct Ground { struct Map_GroundVars map; struct grPushOn_GroundVars pushon; struct ScrollVars scroll; + struct grBigBlueRoute_GroundVars car; } u; }; };