Check for existing save data before saving, confirm before creating new
uiGameMenuSave() now attempts a real load first (via the existing generic
saveLoad()/saveExists() primitives) instead of writing blind. If a save
already exists, it saves straight over it as before. If not, it prompts
via the existing uiConfirm dialog ("No save data found. Create a new
save?") before writing - this is exactly the flow GameCube needs (no
native OS save browser to lean on, unlike PSP), but implemented generically
so it also applies correctly on every other platform without any
platform-specific UI code: saveIsAvailable()/saveExists() already reflect
each platform's real state (e.g. Dolphin's memory-card presence and
existing-file checks), so the same logic just does the right thing
everywhere.
Verified the two branches directly on Linux (temporarily wiring the same
saveLoad -> check -> uiConfirmOpen sequence into rpgInit): with no save
file, saveExists() is false and the confirm dialog opens; with one already
written, it's true and the confirm dialog is correctly skipped. Not
verified via actual menu navigation (no input-injection tooling available
here) or on Dolphin (no devkitPPC toolchain in this environment).
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "uigamemenu.h"
|
||||
#include "ui/frame/uiframe.h"
|
||||
#include "ui/frame/uiconfirm.h"
|
||||
#include "ui/frame/settings/uisettings.h"
|
||||
#include "ui/frame/backpack/uibackpack.h"
|
||||
#include "ui/rpg/textbox/uitextboxmain.h"
|
||||
@@ -29,7 +30,7 @@
|
||||
// slot-select UI yet, and SAVE_FILE_COUNT_MAX > 1 exists for later.
|
||||
#define UI_GAME_MENU_SAVE_SLOT 0
|
||||
|
||||
static void uiGameMenuSaveComplete(errorret_t result, void *user) {
|
||||
static void uiGameMenuSaveWriteComplete(errorret_t result, void *user) {
|
||||
if(errorIsNotOk(result)) {
|
||||
// Generously sized - stringFormat asserts (crashes) rather than
|
||||
// truncating if the message doesn't fit, so this must comfortably fit
|
||||
@@ -46,6 +47,43 @@ static void uiGameMenuSaveComplete(errorret_t result, void *user) {
|
||||
uiTextboxMainSetText("Game saved.");
|
||||
}
|
||||
|
||||
static void uiGameMenuSaveCreateConfirmed(const bool_t confirmed, void *user) {
|
||||
if(!confirmed) {
|
||||
uiTextboxMainSetText("Save cancelled.");
|
||||
return;
|
||||
}
|
||||
|
||||
saveWrite(UI_GAME_MENU_SAVE_SLOT, uiGameMenuSaveWriteComplete, NULL);
|
||||
}
|
||||
|
||||
// Determines whether there's actually save data to overwrite (not just
|
||||
// whether the medium is present) by attempting a real load first - this is
|
||||
// what lets a fresh memory card/stick, with no prior save on it yet, be
|
||||
// told apart from one that already has our data on it. Cheap either way
|
||||
// (a single sector/file read), and correct on every platform without any
|
||||
// platform-specific UI code - saveExists() already reflects each
|
||||
// platform's own notion of "found something."
|
||||
static void uiGameMenuSaveCheckComplete(errorret_t result, void *user) {
|
||||
if(errorIsNotOk(result)) {
|
||||
char_t msg[256];
|
||||
stringFormat(msg, sizeof(msg), "Can't save: %s", result.state->message);
|
||||
errorCatch(result);
|
||||
uiTextboxMainSetText(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if(saveExists(UI_GAME_MENU_SAVE_SLOT)) {
|
||||
saveWrite(UI_GAME_MENU_SAVE_SLOT, uiGameMenuSaveWriteComplete, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
uiConfirmOpen(
|
||||
"No save data found. Create a new save?",
|
||||
uiGameMenuSaveCreateConfirmed,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
static void uiGameMenuSave(void) {
|
||||
if(!saveIsAvailable()) {
|
||||
uiTextboxMainSetText("Can't save - no save device found.");
|
||||
@@ -53,7 +91,7 @@ static void uiGameMenuSave(void) {
|
||||
}
|
||||
if(saveIsBusy()) return;// A save/load dialog (e.g. on PSP) is already up.
|
||||
|
||||
saveWrite(UI_GAME_MENU_SAVE_SLOT, uiGameMenuSaveComplete, NULL);
|
||||
saveLoad(UI_GAME_MENU_SAVE_SLOT, uiGameMenuSaveCheckComplete, NULL);
|
||||
}
|
||||
|
||||
uigamemenu_t UI_GAME_MENU;
|
||||
|
||||
Reference in New Issue
Block a user