mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-14 15:00:30 +02:00
Savedata: Keep the IO thread out of the dialog's state
Replaces the temporary fix that did the hidden modes' IO inside Update. The IO thread read and wrote the dialog's request, display state and save list, all shared with the emulator thread, which kept using them to draw the dialog and reload the request from the game. Now the IO thread works on its own copy of the request, its own SavedataParam and directory names resolved up front, and shares nothing else with the emulator thread but the (locked) file system, MemoryStick_FreeSpace's cached use and sceChnnlsv's scratch buffer and kirk state, the last two now under locks too. It still reads and writes the game's buffers directly, like a PSP's utility threads and sceIoReadAsync do, so a savestate waits for it before it saves or loads memory. Save bookkeeping, the save indicator and display changes happen on the emulator thread when the results are taken, and only the request fields the IO changed are copied back, so a game's own edits in the meantime survive. Hidden modes take the results at the next Update (or, with Host IO timing, the first Update that finds them done). The visible dialogs keep drawing and take them once the IO is done; save and load used to stall the emulator thread for the whole operation. Savestates keep results that haven't been taken yet. When the results land in PSP memory doesn't matter to games, so utility/savedata/filelist now only prints them once the utility has finished. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1f1c478c92
commit
9e69c1f9aa
10 files changed
+261
-139
No files matched your search
@@ -313,7 +313,7 @@ bool SavedataParam::HasKey(const SceUtilitySavedataParam *param) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SavedataParam::Delete(SceUtilitySavedataParam* param, int saveId) {
|
||||
bool SavedataParam::Delete(SceUtilitySavedataParam* param, const std::string &saveDir) {
|
||||
if (!param) {
|
||||
return false;
|
||||
}
|
||||
@@ -324,7 +324,7 @@ bool SavedataParam::Delete(SceUtilitySavedataParam* param, int saveId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string dirPath = GetSaveFilePath(param, GetSaveDir(saveId));
|
||||
std::string dirPath = GetSaveFilePath(param, saveDir);
|
||||
if (dirPath.size() == 0) {
|
||||
ERROR_LOG(Log::sceUtility, "GetSaveFilePath (%.*s) returned empty - cannot delete save directory. Might already be deleted?", (int)sizeof(param->gameName), param->gameName);
|
||||
return false;
|
||||
@@ -1281,7 +1281,7 @@ bool SavedataParam::GetList(SceUtilitySavedataParam *param)
|
||||
return true;
|
||||
}
|
||||
|
||||
int SavedataParam::GetFilesList(SceUtilitySavedataParam *param, u32 requestAddr) {
|
||||
int SavedataParam::GetFilesList(SceUtilitySavedataParam *param, u32 requestAddr, const std::string &saveDirName) {
|
||||
if (!param) {
|
||||
return SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_STATUS;
|
||||
}
|
||||
@@ -1339,7 +1339,7 @@ int SavedataParam::GetFilesList(SceUtilitySavedataParam *param, u32 requestAddr)
|
||||
requestPtr->bind = 1021;
|
||||
|
||||
// Does not list directories, nor recurse into them, and ignores files not ALL UPPERCASE.
|
||||
bool isCrypted = GetSaveCryptMode(param, GetSaveDirName(param, 0)) != 0;
|
||||
bool isCrypted = GetSaveCryptMode(param, saveDirName) != 0;
|
||||
for (const auto &file : files) {
|
||||
if (file.type == FILETYPE_DIRECTORY) {
|
||||
continue;
|
||||
@@ -1795,6 +1795,9 @@ std::string SavedataParam::GetFilename(int idx) const
|
||||
}
|
||||
|
||||
std::string SavedataParam::GetSaveDir(int idx) const {
|
||||
if (!saveDataList || idx < 0 || idx >= saveDataListCount) {
|
||||
return "";
|
||||
}
|
||||
return saveDataList[idx].saveDir;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user