9abf8101da
Rewrote savepsp.c/savestreampsp.c to use sceUtilitySavedataInitStart/ Update/GetStatus/ShutdownStart instead of sceIoOpen/Read/Write, so PSP saves get a proper OS-generated PARAM.SFO (title/savedataTitle/detail) and show up correctly in the native save browser. This dialog spans multiple frames and, per this project's prior experience with the network config dialog, must be pumped non-blocking one step per real engine frame rather than blocked on synchronously - a raw-sceGu blocking loop already froze the app on real hardware for that dialog, since pspGL owns the GU context. So save.h's saveWrite()/saveLoad() are now callback-based (savecallback_t onComplete) instead of returning a result directly, mirroring networkRequestConnection()'s shape, with a new saveUpdate() (wired into engineUpdate()) pumping the active op each frame. Linux/Dolphin behavior is unchanged - their fallback path in save.c still completes synchronously, just via an immediate callback call instead of a direct return. Two real bugs found via PPSSPP testing (not just code review): SAVE/LOAD modes show a confirm screen even for brand-new data, which blocks forever headlessly - switched to AUTOSAVE/AUTOLOAD, which write/read silently and generate the identical PARAM.SFO. And PPSSPP's dialog status goes straight from QUIT to NONE without a separately observable FINISHED in between, which the first version misread as "disappeared without a result" even on a successful save - fixed by tracking whether QUIT was already seen. Confirmed end-to-end in PPSSPP: write, dialog completes, PARAM.SFO + encrypted save.bin appear on the virtual memory stick, and a subsequent load decrypts/deserializes back to the exact original data. Not tested on real PSP hardware.