diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ec26336..d64c6b81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,10 +141,11 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp src/core/libraries/system/msgdialog.h src/core/libraries/system/posix.cpp src/core/libraries/system/posix.h - src/core/libraries/system/savedata.cpp + src/core/libraries/save_data/error_codes.h + src/core/libraries/save_data/savedata.cpp + src/core/libraries/save_data/savedata.h src/core/libraries/system/savedatadialog.cpp src/core/libraries/system/savedatadialog.h - src/core/libraries/system/savedata.h src/core/libraries/system/sysmodule.cpp src/core/libraries/system/sysmodule.h src/core/libraries/system/systemservice.cpp diff --git a/src/common/path_util.cpp b/src/common/path_util.cpp index eafab7bc..d82c8730 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 1836a3ac..618d0bda 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/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 2f1e8ef2..a2dfcbc1 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -12,25 +12,47 @@ namespace Libraries::Kernel { int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) { - LOG_INFO(Kernel_Fs, "path = {} flags = {:#x} mode = {:#x}", path, flags, mode); - ASSERT_MSG(flags == 0, "flags!=0 not supported yet"); - ASSERT_MSG(mode == 0, "mode!=0 not supported yet"); + LOG_INFO(Kernel_Fs, "path = {} flags = {:#x} mode = {}", path, flags, mode); auto* h = Common::Singleton::Instance(); auto* mnt = Common::Singleton::Instance(); - // only open files support! - u32 handle = h->CreateHandle(); - auto* file = h->GetFile(handle); - file->m_guest_name = path; - file->m_host_name = mnt->GetHostFile(file->m_guest_name); + bool read = (flags & 0x3) == ORBIS_KERNEL_O_RDONLY; + bool write = (flags & 0x3) == ORBIS_KERNEL_O_WRONLY; + bool rdwr = (flags & 0x3) == ORBIS_KERNEL_O_RDWR; - file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read); - if (!file->f.IsOpen()) { - h->DeleteHandle(handle); - return SCE_KERNEL_ERROR_EACCES; + bool nonblock = (flags & ORBIS_KERNEL_O_NONBLOCK) != 0; + bool append = (flags & ORBIS_KERNEL_O_APPEND) != 0; + bool fsync = (flags & ORBIS_KERNEL_O_FSYNC) != 0; + bool sync = (flags & ORBIS_KERNEL_O_SYNC) != 0; + bool create = (flags & ORBIS_KERNEL_O_CREAT) != 0; + bool truncate = (flags & ORBIS_KERNEL_O_TRUNC) != 0; + bool excl = (flags & ORBIS_KERNEL_O_EXCL) != 0; + bool dsync = (flags & ORBIS_KERNEL_O_DSYNC) != 0; + bool direct = (flags & ORBIS_KERNEL_O_DIRECT) != 0; + bool directory = (flags & ORBIS_KERNEL_O_DIRECTORY) != 0; + + if (directory) { + UNREACHABLE(); // not supported yet + } else { + u32 handle = h->CreateHandle(); + auto* file = h->GetFile(handle); + file->m_guest_name = path; + file->m_host_name = mnt->GetHostFile(file->m_guest_name); + if (read) { + file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read); + } else if (write && create && truncate) { + file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Write); + } else { + UNREACHABLE(); + } + if (!file->f.IsOpen()) { + h->DeleteHandle(handle); + return SCE_KERNEL_ERROR_EACCES; + } + file->is_opened = true; + return handle; } - file->is_opened = true; - return handle; + return -1; // dummy } int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode) { @@ -56,6 +78,20 @@ int PS4_SYSV_ABI sceKernelClose(int d) { return SCE_OK; } +size_t PS4_SYSV_ABI sceKernelWrite(int d, void* buf, size_t nbytes) { + if (buf == nullptr) { + return SCE_KERNEL_ERROR_EFAULT; + } + auto* h = Common::Singleton::Instance(); + auto* file = h->GetFile(d); + if (file == nullptr) { + return SCE_KERNEL_ERROR_EBADF; + } + file->m_mutex.lock(); + u32 bytes_write = file->f.WriteRaw(buf, static_cast(nbytes)); + file->m_mutex.unlock(); + return bytes_write; +} size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(d); @@ -73,18 +109,19 @@ s64 PS4_SYSV_ABI sceKernelLseek(int d, s64 offset, int whence) { auto* file = h->GetFile(d); file->m_mutex.lock(); + Common::FS::SeekOrigin origin; + if (whence == 0) { + origin = Common::FS::SeekOrigin::SetOrigin; + } if (whence == 1) { - offset = static_cast(file->f.Tell()) + offset; - whence = 0; + origin = Common::FS::SeekOrigin::CurrentPosition; } - if (whence == 2) { - offset = static_cast(file->f.GetSize()) + offset; - whence = 0; + origin = Common::FS::SeekOrigin::End; } - file->f.Seek(offset); + file->f.Seek(offset, origin); auto pos = static_cast(file->f.Tell()); file->m_mutex.unlock(); @@ -111,15 +148,74 @@ s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes) { return bytes_read; } +int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) { + LOG_INFO(Kernel_Fs, "path = {} mode = {}", path, mode); + if (path == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + auto* mnt = Common::Singleton::Instance(); + std::string dir_name = mnt->GetHostFile(path); + if (std::filesystem::exists(dir_name)) { + return SCE_KERNEL_ERROR_EEXIST; + } + + if (!std::filesystem::create_directory(dir_name)) { + return SCE_KERNEL_ERROR_EIO; + } + + if (!std::filesystem::exists(dir_name)) { + return SCE_KERNEL_ERROR_ENOENT; + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceKernelStat(const char* path, OrbisKernelStat* sb) { + LOG_INFO(Kernel_Fs, "(PARTIAL) path = {}", path); + auto* mnt = Common::Singleton::Instance(); + std::string path_name = mnt->GetHostFile(path); + memset(sb, 0, sizeof(OrbisKernelStat)); + bool is_dir = std::filesystem::is_directory(path_name); + bool is_file = std::filesystem::is_regular_file(path_name); + if (!is_dir && !is_file) { + return ORBIS_KERNEL_ERROR_ENOENT; + } + if (std::filesystem::is_directory(path_name)) { + sb->st_mode = 0000777u | 0040000u; + sb->st_size = 0; + sb->st_blksize = 512; + sb->st_blocks = 0; + // TODO incomplete + } else { + sb->st_mode = 0000777u | 0100000u; + sb->st_size = static_cast(std::filesystem::file_size(path_name)); + sb->st_blksize = 512; + sb->st_blocks = (sb->st_size + 511) / 512; + // TODO incomplete + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_stat(const char* path, OrbisKernelStat* sb) { + int result = sceKernelStat(path, sb); + if (result < 0) { + UNREACHABLE(); // TODO + } + return ORBIS_OK; +} + void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen); LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open); LIB_FUNCTION("UK2Tl2DWUns", "libkernel", 1, "libkernel", 1, 1, sceKernelClose); + LIB_FUNCTION("4wSze92BhLI", "libkernel", 1, "libkernel", 1, 1, sceKernelWrite); LIB_FUNCTION("+WRlkKjZvag", "libkernel", 1, "libkernel", 1, 1, _readv); LIB_FUNCTION("Oy6IpwgtYOk", "libkernel", 1, "libkernel", 1, 1, lseek); LIB_FUNCTION("oib76F-12fk", "libkernel", 1, "libkernel", 1, 1, sceKernelLseek); LIB_FUNCTION("Cg4srZ6TKbU", "libkernel", 1, "libkernel", 1, 1, sceKernelRead); + LIB_FUNCTION("1-LFLmRFxxM", "libkernel", 1, "libkernel", 1, 1, sceKernelMkdir); + LIB_FUNCTION("eV9wAD2riIA", "libkernel", 1, "libkernel", 1, 1, sceKernelStat); + LIB_FUNCTION("E6ao34wPw+U", "libScePosix", 1, "libkernel", 1, 1, posix_stat); // openOrbis (to check if it is valid out of OpenOrbis LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1, diff --git a/src/core/libraries/kernel/file_system.h b/src/core/libraries/kernel/file_system.h index b0b2e110..865f1b05 100644 --- a/src/core/libraries/kernel/file_system.h +++ b/src/core/libraries/kernel/file_system.h @@ -4,6 +4,7 @@ #pragma once #include "common/types.h" +#include "thread_management.h" namespace Core::Loader { class SymbolsResolver; @@ -16,6 +17,44 @@ struct SceKernelIovec { std::size_t iov_len; }; +struct OrbisKernelStat { + u32 st_dev; + u32 st_ino; + u16 st_mode; + u16 st_nlink; + u32 st_uid; + u32 st_gid; + u32 st_rdev; + SceKernelTimespec st_atim; + SceKernelTimespec st_mtim; + SceKernelTimespec st_ctim; + s64 st_size; + s64 st_blocks; + u32 st_blksize; + u32 st_flags; + u32 st_gen; + s32 st_lspare; + SceKernelTimespec st_birthtim; + unsigned int : (8 / 2) * (16 - static_cast(sizeof(SceKernelTimespec))); + unsigned int : (8 / 2) * (16 - static_cast(sizeof(SceKernelTimespec))); +}; + +// flags for Open +constexpr int ORBIS_KERNEL_O_RDONLY = 0x0000; +constexpr int ORBIS_KERNEL_O_WRONLY = 0x0001; +constexpr int ORBIS_KERNEL_O_RDWR = 0x0002; + +constexpr int ORBIS_KERNEL_O_NONBLOCK = 0x0004; +constexpr int ORBIS_KERNEL_O_APPEND = 0x0008; +constexpr int ORBIS_KERNEL_O_FSYNC = 0x0080; +constexpr int ORBIS_KERNEL_O_SYNC = 0x0080; +constexpr int ORBIS_KERNEL_O_CREAT = 0x0200; +constexpr int ORBIS_KERNEL_O_TRUNC = 0x0400; +constexpr int ORBIS_KERNEL_O_EXCL = 0x0800; +constexpr int ORBIS_KERNEL_O_DSYNC = 0x1000; +constexpr int ORBIS_KERNEL_O_DIRECT = 0x00010000; +constexpr int ORBIS_KERNEL_O_DIRECTORY = 0x00020000; + int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, /* SceKernelMode*/ u16 mode); int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode); diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index cda68433..bfda21d0 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -43,7 +43,8 @@ static PS4_SYSV_ABI void stack_chk_fail() { } int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { - UNREACHABLE(); + LOG_ERROR(Kernel_Vmm, "(DUMMY) called"); + return SCE_OK; } void PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) { diff --git a/src/core/libraries/kernel/time_management.cpp b/src/core/libraries/kernel/time_management.cpp index 2e3d8896..f32e2b8e 100644 --- a/src/core/libraries/kernel/time_management.cpp +++ b/src/core/libraries/kernel/time_management.cpp @@ -10,6 +10,10 @@ namespace Libraries::Kernel { static u64 initial_ptc; static std::unique_ptr clock; +u64 PS4_SYSV_ABI sceKernelGetTscFrequency() { + return clock->GetTscFrequency(); +} + u64 PS4_SYSV_ABI sceKernelGetProcessTime() { return clock->GetProcessTimeUS(); } @@ -34,6 +38,7 @@ void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("BNowx2l588E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcessTimeCounterFrequency); LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc); + LIB_FUNCTION("1j3S3n-tTW4", "libkernel", 1, "libkernel", 1, 1, sceKernelGetTscFrequency); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/time_management.h b/src/core/libraries/kernel/time_management.h index 91436195..ad420f7c 100644 --- a/src/core/libraries/kernel/time_management.h +++ b/src/core/libraries/kernel/time_management.h @@ -11,6 +11,7 @@ class SymbolsResolver; namespace Libraries::Kernel { +u64 PS4_SYSV_ABI sceKernelGetTscFrequency(); u64 PS4_SYSV_ABI sceKernelGetProcessTime(); u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter(); u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency(); diff --git a/src/core/libraries/libc/libc.cpp b/src/core/libraries/libc/libc.cpp index 5de84738..d709515e 100644 --- a/src/core/libraries/libc/libc.cpp +++ b/src/core/libraries/libc/libc.cpp @@ -444,6 +444,8 @@ void libcSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("cCXjU72Z0Ow", "libc", 1, "libc", 1, 1, ps4__Sin); LIB_FUNCTION("ZtjspkJQ+vw", "libc", 1, "libc", 1, 1, ps4__Fsin); LIB_FUNCTION("dnaeGXbjP6E", "libc", 1, "libc", 1, 1, ps4_exp2); + LIB_FUNCTION("1D0H2KNjshE", "libc", 1, "libc", 1, 1, ps4_powf); + LIB_FUNCTION("DDHG1a6+3q0", "libc", 1, "libc", 1, 1, ps4_roundf); // string functions LIB_FUNCTION("Ovb2dSJOAuE", "libc", 1, "libc", 1, 1, ps4_strcmp); @@ -470,6 +472,7 @@ void libcSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("rQFVBXp-Cxg", "libc", 1, "libc", 1, 1, ps4_fseek); LIB_FUNCTION("SHlt7EhOtqA", "libc", 1, "libc", 1, 1, ps4_fgetpos); LIB_FUNCTION("lbB+UlZqVG0", "libc", 1, "libc", 1, 1, ps4_fread); + LIB_FUNCTION("Qazy8LmXTvw", "libc", 1, "libc", 1, 1, ps4_ftell); // misc LIB_OBJ("P330P3dFF68", "libc", 1, "libc", 1, 1, &g_need_sceLibc); diff --git a/src/core/libraries/libc/libc_math.cpp b/src/core/libraries/libc/libc_math.cpp index 89acb4d7..281585c6 100644 --- a/src/core/libraries/libc/libc_math.cpp +++ b/src/core/libraries/libc/libc_math.cpp @@ -26,6 +26,14 @@ double PS4_SYSV_ABI ps4_pow(double base, double exponent) { return pow(base, exponent); } +float PS4_SYSV_ABI ps4_powf(float x, float y) { + return powf(x, y); +} + +float PS4_SYSV_ABI ps4_roundf(float arg) { + return roundf(arg); +} + double PS4_SYSV_ABI ps4__Sin(double x) { return sin(x); } diff --git a/src/core/libraries/libc/libc_math.h b/src/core/libraries/libc/libc_math.h index 3f49e6a5..83af029e 100644 --- a/src/core/libraries/libc/libc_math.h +++ b/src/core/libraries/libc/libc_math.h @@ -15,5 +15,7 @@ double PS4_SYSV_ABI ps4_pow(double base, double exponent); double PS4_SYSV_ABI ps4__Sin(double x); float PS4_SYSV_ABI ps4__Fsin(float arg); double PS4_SYSV_ABI ps4_exp2(double arg); +float PS4_SYSV_ABI ps4_powf(float x, float y); +float PS4_SYSV_ABI ps4_roundf(float arg); } // namespace Libraries::LibC diff --git a/src/core/libraries/libc/libc_stdio.cpp b/src/core/libraries/libc/libc_stdio.cpp index abbe072c..b1e94676 100644 --- a/src/core/libraries/libc/libc_stdio.cpp +++ b/src/core/libraries/libc/libc_stdio.cpp @@ -70,4 +70,8 @@ int PS4_SYSV_ABI ps4_puts(const char* s) { return std::puts(s); } +long PS4_SYSV_ABI ps4_ftell(FILE* stream) { + return ftell(stream); +} + } // namespace Libraries::LibC diff --git a/src/core/libraries/libc/libc_stdio.h b/src/core/libraries/libc/libc_stdio.h index 15cbe06a..806c17c2 100644 --- a/src/core/libraries/libc/libc_stdio.h +++ b/src/core/libraries/libc/libc_stdio.h @@ -18,5 +18,6 @@ int PS4_SYSV_ABI ps4_fclose(FILE* stream); int PS4_SYSV_ABI ps4_fseek(FILE* stream, long offset, int whence); int PS4_SYSV_ABI ps4_fgetpos(FILE* stream, fpos_t* pos); std::size_t PS4_SYSV_ABI ps4_fread(void* ptr, size_t size, size_t nmemb, FILE* stream); +long PS4_SYSV_ABI ps4_ftell(FILE* stream); } // namespace Libraries::LibC diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp index db61627a..30d1fa6b 100644 --- a/src/core/libraries/libs.cpp +++ b/src/core/libraries/libs.cpp @@ -16,11 +16,11 @@ #include "core/libraries/np_score/np_score.h" #include "core/libraries/np_trophy/np_trophy.h" #include "core/libraries/pad/pad.h" +#include "core/libraries/save_data/savedata.h" #include "core/libraries/screenshot/screenshot.h" #include "core/libraries/system/commondialog.h" #include "core/libraries/system/msgdialog.h" #include "core/libraries/system/posix.h" -#include "core/libraries/system/savedata.h" #include "core/libraries/system/savedatadialog.h" #include "core/libraries/system/sysmodule.h" #include "core/libraries/system/systemservice.h" 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 00000000..0dfe9def --- /dev/null +++ b/src/core/libraries/save_data/error_codes.h @@ -0,0 +1,8 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +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_EXISTS = 0x809f0007; // save data directory,same name exists \ No newline at end of file diff --git a/src/core/libraries/system/savedata.cpp b/src/core/libraries/save_data/savedata.cpp similarity index 90% rename from src/core/libraries/system/savedata.cpp rename to src/core/libraries/save_data/savedata.cpp index c7437cec..e63f9c1d 100644 --- a/src/core/libraries/system/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -1,14 +1,21 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include +#include +#include +#include #include "common/assert.h" #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" -#include "core/libraries/system/savedata.h" +#include "core/libraries/save_data/savedata.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; @@ -331,13 +338,46 @@ 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 + LOG_INFO(Lib_SaveData, "called user_id = {} dir_name = {} blocks = {} mount_mode = {}", + mount->user_id, mount->dir_name->data, mount->blocks, mount->mount_mode); + + auto* param_sfo = Common::Singleton::Instance(); + std::string id(param_sfo->GetString("CONTENT_ID"), 7, 9); + const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / + std::to_string(mount->user_id) / "savedata" / id / + std::string(mount->dir_name->data); + switch (mount->mount_mode) { + case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY: + case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: { + if (!std::filesystem::exists(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; + strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16); + } break; + 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: { + if (std::filesystem::exists(mount_dir)) { + return ORBIS_SAVE_DATA_ERROR_EXISTS; + } + std::filesystem::create_directories(mount_dir); + + auto* mnt = Common::Singleton::Instance(); + mnt->Mount(mount_dir, g_mount_point); + + mount_result->mount_status = 1; + strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16); + } break; + default: + UNREACHABLE(); } - UNREACHABLE(); + mount_result->required_blocks = 0; + + return ORBIS_OK; } int PS4_SYSV_ABI sceSaveDataMount5() { @@ -460,8 +500,13 @@ int PS4_SYSV_ABI sceSaveDataTransferringMount() { return ORBIS_OK; } -int PS4_SYSV_ABI sceSaveDataUmount() { - LOG_ERROR(Lib_SaveData, "(STUBBED) called"); +s32 PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint) { + LOG_INFO(Lib_SaveData, "mountPoint = {}", std::string(mountPoint->data)); + if (std::string(mountPoint->data).empty()) { + return ORBIS_SAVE_DATA_ERROR_PARAMETER; + } + auto* mnt = Common::Singleton::Instance(); + mnt->Unmount(std::string(mountPoint->data)); return ORBIS_OK; } diff --git a/src/core/libraries/system/savedata.h b/src/core/libraries/save_data/savedata.h similarity index 92% rename from src/core/libraries/system/savedata.h rename to src/core/libraries/save_data/savedata.h index 6dfd8820..a4541587 100644 --- a/src/core/libraries/system/savedata.h +++ b/src/core/libraries/save_data/savedata.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(); @@ -132,7 +140,7 @@ int PS4_SYSV_ABI sceSaveDataSyncCloudList(); int PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory(); int PS4_SYSV_ABI sceSaveDataTerminate(); int PS4_SYSV_ABI sceSaveDataTransferringMount(); -int PS4_SYSV_ABI sceSaveDataUmount(); +int PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint); int PS4_SYSV_ABI sceSaveDataUmountSys(); int PS4_SYSV_ABI sceSaveDataUmountWithBackup(); int PS4_SYSV_ABI sceSaveDataUnregisterEventCallback(); diff --git a/src/core/libraries/system/msgdialog.h b/src/core/libraries/system/msgdialog.h index 76a7d3f0..28d37913 100644 --- a/src/core/libraries/system/msgdialog.h +++ b/src/core/libraries/system/msgdialog.h @@ -14,6 +14,13 @@ namespace Libraries::MsgDialog { using OrbisUserServiceUserId = s32; +enum OrbisCommonDialogStatus { + ORBIS_COMMON_DIALOG_STATUS_NONE = 0, + ORBIS_COMMON_DIALOG_STATUS_INITIALIZED = 1, + ORBIS_COMMON_DIALOG_STATUS_RUNNING = 2, + ORBIS_COMMON_DIALOG_STATUS_FINISHED = 3 +}; + enum OrbisMsgDialogMode { ORBIS_MSG_DIALOG_MODE_USER_MSG = 1, ORBIS_MSG_DIALOG_MODE_PROGRESS_BAR = 2,