Merge pull request #233 from shadps4-emu/miscFixes2

Misc Fixes
This commit is contained in:
georgemoralis 2024-07-05 09:36:01 +03:00 committed by GitHub
commit 67af53fd58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 566 additions and 105 deletions

3
.gitmodules vendored
View File

@ -58,3 +58,6 @@
[submodule "externals/tracy"] [submodule "externals/tracy"]
path = externals/tracy path = externals/tracy
url = https://github.com/shadps4-emu/tracy.git url = https://github.com/shadps4-emu/tracy.git
[submodule "externals/hwinfo"]
path = externals/hwinfo
url = https://github.com/lfreist/hwinfo.git

View File

@ -544,7 +544,7 @@ endif()
create_target_directory_groups(shadps4) create_target_directory_groups(shadps4)
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient) target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient hwinfo::HWinfo)
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::SPIRV glslang::glslang SDL3::SDL3) target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::SPIRV glslang::glslang SDL3::SDL3)
if (NOT ENABLE_QT_GUI) if (NOT ENABLE_QT_GUI)

View File

@ -140,3 +140,6 @@ option(TRACY_ON_DEMAND "" ON)
option(TRACY_NO_FRAME_IMAGE "" ON) option(TRACY_NO_FRAME_IMAGE "" ON)
option(TRACY_FIBERS "" ON) # For AmdGpu frontend profiling option(TRACY_FIBERS "" ON) # For AmdGpu frontend profiling
add_subdirectory(tracy) add_subdirectory(tracy)
# hwinfo
add_subdirectory(hwinfo)

1
externals/hwinfo vendored Submodule

@ -0,0 +1 @@
Subproject commit 81ea6332fd4839890b1904f9668865145450f8da

View File

@ -20,7 +20,11 @@ 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

@ -52,7 +52,7 @@ int PS4_SYSV_ABI sceAppContentAddcontUnmount() {
int PS4_SYSV_ABI sceAppContentAppParamGetInt(OrbisAppContentAppParamId paramId, s32* value) { int PS4_SYSV_ABI sceAppContentAppParamGetInt(OrbisAppContentAppParamId paramId, s32* value) {
if (value == nullptr) if (value == nullptr)
return 0x80D90002; return ORBIS_APP_CONTENT_ERROR_PARAMETER;
auto* param_sfo = Common::Singleton<PSF>::Instance(); auto* param_sfo = Common::Singleton<PSF>::Instance();
switch (paramId) { switch (paramId) {
case ORBIS_APP_CONTENT_APPPARAM_ID_SKU_FLAG: case ORBIS_APP_CONTENT_APPPARAM_ID_SKU_FLAG:
@ -70,9 +70,18 @@ int PS4_SYSV_ABI sceAppContentAppParamGetInt(OrbisAppContentAppParamId paramId,
case ORBIS_APP_CONTENT_APPPARAM_ID_USER_DEFINED_PARAM_4: case ORBIS_APP_CONTENT_APPPARAM_ID_USER_DEFINED_PARAM_4:
*value = param_sfo->GetInteger("USER_DEFINED_PARAM_4"); *value = param_sfo->GetInteger("USER_DEFINED_PARAM_4");
break; break;
default:
LOG_ERROR(Lib_AppContent, " paramId = {}, value = {} paramId is not valid", paramId,
*value);
return ORBIS_APP_CONTENT_ERROR_PARAMETER;
} }
LOG_ERROR(Lib_AppContent, " paramId = {}, value = {}", paramId, *value); if (*value == -1) {
return *value == -1 ? 0x80D90005 : ORBIS_OK; LOG_ERROR(Lib_AppContent,
" paramId = {}, value = {} value is not valid can't read param.sfo?", paramId,
*value);
return ORBIS_APP_CONTENT_ERROR_PARAMETER;
}
return ORBIS_OK;
} }
int PS4_SYSV_ABI sceAppContentAppParamGetString() { int PS4_SYSV_ABI sceAppContentAppParamGetString() {
@ -120,8 +129,11 @@ int PS4_SYSV_ABI sceAppContentGetAddcontInfo() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceAppContentGetAddcontInfoList() { int PS4_SYSV_ABI sceAppContentGetAddcontInfoList(u32 service_label,
LOG_ERROR(Lib_AppContent, "(STUBBED) called"); OrbisAppContentAddcontInfo* list, u32 list_num,
u32* hit_num) {
*hit_num = 0;
LOG_ERROR(Lib_AppContent, "(DUMMY) called");
return ORBIS_OK; return ORBIS_OK;
} }

View File

@ -31,22 +31,29 @@ struct OrbisAppContentBootParam {
}; };
typedef u32 OrbisAppContentTemporaryDataOption; typedef u32 OrbisAppContentTemporaryDataOption;
constexpr int ORBIS_APP_CONTENT_MOUNTPOINT_DATA_MAXSIZE = 16;
typedef struct OrbisAppContentMountPoint {
constexpr int ORBIS_APP_CONTENT_MOUNTPOINT_DATA_MAXSIZE = 16;
struct OrbisAppContentMountPoint {
char data[ORBIS_APP_CONTENT_MOUNTPOINT_DATA_MAXSIZE]; char data[ORBIS_APP_CONTENT_MOUNTPOINT_DATA_MAXSIZE];
} OrbisAppContentMountPoint; };
constexpr int ORBIS_APP_CONTENT_TEMPORARY_DATA_OPTION_NONE = 0; constexpr int ORBIS_APP_CONTENT_TEMPORARY_DATA_OPTION_NONE = 0;
constexpr int ORBIS_APP_CONTENT_TEMPORARY_DATA_OPTION_FORMAT = (1 << 0); constexpr int ORBIS_APP_CONTENT_TEMPORARY_DATA_OPTION_FORMAT = (1 << 0);
constexpr int ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE = 17; constexpr int ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE = 17;
typedef struct OrbisNpUnifiedEntitlementLabel {
struct OrbisNpUnifiedEntitlementLabel {
char data[ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE]; char data[ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE];
} OrbisNpUnifiedEntitlementLabel; char padding[3];
};
typedef u32 OrbisAppContentAppParamId; typedef u32 OrbisAppContentAppParamId;
struct OrbisAppContentAddcontInfo {
OrbisNpUnifiedEntitlementLabel entitlement_label;
u32 status;
};
int PS4_SYSV_ABI _Z5dummyv(); int PS4_SYSV_ABI _Z5dummyv();
int PS4_SYSV_ABI sceAppContentAddcontDelete(); int PS4_SYSV_ABI sceAppContentAddcontDelete();
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownload(); int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownload();
@ -64,7 +71,9 @@ int PS4_SYSV_ABI sceAppContentDownloadDataFormat();
int PS4_SYSV_ABI sceAppContentDownloadDataGetAvailableSpaceKb(); int PS4_SYSV_ABI sceAppContentDownloadDataGetAvailableSpaceKb();
int PS4_SYSV_ABI sceAppContentGetAddcontDownloadProgress(); int PS4_SYSV_ABI sceAppContentGetAddcontDownloadProgress();
int PS4_SYSV_ABI sceAppContentGetAddcontInfo(); int PS4_SYSV_ABI sceAppContentGetAddcontInfo();
int PS4_SYSV_ABI sceAppContentGetAddcontInfoList(); int PS4_SYSV_ABI sceAppContentGetAddcontInfoList(u32 service_label,
OrbisAppContentAddcontInfo* list, u32 list_num,
u32* hit_num);
int PS4_SYSV_ABI sceAppContentGetEntitlementKey(); int PS4_SYSV_ABI sceAppContentGetEntitlementKey();
int PS4_SYSV_ABI sceAppContentGetRegion(); int PS4_SYSV_ABI sceAppContentGetRegion();
int PS4_SYSV_ABI sceAppContentInitialize(const OrbisAppContentInitParam* initParam, int PS4_SYSV_ABI sceAppContentInitialize(const OrbisAppContentInitParam* initParam,

View File

@ -453,3 +453,6 @@ constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_HANDLE = 0x80551608;
constexpr int ORBIS_NP_TROPHY_ERROR_HANDLE_EXCEEDS_MAX = 0x80551624; constexpr int ORBIS_NP_TROPHY_ERROR_HANDLE_EXCEEDS_MAX = 0x80551624;
constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_ALREADY_EXISTS = 0x80551613; constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_ALREADY_EXISTS = 0x80551613;
constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_EXCEEDS_MAX = 0x80551622; constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_EXCEEDS_MAX = 0x80551622;
// AppContent library
constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002;

View File

@ -90,7 +90,11 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
} }
if (!file->f.IsOpen()) { if (!file->f.IsOpen()) {
h->DeleteHandle(handle); h->DeleteHandle(handle);
return SCE_KERNEL_ERROR_EACCES; if (create) {
return ORBIS_KERNEL_ERROR_EACCES;
} else {
return ORBIS_KERNEL_ERROR_ENOENT;
}
} }
} }
file->is_opened = true; file->is_opened = true;
@ -227,7 +231,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

@ -1292,6 +1292,19 @@ int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) {
UNREACHABLE(); UNREACHABLE();
} }
int PS4_SYSV_ABI scePthreadGetthreadid() {
return (int)(size_t)g_pthread_self;
}
int PS4_SYSV_ABI scePthreadGetprio(ScePthread thread, int* prio) {
*prio = thread->prio;
return ORBIS_OK;
}
int PS4_SYSV_ABI scePthreadSetprio(ScePthread thread, int prio) {
thread->prio = prio;
return ORBIS_OK;
}
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate); LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate);
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init); LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
@ -1312,6 +1325,9 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("3kg7rT0NQIs", "libkernel", 1, "libkernel", 1, 1, scePthreadExit); LIB_FUNCTION("3kg7rT0NQIs", "libkernel", 1, "libkernel", 1, 1, scePthreadExit);
LIB_FUNCTION("7Xl257M4VNI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_equal); LIB_FUNCTION("7Xl257M4VNI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_equal);
LIB_FUNCTION("h9CcP3J0oVM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_join); LIB_FUNCTION("h9CcP3J0oVM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_join);
LIB_FUNCTION("EI-5-jlq2dE", "libkernel", 1, "libkernel", 1, 1, scePthreadGetthreadid);
LIB_FUNCTION("1tKyG7RlMJo", "libkernel", 1, "libkernel", 1, 1, scePthreadGetprio);
LIB_FUNCTION("W0Hpm2X0uPE", "libkernel", 1, "libkernel", 1, 1, scePthreadSetprio);
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf); LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf);
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self); LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);

