mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-14 08:12:16 +00:00
core/libraries/save_data: Implement wildcard searches on sceSaveDataDirNameSearch
(#817)
* libraries/save_data: Implement wildcards and params * clang-format
This commit is contained in:
parent
f1fd846762
commit
ffd0f7b53a
3 changed files with 63 additions and 19 deletions
|
@ -295,7 +295,7 @@ ScePthread PS4_SYSV_ABI scePthreadSelf() {
|
||||||
|
|
||||||
int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr,
|
int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr,
|
||||||
const /*SceKernelCpumask*/ u64 mask) {
|
const /*SceKernelCpumask*/ u64 mask) {
|
||||||
LOG_INFO(Kernel_Pthread, "called");
|
LOG_DEBUG(Kernel_Pthread, "called");
|
||||||
|
|
||||||
if (pattr == nullptr || *pattr == nullptr) {
|
if (pattr == nullptr || *pattr == nullptr) {
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
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) {
|
int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpumask*/ u64 mask) {
|
||||||
LOG_INFO(Kernel_Pthread, "called");
|
LOG_DEBUG(Kernel_Pthread, "called");
|
||||||
|
|
||||||
if (thread == nullptr) {
|
if (thread == nullptr) {
|
||||||
return SCE_KERNEL_ERROR_ESRCH;
|
return SCE_KERNEL_ERROR_ESRCH;
|
||||||
|
|
|
@ -179,15 +179,21 @@ int PS4_SYSV_ABI sceSaveDataDeleteUser() {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond* cond,
|
int PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond* cond,
|
||||||
OrbisSaveDataDirNameSearchResult* result) {
|
OrbisSaveDataDirNameSearchResult* result) {
|
||||||
if (cond == nullptr)
|
if (cond == nullptr || result == nullptr)
|
||||||
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
|
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) /
|
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
|
||||||
std::to_string(cond->userId) / game_serial;
|
std::to_string(cond->userId) / game_serial;
|
||||||
if (!mount_dir.empty() && std::filesystem::exists(mount_dir)) {
|
if (!mount_dir.empty() && std::filesystem::exists(mount_dir)) {
|
||||||
if (cond->dirName == nullptr || std::string_view(cond->dirName->data)
|
int maxDirNum = result->dirNamesNum; // Games set a maximum of directories to search for
|
||||||
.empty()) { // look for all dirs if no dir is provided.
|
int i = 0;
|
||||||
for (int i = 0; const auto& entry : std::filesystem::directory_iterator(mount_dir)) {
|
|
||||||
|
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()) &&
|
if (std::filesystem::is_directory(entry.path()) &&
|
||||||
entry.path().filename().string() != "sdmemory") {
|
entry.path().filename().string() != "sdmemory") {
|
||||||
// sceSaveDataDirNameSearch does not search for dataMemory1/2 dirs.
|
// sceSaveDataDirNameSearch does not search for dataMemory1/2 dirs.
|
||||||
|
@ -199,13 +205,50 @@ int PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond*
|
||||||
result->setNum = i;
|
result->setNum = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // Need a game to test.
|
} else {
|
||||||
LOG_ERROR(Lib_SaveData, "Check Me. sceSaveDataDirNameSearch: dirName = {}",
|
// Game checks for a specific directory.
|
||||||
cond->dirName->data);
|
LOG_INFO(Lib_SaveData, "dirName = {}", cond->dirName->data);
|
||||||
strncpy(result->dirNames[0].data, cond->dirName->data, 32);
|
|
||||||
result->hitNum = 1;
|
// Games can pass '%' as a wildcard
|
||||||
result->dirNamesNum = 1;
|
// e.g. `SAVELIST%` searches for all folders with names starting with `SAVELIST`
|
||||||
result->setNum = 1;
|
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<u8>((void*)result->params, sizeof(OrbisSaveDataParam));
|
||||||
|
file.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result->hitNum = 0;
|
result->hitNum = 0;
|
||||||
|
|
|
@ -194,11 +194,6 @@ void WindowSDL::onKeyPress(const SDL_Event* event) {
|
||||||
ax = Input::GetAxis(-0x80, 0x80, axisvalue);
|
ax = Input::GetAxis(-0x80, 0x80, axisvalue);
|
||||||
break;
|
break;
|
||||||
case SDLK_S:
|
case SDLK_S:
|
||||||
if (event->key.mod == SDL_KMOD_LCTRL) {
|
|
||||||
// Trigger rdoc capture
|
|
||||||
VideoCore::TriggerCapture();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
axis = Input::Axis::LeftY;
|
axis = Input::Axis::LeftY;
|
||||||
if (event->type == SDL_EVENT_KEY_DOWN) {
|
if (event->type == SDL_EVENT_KEY_DOWN) {
|
||||||
axisvalue += 127;
|
axisvalue += 127;
|
||||||
|
@ -287,6 +282,12 @@ void WindowSDL::onKeyPress(const SDL_Event* event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SDLK_F12:
|
||||||
|
if (event->type == SDL_EVENT_KEY_DOWN) {
|
||||||
|
// Trigger rdoc capture
|
||||||
|
VideoCore::TriggerCapture();
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue