From f9820bd2268401a789c062212b016168e9a69029 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 4 Sep 2026 08:46:18 -0500 Subject: [PATCH] Fix crash when continuing without a save device saveLoadSlot() and uiSelectSaveNameEntered() both asserted SAVE.deviceCurrent != 0xFF unconditionally, crashing as soon as a player dismissed the "no save device found" prompt and tried to start a game or name a new save. Both now fall back to an in-memory-only slot (no device to persist to) instead of asserting, matching the "continue without a save device" flow the main menu cutscene already offers. Verified fixed on Dolphin/GameCube; built clean on Linux and GameCube (Docker). Co-Authored-By: Claude Sonnet 5 --- src/dusk/save/save.c | 8 +++++++- src/dusk/ui/dialog/save/uiselectsave.c | 20 ++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/dusk/save/save.c b/src/dusk/save/save.c index 71028594..9874680e 100644 --- a/src/dusk/save/save.c +++ b/src/dusk/save/save.c @@ -208,9 +208,15 @@ errorret_t saveSaveSlot() { } errorret_t saveLoadSlot() { - assertTrue(SAVE.deviceCurrent != 0xFF, "No current device"); assertTrue(SAVE.slotCurrent < SAVE_SLOT_COUNT, "Invalid slot index"); + if(SAVE.deviceCurrent == 0xFF) { + // No save device available, so we assume an empty slot. + saveSlotInit(&SAVE.slot); + SAVE.caches[SAVE.slotCurrent] = SAVE.slot.cachedData; + errorOk(); + } + errorChain(saveDeviceSlotRead( &SAVE.devices[SAVE.deviceCurrent], &SAVE.slot, diff --git a/src/dusk/ui/dialog/save/uiselectsave.c b/src/dusk/ui/dialog/save/uiselectsave.c index 12179ff8..ff20070b 100644 --- a/src/dusk/ui/dialog/save/uiselectsave.c +++ b/src/dusk/ui/dialog/save/uiselectsave.c @@ -99,20 +99,24 @@ void uiSelectSaveNameEntered( ) { if(!confirmed) return; - assertTrue(SAVE.deviceCurrent != 0xFF, "No current device"); const uint8_t index = UI_SELECT_SAVE.pendingNameIndex; saveslot_t slot; saveSlotInit(&slot); stringCopy(slot.cachedData.name, text, SAVE_SLOT_NAME_LENGTH); - errorret_t writeResult = saveDeviceSlotWrite( - &SAVE.devices[SAVE.deviceCurrent], &slot, index - ); - if(errorIsNotOk(writeResult)) { - errorCatch(errorPrint(writeResult)); - uiFatalErrorOpen(writeResult.state->message); - return; + // No save device available - proceed with an in-memory-only slot rather + // than writing to a device that doesn't exist (see saveLoadSlot()'s own + // comment on the same "continue without a save device" flow). + if(SAVE.deviceCurrent != 0xFF) { + errorret_t writeResult = saveDeviceSlotWrite( + &SAVE.devices[SAVE.deviceCurrent], &slot, index + ); + if(errorIsNotOk(writeResult)) { + errorCatch(errorPrint(writeResult)); + uiFatalErrorOpen(writeResult.state->message); + return; + } } SAVE.caches[index] = slot.cachedData;