Fix PSP memory stick availability check on real hardware

sceIoGetstat on a bare device root ("ms0:/") returns EINVAL on real
PSP hardware even when a memory stick is present - confirmed via a
diagnostic print during hardware testing. Switched to sceIoDopen/
sceIoDclose, the SDK's own documented way to probe a device root,
which real hardware handles correctly.

Also adds a temporary unconditional settings write once a save device
is selected, to confirm the write path itself works on hardware now
that availability detection is fixed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 17:22:24 -05:00
parent e225a076f0
commit 28f5e66662
4 changed files with 16 additions and 7 deletions
+7
View File
@@ -75,6 +75,13 @@ errorret_t saveUpdate() {
// Reset slot, implying no slot has been selected.
SAVE.slotCurrent = 0xFF;
// TEST: write settings back out immediately once a device is
// selected, to confirm the write path actually works on hardware.
errorChain(saveDeviceSettingsWrite(
&SAVE.devices[SAVE.deviceCurrent],
&SAVE.settings
));
SAVE.findingAvailableDevice = false;
SAVE.findAvailableCallback(
&SAVE.devices[SAVE.deviceCurrent],
+1 -3
View File
@@ -23,7 +23,7 @@ void sceneInitialSaveDeviceRetryCallback(const uint8_t opt, void *u);
CUTSCENE(INITIAL, 0, DEFAULT,
CUTSCENE_MODAL(
"Checking for save data...",
"Checking for save data... Please wait."
"Please wait."
),
CUTSCENE_WAIT(1.0f),
CUTSCENE_CALLBACK(sceneInitialFindDevices),
@@ -58,8 +58,6 @@ void sceneInitialSaveDeviceRetryCallback(const uint8_t opt, void *u) {
cutsceneGoTo(opt == 0 ? "RETRY" : "CONTINUE");
}
errorret_t sceneInitialInit(scenedata_t *sceneData) {
assertNotNull(sceneData, "Scene data cannot be null");
memoryZero(&sceneData->initial, sizeof(sceneinitial_t));
-1
View File
@@ -517,7 +517,6 @@ errorret_t inputInitLinux(void) {
X("tab", INPUT_ACTION_CANCEL);
X("q", INPUT_ACTION_CANCEL);
X("escape", INPUT_ACTION_RAGEQUIT);
X("enter", INPUT_ACTION_PAUSE);
X("`", INPUT_ACTION_CONSOLE);
#endif
+8 -3
View File
@@ -38,13 +38,18 @@ void saveDevicePSPCheckAvailability(savedevice_t *device) {
// Confirm the memory stick is actually reachable - the real save/load
// (via sceUtilitySavedata) only reports failure once a save/load is
// attempted, so this is checked separately up front.
SceIoStat stat;
if(sceIoGetstat(SAVE_DEVICE_PSP_ROOT, &stat) < 0) {
// attempted, so this is checked separately up front. sceIoGetstat on a
// bare device root (e.g. "ms0:/") is unreliable on real hardware -
// confirmed returning EINVAL there even with a memory stick present -
// so open/close the root directory instead, which is the SDK's own
// documented way to probe a device (see sceIoDopen's doc comment).
SceUID dir = sceIoDopen(SAVE_DEVICE_PSP_ROOT);
if(dir < 0) {
device->state = SAVE_DEVICE_STATE_UNAVAILABLE;
device->reasonKey = "save.psp.no_memory_stick";
return saveDeviceFireCallback(device);
}
sceIoDclose(dir);
device->state = SAVE_DEVICE_STATE_AVAILABLE;
device->reasonKey = NULL;