|
Nugget
|
A Sony-compatible memory card filesystem. More...
#include <psyqo/memory-card-filesystem.hh>
Classes | |
| struct | FileEntry |
| A directory listing entry. More... | |
| struct | FileInfo |
| A file's on-card metadata: its title and icon. More... | |
| struct | Icon |
| A save icon, in the native PlayStation format. More... | |
Public Types | |
| using | Error = MemoryCard::Error |
| using | Port = MemoryCard::Port |
Public Member Functions | |
| MemoryCardFileSystem (MemoryCard &card) | |
| bool | isIdle () const |
| Whether the filesystem is ready to accept a new operation. | |
| void | getCardState (Port port, eastl::function< void(Error)> &&callback) |
| Determines whether a usable, formatted card is present. | |
| void | format (Port port, eastl::function< void(Error)> &&callback) |
| Writes a fresh, empty Sony filesystem to the card. | |
| void | getFreeBlockCount (Port port, uint32_t *outFreeBlocks, eastl::function< void(Error)> &&callback) |
| Counts the free 8KiB blocks (0..15) into *outFreeBlocks. | |
| void | listFiles (Port port, FileEntry *out, uint32_t maxEntries, uint32_t *outCount, eastl::function< void(Error)> &&callback) |
| Lists the files on the card. | |
| void | fileExists (Port port, const char *name, bool *outExists, eastl::function< void(Error)> &&callback) |
| Reports whether a named file exists, into *outExists. | |
| void | readFile (Port port, const char *name, void *buffer, uint32_t maxLen, uint32_t *outLen, eastl::function< void(Error)> &&callback) |
| Reads the payload of a file. | |
| void | readFileInfo (Port port, const char *name, FileInfo *out, eastl::function< void(Error)> &&callback) |
| Reads a file's title and icon. | |
| void | writeFile (Port port, const char *name, const char *title, const Icon &icon, const void *data, uint32_t dataLen, eastl::function< void(Error)> &&callback) |
| Creates or overwrites a file. | |
| void | deleteFile (Port port, const char *name, eastl::function< void(Error)> &&callback) |
| Deletes a file, freeing all of its blocks. | |
| Error | getCardStateBlocking (GPU &gpu, Port port) |
| Error | formatBlocking (GPU &gpu, Port port) |
| Error | getFreeBlockCountBlocking (GPU &gpu, Port port, uint32_t *outFreeBlocks) |
| Error | listFilesBlocking (GPU &gpu, Port port, FileEntry *out, uint32_t maxEntries, uint32_t *outCount) |
| Error | fileExistsBlocking (GPU &gpu, Port port, const char *name, bool *outExists) |
| Error | readFileBlocking (GPU &gpu, Port port, const char *name, void *buffer, uint32_t maxLen, uint32_t *outLen) |
| Error | readFileInfoBlocking (GPU &gpu, Port port, const char *name, FileInfo *out) |
| Error | writeFileBlocking (GPU &gpu, Port port, const char *name, const char *title, const Icon &icon, const void *data, uint32_t dataLen) |
| Error | deleteFileBlocking (GPU &gpu, Port port, const char *name) |
A Sony-compatible memory card filesystem.
This class implements the on-card filesystem used by the retail PlayStation BIOS, on top of the raw sector access provided by MemoryCard. Files written through it are 100% compatible with the BIOS memory card manager: they show up with their title and icon, and can be copied or deleted from the BIOS like any other save.
The card is laid out as a 16-block device (block 0 is the directory, blocks 1..15 hold files). A file occupies one or more whole 8KiB blocks, chained through the directory as a linked list. The first block of a file starts with a "title frame" (magic "SC", a Shift-JIS title and a 16-colour palette) followed by 1..3 icon frames (16x16, 4bpp); the rest of the blocks hold the caller's payload.
A whole filesystem operation is a transaction that spans many individual sector transfers and therefore several frames. To avoid stalling the main loop for that whole time, operations are asynchronous, following the same contract as CDRomDevice: only ONE operation may be in flight at a time, and progress is driven by chaining the MemoryCard device's own interrupt-driven sector transfers - each transfer's completion callback issues the next - so the game keeps running between sectors, with no timer. Every operation comes in two forms:
eastl::function callback that is invoked, from the main loop during callback pumping, with the resulting MemoryCard::Error; and*Blocking(GPU&) variant that pumps the GPU until the operation completes and returns the error directly.The SIO0Bus is owned for the entire transaction, so AdvancedPad stands down for its full duration (see the MemoryCard warning: this filesystem is usable with AdvancedPad only, never SimplePad).
|
inlineexplicit |
| void psyqo::MemoryCardFileSystem::deleteFile | ( | Port | port, |
| const char * | name, | ||
| eastl::function< void(Error)> && | callback | ||
| ) |
Deletes a file, freeing all of its blocks.
| void psyqo::MemoryCardFileSystem::fileExists | ( | Port | port, |
| const char * | name, | ||
| bool * | outExists, | ||
| eastl::function< void(Error)> && | callback | ||
| ) |
Reports whether a named file exists, into *outExists.
| Error psyqo::MemoryCardFileSystem::fileExistsBlocking | ( | GPU & | gpu, |
| Port | port, | ||
| const char * | name, | ||
| bool * | outExists | ||
| ) |
Writes a fresh, empty Sony filesystem to the card.
This erases the directory; any existing files become unreachable. The 15 file blocks themselves are not touched (they are simply marked free), matching what the BIOS does.
| void psyqo::MemoryCardFileSystem::getCardState | ( | Port | port, |
| eastl::function< void(Error)> && | callback | ||
| ) |
Determines whether a usable, formatted card is present.
| void psyqo::MemoryCardFileSystem::getFreeBlockCount | ( | Port | port, |
| uint32_t * | outFreeBlocks, | ||
| eastl::function< void(Error)> && | callback | ||
| ) |
Counts the free 8KiB blocks (0..15) into *outFreeBlocks.
| Error psyqo::MemoryCardFileSystem::getFreeBlockCountBlocking | ( | GPU & | gpu, |
| Port | port, | ||
| uint32_t * | outFreeBlocks | ||
| ) |
|
inline |
Whether the filesystem is ready to accept a new operation.
| void psyqo::MemoryCardFileSystem::listFiles | ( | Port | port, |
| FileEntry * | out, | ||
| uint32_t | maxEntries, | ||
| uint32_t * | outCount, | ||
| eastl::function< void(Error)> && | callback | ||
| ) |
Lists the files on the card.
| out | An array to receive up to maxEntries entries. |
| outCount | Receives the number of files found (may exceed maxEntries, in which case only maxEntries were written). |
| Error psyqo::MemoryCardFileSystem::listFilesBlocking | ( | GPU & | gpu, |
| Port | port, | ||
| FileEntry * | out, | ||
| uint32_t | maxEntries, | ||
| uint32_t * | outCount | ||
| ) |
| void psyqo::MemoryCardFileSystem::readFile | ( | Port | port, |
| const char * | name, | ||
| void * | buffer, | ||
| uint32_t | maxLen, | ||
| uint32_t * | outLen, | ||
| eastl::function< void(Error)> && | callback | ||
| ) |
Reads the payload of a file.
Returns the bytes that follow the title and icon frames, i.e. exactly the data region passed to writeFile, rounded up to whole frames. The caller is responsible for knowing the logical length of its own payload (typically via a small header it embeds in data).
| buffer | Receives up to maxLen payload bytes. |
| outLen | Receives the number of payload bytes available (capped at maxLen). |
| Error psyqo::MemoryCardFileSystem::readFileBlocking | ( | GPU & | gpu, |
| Port | port, | ||
| const char * | name, | ||
| void * | buffer, | ||
| uint32_t | maxLen, | ||
| uint32_t * | outLen | ||
| ) |
| void psyqo::MemoryCardFileSystem::readFileInfo | ( | Port | port, |
| const char * | name, | ||
| FileInfo * | out, | ||
| eastl::function< void(Error)> && | callback | ||
| ) |
Reads a file's title and icon.
Fills *out with the file's title frame (the raw Shift-JIS title and the icon palette) and its icon bitmap frames, so a caller can display saved blocks the way the BIOS manager does. This is the read counterpart to writeFile's title and icon; it reads only the file's first block, never the payload.
| name | The Sony filename to look up. Must stay valid until the callback fires. |
| out | Receives the title and icon. Must stay valid until the callback fires. |
| Error psyqo::MemoryCardFileSystem::readFileInfoBlocking | ( | GPU & | gpu, |
| Port | port, | ||
| const char * | name, | ||
| FileInfo * | out | ||
| ) |
| void psyqo::MemoryCardFileSystem::writeFile | ( | Port | port, |
| const char * | name, | ||
| const char * | title, | ||
| const Icon & | icon, | ||
| const void * | data, | ||
| uint32_t | dataLen, | ||
| eastl::function< void(Error)> && | callback | ||
| ) |
Creates or overwrites a file.
The file is sized to hold the title frame, the icon frames and dataLen payload bytes, rounded up to whole 8KiB blocks. If a file with the same name already exists it is replaced. The data is written first and the directory committed last, so an interrupted write never leaves a referenced but corrupt file.
| name | The Sony filename (up to 20 characters). The pointer must stay valid until the callback fires. |
| title | The save title, as a UTF-8 string, encoded to the 64-byte Shift-JIS field the BIOS manager displays, with printable ASCII promoted to its fullwidth form. Must stay valid until the callback fires. |
| icon | The save icon. Copied, so it need not outlive the call. |
| data | The payload bytes. Must stay valid until the callback fires. |
| dataLen | The number of payload bytes. |
| Error psyqo::MemoryCardFileSystem::writeFileBlocking | ( | GPU & | gpu, |
| Port | port, | ||
| const char * | name, | ||
| const char * | title, | ||
| const Icon & | icon, | ||
| const void * | data, | ||
| uint32_t | dataLen | ||
| ) |