Fix sound test menu reloc flood + SSB64_START_SCENE crash on exit#74
Merged
Fix sound test menu reloc flood + SSB64_START_SCENE crash on exit#74
Conversation
mnSoundTestUpdateNumberSprites value-copies digit Sprites with sobj->sprite = *lbRelocGetFileData(Sprite*, ...), bypassing the portFixupSprite/Bitmap/SpriteBitmapData chain that lbCommonMakeSObjForGObj normally applies. Only digit 0 happened to be fixed up (via the line-1421 SObj setup); digits 1-9 stayed in pass1-BSWAP32 form, so nbitmaps read 36 (originally ndisplist), the renderer walked 36 garbage Bitmaps, and lbCommonDrawSObjBitmap NULL-skipped every draw — selected-track digits didn't render and the log flooded with ~35k RelocPointerTable stale-token errors per session. Pre-fixup all 10 digits in mnSoundTestSetupFiles, mirroring the established ifCommonPlayerDamageSetDigitAttr pattern for the same file (llIFCommonPlayerDamageFileID). Separately, SSB64_START_SCENE=59 lets the user jump straight into Sound Test on a fresh save where LBBACKUP_UNLOCK_MASK_SOUNDTEST isn't set. mnDataInitVars then maps scene_prev=SoundTest -> sMNDataOption=SoundTest without validating against the unlock mask (the decomp assumes scene_prev can only name a reachable scene). Exiting back to Data crashed in mnDataSetOptionSpriteColors at offset 0xC8 because mnDataMakeSoundTest was skipped and sMNDataOptionSoundTestGObj stayed NULL. Restore the invariant at the override site by ORing LBBACKUP_UNLOCK_MASK_ALL into the backup data when SSB64_START_SCENE is honoured, so every consumer sees consistent state without each having to defend against the gap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related fixes for the Sound Test menu under the LP64 port. Independently confirmed via
SSB64_START_SCENE=59:src/mn/mndata/mnsoundtest.c— pre-fixup the 10 digit Sprites inllIFCommonPlayerDamageFileIDat file-load time.mnSoundTestUpdateNumberSpritesdoessobj->sprite = *lbRelocGetFileData(Sprite*, ...), which value-copies the digit Sprite from file data without going throughlbCommonMakeSObjForGObj. On LP64 the file has only had pass1 BSWAP32 applied, sonbitmapsreads as the originalndisplist(36) and the renderer walks 36 garbage Bitmap structs per draw. Symptom: selected-track digits never render and~35,000RelocPointerTable invalid/stale-token errors per session. Mirrors the existingifCommonPlayerDamageSetDigitAttrpattern (same file, same digit sprites, same trap, already fixed there).src/sc/scmanager.c— whenSSB64_START_SCENEhonours an override, ORLBBACKUP_UNLOCK_MASK_ALLintogSCManagerBackupData.unlock_mask. The decomp assumesscene_prevonly ever names a scene the player was allowed to reach; that invariant gatesmnDataMakeSoundTest()(and likely other unlock-conditional GObj setups). The override violates it on a fresh save: jumping into Sound Test and pressing B back to Data setssMNDataOption=SoundTestwhilesMNDataOptionSoundTestGObj=NULL, crashing inmnDataSetOptionSpriteColorsat offset 0xC8. Restoring the invariant at the override site (rather than clamping at every consumer) keeps mndata.c and any future unlock-conditional menus correct without per-site defensive guards.Verification
SSB64_START_SCENE=59+ navigate music/sounds/voices: digits render correctly across all 10 positions, RelocPointerTable error count went from35,003→0, NULL bitmap->buf log went from20→0.Test plan
SSB64_START_SCENE=59on fresh save: enter, scrub all three options, B-back to Data, exit to Title — should be clean.getenv("SSB64_START_SCENE") != NULL, so normal play is unaffected).🤖 Generated with Claude Code