From ffd0f7b53ac40dc8cbb9ebad9e6f29ea71896f35 Mon Sep 17 00:00:00 2001 From: "Daniel R." <47796739+polybiusproxy@users.noreply.github.com> Date: Fri, 6 Sep 2024 23:01:00 +0200 Subject: [PATCH] core/libraries/save_data: Implement wildcard searches on `sceSaveDataDirNameSearch` (#817) * libraries/save_data: Implement wildcards and params * clang-format --- .../libraries/kernel/thread_management.cpp | 4 +- src/core/libraries/save_data/savedata.cpp | 67 +++++++++++++++---- src/sdl_window.cpp | 11 +-- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index 919afcb4..8f97ed87 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -295,7 +295,7 @@ ScePthread PS4_SYSV_ABI scePthreadSelf() { int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr, const /*SceKernelCpumask*/ u64 mask) { - LOG_INFO(Kernel_Pthread, "called"); + LOG_DEBUG(Kernel_Pthread, "called"); if (pattr == nullptr || *pattr == nullptr) { return SCE_KERNEL_ERROR_EINVAL; @@ -387,7 +387,7 @@ int PS4_SYSV_ABI posix_pthread_attr_setstacksize(ScePthreadAttr* attr, size_t st } int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpumask*/ u64 mask) { - LOG_INFO(Kernel_Pthread, "called"); + LOG_DEBUG(Kernel_Pthread, "called"); if (thread == nullptr) { return SCE_KERNEL_ERROR_ESRCH; diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index 959a7570..779c922e 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -179,15 +179,21 @@ int PS4_SYSV_ABI sceSaveDataDeleteUser() { int PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond* cond, OrbisSaveDataDirNameSearchResult* result) { - if (cond == nullptr) + if (cond == nullptr || result == nullptr) return ORBIS_SAVE_DATA_ERROR_PARAMETER; - LOG_INFO(Lib_SaveData, "called"); + LOG_INFO(Lib_SaveData, "Number of directories = {}", result->dirNamesNum); const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / std::to_string(cond->userId) / game_serial; if (!mount_dir.empty() && std::filesystem::exists(mount_dir)) { - if (cond->dirName == nullptr || std::string_view(cond->dirName->data) - .empty()) { // look for all dirs if no dir is provided. - for (int i = 0; const auto& entry : std::filesystem::directory_iterator(mount_dir)) { + int maxDirNum = result->dirNamesNum; // Games set a maximum of directories to search for + int i = 0; + + if (cond->dirName == nullptr || std::string_view(cond->dirName->data).empty()) { + // Look for all dirs if no dir is provided. + for (const auto& entry : std::filesystem::directory_iterator(mount_dir)) { + if (i >= maxDirNum) + break; + if (std::filesystem::is_directory(entry.path()) && entry.path().filename().string() != "sdmemory") { // sceSaveDataDirNameSearch does not search for dataMemory1/2 dirs. @@ -199,13 +205,50 @@ int PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond* result->setNum = i; } } - } else { // Need a game to test. - LOG_ERROR(Lib_SaveData, "Check Me. sceSaveDataDirNameSearch: dirName = {}", - cond->dirName->data); - strncpy(result->dirNames[0].data, cond->dirName->data, 32); - result->hitNum = 1; - result->dirNamesNum = 1; - result->setNum = 1; + } else { + // Game checks for a specific directory. + LOG_INFO(Lib_SaveData, "dirName = {}", cond->dirName->data); + + // Games can pass '%' as a wildcard + // e.g. `SAVELIST%` searches for all folders with names starting with `SAVELIST` + std::string baseName(cond->dirName->data); + u64 wildcardPos = baseName.find('%'); + if (wildcardPos != std::string::npos) { + baseName = baseName.substr(0, wildcardPos); + } + + for (const auto& entry : std::filesystem::directory_iterator(mount_dir)) { + if (i >= maxDirNum) + break; + + if (std::filesystem::is_directory(entry.path())) { + std::string dirName = entry.path().filename().string(); + + if (wildcardPos != std::string::npos) { + if (dirName.compare(0, baseName.size(), baseName) != 0) { + continue; + } + } else if (wildcardPos == std::string::npos && dirName != cond->dirName->data) { + continue; + } + + strncpy(result->dirNames[i].data, cond->dirName->data, 32); + + i++; + result->hitNum = i; + result->dirNamesNum = i; + result->setNum = i; + } + } + } + + if (result->params != nullptr) { + Common::FS::IOFile file(mount_dir / cond->dirName->data / "param.txt", + Common::FS::FileAccessMode::Read); + if (file.IsOpen()) { + file.ReadRaw((void*)result->params, sizeof(OrbisSaveDataParam)); + file.Close(); + } } } else { result->hitNum = 0; diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index b83afd29..31460d07 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -194,11 +194,6 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { ax = Input::GetAxis(-0x80, 0x80, axisvalue); break; case SDLK_S: - if (event->key.mod == SDL_KMOD_LCTRL) { - // Trigger rdoc capture - VideoCore::TriggerCapture(); - break; - } axis = Input::Axis::LeftY; if (event->type == SDL_EVENT_KEY_DOWN) { axisvalue += 127; @@ -287,6 +282,12 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { } } break; + case SDLK_F12: + if (event->type == SDL_EVENT_KEY_DOWN) { + // Trigger rdoc capture + VideoCore::TriggerCapture(); + } + break; default: break; }