forked from shadps4-emu/shadPS4
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite Save Data & Impl Save Data Dialog (shadps4-emu#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
- Loading branch information
1 parent
077f898
commit 0f4bcd8
Showing
51 changed files
with
4,898 additions
and
1,113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
import std.io; | ||
import std.sys; | ||
|
||
struct Header { | ||
u32 magic; | ||
u32 version; | ||
u32 key_table_offset; | ||
u32 data_table_offset; | ||
u32 index_table_entries; | ||
}; | ||
|
||
struct KeyEntry { | ||
char name[]; | ||
} [[inline]]; | ||
|
||
struct DataEntry<auto fmt, auto size> { | ||
if (fmt == 0x0404) { | ||
u32 int_value; | ||
} else if(fmt == 0x0004) { | ||
char bin_value[size]; | ||
} else if(fmt == 0x0204) { | ||
char str_value[size]; | ||
} else { | ||
std::warning("unknown fmt type"); | ||
} | ||
} [[inline]]; | ||
|
||
struct IndexEntry { | ||
u16 key_offset; | ||
u16 param_fmt; | ||
u32 param_len; | ||
u32 param_max_len; | ||
u32 data_offset; | ||
}; | ||
|
||
struct Entry<auto KeyTableOffset, auto DataTableOffset> { | ||
u64 begin = $; | ||
IndexEntry index; | ||
KeyEntry key @ KeyTableOffset + index.key_offset; | ||
DataEntry<index.param_fmt, index.param_len> data @ DataTableOffset + index.data_offset; | ||
u8 data_empty[index.param_max_len - index.param_len] @ DataTableOffset + index.data_offset + index.param_len; | ||
$ = begin + sizeof(IndexEntry); | ||
}; | ||
|
||
Header header @ 0; | ||
std::assert(header.magic == 0x46535000, "Miss match magic"); | ||
std::assert(header.version == 0x00000101, "Miss match version"); | ||
|
||
Entry<header.key_table_offset, header.data_table_offset> list[header.index_table_entries] @ 0x14; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#pragma once | ||
|
||
#include <string_view> | ||
|
||
#include "assert.h" | ||
|
||
namespace Common { | ||
|
||
/** | ||
* @brief A null-terminated string with a fixed maximum length | ||
* This class is not meant to be used as a general-purpose string class | ||
* It is meant to be used as `char[N]` where memory layout is fixed | ||
* @tparam N Maximum length of the string | ||
* @tparam T Type of character | ||
*/ | ||
template <size_t N, typename T = char> | ||
class CString { | ||
T data[N]{}; | ||
|
||
public: | ||
class Iterator; | ||
|
||
CString() = default; | ||
|
||
template <size_t M> | ||
explicit CString(const CString<M>& other) | ||
requires(M <= N) | ||
{ | ||
std::ranges::copy(other.begin(), other.end(), data); | ||
} | ||
|
||
void FromString(const std::basic_string_view<T>& str) { | ||
size_t p = str.copy(data, N - 1); | ||
data[p] = '\0'; | ||
} | ||
|
||
void Zero() { | ||
std::ranges::fill(data, 0); | ||
} | ||
|
||
#pragma clang diagnostic push | ||
#pragma clang diagnostic ignored "-Wtautological-undefined-compare" | ||
explicit(false) operator std::basic_string_view<T>() const { | ||
if (this == nullptr) { | ||
return {}; | ||
} | ||
return std::basic_string_view<T>{data}; | ||
} | ||
|
||
explicit operator std::basic_string<T>() const { | ||
if (this == nullptr) { | ||
return {}; | ||
} | ||
return std::basic_string<T>{data}; | ||
} | ||
|
||
std::basic_string<T> to_string() const { | ||
if (this == nullptr) { | ||
return {}; | ||
} | ||
return std::basic_string<T>{data}; | ||
} | ||
|
||
std::basic_string_view<T> to_view() const { | ||
if (this == nullptr) { | ||
return {}; | ||
} | ||
return std::basic_string_view<T>{data}; | ||
} | ||
#pragma clang diagnostic pop | ||
|
||
char* begin() { | ||
return data; | ||
} | ||
|
||
const char* begin() const { | ||
return data; | ||
} | ||
|
||
char* end() { | ||
return data + N; | ||
} | ||
|
||
const char* end() const { | ||
return data + N; | ||
} | ||
|
||
T& operator[](size_t idx) { | ||
return data[idx]; | ||
} | ||
|
||
const T& operator[](size_t idx) const { | ||
return data[idx]; | ||
} | ||
|
||
class Iterator { | ||
T* ptr; | ||
T* end; | ||
|
||
public: | ||
using difference_type = std::ptrdiff_t; | ||
using value_type = T; | ||
using pointer = T*; | ||
using reference = T&; | ||
using iterator_category = std::random_access_iterator_tag; | ||
|
||
Iterator() = default; | ||
explicit Iterator(T* ptr) : ptr(ptr), end(ptr + N) {} | ||
|
||
Iterator& operator++() { | ||
++ptr; | ||
return *this; | ||
} | ||
|
||
Iterator operator++(int) { | ||
Iterator tmp = *this; | ||
++ptr; | ||
return tmp; | ||
} | ||
|
||
operator T*() { | ||
ASSERT_MSG(ptr >= end, "CString iterator out of bounds"); | ||
return ptr; | ||
} | ||
}; | ||
}; | ||
static_assert(sizeof(CString<13>) == sizeof(char[13])); // Ensure size still matches a simple array | ||
static_assert(std::weakly_incrementable<CString<13>::Iterator>); | ||
|
||
} // namespace Common |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.