[VFS] Rewrote STFS to use memory mapping

- Replaced old-style buffer, buffer_length with std::span
- Added STFS and SVOD specific Entry and File classes
- Other smaller improvements
This commit is contained in:
Gliniak
2025-05-13 21:05:46 +02:00
committed by Radosław Gliński
parent e85c2392ba
commit fe739208b6
36 changed files with 481 additions and 206 deletions

View File

@@ -7,13 +7,9 @@
******************************************************************************
*/
#include <algorithm>
#include <vector>
#include "xenia/base/logging.h"
#include "xenia/vfs/devices/xcontent_container_device.h"
#include "xenia/vfs/devices/xcontent_container_entry.h"
#include "xenia/vfs/devices/xcontent_devices/svod_container_device.h"
#include "xenia/base/logging.h"
#include "xenia/vfs/devices/xcontent_devices/svod_container_entry.h"
namespace xe {
namespace vfs {
@@ -26,10 +22,15 @@ SvodContainerDevice::SvodContainerDevice(const std::string_view mount_path,
SetName("FATX");
}
SvodContainerDevice::~SvodContainerDevice() { CloseFiles(); }
SvodContainerDevice::~SvodContainerDevice() {
for (auto& file : files_) {
fclose(file.second);
}
files_.clear();
files_total_size_ = 0;
}
SvodContainerDevice::Result SvodContainerDevice::LoadHostFiles(
FILE* header_file) {
SvodContainerDevice::Result SvodContainerDevice::LoadHostFiles() {
std::filesystem::path data_fragment_path = host_path_;
data_fragment_path += ".data";
if (!std::filesystem::exists(data_fragment_path)) {
@@ -58,7 +59,7 @@ SvodContainerDevice::Result SvodContainerDevice::LoadHostFiles(
auto file = xe::filesystem::OpenFile(path, "rb");
if (!file) {
XELOGI("Failed to map SVOD file {}.", path);
CloseFiles();
// CloseFiles();
return Result::kReadError;
}
@@ -100,7 +101,7 @@ XContentContainerDevice::Result SvodContainerDevice::Read() {
const uint64_t root_creation_timestamp =
decode_fat_timestamp(root_data.creation_date, root_data.creation_time);
auto root_entry = new XContentContainerEntry(this, nullptr, "", &files_);
auto root_entry = new SvodContainerEntry(this, nullptr, "", &files_);
root_entry->attributes_ = kFileAttributeDirectory;
root_entry->access_timestamp_ = root_creation_timestamp;
root_entry->create_timestamp_ = root_creation_timestamp;
@@ -112,7 +113,7 @@ XContentContainerDevice::Result SvodContainerDevice::Read() {
}
SvodContainerDevice::Result SvodContainerDevice::ReadEntry(
uint32_t block, uint32_t ordinal, XContentContainerEntry* parent) {
uint32_t block, uint32_t ordinal, SvodContainerEntry* parent) {
// For games with a large amount of files, the ordinal offset can overrun
// the current block and potentially hit a hash block.
size_t ordinal_offset = ordinal * 0x4;
@@ -184,7 +185,7 @@ SvodContainerDevice::Result SvodContainerDevice::ReadEntry(
// NOTE: SVOD entries don't have timestamps for individual files, which can
// cause issues when decrypting games. Using the root entry's timestamp
// solves this issues.
auto entry = XContentContainerEntry::Create(this, parent, name, &files_);
auto entry = SvodContainerEntry::Create(this, parent, name, &files_);
if (dir_entry.attributes & kFileAttributeDirectory) {
// Entry is a directory
entry->attributes_ = kFileAttributeDirectory | kFileAttributeReadOnly;