diff options
| author | quarrel07 <178681861+quarrel07@users.noreply.github.com> | 2026-08-01 23:29:56 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-01 22:29:56 -0600 |
| commit | 8629bec3205b35b6f052a5f0a0164b8132ac1304 (patch) | |
| tree | 45594c74a153377f618426ef62d77cb3a3db5a48 /src/racing | |
| parent | aa6c9c10caf3630ca37cb45bafc0485b76605445 (diff) | |
Fix the warning-flagged real bugs across the codebase (#691, 1 of 3) (#725)
* menu_items: fix the real-bug-tier compiler warnings (#691 batch 1)
Six fixes, all in menu_items.c, all verified by menu playtest on macOS:
- BSWAP16(*color0++) advanced the pointer twice per pixel on little-endian
builds (the macro evaluates its argument twice) and mixed bytes from two
different pixels. Read first, increment separately. Note: this function
(func_8009A9FC) currently has no callers, so the corruption was latent,
not live.
- func_8009B9D0 fell off the end on a lookup miss, returning garbage (the
existing code comment already suspected this). The miss path now returns
the display list head unchanged, i.e. draws nothing.
- update_ok_menu_item read an uninitialized stack slot for unknown menu
item types; now selects an explicit no-animation value, matching what
the garbage read did in practice.
- pause_menu_item_box_cursor: removed the three empty 'if (x2);' matching
artifacts. The x/y/z spin state itself is untouched.
- func_800A1FB0: initialized var_s4/var_s5 against the guarded-but-warned
switch default.
- func_800A54EC: initialized the pause cursor position pointer against its
unreachable mode-switch default (would have been a null-deref class bug
if mode values ever grew).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* collision: define the G_ENDDL opcode shifts, return 0 when no tyre surface found
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* replays: cast staff-ghost pointer comparisons, return 0 for empty ghost buffer
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* update_objects: return 0 from conditional step helpers, fix TLUT pointer comparison, init train draw distances
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* render_player: remove the impossible lamp range (vanilla bug, never glowed on N64 either)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* math_util_2: return the vector, not the address of the parameter slot
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Crab: remove inner declaration shadowing the initialized objectIndex
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* editor: honor InverseMatrix failure (bool was compared against 2, always true)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Track.h: drop dead null checks on array members
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* shells: drop always-true angle and surface gates (behavior unchanged, s16 made them tautological)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* particles: make the no-return particle setters void
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* effects/stubs/skybox/main: align signatures with functions that return nothing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* menus/save: type the pak status variable as s32, return BAD_READ on the fall-off path
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* audio: remove uninitialized-read matching artifacts, init isSound
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* code_80005FD0/code_80086E70: init dead bomb kart pointer and the no_init variable
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* port/engine UI: fix printf-style format types and non-literal format string
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* render_objects: feed the unused texture param to the uninitialized img walker
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Format the changed lines per .clang-format
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Address review: strip explanatory comments, drop vec3f pointer returns
Comments moved to the PR record; the one flagged worth keeping stays.
vec3f_set_xyz/normalize/cross_product return void now since the out
argument is the interface and nothing used the pointer.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Update actors_extended.c
* Add checkbox for 'Shells Shoot Straight' option
* Update render_player.c
* Update PortMenu.cpp
* Update render_player.c
* Update actors_extended.c
* Update render_player.c
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: MegaMech <MegaMech@users.noreply.github.com>
Diffstat (limited to 'src/racing')
| -rw-r--r-- | src/racing/actors_extended.c | 149 | ||||
| -rw-r--r-- | src/racing/collision.c | 12 | ||||
| -rw-r--r-- | src/racing/skybox_and_splitscreen.c | 5 | ||||
| -rw-r--r-- | src/racing/skybox_and_splitscreen.h | 2 |
4 files changed, 96 insertions, 72 deletions
diff --git a/src/racing/actors_extended.c b/src/racing/actors_extended.c index 8a1676f1c..b629ec4ce 100644 --- a/src/racing/actors_extended.c +++ b/src/racing/actors_extended.c @@ -438,81 +438,104 @@ void update_actor_triple_shell(TripleShellParent* parent, s16 shellType) { if (parent->firePressed > 0.0f) { // Fires a shell and resets firePressed to zero if (parent->shellIndices[0] > 0.0f) { shell = (struct ShellActor*) GET_ACTOR((s16) parent->shellIndices[0]); - if ((shell->rotAngle < 0x38E) || (shell->rotAngle >= -0x38D)) { - someVelocity[0] = 0; - someVelocity[1] = 0; - someVelocity[2] = 8; - func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); - shell->velocity[0] = someVelocity[0]; - shell->velocity[1] = someVelocity[1]; - shell->velocity[2] = someVelocity[2]; - shell->state = MOVING_SHELL; - shell->someTimer = 0x001E; - func_800C9060(parent->playerId, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x04)); - func_800C90F4(parent->playerId, - (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); - if (parent->type == ACTOR_TRIPLE_RED_SHELL) { - add_red_shell_in_unexpired_actor_list(parent->shellIndices[0]); - } else { - add_green_shell_in_unexpired_actor_list(parent->shellIndices[0]); + /** + * Below is a feature that continues holding triple shells until they are aiming forward. + * In decomp the three gShellsShootStraight conditions always evaluated to true, + * thus negating the feature from ever working. + * It has been re-added in for experimental purposes with slight adjustments + * to behave correctly and for clean code. + */ + if (CVarGetInteger("gShellsShootStraight", 0)) { + // Forces shell 1 to fire inside a cone of -5 to +5 degrees + if ((shell->rotAngle < -0x38E) || (shell->rotAngle > 0x38E)) { + break; } - parent->shellIndices[0] = -1.0f; - parent->shellsAvailable -= 1; - parent->firePressed -= 1.0f; - break; } + someVelocity[0] = 0; + someVelocity[1] = 0; + someVelocity[2] = 8; + func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); + shell->velocity[0] = someVelocity[0]; + shell->velocity[1] = someVelocity[1]; + shell->velocity[2] = someVelocity[2]; + shell->state = MOVING_SHELL; + shell->someTimer = 0x001E; + func_800C9060(parent->playerId, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x04)); + func_800C90F4(parent->playerId, + (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); + if (parent->type == ACTOR_TRIPLE_RED_SHELL) { + add_red_shell_in_unexpired_actor_list(parent->shellIndices[0]); + } else { + add_green_shell_in_unexpired_actor_list(parent->shellIndices[0]); + } + parent->shellIndices[0] = -1.0f; + parent->shellsAvailable -= 1; + parent->firePressed -= 1.0f; + break; } if (parent->shellIndices[1] > 0.0f) { shell = (struct ShellActor*) GET_ACTOR((s16) parent->shellIndices[1]); - if ((shell->rotAngle < 0xAA1) || (shell->rotAngle >= 0x38F)) { - someVelocity[0] = 0; - someVelocity[1] = 0; - someVelocity[2] = 8; - func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); - shell->velocity[0] = someVelocity[0]; - shell->velocity[1] = someVelocity[1]; - shell->velocity[2] = someVelocity[2]; - shell->state = MOVING_SHELL; - shell->someTimer = 0x001E; - func_800C90F4(parent->playerId, - (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); - func_800C9060(parent->playerId, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x04)); - if (parent->type == ACTOR_TRIPLE_RED_SHELL) { - add_red_shell_in_unexpired_actor_list(parent->shellIndices[1]); - } else { - add_green_shell_in_unexpired_actor_list(parent->shellIndices[1]); + if (CVarGetInteger("gShellsShootStraight", 0)) { + // Forces shell 2 to fire inside a cone of 5 to 14.95 degrees + if ((shell->rotAngle < 0x38E) || (shell->rotAngle > 0xAA1)) { + break; } - parent->shellIndices[1] = -1.0f; - parent->shellsAvailable -= 1; - parent->firePressed -= 1.0f; - break; } + someVelocity[0] = 0; + someVelocity[1] = 0; + someVelocity[2] = 8; + func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); + shell->velocity[0] = someVelocity[0]; + shell->velocity[1] = someVelocity[1]; + shell->velocity[2] = someVelocity[2]; + shell->state = MOVING_SHELL; + shell->someTimer = 0x001E; + func_800C90F4(parent->playerId, + (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); + func_800C9060(parent->playerId, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x04)); + if (parent->type == ACTOR_TRIPLE_RED_SHELL) { + add_red_shell_in_unexpired_actor_list(parent->shellIndices[1]); + } else { + add_green_shell_in_unexpired_actor_list(parent->shellIndices[1]); + } + parent->shellIndices[1] = -1.0f; + parent->shellsAvailable -= 1; + parent->firePressed -= 1.0f; + break; } if (parent->shellIndices[2] > 0.0f) { shell = (struct ShellActor*) GET_ACTOR((s16) parent->shellIndices[2]); - if ((shell->rotAngle < -0x38E) || (shell->rotAngle >= -0x71B)) { - someVelocity[0] = 0; - someVelocity[1] = 0; - someVelocity[2] = 8; - func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); - shell->velocity[0] = someVelocity[0]; - shell->velocity[1] = someVelocity[1]; - shell->velocity[2] = someVelocity[2]; - shell->state = MOVING_SHELL; - shell->someTimer = 0x001E; - func_800C9060(parent->playerId, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x04)); - func_800C90F4(parent->playerId, - (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); - if (parent->type == ACTOR_TRIPLE_RED_SHELL) { - add_red_shell_in_unexpired_actor_list(parent->shellIndices[2]); - } else { - add_green_shell_in_unexpired_actor_list(parent->shellIndices[2]); + if (CVarGetInteger("gShellsShootStraight", 0)) { + /** + * Forces shell 3 to fire inside a cone of -5 to -14.95 degrees + * -0xAA1 was originally -10 degrees (0x71C). However, + * shell 3 would continue looping for a bit so it's been adjusted to mirror shell 2 + */ + if ((shell->rotAngle < -0xAA1) || (shell->rotAngle > -0x38E)) { + break; } - parent->shellIndices[2] = -1.0f; - parent->shellsAvailable -= 1; - parent->firePressed -= 1.0f; - break; } + someVelocity[0] = 0; + someVelocity[1] = 0; + someVelocity[2] = 8; + func_802B64C4(someVelocity, player->rotation[1] + player->unk_0C0); + shell->velocity[0] = someVelocity[0]; + shell->velocity[1] = someVelocity[1]; + shell->velocity[2] = someVelocity[2]; + shell->state = MOVING_SHELL; + shell->someTimer = 0x001E; + func_800C9060(parent->playerId, SOUND_ARG_LOAD(0x19, 0x00, 0x80, 0x04)); + func_800C90F4(parent->playerId, + (player->characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x00)); + if (parent->type == ACTOR_TRIPLE_RED_SHELL) { + add_red_shell_in_unexpired_actor_list(parent->shellIndices[2]); + } else { + add_green_shell_in_unexpired_actor_list(parent->shellIndices[2]); + } + parent->shellIndices[2] = -1.0f; + parent->shellsAvailable -= 1; + parent->firePressed -= 1.0f; + break; } } break; diff --git a/src/racing/collision.c b/src/racing/collision.c index fd653df96..225dee00e 100644 --- a/src/racing/collision.c +++ b/src/racing/collision.c @@ -24,7 +24,7 @@ void nullify_displaylist(uintptr_t addr) { Gfx* macro; macro = (Gfx*) addr; - macro->words.w0 = (G_ENDDL << 24); + macro->words.w0 = ((u32) (G_ENDDL & 0xFF) << 24); macro->words.w1 = 0; } @@ -689,10 +689,10 @@ UNUSED s32 detect_tyre_collision(KartTyre* tyre) { } tyre->baseHeight = tyreY; tyre->surfaceType = 0; - //! @bug - // Another function that has a return value but doesn't have an explicit return statement in one of its codepaths. - // The return value at this point will be whatever was last returned by func_802AAE4C/func_802AB6C4/func_802AB288 - // depending on which (if any) if statements were entered on the loop's last cycle + // Used to fall off the end here (see git history for the original @bug + // note): the return value was whatever the last helper call left behind. + // No surface was found, so report no collision. + return 0; } s32 is_colliding_with_drivable_surface(struct Collision* collision, f32 boundingBoxSize, f32 newX, f32 newY, f32 newZ, @@ -2187,7 +2187,7 @@ void find_vtx_and_set_colours(Gfx* displayList, s8 alpha, u8 red, u8 green, u8 b lo = gfx->words.w0; hi = gfx->words.w1; opcode = GFX_GET_OPCODE(lo); - if (opcode == (G_ENDDL << 24)) { + if (opcode == ((u32) (G_ENDDL & 0xFF) << 24)) { break; } else if (opcode == (G_DL << 24)) { find_vtx_and_set_colours((Gfx*) hi, alpha, red, green, blue); diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index dff50e117..c669f59d1 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -257,7 +257,7 @@ UNUSED void func_802A40D4(void) { UNUSED void func_802A40DC(void) { } -UNUSED s32 set_viewport2(void) { +UNUSED void set_viewport2(void) { gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gScreenOneCtx->viewport)); gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); gSPSetGeometryMode(gDisplayListHead++, @@ -623,7 +623,8 @@ void render_screens(ScreenContext* screen, s32 mode, s32 someId, s32 playerId) { s32 screenId = screen - gScreenContexts; if (NULL == camera) { - printf("[skybox_and_splitscreen.c] Skipping rendering for screen %d. This viewport has no camera\n", screen - gScreenContexts); + printf("[skybox_and_splitscreen.c] Skipping rendering for screen %ld. This viewport has no camera\n", + (long) (screen - gScreenContexts)); return; } diff --git a/src/racing/skybox_and_splitscreen.h b/src/racing/skybox_and_splitscreen.h index 38748f36a..81be1edf3 100644 --- a/src/racing/skybox_and_splitscreen.h +++ b/src/racing/skybox_and_splitscreen.h @@ -26,7 +26,7 @@ void func_802A40C4(void); void func_802A40CC(void); void func_802A40D4(void); void func_802A40DC(void); -s32 set_viewport2(void); +void set_viewport2(void); void set_viewport(void); void select_framebuffer(void); void func_802A4300(void); |