View File

@ -58,6 +58,7 @@ struct PthreadInternal {
std::atomic_bool is_free; std::atomic_bool is_free;
using Destructor = std::pair<OrbisPthreadKey, PthreadKeyDestructor>; using Destructor = std::pair<OrbisPthreadKey, PthreadKeyDestructor>;
std::vector<Destructor> key_destructors; std::vector<Destructor> key_destructors;
int prio;
}; };
struct PthreadAttrInternal { struct PthreadAttrInternal {

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:
@ -347,12 +426,10 @@ 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;
std::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);
break; mnt->Mount(mount_dir, mount_result->mount_point.data);
} } 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:
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:
@ -362,16 +439,19 @@ s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode,
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: {
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 |
@ -379,12 +459,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();
@ -399,9 +477,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);
} }
@ -410,9 +488,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);
} }
@ -461,8 +539,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;
} }
@ -476,8 +562,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;
} }
@ -486,23 +581,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;
} }
@ -521,8 +682,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;
} }
@ -537,12 +698,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;
} }
@ -551,8 +716,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,68 @@ 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 +248,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 +266,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 +285,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 +308,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 +323,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

@ -15,12 +15,14 @@
#include "common/logging/backend.h" #include "common/logging/backend.h"
#include "common/path_util.h" #include "common/path_util.h"
#include "common/singleton.h" #include "common/singleton.h"
#include "common/version.h"
#include "core/file_sys/fs.h" #include "core/file_sys/fs.h"
#include "core/libraries/kernel/thread_management.h" #include "core/libraries/kernel/thread_management.h"
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
#include "core/linker.h" #include "core/linker.h"
#include "core/memory.h" #include "core/memory.h"
#include "emulator.h" #include "emulator.h"
#include "hwinfo/hwinfo.h"
Frontend::WindowSDL* g_window = nullptr; Frontend::WindowSDL* g_window = nullptr;
@ -40,6 +42,8 @@ Emulator::Emulator()
// Start logger. // Start logger.
Common::Log::Initialize(); Common::Log::Initialize();
Common::Log::Start(); Common::Log::Start();
LOG_INFO(Loader, "Starting shadps4 emulator v{} ", Common::VERSION);
PrintSystemInfo();
} }
Emulator::~Emulator() { Emulator::~Emulator() {
@ -85,6 +89,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.
@ -174,4 +181,17 @@ void Emulator::LoadSystemModules(const std::filesystem::path& file) {
} }
} }
void Emulator::PrintSystemInfo() {
auto cpus = hwinfo::getAllCPUs();
for (const auto& cpu : cpus) {
LOG_INFO(Loader, "CPU #{} {}", cpu.id(), cpu.modelName());
}
hwinfo::OS os;
LOG_INFO(Loader, "{}", os.name());
auto gpus = hwinfo::getAllGPUs();
for (auto& gpu : gpus) {
LOG_INFO(Loader, "GPU #{} {}", gpu.id(), gpu.name());
}
}
} // namespace Core } // namespace Core

View File

@ -29,6 +29,7 @@ public:
private: private:
void LoadSystemModules(const std::filesystem::path& file); void LoadSystemModules(const std::filesystem::path& file);
void PrintSystemInfo();
Core::MemoryManager* memory; Core::MemoryManager* memory;
Input::GameController* controller = Common::Singleton<Input::GameController>::Instance(); Input::GameController* controller = Common::Singleton<Input::GameController>::Instance();