diff --git a/CMakeLists.txt b/CMakeLists.txt index a86f645e8..fcc28b5eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,6 +145,7 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp src/core/libraries/system/posix.h src/core/libraries/save_data/save_data.cpp src/core/libraries/save_data/save_data.h + src/core/libraries/save_data/error_codes.h src/core/libraries/system/savedatadialog.cpp src/core/libraries/system/savedatadialog.h src/core/libraries/system/sysmodule.cpp diff --git a/src/common/path_util.cpp b/src/common/path_util.cpp index eafab7bc0..d82c87305 100644 --- a/src/common/path_util.cpp +++ b/src/common/path_util.cpp @@ -35,6 +35,7 @@ static auto UserPaths = [] { create_path(PathType::LogDir, user_dir / LOG_DIR); create_path(PathType::ScreenshotsDir, user_dir / SCREENSHOTS_DIR); create_path(PathType::ShaderDir, user_dir / SHADER_DIR); + create_path(PathType::SaveDataDir, user_dir / SAVEDATA_DIR); return paths; }(); diff --git a/src/common/path_util.h b/src/common/path_util.h index 1836a3acb..618d0bda8 100644 --- a/src/common/path_util.h +++ b/src/common/path_util.h @@ -13,7 +13,7 @@ enum class PathType { LogDir, // Where log files are stored. ScreenshotsDir, // Where screenshots are stored. ShaderDir, // Where shaders are stored. - App0, // Where guest application data is stored. + SaveDataDir, // Where guest save data is stored. }; constexpr auto PORTABLE_DIR = "user"; @@ -22,7 +22,7 @@ constexpr auto PORTABLE_DIR = "user"; constexpr auto LOG_DIR = "log"; constexpr auto SCREENSHOTS_DIR = "screenshots"; constexpr auto SHADER_DIR = "shader"; -constexpr auto APP0_DIR = "app0"; +constexpr auto SAVEDATA_DIR = "savedata"; // Filenames constexpr auto LOG_FILE = "shad_log.txt"; diff --git a/src/core/libraries/save_data/error_codes.h b/src/core/libraries/save_data/error_codes.h new file mode 100644 index 000000000..05bc629b0 --- /dev/null +++ b/src/core/libraries/save_data/error_codes.h @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +constexpr int ORBIS_SAVE_DATA_ERROR_NOT_FOUND = 0x809f0008; // save data doesn't exist diff --git a/src/core/libraries/save_data/save_data.cpp b/src/core/libraries/save_data/save_data.cpp index 93a97d3eb..0438db805 100644 --- a/src/core/libraries/save_data/save_data.cpp +++ b/src/core/libraries/save_data/save_data.cpp @@ -1,14 +1,20 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include +#include #include "common/assert.h" #include "common/logging/log.h" +#include "common/path_util.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/save_data/save_data.h" +#include "error_codes.h" namespace Libraries::SaveData { +static std::string g_mount_point = "/savedata0"; // temp mount point (todo) + int PS4_SYSV_ABI sceSaveDataAbort() { LOG_ERROR(Lib_SaveData, "(STUBBED) called"); return ORBIS_OK; @@ -290,17 +296,17 @@ int PS4_SYSV_ABI sceSaveDataGetUpdatedDataCount() { } int PS4_SYSV_ABI sceSaveDataInitialize() { - LOG_ERROR(Lib_SaveData, "(STUBBED) called"); + LOG_WARNING(Lib_SaveData, "(DUMMY) called"); return ORBIS_OK; } int PS4_SYSV_ABI sceSaveDataInitialize2() { - LOG_ERROR(Lib_SaveData, "(STUBBED) called"); + LOG_WARNING(Lib_SaveData, "(DUMMY) called"); return ORBIS_OK; } int PS4_SYSV_ABI sceSaveDataInitialize3() { - LOG_ERROR(Lib_SaveData, "(DUMMY) called"); + LOG_WARNING(Lib_SaveData, "(DUMMY) called"); return ORBIS_OK; } @@ -331,13 +337,30 @@ int PS4_SYSV_ABI sceSaveDataMount() { s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount, OrbisSaveDataMountResult* mount_result) { - // will return save data not found , breakpoint for others LOG_ERROR(Lib_SaveData, "(DUMMY) called user_id = {} dir_name = {} blocks = {} mount_mode = {}", mount->user_id, mount->dir_name->data, mount->blocks, mount->mount_mode); - if (mount->mount_mode == 1) { // open - return 0x809F0008; // save data not found + + bool rdonly = (mount->mount_mode & ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY) != 0; + bool rdwr = (mount->mount_mode & ORBIS_SAVE_DATA_MOUNT_MODE_RDWR) != 0; + bool create = (mount->mount_mode & ORBIS_SAVE_DATA_MOUNT_MODE_CREATE) != 0; + bool destruct_off = (mount->mount_mode & ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF) != 0; + bool copy_icon = (mount->mount_mode & ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON) != 0; + bool create2 = (mount->mount_mode & ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2) != 0; + + const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / + std::string(mount->dir_name->data); + + if (rdonly) { + if (!std::filesystem::is_directory(mount_dir)) { + return ORBIS_SAVE_DATA_ERROR_NOT_FOUND; + } + auto* mnt = Common::Singleton::Instance(); + mnt->Mount(mount_dir, g_mount_point); + + mount_result->mount_status = 0; + strcpy_s(mount_result->mount_point.data, 16, g_mount_point.c_str()); } - UNREACHABLE(); + return ORBIS_OK; } int PS4_SYSV_ABI sceSaveDataMount5() { diff --git a/src/core/libraries/save_data/save_data.h b/src/core/libraries/save_data/save_data.h index 6dfd8820d..60a19c9ae 100644 --- a/src/core/libraries/save_data/save_data.h +++ b/src/core/libraries/save_data/save_data.h @@ -42,6 +42,14 @@ struct OrbisSaveDataMountResult { s32 unk1; }; +// savedataMount2 mountModes (ORed values) +constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY = 1; +constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDWR = 2; +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_COPY_ICON = 16; +constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 = 32; + int PS4_SYSV_ABI sceSaveDataAbort(); int PS4_SYSV_ABI sceSaveDataBackup(); int PS4_SYSV_ABI sceSaveDataBindPsnAccount();