Rewrite Save Data & Impl Save Data Dialog (#824)

* core: Rewrite PSF parser & add encoder

add .sfo hex pattern to /scripts

* core/fs: allow to mount path as read-only

* common: Add CString wrapper to handle native null-terminated strings

* SaveData: rewrite to implement full functionality

* mock value for SYSTEM_VER

* SavaData: backup features

* SavaData: SaveDataMemory features

* imgui Ref-counted textures

- has a background thread to decode textures

* imgui: rework gamepad navigation

* PSF: fixed psf not using enum class for PSFEntryFmt (was a standard old ugly enum)

- Add null check to CString when itself is used in a nullable field

* SaveDataDialog implementation

- Fix Mounting/Unmounting check of SaveInstance
This commit is contained in:
Vinicius Rangel 2024-09-20 06:34:19 -03:00 committed by GitHub
parent 077f8981a7
commit 0f4bcd8c83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 4919 additions and 1134 deletions

View file

@ -179,11 +179,16 @@ int PS4_SYSV_ABI sceKernelUnlink(const char* path) {
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
const auto host_path = mnt->GetHostPath(path);
bool ro = false;
const auto host_path = mnt->GetHostPath(path, &ro);
if (host_path.empty()) {
return SCE_KERNEL_ERROR_EACCES;
}
if (ro) {
return SCE_KERNEL_ERROR_EROFS;
}
if (std::filesystem::is_directory(host_path)) {
return SCE_KERNEL_ERROR_EPERM;
}
@ -270,11 +275,18 @@ int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) {
return SCE_KERNEL_ERROR_EINVAL;
}
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
const auto dir_name = mnt->GetHostPath(path);
bool ro = false;
const auto dir_name = mnt->GetHostPath(path, &ro);
if (std::filesystem::exists(dir_name)) {
return SCE_KERNEL_ERROR_EEXIST;
}
if (ro) {
return SCE_KERNEL_ERROR_EROFS;
}
// CUSA02456: path = /aotl after sceSaveDataMount(mode = 1)
if (dir_name.empty() || !std::filesystem::create_directory(dir_name)) {
return SCE_KERNEL_ERROR_EIO;
@ -299,7 +311,8 @@ int PS4_SYSV_ABI posix_mkdir(const char* path, u16 mode) {
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();
const auto path_name = mnt->GetHostPath(path);
bool ro = false;
const auto path_name = mnt->GetHostPath(path, &ro);
std::memset(sb, 0, sizeof(OrbisKernelStat));
const bool is_dir = std::filesystem::is_directory(path_name);
const bool is_file = std::filesystem::is_regular_file(path_name);
@ -319,6 +332,10 @@ int PS4_SYSV_ABI sceKernelStat(const char* path, OrbisKernelStat* sb) {
sb->st_blocks = (sb->st_size + 511) / 512;
// TODO incomplete
}
if (ro) {
sb->st_mode &= ~0000555u;
}
return ORBIS_OK;
}
@ -500,11 +517,18 @@ s64 PS4_SYSV_ABI sceKernelPwrite(int d, void* buf, size_t nbytes, s64 offset) {
s32 PS4_SYSV_ABI sceKernelRename(const char* from, const char* to) {
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
const auto src_path = mnt->GetHostPath(from);
bool ro = false;
const auto src_path = mnt->GetHostPath(from, &ro);
if (!std::filesystem::exists(src_path)) {
return ORBIS_KERNEL_ERROR_ENOENT;
}
const auto dst_path = mnt->GetHostPath(to);
if (ro) {
return SCE_KERNEL_ERROR_EROFS;
}
const auto dst_path = mnt->GetHostPath(to, &ro);
if (ro) {
return SCE_KERNEL_ERROR_EROFS;
}
const bool src_is_dir = std::filesystem::is_directory(src_path);
const bool dst_is_dir = std::filesystem::is_directory(dst_path);
if (src_is_dir && !dst_is_dir) {

View file

@ -244,7 +244,7 @@ int PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time,
int PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(int* ver) {
auto* param_sfo = Common::Singleton<PSF>::Instance();
int version = param_sfo->GetInteger("SYSTEM_VER");
int version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000);
LOG_INFO(Kernel, "returned system version = {:#x}", version);
*ver = version;
return (version > 0) ? ORBIS_OK : ORBIS_KERNEL_ERROR_EINVAL;