mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-05-03 02:34:48 +12:00
ExtSaveData work
This commit is contained in:
parent
902b877c40
commit
995dfb81df
12 changed files with 68 additions and 28 deletions
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
@ -72,14 +73,24 @@ struct FSPath {
|
|||
}
|
||||
};
|
||||
|
||||
class ArchiveBase;
|
||||
struct FilePerms {
|
||||
u32 raw;
|
||||
|
||||
FilePerms(u32 val) : raw(val) {}
|
||||
bool read() const { return (raw & 1) != 0; }
|
||||
bool write() const { return (raw & 2) != 0; }
|
||||
bool create() const { return (raw & 4) != 0; }
|
||||
};
|
||||
|
||||
class ArchiveBase;
|
||||
struct FileSession {
|
||||
ArchiveBase* archive = nullptr;
|
||||
FILE* fd = nullptr; // File descriptor for file sessions that require them.
|
||||
FSPath path;
|
||||
bool isOpen;
|
||||
|
||||
FileSession(ArchiveBase* archive, const FSPath& filePath, bool isOpen = true) : archive(archive), path(path), isOpen(isOpen) {}
|
||||
FileSession(ArchiveBase* archive, const FSPath& filePath, FILE* fd, bool isOpen = true) :
|
||||
archive(archive), path(path), fd(fd), isOpen(isOpen) {}
|
||||
};
|
||||
|
||||
struct ArchiveSession {
|
||||
|
@ -90,9 +101,16 @@ struct ArchiveSession {
|
|||
ArchiveSession(ArchiveBase* archive, const FSPath& filePath, bool isOpen = true) : archive(archive), path(path), isOpen(isOpen) {}
|
||||
};
|
||||
|
||||
// Represents a file descriptor obtained from OpenFile. If the optional is nullopt, opening the file failed.
|
||||
// Otherwise the fd of the opened file is returned (or nullptr if the opened file doesn't require one)
|
||||
using FileDescriptor = std::optional<FILE*>;
|
||||
|
||||
class ArchiveBase {
|
||||
protected:
|
||||
using Handle = u32;
|
||||
static constexpr FileDescriptor NoFile = nullptr;
|
||||
static constexpr FileDescriptor FileError = std::nullopt;
|
||||
|
||||
Memory& mem;
|
||||
|
||||
// Returns if a specified 3DS path in UTF16 or ASCII format is safe or not
|
||||
|
@ -143,7 +161,8 @@ protected:
|
|||
public:
|
||||
virtual std::string name() = 0;
|
||||
virtual u64 getFreeBytes() = 0;
|
||||
virtual bool openFile(const FSPath& path) = 0;
|
||||
// Returns nullopt if opening the file failed, otherwise returns a file descriptor to it (nullptr if none is needed)
|
||||
virtual FileDescriptor openFile(const FSPath& path, const FilePerms& perms) = 0;
|
||||
|
||||
virtual ArchiveBase* openArchive(const FSPath& path) = 0;
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ public:
|
|||
u64 getFreeBytes() override { Helpers::panic("ExtSaveData::GetFreeBytes unimplemented"); return 0; }
|
||||
std::string name() override { return "ExtSaveData"; }
|
||||
|
||||
bool openFile(const FSPath& path) override;
|
||||
ArchiveBase* openArchive(const FSPath& path) override;
|
||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
||||
|
||||
bool isShared = false;
|
||||
|
|
|
@ -8,8 +8,8 @@ public:
|
|||
u64 getFreeBytes() override { return 0; }
|
||||
std::string name() override { return "SelfNCCH"; }
|
||||
|
||||
bool openFile(const FSPath& path) override;
|
||||
ArchiveBase* openArchive(const FSPath& path) override;
|
||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
||||
|
||||
// Returns whether the cart has a RomFS
|
||||
|
|
|
@ -8,8 +8,8 @@ public:
|
|||
u64 getFreeBytes() override { Helpers::panic("SaveData::GetFreeBytes unimplemented"); return 0; }
|
||||
std::string name() override { return "SaveData"; }
|
||||
|
||||
bool openFile(const FSPath& path) override;
|
||||
ArchiveBase* openArchive(const FSPath& path) override;
|
||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
||||
|
||||
// Returns whether the cart has save data or not
|
||||
|
|
|
@ -8,7 +8,7 @@ public:
|
|||
u64 getFreeBytes() override { Helpers::panic("SDMC::GetFreeBytes unimplemented"); return 0; }
|
||||
std::string name() override { return "SDMC"; }
|
||||
|
||||
bool openFile(const FSPath& path) override;
|
||||
ArchiveBase* openArchive(const FSPath& path) override;
|
||||
FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override;
|
||||
std::optional<u32> readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override;
|
||||
};
|
|
@ -24,6 +24,9 @@ class IOFile {
|
|||
public:
|
||||
IOFile() {}
|
||||
IOFile(FILE* handle) : handle(handle) {}
|
||||
IOFile(const std::filesystem::path& path, const char* permissions = "rb") {
|
||||
open(path, permissions);
|
||||
}
|
||||
|
||||
bool isOpen() {
|
||||
return handle != nullptr;
|
||||
|
@ -86,6 +89,10 @@ public:
|
|||
return seek(0, SEEK_SET);
|
||||
}
|
||||
|
||||
FILE* getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void setAppDataDir(const char* dir) {
|
||||
if (!dir) Helpers::panic("Failed to set app data directory");
|
||||
appData = std::filesystem::path(dir);
|
||||
|
|
|
@ -26,7 +26,7 @@ class FSService {
|
|||
|
||||
ArchiveBase* getArchiveFromID(u32 id);
|
||||
std::optional<Handle> openArchiveHandle(u32 archiveID, const FSPath& path);
|
||||
std::optional<Handle> openFileHandle(ArchiveBase* archive, const FSPath& path);
|
||||
std::optional<Handle> openFileHandle(ArchiveBase* archive, const FSPath& path, const FilePerms& perms);
|
||||
FSPath readPath(u32 type, u32 pointer, u32 size);
|
||||
|
||||
// Service commands
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue