- Several SaveData functions. Dysmantle and we are doomed should save and load now.

This commit is contained in:
raziel1000 2024-07-04 01:51:46 -06:00
parent 3875c00281
commit 0ecc54032c
7 changed files with 488 additions and 92 deletions

View File

@ -18,7 +18,12 @@ void MntPoints::Mount(const std::filesystem::path& host_folder, const std::strin
m_mnt_pairs.push_back(pair); m_mnt_pairs.push_back(pair);
} }
void MntPoints::Unmount(const std::string& path) {} // TODO! void MntPoints::Unmount(const std::filesystem::path& host_folder, const std::string& guest_folder) {
auto it = std::remove_if(m_mnt_pairs.begin(), m_mnt_pairs.end(), [&](const MntPair& pair) {
return pair.guest_path == guest_folder;
});
m_mnt_pairs.erase(it, m_mnt_pairs.end());
}
void MntPoints::UnmountAll() { void MntPoints::UnmountAll() {
std::scoped_lock lock{m_mutex}; std::scoped_lock lock{m_mutex};

View File

@ -22,7 +22,7 @@ public:
virtual ~MntPoints() = default; virtual ~MntPoints() = default;
void Mount(const std::filesystem::path& host_folder, const std::string& guest_folder); void Mount(const std::filesystem::path& host_folder, const std::string& guest_folder);
void Unmount(const std::string& path); void Unmount(const std::filesystem::path& host_folder, const std::string& guest_folder);
void UnmountAll(); void UnmountAll();
std::string GetHostDirectory(const std::string& guest_directory); std::string GetHostDirectory(const std::string& guest_directory);
std::string GetHostFile(const std::string& guest_file); std::string GetHostFile(const std::string& guest_file);

View File

@ -227,7 +227,8 @@ int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) {
return SCE_KERNEL_ERROR_EEXIST; return SCE_KERNEL_ERROR_EEXIST;
} }
if (!std::filesystem::create_directory(dir_name)) { //CUSA02456: path = /aotl after sceSaveDataMount(mode = 1)
if (dir_name.empty() || !std::filesystem::create_directory(dir_name)) {
return SCE_KERNEL_ERROR_EIO; return SCE_KERNEL_ERROR_EIO;
} }

View File

@ -3,6 +3,26 @@
#pragma once #pragma once
constexpr int ORBIS_SAVE_DATA_ERROR_PARAMETER = 0x809f0000; constexpr int ORBIS_SAVE_DATA_ERROR_PARAMETER = 0x809F0000;
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_FOUND = 0x809f0008; // save data doesn't exist constexpr int ORBIS_SAVE_DATA_ERROR_NOT_INITIALIZED = 0x809F0001;
constexpr int ORBIS_SAVE_DATA_ERROR_EXISTS = 0x809f0007; // save data directory,same name exists constexpr int ORBIS_SAVE_DATA_ERROR_OUT_OF_MEMORY = 0x809F0002;
constexpr int ORBIS_SAVE_DATA_ERROR_BUSY = 0x809F0003;
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_MOUNTED = 0x809F0004;
constexpr int ORBIS_SAVE_DATA_ERROR_NO_PERMISSION = 0x809F0005;
constexpr int ORBIS_SAVE_DATA_ERROR_FINGERPRINT_MISMATCH = 0x809F0006;
constexpr int ORBIS_SAVE_DATA_ERROR_EXISTS = 0x809F0007;
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_FOUND = 0x809F0008;
constexpr int ORBIS_SAVE_DATA_ERROR_NO_SPACE_FS = 0x809F000A;
constexpr int ORBIS_SAVE_DATA_ERROR_INTERNAL = 0x809F000B;
constexpr int ORBIS_SAVE_DATA_ERROR_MOUNT_FULL = 0x809F000C;
constexpr int ORBIS_SAVE_DATA_ERROR_BAD_MOUNTED = 0x809F000D;
constexpr int ORBIS_SAVE_DATA_ERROR_FILE_NOT_FOUND = 0x809F000E;
constexpr int ORBIS_SAVE_DATA_ERROR_BROKEN = 0x809F000F;
constexpr int ORBIS_SAVE_DATA_ERROR_INVALID_LOGIN_USER = 0x809F0011;
constexpr int ORBIS_SAVE_DATA_ERROR_MEMORY_NOT_READY = 0x809F0012;
constexpr int ORBIS_SAVE_DATA_ERROR_BACKUP_BUSY = 0x809F0013;
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_REGIST_CALLBACK = 0x809F0015;
constexpr int ORBIS_SAVE_DATA_ERROR_BUSY_FOR_SAVING = 0x809F0016;
constexpr int ORBIS_SAVE_DATA_ERROR_LIMITATION_OVER = 0x809F0017;
constexpr int ORBIS_SAVE_DATA_ERROR_EVENT_BUSY = 0x809F0018;
constexpr int ORBIS_SAVE_DATA_ERROR_PARAMSFO_TRANSFER_TITLE_ID_NOT_FOUND = 0x809F0019;

View File

@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <span>
#include <vector>
#include <common/path_util.h> #include <common/path_util.h>
#include <common/singleton.h> #include <common/singleton.h>
#include <core/file_format/psf.h> #include <core/file_format/psf.h>
@ -13,8 +15,8 @@
#include "error_codes.h" #include "error_codes.h"
namespace Libraries::SaveData { namespace Libraries::SaveData {
static std::string g_mount_point = "/savedata0"; // temp mount point (todo) static std::string g_mount_point = "/savedata0"; // temp mount point (todo)
std::string game_serial;
int PS4_SYSV_ABI sceSaveDataAbort() { int PS4_SYSV_ABI sceSaveDataAbort() {
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); LOG_ERROR(Lib_SaveData, "(STUBBED) called");
@ -46,8 +48,14 @@ int PS4_SYSV_ABI sceSaveDataChangeInternal() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataCheckBackupData() { int PS4_SYSV_ABI sceSaveDataCheckBackupData(const OrbisSaveDataCheckBackupData* check) {
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
std::string mount_dir = mnt->GetHostFile(check->dirName->data);
if (!std::filesystem::exists(mount_dir)) {
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
}
LOG_INFO(Lib_SaveData, "called = {}", mount_dir);
return ORBIS_OK; return ORBIS_OK;
} }
@ -136,8 +144,14 @@ int PS4_SYSV_ABI sceSaveDataDebugTarget() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataDelete() { int PS4_SYSV_ABI sceSaveDataDelete(const OrbisSaveDataDelete* del) {
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(1) / game_serial / std::string(del->dirName->data);
LOG_INFO(Lib_SaveData, "called: dirname = {}, mount_dir = {}", (char*)del->dirName->data,
mount_dir.string());
if (std::filesystem::exists(mount_dir) && std::filesystem::is_directory(mount_dir)) {
std::filesystem::remove_all(mount_dir);
}
return ORBIS_OK; return ORBIS_OK;
} }
@ -161,8 +175,14 @@ int PS4_SYSV_ABI sceSaveDataDeleteUser() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataDirNameSearch() { int PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond* cond,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); OrbisSaveDataDirNameSearchResult* result) {
if (cond == nullptr || cond->dirName == nullptr)
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
LOG_ERROR(Lib_SaveData,
"TODO sceSaveDataDirNameSearch: search_dir_name = {}, key = {}, result = {}",
cond->dirName->data, (int)cond->key, (result->infos == nullptr));
return ORBIS_OK; return ORBIS_OK;
} }
@ -226,8 +246,22 @@ int PS4_SYSV_ABI sceSaveDataGetEventInfo() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataGetEventResult() { int PS4_SYSV_ABI sceSaveDataGetEventResult(const OrbisSaveDataEventParam* eventParam,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); OrbisSaveDataEvent* event) {
LOG_INFO(Lib_SaveData, "called sceSaveDataGetEventResult : null = {}", (eventParam == nullptr));
if (eventParam == nullptr)
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(1) / game_serial; // fix me
Common::FS::IOFile file(mount_dir / "param.txt", Common::FS::FileAccessMode::Read);
OrbisSaveDataParam* param = new OrbisSaveDataParam{};
file.ReadRaw<u8>(param, sizeof(OrbisSaveDataParam));
LOG_INFO(Lib_SaveData, "called");
event->userId = 1;
return ORBIS_OK; return ORBIS_OK;
} }
@ -241,8 +275,11 @@ int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataGetMountInfo() { int PS4_SYSV_ABI sceSaveDataGetMountInfo(const OrbisSaveDataMountPoint* mountPoint,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); OrbisSaveDataMountInfo* info) {
LOG_INFO(Lib_SaveData, "called");
info->blocks = ORBIS_SAVE_DATA_BLOCKS_MAX;
info->freeBlocks = ORBIS_SAVE_DATA_BLOCKS_MAX;
return ORBIS_OK; return ORBIS_OK;
} }
@ -261,13 +298,43 @@ int PS4_SYSV_ABI sceSaveDataGetSaveDataCount() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory() { int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory(const u32 userId, void* buf, const size_t bufSize,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); const int64_t offset) {
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(userId) / game_serial / "save_mem1.sav";
Common::FS::IOFile file(mount_dir, Common::FS::FileAccessMode::Read);
if (!file.IsOpen()) {
return false;
}
file.Seek(offset);
size_t nbytes = file.ReadRaw<u8>(buf, bufSize);
LOG_INFO(Lib_SaveData, "called: bufSize = {}, offset = {}", bufSize, offset, nbytes);
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2() { int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(OrbisSaveDataMemoryGet2* getParam) {
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(getParam->userId) / game_serial;
if (getParam == nullptr)
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
if (getParam->data != nullptr) {
Common::FS::IOFile file(mount_dir / "save_mem2.sav", Common::FS::FileAccessMode::Read);
if (!file.IsOpen()) {
return false;
}
file.Seek(getParam->data->offset);
size_t nbytes = file.ReadRaw<u8>(getParam->data->buf, getParam->data->bufSize);
LOG_INFO(Lib_SaveData, "called: bufSize = {}, offset = {}", getParam->data->bufSize,
getParam->data->offset);
}
if (getParam->param != nullptr) {
Common::FS::IOFile file1(mount_dir / "param.txt", Common::FS::FileAccessMode::Read);
size_t nbytes = file1.ReadRaw<u8>(getParam->param, sizeof(OrbisSaveDataParam));
}
return ORBIS_OK; return ORBIS_OK;
} }
@ -297,17 +364,23 @@ int PS4_SYSV_ABI sceSaveDataGetUpdatedDataCount() {
} }
int PS4_SYSV_ABI sceSaveDataInitialize() { int PS4_SYSV_ABI sceSaveDataInitialize() {
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); LOG_INFO(Lib_SaveData, "called");
static auto* param_sfo = Common::Singleton<PSF>::Instance();
game_serial = std::string(param_sfo->GetString("CONTENT_ID"), 7, 9);
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataInitialize2() { int PS4_SYSV_ABI sceSaveDataInitialize2() {
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); LOG_INFO(Lib_SaveData, "called");
static auto* param_sfo = Common::Singleton<PSF>::Instance();
game_serial = std::string(param_sfo->GetString("CONTENT_ID"), 7, 9);
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataInitialize3() { int PS4_SYSV_ABI sceSaveDataInitialize3() {
LOG_ERROR(Lib_SaveData, "(DUMMY) called"); LOG_INFO(Lib_SaveData, "called");
static auto* param_sfo = Common::Singleton<PSF>::Instance();
game_serial = std::string(param_sfo->GetString("CONTENT_ID"), 7, 9);
return ORBIS_OK; return ORBIS_OK;
} }
@ -326,18 +399,24 @@ int PS4_SYSV_ABI sceSaveDataIsMounted() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataLoadIcon() { int PS4_SYSV_ABI sceSaveDataLoadIcon(const OrbisSaveDataMountPoint* mountPoint,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); OrbisSaveDataIcon* icon) {
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
std::string mount_dir = mnt->GetHostFile(mountPoint->data);
LOG_INFO(Lib_SaveData, "called: dir = {}", mount_dir);
if (icon != nullptr) {
Common::FS::IOFile file(mount_dir + "/save_data.png", Common::FS::FileAccessMode::Read);
icon->bufSize = file.GetSize();
size_t nbytes = file.ReadRaw<u8>(icon->buf, icon->bufSize);
}
return ORBIS_OK; return ORBIS_OK;
} }
s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode, s32 saveDataMount(u32 user_id, char* dir_name, u32 mount_mode,
OrbisSaveDataMountResult* mount_result) { OrbisSaveDataMountResult* mount_result) {
auto* param_sfo = Common::Singleton<PSF>::Instance();
std::string id(param_sfo->GetString("CONTENT_ID"), 7, 9);
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(user_id) / "savedata" / id / dir_name; std::to_string(user_id) / game_serial / dir_name;
switch (mount_mode) { switch (mount_mode) {
case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY: case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY:
case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR:
@ -346,10 +425,9 @@ s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode,
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND; return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
} }
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance(); auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
mnt->Mount(mount_dir, g_mount_point);
mount_result->mount_status = 0; mount_result->mount_status = 0;
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16); std::strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
mnt->Mount(mount_dir, mount_result->mount_point.data);
} break; } break;
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE: case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE:
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY: case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY:
@ -357,17 +435,22 @@ s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode,
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR | case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON: ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON:
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF | case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF |
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON: { ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON:
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF: {
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
if (std::filesystem::exists(mount_dir)) { if (std::filesystem::exists(mount_dir)) {
std::strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
mnt->Mount(mount_dir, mount_result->mount_point.data);
mount_result->required_blocks = 0;
mount_result->mount_status = 0;
return ORBIS_SAVE_DATA_ERROR_EXISTS; return ORBIS_SAVE_DATA_ERROR_EXISTS;
} }
std::filesystem::create_directories(mount_dir); if (std::filesystem::create_directories(mount_dir)) {
std::strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance(); mnt->Mount(mount_dir, mount_result->mount_point.data);
mnt->Mount(mount_dir, g_mount_point); mount_result->mount_status = 1;
}
mount_result->mount_status = 1;
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
} break; } break;
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR:
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR | case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
@ -375,12 +458,10 @@ s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode,
if (!std::filesystem::exists(mount_dir)) { if (!std::filesystem::exists(mount_dir)) {
std::filesystem::create_directories(mount_dir); std::filesystem::create_directories(mount_dir);
} }
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance(); auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
mnt->Mount(mount_dir, g_mount_point); std::strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
mnt->Mount(mount_dir, mount_result->mount_point.data);
mount_result->mount_status = 1; mount_result->mount_status = 1;
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
} break; } break;
default: default:
UNREACHABLE(); UNREACHABLE();
@ -395,9 +476,9 @@ s32 PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
if (mount == nullptr) { if (mount == nullptr) {
return ORBIS_SAVE_DATA_ERROR_PARAMETER; return ORBIS_SAVE_DATA_ERROR_PARAMETER;
} }
LOG_INFO(Lib_SaveData, "called: mount = {}, mode = {}, blocks = {}", mount->dir_name->data, LOG_INFO(Lib_SaveData, "called: dirName = {}, mode = {}, blocks = {}", mount->dir_name->data,
mount->mount_mode, mount->blocks); mount->mount_mode, mount->blocks);
return saveDataMount(mount->user_id, std::string(mount->dir_name->data), mount->mount_mode, return saveDataMount(mount->user_id, (char*)mount->dir_name->data, mount->mount_mode,
mount_result); mount_result);
} }
@ -406,9 +487,9 @@ s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
if (mount == nullptr) { if (mount == nullptr) {
return ORBIS_SAVE_DATA_ERROR_PARAMETER; return ORBIS_SAVE_DATA_ERROR_PARAMETER;
} }
LOG_INFO(Lib_SaveData, "called: mount = {}, mode = {}, blocks = {}", mount->dir_name->data, LOG_INFO(Lib_SaveData, "called: dirName = {}, mode = {}, blocks = {}", mount->dir_name->data,
mount->mount_mode, mount->blocks); mount->mount_mode, mount->blocks);
return saveDataMount(mount->user_id, std::string(mount->dir_name->data), mount->mount_mode, return saveDataMount(mount->user_id, (char*)mount->dir_name->data, mount->mount_mode,
mount_result); mount_result);
} }
@ -457,8 +538,16 @@ int PS4_SYSV_ABI sceSaveDataRestoreLoadSaveDataMemory() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataSaveIcon() { int PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); const OrbisSaveDataIcon* icon) {
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
std::string mount_dir = mnt->GetHostFile(mountPoint->data);
LOG_INFO(Lib_SaveData, "called = {}", mount_dir);
if (icon != nullptr) {
Common::FS::IOFile file(mount_dir + "/save_data.png", Common::FS::FileAccessMode::Write);
file.WriteRaw<u8>((void*)icon->buf, icon->bufSize);
}
return ORBIS_OK; return ORBIS_OK;
} }
@ -472,8 +561,17 @@ int PS4_SYSV_ABI sceSaveDataSetEventInfo() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataSetParam() { int PS4_SYSV_ABI sceSaveDataSetParam(const OrbisSaveDataMountPoint* mountPoint,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); OrbisSaveDataParamType paramType, const void* paramBuf,
size_t paramBufSize) {
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
std::string mount_dir = mnt->GetHostFile(mountPoint->data);
LOG_INFO(Lib_SaveData, "called = {}, mountPoint->data = {}", mount_dir, mountPoint->data);
if (paramBuf != nullptr) {
Common::FS::IOFile file(mount_dir + "/param.txt", Common::FS::FileAccessMode::Write);
file.WriteRaw<u8>((void*)paramBuf, paramBufSize);
}
return ORBIS_OK; return ORBIS_OK;
} }
@ -482,23 +580,89 @@ int PS4_SYSV_ABI sceSaveDataSetSaveDataLibraryUser() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory() { int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory(const u32 userId, const void* buf,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); const size_t bufSize, const int64_t offset) {
LOG_INFO(Lib_SaveData, "called");
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(userId) / game_serial / "save_mem1.sav";
Common::FS::IOFile file(mount_dir, Common::FS::FileAccessMode::Write);
file.Seek(offset);
file.WriteRaw<u8>((void*)buf, bufSize);
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory2() { int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory2(const OrbisSaveDataMemorySet2* setParam) {
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); LOG_INFO(Lib_SaveData, "called: dataNum = {}, slotId= {}", setParam->dataNum, setParam->slotId);
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(setParam->userId) / game_serial;
if (setParam->data != nullptr) {
Common::FS::IOFile file(mount_dir / "save_mem2.sav", Common::FS::FileAccessMode::Write);
if (!file.IsOpen())
return -1;
file.Seek(setParam->data->offset);
file.WriteRaw<u8>((void*)setParam->data->buf, setParam->data->bufSize);
}
if (setParam->param != nullptr) {
Common::FS::IOFile file(mount_dir / "param.txt", Common::FS::FileAccessMode::Write);
file.WriteRaw<u8>((void*)setParam->param, sizeof(OrbisSaveDataParam));
}
if (setParam->icon != nullptr) {
Common::FS::IOFile file(mount_dir / "save_icon.png", Common::FS::FileAccessMode::Write);
file.WriteRaw<u8>((void*)setParam->icon->buf, setParam->icon->bufSize);
}
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory() { int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory(u32 userId, size_t memorySize,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); OrbisSaveDataParam* param) {
LOG_INFO(Lib_SaveData, "called:userId = {}, memorySize = {}", userId, memorySize);
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(userId) / game_serial;
if (std::filesystem::exists(mount_dir)) {
return ORBIS_SAVE_DATA_ERROR_EXISTS;
}
std::filesystem::create_directories(mount_dir);
std::vector<u8> buf(memorySize);
Common::FS::IOFile::WriteBytes(mount_dir / "save_mem1.sav", buf);
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2() { int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(const OrbisSaveDataMemorySetup2* setupParam,
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); OrbisSaveDataMemorySetupResult* result) {
if (setupParam == nullptr) {
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
}
LOG_INFO(Lib_SaveData, "called");
// if (setupParam->option == 1) { // check this later.
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(setupParam->userId) / game_serial;
if (std::filesystem::exists(mount_dir) &&
std::filesystem::exists(mount_dir / "save_mem2.sav")) {
Common::FS::IOFile file(mount_dir / "save_mem2.sav", Common::FS::FileAccessMode::Read);
if (!file.IsOpen())
return -1;
// Bunny - CUSA07988 has a null result, having null result is checked and valid.
if (result != nullptr)
result->existedMemorySize = file.GetSize(); // Assign the saved data size.
// do not return ORBIS_SAVE_DATA_ERROR_EXISTS, as it will not trigger
// sceSaveDataGetSaveDataMemory2.
} else {
std::filesystem::create_directories(mount_dir);
std::vector<u8> buf(setupParam->memorySize); // check if > 0x1000000 (16.77mb) or x2?
Common::FS::IOFile::WriteBytes(mount_dir / "save_mem2.sav", buf);
std::vector<u8> paramBuf(sizeof(OrbisSaveDataParam));
Common::FS::IOFile::WriteBytes(mount_dir / "param.txt", paramBuf);
std::vector<u8> iconBuf(setupParam->iconMemorySize);
Common::FS::IOFile::WriteBytes(mount_dir / "save_icon.png", iconBuf);
}
return ORBIS_OK; return ORBIS_OK;
} }
@ -517,8 +681,8 @@ int PS4_SYSV_ABI sceSaveDataSyncCloudList() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory() { int PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory(OrbisSaveDataMemorySync* syncParam) {
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); LOG_ERROR(Lib_SaveData, "(STUBBED) called: option = {}", syncParam->option);
return ORBIS_OK; return ORBIS_OK;
} }
@ -533,12 +697,16 @@ int PS4_SYSV_ABI sceSaveDataTransferringMount() {
} }
s32 PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint) { s32 PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint) {
LOG_INFO(Lib_SaveData, "mountPoint = {}", std::string(mountPoint->data));
if (std::string(mountPoint->data).empty()) { if (std::string(mountPoint->data).empty()) {
return ORBIS_SAVE_DATA_ERROR_PARAMETER; return ORBIS_SAVE_DATA_ERROR_NOT_MOUNTED;
} }
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(1) / game_serial / mountPoint->data;
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance(); auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
mnt->Unmount(std::string(mountPoint->data));
mnt->Unmount(mount_dir, mountPoint->data);
LOG_INFO(Lib_SaveData, "mountPoint = {}", std::string(mountPoint->data));
return ORBIS_OK; return ORBIS_OK;
} }
@ -547,8 +715,27 @@ int PS4_SYSV_ABI sceSaveDataUmountSys() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceSaveDataUmountWithBackup() { int PS4_SYSV_ABI sceSaveDataUmountWithBackup(const OrbisSaveDataMountPoint* mountPoint) {
LOG_ERROR(Lib_SaveData, "(STUBBED) called"); LOG_ERROR(Lib_SaveData, "called = {}", std::string(mountPoint->data));
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
std::string mount_dir = mnt->GetHostFile(mountPoint->data);
if (!std::filesystem::exists(mount_dir)) {
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
} else {
std::filesystem::path mnt_dir(mount_dir);
std::filesystem::create_directories(mnt_dir.parent_path() / "backup");
for (const auto& entry : std::filesystem::recursive_directory_iterator(mnt_dir)) {
const auto& path = entry.path();
std::filesystem::path target_path = mnt_dir.parent_path() / "backup";
if (std::filesystem::is_regular_file(path)) {
std::filesystem::copy(path, target_path,
std::filesystem::copy_options::overwrite_existing);
}
}
mnt->Unmount(mount_dir, mountPoint->data);
}
return ORBIS_OK; return ORBIS_OK;
} }

View File

@ -43,19 +43,18 @@ struct OrbisSaveDataMountResult {
}; };
constexpr int ORBIS_SAVE_DATA_TITLE_ID_DATA_SIZE = 10; constexpr int ORBIS_SAVE_DATA_TITLE_ID_DATA_SIZE = 10;
typedef struct OrbisSaveDataTitleId { struct OrbisSaveDataTitleId {
char data[ORBIS_SAVE_DATA_TITLE_ID_DATA_SIZE]; char data[ORBIS_SAVE_DATA_TITLE_ID_DATA_SIZE];
char padding[6]; char padding[6];
};
} OrbisSaveDataTitleId;
constexpr int ORBIS_SAVE_DATA_FINGERPRINT_DATA_SIZE = 65; constexpr int ORBIS_SAVE_DATA_FINGERPRINT_DATA_SIZE = 65;
typedef struct OrbisSaveDataFingerprint { struct OrbisSaveDataFingerprint {
char data[ORBIS_SAVE_DATA_FINGERPRINT_DATA_SIZE]; char data[ORBIS_SAVE_DATA_FINGERPRINT_DATA_SIZE];
char padding[15]; char padding[15];
} OrbisSaveDataFingerprint; };
typedef struct OrbisSaveDataMount { struct OrbisSaveDataMount {
s32 user_id; s32 user_id;
s32 pad; s32 pad;
const OrbisSaveDataTitleId* titleId; const OrbisSaveDataTitleId* titleId;
@ -64,7 +63,114 @@ typedef struct OrbisSaveDataMount {
u64 blocks; u64 blocks;
u32 mount_mode; u32 mount_mode;
u8 reserved[32]; u8 reserved[32];
} OrbisSaveDataMount; };
typedef u32 OrbisSaveDataParamType;
constexpr int ORBIS_SAVE_DATA_TITLE_MAXSIZE = 128;
constexpr int ORBIS_SAVE_DATA_SUBTITLE_MAXSIZE = 128;
constexpr int ORBIS_SAVE_DATA_DETAIL_MAXSIZE = 1024;
struct OrbisSaveDataParam {
char title[ORBIS_SAVE_DATA_TITLE_MAXSIZE];
char subTitle[ORBIS_SAVE_DATA_SUBTITLE_MAXSIZE];
char detail[ORBIS_SAVE_DATA_DETAIL_MAXSIZE];
u32 userParam;
int : 32;
time_t mtime;
u8 reserved[32];
};
struct OrbisSaveDataIcon {
void* buf;
size_t bufSize;
size_t dataSize;
u8 reserved[32];
};
typedef u32 OrbisSaveDataSaveDataMemoryOption;
#define ORBIS_SAVE_DATA_MEMORY_OPTION_NONE (0x00000000)
#define ORBIS_SAVE_DATA_MEMORY_OPTION_SET_PARAM (0x00000001 << 0)
#define ORBIS_SAVE_DATA_MEMORY_OPTION_DOUBLE_BUFFER (0x00000001 << 1)
struct OrbisSaveDataMemorySetup2 {
OrbisSaveDataSaveDataMemoryOption option;
s32 userId;
size_t memorySize;
size_t iconMemorySize;
const OrbisSaveDataParam* initParam;
const OrbisSaveDataIcon* initIcon;
u32 slotId;
u8 reserved[20];
};
struct OrbisSaveDataMemorySetupResult {
size_t existedMemorySize;
u8 reserved[16];
};
typedef u32 OrbisSaveDataEventType;
#define SCE_SAVE_DATA_EVENT_TYPE_INVALID (0)
#define SCE_SAVE_DATA_EVENT_TYPE_UMOUNT_BACKUP_END (1)
#define SCE_SAVE_DATA_EVENT_TYPE_BACKUP_END (2)
#define SCE_SAVE_DATA_EVENT_TYPE_SAVE_DATA_MEMORY_SYNC_END (3)
struct OrbisSaveDataEvent {
OrbisSaveDataEventType type;
s32 errorCode;
s32 userId;
u8 padding[4];
OrbisSaveDataTitleId titleId;
OrbisSaveDataDirName dirName;
u8 reserved[40];
};
struct OrbisSaveDataMemoryData {
void* buf;
size_t bufSize;
off_t offset;
u8 reserved[40];
};
struct OrbisSaveDataMemoryGet2 {
s32 userId;
u8 padding[4];
OrbisSaveDataMemoryData* data;
OrbisSaveDataParam* param;
OrbisSaveDataIcon* icon;
u32 slotId;
u8 reserved[28];
};
struct OrbisSaveDataMemorySet2 {
s32 userId;
u8 padding[4];
const OrbisSaveDataMemoryData* data;
const OrbisSaveDataParam* param;
const OrbisSaveDataIcon* icon;
u32 dataNum;
u8 slotId;
u8 reserved[24];
};
struct OrbisSaveDataCheckBackupData {
s32 userId;
int : 32;
const OrbisSaveDataTitleId* titleId;
const OrbisSaveDataDirName* dirName;
OrbisSaveDataParam* param;
OrbisSaveDataIcon* icon;
u8 reserved[32];
};
struct OrbisSaveDataMountInfo {
u64 blocks;
u64 freeBlocks;
u8 reserved[32];
};
#define ORBIS_SAVE_DATA_BLOCK_SIZE (32768)
#define ORBIS_SAVE_DATA_BLOCKS_MIN2 (96)
#define ORBIS_SAVE_DATA_BLOCKS_MAX (32768)
// savedataMount2 mountModes (ORed values) // savedataMount2 mountModes (ORed values)
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY = 1; constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY = 1;
@ -73,6 +179,69 @@ constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_CREATE = 4;
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF = 8; constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF = 8;
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON = 16; constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON = 16;
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 = 32; constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 = 32;
typedef struct _OrbisSaveDataEventParam OrbisSaveDataEventParam;
typedef u32 OrbisSaveDataSortKey;
#define ORBIS_SAVE_DATA_SORT_KEY_DIRNAME (0)
#define ORBIS_SAVE_DATA_SORT_KEY_USER_PARAM (1)
#define ORBIS_SAVE_DATA_SORT_KEY_BLOCKS (2)
#define ORBIS_SAVE_DATA_SORT_KEY_MTIME (3)
#define ORBIS_SAVE_DATA_SORT_KEY_FREE_BLOCKS (5)
typedef u32 OrbisSaveDataSortOrder;
#define ORBIS_SAVE_DATA_SORT_ORDER_ASCENT (0)
#define ORBIS_SAVE_DATA_SORT_ORDER_DESCENT (1)
struct OrbisSaveDataDirNameSearchCond {
s32 userId;
int : 32;
const OrbisSaveDataTitleId* titleId;
const OrbisSaveDataDirName* dirName;
OrbisSaveDataSortKey key;
OrbisSaveDataSortOrder order;
u8 reserved[32];
};
struct OrbisSaveDataSearchInfo {
u64 blocks;
u64 freeBlocks;
u8 reserved[32];
};
struct OrbisSaveDataDirNameSearchResult {
u32 hitNum;
int : 32;
OrbisSaveDataDirName* dirNames;
u32 dirNamesNum;
u32 setNum;
OrbisSaveDataParam* params;
OrbisSaveDataSearchInfo* infos;
u8 reserved[12];
int : 32;
};
struct OrbisSaveDataDelete {
s32 userId;
int : 32;
const OrbisSaveDataTitleId* titleId;
const OrbisSaveDataDirName* dirName;
u32 unused;
u8 reserved[32];
int : 32;
};
typedef u32 OrbisSaveDataMemorySyncOption;
#define SCE_SAVE_DATA_MEMORY_SYNC_OPTION_NONE (0x00000000)
#define SCE_SAVE_DATA_MEMORY_SYNC_OPTION_BLOCKING (0x00000001 << 0)
struct OrbisSaveDataMemorySync {
s32 userId;
u32 slotId;
OrbisSaveDataMemorySyncOption option;
u8 reserved[28];
};
int PS4_SYSV_ABI sceSaveDataAbort(); int PS4_SYSV_ABI sceSaveDataAbort();
int PS4_SYSV_ABI sceSaveDataBackup(); int PS4_SYSV_ABI sceSaveDataBackup();
@ -80,7 +249,7 @@ int PS4_SYSV_ABI sceSaveDataBindPsnAccount();
int PS4_SYSV_ABI sceSaveDataBindPsnAccountForSystemBackup(); int PS4_SYSV_ABI sceSaveDataBindPsnAccountForSystemBackup();
int PS4_SYSV_ABI sceSaveDataChangeDatabase(); int PS4_SYSV_ABI sceSaveDataChangeDatabase();
int PS4_SYSV_ABI sceSaveDataChangeInternal(); int PS4_SYSV_ABI sceSaveDataChangeInternal();
int PS4_SYSV_ABI sceSaveDataCheckBackupData(); int PS4_SYSV_ABI sceSaveDataCheckBackupData(const OrbisSaveDataCheckBackupData* check);
int PS4_SYSV_ABI sceSaveDataCheckBackupDataForCdlg(); int PS4_SYSV_ABI sceSaveDataCheckBackupDataForCdlg();
int PS4_SYSV_ABI sceSaveDataCheckBackupDataInternal(); int PS4_SYSV_ABI sceSaveDataCheckBackupDataInternal();
int PS4_SYSV_ABI sceSaveDataCheckCloudData(); int PS4_SYSV_ABI sceSaveDataCheckCloudData();
@ -98,12 +267,13 @@ int PS4_SYSV_ABI sceSaveDataDebugCreateSaveDataRoot();
int PS4_SYSV_ABI sceSaveDataDebugGetThreadId(); int PS4_SYSV_ABI sceSaveDataDebugGetThreadId();
int PS4_SYSV_ABI sceSaveDataDebugRemoveSaveDataRoot(); int PS4_SYSV_ABI sceSaveDataDebugRemoveSaveDataRoot();
int PS4_SYSV_ABI sceSaveDataDebugTarget(); int PS4_SYSV_ABI sceSaveDataDebugTarget();
int PS4_SYSV_ABI sceSaveDataDelete(); int PS4_SYSV_ABI sceSaveDataDelete(const OrbisSaveDataDelete* del);
int PS4_SYSV_ABI sceSaveDataDelete5(); int PS4_SYSV_ABI sceSaveDataDelete5();
int PS4_SYSV_ABI sceSaveDataDeleteAllUser(); int PS4_SYSV_ABI sceSaveDataDeleteAllUser();
int PS4_SYSV_ABI sceSaveDataDeleteCloudData(); int PS4_SYSV_ABI sceSaveDataDeleteCloudData();
int PS4_SYSV_ABI sceSaveDataDeleteUser(); int PS4_SYSV_ABI sceSaveDataDeleteUser();
int PS4_SYSV_ABI sceSaveDataDirNameSearch(); int PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond* cond,
OrbisSaveDataDirNameSearchResult* result);
int PS4_SYSV_ABI sceSaveDataDirNameSearchInternal(); int PS4_SYSV_ABI sceSaveDataDirNameSearchInternal();
int PS4_SYSV_ABI sceSaveDataDownload(); int PS4_SYSV_ABI sceSaveDataDownload();
int PS4_SYSV_ABI sceSaveDataGetAllSize(); int PS4_SYSV_ABI sceSaveDataGetAllSize();
@ -116,15 +286,18 @@ int PS4_SYSV_ABI sceSaveDataGetClientThreadPriority();
int PS4_SYSV_ABI sceSaveDataGetCloudQuotaInfo(); int PS4_SYSV_ABI sceSaveDataGetCloudQuotaInfo();
int PS4_SYSV_ABI sceSaveDataGetDataBaseFilePath(); int PS4_SYSV_ABI sceSaveDataGetDataBaseFilePath();
int PS4_SYSV_ABI sceSaveDataGetEventInfo(); int PS4_SYSV_ABI sceSaveDataGetEventInfo();
int PS4_SYSV_ABI sceSaveDataGetEventResult(); int PS4_SYSV_ABI sceSaveDataGetEventResult(const OrbisSaveDataEventParam* eventParam,
OrbisSaveDataEvent* event);
int PS4_SYSV_ABI sceSaveDataGetFormat(); int PS4_SYSV_ABI sceSaveDataGetFormat();
int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount(); int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount();
int PS4_SYSV_ABI sceSaveDataGetMountInfo(); int PS4_SYSV_ABI sceSaveDataGetMountInfo(const OrbisSaveDataMountPoint* mountPoint,
OrbisSaveDataMountInfo* info);
int PS4_SYSV_ABI sceSaveDataGetParam(); int PS4_SYSV_ABI sceSaveDataGetParam();
int PS4_SYSV_ABI sceSaveDataGetProgress(); int PS4_SYSV_ABI sceSaveDataGetProgress();
int PS4_SYSV_ABI sceSaveDataGetSaveDataCount(); int PS4_SYSV_ABI sceSaveDataGetSaveDataCount();
int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory(); int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory(const u32 userId, void* buf, const size_t bufSize,
int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(); const int64_t offset);
int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(OrbisSaveDataMemoryGet2* getParam);
int PS4_SYSV_ABI sceSaveDataGetSaveDataRootDir(); int PS4_SYSV_ABI sceSaveDataGetSaveDataRootDir();
int PS4_SYSV_ABI sceSaveDataGetSaveDataRootPath(); int PS4_SYSV_ABI sceSaveDataGetSaveDataRootPath();
int PS4_SYSV_ABI sceSaveDataGetSaveDataRootUsbPath(); int PS4_SYSV_ABI sceSaveDataGetSaveDataRootUsbPath();
@ -136,7 +309,8 @@ int PS4_SYSV_ABI sceSaveDataInitialize3();
int PS4_SYSV_ABI sceSaveDataInitializeForCdlg(); int PS4_SYSV_ABI sceSaveDataInitializeForCdlg();
int PS4_SYSV_ABI sceSaveDataIsDeletingUsbDb(); int PS4_SYSV_ABI sceSaveDataIsDeletingUsbDb();
int PS4_SYSV_ABI sceSaveDataIsMounted(); int PS4_SYSV_ABI sceSaveDataIsMounted();
int PS4_SYSV_ABI sceSaveDataLoadIcon(); int PS4_SYSV_ABI sceSaveDataLoadIcon(const OrbisSaveDataMountPoint* mountPoint,
OrbisSaveDataIcon* icon);
int PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount, int PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
OrbisSaveDataMountResult* mount_result); OrbisSaveDataMountResult* mount_result);
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount, s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
@ -150,24 +324,30 @@ int PS4_SYSV_ABI sceSaveDataRegisterEventCallback();
int PS4_SYSV_ABI sceSaveDataRestoreBackupData(); int PS4_SYSV_ABI sceSaveDataRestoreBackupData();
int PS4_SYSV_ABI sceSaveDataRestoreBackupDataForCdlg(); int PS4_SYSV_ABI sceSaveDataRestoreBackupDataForCdlg();
int PS4_SYSV_ABI sceSaveDataRestoreLoadSaveDataMemory(); int PS4_SYSV_ABI sceSaveDataRestoreLoadSaveDataMemory();
int PS4_SYSV_ABI sceSaveDataSaveIcon(); int PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint,
const OrbisSaveDataIcon* icon);
int PS4_SYSV_ABI sceSaveDataSetAutoUploadSetting(); int PS4_SYSV_ABI sceSaveDataSetAutoUploadSetting();
int PS4_SYSV_ABI sceSaveDataSetEventInfo(); int PS4_SYSV_ABI sceSaveDataSetEventInfo();
int PS4_SYSV_ABI sceSaveDataSetParam(); int PS4_SYSV_ABI sceSaveDataSetParam(const OrbisSaveDataMountPoint* mountPoint,
OrbisSaveDataParamType paramType, const void* paramBuf,
size_t paramBufSize);
int PS4_SYSV_ABI sceSaveDataSetSaveDataLibraryUser(); int PS4_SYSV_ABI sceSaveDataSetSaveDataLibraryUser();
int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory(); int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory(const u32 userId, const void* buf,
int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory2(); const size_t bufSize, const int64_t offset);
int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory(); int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory2(const OrbisSaveDataMemorySet2* setParam);
int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(); int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory(u32 userId, size_t memorySize,
OrbisSaveDataParam* param);
int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(const OrbisSaveDataMemorySetup2* setupParam,
OrbisSaveDataMemorySetupResult* result);
int PS4_SYSV_ABI sceSaveDataShutdownStart(); int PS4_SYSV_ABI sceSaveDataShutdownStart();
int PS4_SYSV_ABI sceSaveDataSupportedFakeBrokenStatus(); int PS4_SYSV_ABI sceSaveDataSupportedFakeBrokenStatus();
int PS4_SYSV_ABI sceSaveDataSyncCloudList(); int PS4_SYSV_ABI sceSaveDataSyncCloudList();
int PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory(); int PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory(OrbisSaveDataMemorySync* syncParam);
int PS4_SYSV_ABI sceSaveDataTerminate(); int PS4_SYSV_ABI sceSaveDataTerminate();
int PS4_SYSV_ABI sceSaveDataTransferringMount(); int PS4_SYSV_ABI sceSaveDataTransferringMount();
int PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint); int PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint);
int PS4_SYSV_ABI sceSaveDataUmountSys(); int PS4_SYSV_ABI sceSaveDataUmountSys();
int PS4_SYSV_ABI sceSaveDataUmountWithBackup(); int PS4_SYSV_ABI sceSaveDataUmountWithBackup(const OrbisSaveDataMountPoint* mountPoint);
int PS4_SYSV_ABI sceSaveDataUnregisterEventCallback(); int PS4_SYSV_ABI sceSaveDataUnregisterEventCallback();
int PS4_SYSV_ABI sceSaveDataUpload(); int PS4_SYSV_ABI sceSaveDataUpload();
int PS4_SYSV_ABI Func_02E4C4D201716422(); int PS4_SYSV_ABI Func_02E4C4D201716422();

View File

@ -85,6 +85,9 @@ void Emulator::Run(const std::filesystem::path& file) {
} }
mnt->Mount(mount_data_dir, "/data"); // should just exist, manually create with game serial mnt->Mount(mount_data_dir, "/data"); // should just exist, manually create with game serial
const auto& mount_temp_dir = Common::FS::GetUserPath(Common::FS::PathType::TempDataDir) / id; const auto& mount_temp_dir = Common::FS::GetUserPath(Common::FS::PathType::TempDataDir) / id;
if (!std::filesystem::exists(mount_temp_dir)) {
std::filesystem::create_directory(mount_temp_dir);
}
mnt->Mount(mount_temp_dir, "/temp0"); // called in app_content ==> stat/mkdir mnt->Mount(mount_temp_dir, "/temp0"); // called in app_content ==> stat/mkdir
// Initialize kernel and library facilities. // Initialize kernel and library facilities.