Merge pull request #125 from shadps4-emu/savedata
Savedata + filesystem implementations
This commit is contained in:
commit
96cf59efea
|
@ -141,10 +141,11 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
||||||
src/core/libraries/system/msgdialog.h
|
src/core/libraries/system/msgdialog.h
|
||||||
src/core/libraries/system/posix.cpp
|
src/core/libraries/system/posix.cpp
|
||||||
src/core/libraries/system/posix.h
|
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.cpp
|
||||||
src/core/libraries/system/savedatadialog.h
|
src/core/libraries/system/savedatadialog.h
|
||||||
src/core/libraries/system/savedata.h
|
|
||||||
src/core/libraries/system/sysmodule.cpp
|
src/core/libraries/system/sysmodule.cpp
|
||||||
src/core/libraries/system/sysmodule.h
|
src/core/libraries/system/sysmodule.h
|
||||||
src/core/libraries/system/systemservice.cpp
|
src/core/libraries/system/systemservice.cpp
|
||||||
|
|
|
@ -35,6 +35,7 @@ static auto UserPaths = [] {
|
||||||
create_path(PathType::LogDir, user_dir / LOG_DIR);
|
create_path(PathType::LogDir, user_dir / LOG_DIR);
|
||||||
create_path(PathType::ScreenshotsDir, user_dir / SCREENSHOTS_DIR);
|
create_path(PathType::ScreenshotsDir, user_dir / SCREENSHOTS_DIR);
|
||||||
create_path(PathType::ShaderDir, user_dir / SHADER_DIR);
|
create_path(PathType::ShaderDir, user_dir / SHADER_DIR);
|
||||||
|
create_path(PathType::SaveDataDir, user_dir / SAVEDATA_DIR);
|
||||||
|
|
||||||
return paths;
|
return paths;
|
||||||
}();
|
}();
|
||||||
|
|
|
@ -13,7 +13,7 @@ enum class PathType {
|
||||||
LogDir, // Where log files are stored.
|
LogDir, // Where log files are stored.
|
||||||
ScreenshotsDir, // Where screenshots are stored.
|
ScreenshotsDir, // Where screenshots are stored.
|
||||||
ShaderDir, // Where shaders 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";
|
constexpr auto PORTABLE_DIR = "user";
|
||||||
|
@ -22,7 +22,7 @@ constexpr auto PORTABLE_DIR = "user";
|
||||||
constexpr auto LOG_DIR = "log";
|
constexpr auto LOG_DIR = "log";
|
||||||
constexpr auto SCREENSHOTS_DIR = "screenshots";
|
constexpr auto SCREENSHOTS_DIR = "screenshots";
|
||||||
constexpr auto SHADER_DIR = "shader";
|
constexpr auto SHADER_DIR = "shader";
|
||||||
constexpr auto APP0_DIR = "app0";
|
constexpr auto SAVEDATA_DIR = "savedata";
|
||||||
|
|
||||||
// Filenames
|
// Filenames
|
||||||
constexpr auto LOG_FILE = "shad_log.txt";
|
constexpr auto LOG_FILE = "shad_log.txt";
|
||||||
|
|
|
@ -12,19 +12,39 @@
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
|
int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
|
||||||
LOG_INFO(Kernel_Fs, "path = {} flags = {:#x} mode = {:#x}", path, flags, mode);
|
LOG_INFO(Kernel_Fs, "path = {} flags = {:#x} mode = {}", path, flags, mode);
|
||||||
ASSERT_MSG(flags == 0, "flags!=0 not supported yet");
|
|
||||||
ASSERT_MSG(mode == 0, "mode!=0 not supported yet");
|
|
||||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
|
|
||||||
// only open files support!
|
bool read = (flags & 0x3) == ORBIS_KERNEL_O_RDONLY;
|
||||||
|
bool write = (flags & 0x3) == ORBIS_KERNEL_O_WRONLY;
|
||||||
|
bool rdwr = (flags & 0x3) == ORBIS_KERNEL_O_RDWR;
|
||||||
|
|
||||||
|
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();
|
u32 handle = h->CreateHandle();
|
||||||
auto* file = h->GetFile(handle);
|
auto* file = h->GetFile(handle);
|
||||||
file->m_guest_name = path;
|
file->m_guest_name = path;
|
||||||
file->m_host_name = mnt->GetHostFile(file->m_guest_name);
|
file->m_host_name = mnt->GetHostFile(file->m_guest_name);
|
||||||
|
if (read) {
|
||||||
file->f.Open(file->m_host_name, Common::FS::FileAccessMode::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()) {
|
if (!file->f.IsOpen()) {
|
||||||
h->DeleteHandle(handle);
|
h->DeleteHandle(handle);
|
||||||
return SCE_KERNEL_ERROR_EACCES;
|
return SCE_KERNEL_ERROR_EACCES;
|
||||||
|
@ -32,6 +52,8 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
|
||||||
file->is_opened = true;
|
file->is_opened = true;
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
return -1; // dummy
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode) {
|
int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode) {
|
||||||
LOG_INFO(Kernel_Fs, "posix open redirect to sceKernelOpen\n");
|
LOG_INFO(Kernel_Fs, "posix open redirect to sceKernelOpen\n");
|
||||||
|
@ -56,6 +78,20 @@ int PS4_SYSV_ABI sceKernelClose(int d) {
|
||||||
return SCE_OK;
|
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<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->GetFile(d);
|
||||||
|
if (file == nullptr) {
|
||||||
|
return SCE_KERNEL_ERROR_EBADF;
|
||||||
|
}
|
||||||
|
file->m_mutex.lock();
|
||||||
|
u32 bytes_write = file->f.WriteRaw<u8>(buf, static_cast<u32>(nbytes));
|
||||||
|
file->m_mutex.unlock();
|
||||||
|
return bytes_write;
|
||||||
|
}
|
||||||
size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) {
|
size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) {
|
||||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
auto* file = h->GetFile(d);
|
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);
|
auto* file = h->GetFile(d);
|
||||||
|
|
||||||
file->m_mutex.lock();
|
file->m_mutex.lock();
|
||||||
|
Common::FS::SeekOrigin origin;
|
||||||
|
if (whence == 0) {
|
||||||
|
origin = Common::FS::SeekOrigin::SetOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
if (whence == 1) {
|
if (whence == 1) {
|
||||||
offset = static_cast<int64_t>(file->f.Tell()) + offset;
|
origin = Common::FS::SeekOrigin::CurrentPosition;
|
||||||
whence = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (whence == 2) {
|
if (whence == 2) {
|
||||||
offset = static_cast<int64_t>(file->f.GetSize()) + offset;
|
origin = Common::FS::SeekOrigin::End;
|
||||||
whence = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file->f.Seek(offset);
|
file->f.Seek(offset, origin);
|
||||||
auto pos = static_cast<int64_t>(file->f.Tell());
|
auto pos = static_cast<int64_t>(file->f.Tell());
|
||||||
|
|
||||||
file->m_mutex.unlock();
|
file->m_mutex.unlock();
|
||||||
|
@ -111,15 +148,74 @@ s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes) {
|
||||||
return bytes_read;
|
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<Core::FileSys::MntPoints>::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<Core::FileSys::MntPoints>::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<int64_t>(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) {
|
void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
||||||
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
||||||
LIB_FUNCTION("UK2Tl2DWUns", "libkernel", 1, "libkernel", 1, 1, sceKernelClose);
|
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("+WRlkKjZvag", "libkernel", 1, "libkernel", 1, 1, _readv);
|
||||||
LIB_FUNCTION("Oy6IpwgtYOk", "libkernel", 1, "libkernel", 1, 1, lseek);
|
LIB_FUNCTION("Oy6IpwgtYOk", "libkernel", 1, "libkernel", 1, 1, lseek);
|
||||||
LIB_FUNCTION("oib76F-12fk", "libkernel", 1, "libkernel", 1, 1, sceKernelLseek);
|
LIB_FUNCTION("oib76F-12fk", "libkernel", 1, "libkernel", 1, 1, sceKernelLseek);
|
||||||
LIB_FUNCTION("Cg4srZ6TKbU", "libkernel", 1, "libkernel", 1, 1, sceKernelRead);
|
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
|
// openOrbis (to check if it is valid out of OpenOrbis
|
||||||
LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
#include "thread_management.h"
|
||||||
|
|
||||||
namespace Core::Loader {
|
namespace Core::Loader {
|
||||||
class SymbolsResolver;
|
class SymbolsResolver;
|
||||||
|
@ -16,6 +17,44 @@ struct SceKernelIovec {
|
||||||
std::size_t iov_len;
|
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<int>(sizeof(SceKernelTimespec)));
|
||||||
|
unsigned int : (8 / 2) * (16 - static_cast<int>(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 sceKernelOpen(const char* path, int flags, /* SceKernelMode*/ u16 mode);
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode);
|
int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode);
|
||||||
|
|
|
@ -43,7 +43,8 @@ static PS4_SYSV_ABI void stack_chk_fail() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) {
|
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) {
|
void PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) {
|
||||||
|
|
|
@ -10,6 +10,10 @@ namespace Libraries::Kernel {
|
||||||
static u64 initial_ptc;
|
static u64 initial_ptc;
|
||||||
static std::unique_ptr<Common::NativeClock> clock;
|
static std::unique_ptr<Common::NativeClock> clock;
|
||||||
|
|
||||||
|
u64 PS4_SYSV_ABI sceKernelGetTscFrequency() {
|
||||||
|
return clock->GetTscFrequency();
|
||||||
|
}
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTime() {
|
u64 PS4_SYSV_ABI sceKernelGetProcessTime() {
|
||||||
return clock->GetProcessTimeUS();
|
return clock->GetProcessTimeUS();
|
||||||
}
|
}
|
||||||
|
@ -34,6 +38,7 @@ void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("BNowx2l588E", "libkernel", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("BNowx2l588E", "libkernel", 1, "libkernel", 1, 1,
|
||||||
sceKernelGetProcessTimeCounterFrequency);
|
sceKernelGetProcessTimeCounterFrequency);
|
||||||
LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc);
|
LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc);
|
||||||
|
LIB_FUNCTION("1j3S3n-tTW4", "libkernel", 1, "libkernel", 1, 1, sceKernelGetTscFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -11,6 +11,7 @@ class SymbolsResolver;
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
|
u64 PS4_SYSV_ABI sceKernelGetTscFrequency();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTime();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTime();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency();
|
||||||
|
|
|
@ -444,6 +444,8 @@ void libcSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("cCXjU72Z0Ow", "libc", 1, "libc", 1, 1, ps4__Sin);
|
LIB_FUNCTION("cCXjU72Z0Ow", "libc", 1, "libc", 1, 1, ps4__Sin);
|
||||||
LIB_FUNCTION("ZtjspkJQ+vw", "libc", 1, "libc", 1, 1, ps4__Fsin);
|
LIB_FUNCTION("ZtjspkJQ+vw", "libc", 1, "libc", 1, 1, ps4__Fsin);
|
||||||
LIB_FUNCTION("dnaeGXbjP6E", "libc", 1, "libc", 1, 1, ps4_exp2);
|
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
|
// string functions
|
||||||
LIB_FUNCTION("Ovb2dSJOAuE", "libc", 1, "libc", 1, 1, ps4_strcmp);
|
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("rQFVBXp-Cxg", "libc", 1, "libc", 1, 1, ps4_fseek);
|
||||||
LIB_FUNCTION("SHlt7EhOtqA", "libc", 1, "libc", 1, 1, ps4_fgetpos);
|
LIB_FUNCTION("SHlt7EhOtqA", "libc", 1, "libc", 1, 1, ps4_fgetpos);
|
||||||
LIB_FUNCTION("lbB+UlZqVG0", "libc", 1, "libc", 1, 1, ps4_fread);
|
LIB_FUNCTION("lbB+UlZqVG0", "libc", 1, "libc", 1, 1, ps4_fread);
|
||||||
|
LIB_FUNCTION("Qazy8LmXTvw", "libc", 1, "libc", 1, 1, ps4_ftell);
|
||||||
|
|
||||||
// misc
|
// misc
|
||||||
LIB_OBJ("P330P3dFF68", "libc", 1, "libc", 1, 1, &g_need_sceLibc);
|
LIB_OBJ("P330P3dFF68", "libc", 1, "libc", 1, 1, &g_need_sceLibc);
|
||||||
|
|
|
@ -26,6 +26,14 @@ double PS4_SYSV_ABI ps4_pow(double base, double exponent) {
|
||||||
return pow(base, 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) {
|
double PS4_SYSV_ABI ps4__Sin(double x) {
|
||||||
return sin(x);
|
return sin(x);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,5 +15,7 @@ double PS4_SYSV_ABI ps4_pow(double base, double exponent);
|
||||||
double PS4_SYSV_ABI ps4__Sin(double x);
|
double PS4_SYSV_ABI ps4__Sin(double x);
|
||||||
float PS4_SYSV_ABI ps4__Fsin(float arg);
|
float PS4_SYSV_ABI ps4__Fsin(float arg);
|
||||||
double PS4_SYSV_ABI ps4_exp2(double 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
|
} // namespace Libraries::LibC
|
||||||
|
|
|
@ -70,4 +70,8 @@ int PS4_SYSV_ABI ps4_puts(const char* s) {
|
||||||
return std::puts(s);
|
return std::puts(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long PS4_SYSV_ABI ps4_ftell(FILE* stream) {
|
||||||
|
return ftell(stream);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Libraries::LibC
|
} // namespace Libraries::LibC
|
||||||
|
|
|
@ -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_fseek(FILE* stream, long offset, int whence);
|
||||||
int PS4_SYSV_ABI ps4_fgetpos(FILE* stream, fpos_t* pos);
|
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);
|
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
|
} // namespace Libraries::LibC
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
#include "core/libraries/np_score/np_score.h"
|
#include "core/libraries/np_score/np_score.h"
|
||||||
#include "core/libraries/np_trophy/np_trophy.h"
|
#include "core/libraries/np_trophy/np_trophy.h"
|
||||||
#include "core/libraries/pad/pad.h"
|
#include "core/libraries/pad/pad.h"
|
||||||
|
#include "core/libraries/save_data/savedata.h"
|
||||||
#include "core/libraries/screenshot/screenshot.h"
|
#include "core/libraries/screenshot/screenshot.h"
|
||||||
#include "core/libraries/system/commondialog.h"
|
#include "core/libraries/system/commondialog.h"
|
||||||
#include "core/libraries/system/msgdialog.h"
|
#include "core/libraries/system/msgdialog.h"
|
||||||
#include "core/libraries/system/posix.h"
|
#include "core/libraries/system/posix.h"
|
||||||
#include "core/libraries/system/savedata.h"
|
|
||||||
#include "core/libraries/system/savedatadialog.h"
|
#include "core/libraries/system/savedatadialog.h"
|
||||||
#include "core/libraries/system/sysmodule.h"
|
#include "core/libraries/system/sysmodule.h"
|
||||||
#include "core/libraries/system/systemservice.h"
|
#include "core/libraries/system/systemservice.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
|
|
@ -1,14 +1,21 @@
|
||||||
// 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 <common/path_util.h>
|
||||||
|
#include <common/singleton.h>
|
||||||
|
#include <core/file_format/psf.h>
|
||||||
|
#include <core/file_sys/fs.h>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.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 {
|
namespace Libraries::SaveData {
|
||||||
|
|
||||||
|
static std::string g_mount_point = "/savedata0"; // temp mount point (todo)
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceSaveDataAbort() {
|
int PS4_SYSV_ABI sceSaveDataAbort() {
|
||||||
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -331,14 +338,47 @@ int PS4_SYSV_ABI sceSaveDataMount() {
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
|
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
|
||||||
OrbisSaveDataMountResult* mount_result) {
|
OrbisSaveDataMountResult* mount_result) {
|
||||||
// will return save data not found , breakpoint for others
|
LOG_INFO(Lib_SaveData, "called user_id = {} dir_name = {} blocks = {} mount_mode = {}",
|
||||||
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);
|
mount->user_id, mount->dir_name->data, mount->blocks, mount->mount_mode);
|
||||||
if (mount->mount_mode == 1) { // open
|
|
||||||
return 0x809F0008; // save data not found
|
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) /
|
||||||
|
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<Core::FileSys::MntPoints>::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<Core::FileSys::MntPoints>::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() {
|
int PS4_SYSV_ABI sceSaveDataMount5() {
|
||||||
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
||||||
|
@ -460,8 +500,13 @@ int PS4_SYSV_ABI sceSaveDataTransferringMount() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceSaveDataUmount() {
|
s32 PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint) {
|
||||||
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
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<Core::FileSys::MntPoints>::Instance();
|
||||||
|
mnt->Unmount(std::string(mountPoint->data));
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,14 @@ struct OrbisSaveDataMountResult {
|
||||||
s32 unk1;
|
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 sceSaveDataAbort();
|
||||||
int PS4_SYSV_ABI sceSaveDataBackup();
|
int PS4_SYSV_ABI sceSaveDataBackup();
|
||||||
int PS4_SYSV_ABI sceSaveDataBindPsnAccount();
|
int PS4_SYSV_ABI sceSaveDataBindPsnAccount();
|
||||||
|
@ -132,7 +140,7 @@ int PS4_SYSV_ABI sceSaveDataSyncCloudList();
|
||||||
int PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory();
|
int PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory();
|
||||||
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();
|
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();
|
||||||
int PS4_SYSV_ABI sceSaveDataUnregisterEventCallback();
|
int PS4_SYSV_ABI sceSaveDataUnregisterEventCallback();
|
|
@ -14,6 +14,13 @@ namespace Libraries::MsgDialog {
|
||||||
|
|
||||||
using OrbisUserServiceUserId = s32;
|
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 {
|
enum OrbisMsgDialogMode {
|
||||||
ORBIS_MSG_DIALOG_MODE_USER_MSG = 1,
|
ORBIS_MSG_DIALOG_MODE_USER_MSG = 1,
|
||||||
ORBIS_MSG_DIALOG_MODE_PROGRESS_BAR = 2,
|
ORBIS_MSG_DIALOG_MODE_PROGRESS_BAR = 2,
|
||||||
|
|
Loading…
Reference in New Issue