From a37441b221f29c0bf2dc513b4681520c3b89bf4c Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 8 Aug 2023 16:38:31 +0200 Subject: [PATCH] port: hackfix a bunch of UB and seg-related issues game now runs with -O2 --- src/game/bg.c | 12 ++++++++++-- src/game/chraction.c | 15 +++++++++++++++ src/game/game_1531a0.c | 2 ++ src/game/modeldef.c | 3 +++ src/game/race.c | 35 +++++++++++++++++++++++++++++++++++ src/include/data.h | 3 +++ src/include/types.h | 4 ++++ src/lib/audiomgr.c | 4 ++++ src/lib/mp3/decoder.c | 6 ++++++ 9 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/game/bg.c b/src/game/bg.c index 05e73f020..c05b5ce1d 100644 --- a/src/game/bg.c +++ b/src/game/bg.c @@ -3810,8 +3810,12 @@ bool bgTestHitOnObj(struct coord *arg0, struct coord *arg1, struct coord *arg2, hit = true; if (imggdl == NULL - || (imggdl->words.w1 & 0x0f000000) == 0x0f000000 - || (imggdl->words.w1 & 0x05000000) == 0x05000000) { +#ifdef PLATFORM_N64 + || (imggdl->words.w1 & 0x0f000000) == 0x0f000000 + || (imggdl->words.w1 & 0x05000000) == 0x05000000) { +#else // not sure if the above check even works right on N64, but we can test easily for seg addresses + || (imggdl->words.w1 & 1)) { +#endif texturenum = -1; } else { s32 tmp = PHYS_TO_K0(UNSEGADDR(imggdl->words.w1) - 8); @@ -4307,8 +4311,12 @@ bool bgTestHitInVtxBatch(struct coord *arg0, struct coord *arg1, struct coord *a } if (tmpgdl == gdl +#ifdef PLATFORM_N64 || (tmpgdl->words.w1 & 0x0f000000) == 0x0f000000 || (tmpgdl->words.w1 & 0x05000000) == 0x05000000) { +#else // not sure if the above check even works right on N64, but we can test easily for seg addresses + || (tmpgdl->words.w1 & 1)) { +#endif texturenum = -1; } else { s32 tmp = UNSEGADDR(tmpgdl->words.w1) - 8; diff --git a/src/game/chraction.c b/src/game/chraction.c index 831bac5c8..015559cb9 100644 --- a/src/game/chraction.c +++ b/src/game/chraction.c @@ -1306,6 +1306,21 @@ struct attackanimconfig g_AttackAnimDualRun = { ANIM_006E, 0, 0, 0, 0, - struct attackanimconfig g_AttackAnimDualCrossedWalk = { ANIM_006D, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 }; struct attackanimconfig g_AttackAnimDualCrossedRun = { ANIM_006F, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 }; +#ifdef AVOID_UB +// don't depend on global var order +struct attackanimconfig *g_AttackAnimArray[] = { + &g_AttackAnimHeavyWalk, + &g_AttackAnimHeavyRun, + &g_AttackAnimLightWalk, + &g_AttackAnimLightRun, + &g_AttackAnimDualWalk, + &g_AttackAnimDualRun, + &g_AttackAnimDualCrossedWalk, + &g_AttackAnimDualCrossedRun, + NULL +}; +#endif + struct attackanimconfig var80067c50[] = { { ANIM_0057, 0, 0, 1.5707963705063, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 }, { ANIM_0056, 0, 0, 4.7123889923096, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 }, diff --git a/src/game/game_1531a0.c b/src/game/game_1531a0.c index cbce0e2f0..5c7729897 100644 --- a/src/game/game_1531a0.c +++ b/src/game/game_1531a0.c @@ -119,9 +119,11 @@ u16 var8007fb3c[] = { u16 var8007fb5c[] = { 0xff00, 0xff58, 0xff74, 0xff90, 0xffac, 0xffc8, 0xffe4, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, +#ifndef AVOID_UB // these are actually loaded as one big palette }; u16 var8007fb7c[] = { +#endif 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff18, 0xff30, 0xff5c, 0xff88, 0xffb4, 0xffd8, 0xffff, }; diff --git a/src/game/modeldef.c b/src/game/modeldef.c index 06668c85e..0d0913ff7 100644 --- a/src/game/modeldef.c +++ b/src/game/modeldef.c @@ -104,6 +104,9 @@ struct skeleton *g_Skeletons[] = { &g_SkelWireFence, &g_SkelRemoteMine, &g_SkelBB, +#ifdef AVOID_UB + NULL // terminate list for sure +#endif }; void modeldef0f1a7560(struct modeldef *modeldef, u16 filenum, u32 arg2, struct modeldef *modeldef2, struct texpool *texpool, bool arg5) diff --git a/src/game/race.c b/src/game/race.c index 6285babbe..7e299c002 100644 --- a/src/game/race.c +++ b/src/game/race.c @@ -59,6 +59,33 @@ s32 raceInitAnimGroup(struct attackanimconfig *configs) return count; } +#ifdef AVOID_UB +// TODO: make raceInitAnimGroup call this or something +s32 raceInitAnimConfigSingle(struct attackanimconfig *config) +{ + s32 count = 0; + + + if (config->animnum != 0) { + u16 angle = raceGetAnimSumAngleAsInt(config->animnum, 0, floor(config->unk04)); + + if (config->unk04 > 0) { + if (angle < 0x8000) { + config->unk08 = angle * 0.00009585853695171f / config->unk04; + } else { + config->unk08 = (angle * 0.00009585853695171f - M_BADTAU) / config->unk04; + } + } else { + config->unk08 = 0; + } + + count++; + } + + return count; +} +#endif + void raceInitAnimGroups(struct attackanimgroup **groups) { s32 i; @@ -125,5 +152,13 @@ void raceInitAnims(void) } raceInitAnimGroup(g_RollAttackAnims); + +#ifdef AVOID_UB + // don't depend on globalvar order + for (s32 i = 0; g_AttackAnimArray[i]; ++i) { + raceInitAnimConfigSingle(g_AttackAnimArray[i]); + } +#else raceInitAnimGroup(&g_AttackAnimHeavyWalk); +#endif } diff --git a/src/include/data.h b/src/include/data.h index 6c6637b4b..d913fa477 100644 --- a/src/include/data.h +++ b/src/include/data.h @@ -187,6 +187,9 @@ extern struct attackanimconfig g_AttackAnimLightWalk; extern struct attackanimconfig g_AttackAnimLightRun; extern struct attackanimconfig g_AttackAnimDualWalk; extern struct attackanimconfig g_AttackAnimDualRun; +#ifdef AVOID_UB +extern struct attackanimconfig *g_AttackAnimArray[]; +#endif extern u32 g_StageFlags; extern struct chrdata *g_BgChrs; extern s16 *g_BgChrnums; diff --git a/src/include/types.h b/src/include/types.h index 43bfd9a5b..4e3f8737f 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -190,7 +190,11 @@ struct g_vars { /*0x35b*/ u8 alwaystick; /*0x35c*/ u16 updateframe; /*0x35e*/ u16 prevupdateframe; +#ifdef AVOID_UB // there will be an OOB access otherwise; this does fuck up the offsets here though + /*0x360*/ struct propstate propstates[8]; +#else /*0x360*/ struct propstate propstates[7]; +#endif /*0x424*/ struct chrdata *chrdata; /*0x428*/ struct truckobj *truck; /*0x42c*/ struct heliobj *heli; diff --git a/src/lib/audiomgr.c b/src/lib/audiomgr.c index 31e1f2aaa..4e1deff92 100644 --- a/src/lib/audiomgr.c +++ b/src/lib/audiomgr.c @@ -114,7 +114,9 @@ void amgrCreate(ALSynConfig *config) g_AudioManager.audioInfo[i]->data = alHeapAlloc(&g_SndHeap, 1, PAL ? 3688 : 1024 * 3); } +#ifndef AVOID_UB // these will be used after this scope ends, triggering a big boom { +#endif s32 sp590[] = { 0x00000001, 0x000014a0, 0x00000000, 0x00001358, 0x00004d0c, 0x00000000, 0x000053ff, 0x00000000, 0x00000000, 0x00000000 }; s32 sp568[] = { 0x00000001, 0x000001b8, 0x00000000, 0x00000068, 0x00004000, 0x00000000, 0x00007fff, 0x00001db0, 0x00001b58, 0x00000000 }; s32 sp540[] = { 0x00000001, 0x000001b8, 0x00000000, 0x00000068, 0x00000000, 0x00005fff, 0x00007fff, 0x0000017c, 0x000001f4, 0x00000000 }; @@ -138,7 +140,9 @@ void amgrCreate(ALSynConfig *config) config->params[i] = (s32 *) (IS4MB() ? sp198 : sp068); } } +#ifndef AVOID_UB } +#endif n_alInit(&g_AudioManager.g, config); func00030bfc(0, 60); diff --git a/src/lib/mp3/decoder.c b/src/lib/mp3/decoder.c index 81f62eb01..5751abbb0 100644 --- a/src/lib/mp3/decoder.c +++ b/src/lib/mp3/decoder.c @@ -2370,6 +2370,12 @@ bool mp3dec00040164(struct asistream *stream, u32 gr, u32 ch) sp1b4 = var700579b8[sp1bc].unk2e[sfb] * 3; } } else { +#ifdef AVOID_UB + if (sfb > 20) { + // avoid going out of unk00[] bounds + sp1b8 = 0; + } else +#endif sp1b8 = var700579b8[sp1bc].unk00[++sfb + 1]; } }