157 lines
3.9 KiB
Text
157 lines
3.9 KiB
Text
== Files and Saves
|
|
|
|
Declared in `<joey/file.h>`.
|
|
|
|
Two directories sit beside the executable, staged there by each platform's disk
|
|
packager:
|
|
|
|
* `DATA/` -- read-only game content: levels, sprites, audio.
|
|
* `SAVES/` -- writable saves and preferences.
|
|
|
|
DVX is the exception, because its programs share one current directory:
|
|
there `DATA/` is beside the program, in its folder under DVX's `APPS`, and
|
|
`SAVES/` is in the program's own settings folder, `CONFIG\APPS\JOEYLIB\NAME`,
|
|
which DVX keeps apart from the program files so a reinstall never overwrites
|
|
it. The calls below find both there by themselves.
|
|
|
|
Both are addressed by a *bare name relative to their directory*. The prefix is
|
|
added for you, so never hard-code `"DATA/"` or `"SAVES/"` yourself.
|
|
|
|
[IMPORTANT]
|
|
====
|
|
Keep names portable across the retro filesystems: at most 8 characters plus a
|
|
short extension, letters and digits only, so they satisfy both ProDOS and DOS
|
|
8.3. Do not depend on case being preserved.
|
|
====
|
|
|
|
A failed open or write is non-fatal and simply reports failure, so save code
|
|
can degrade gracefully on a platform or volume where `SAVES/` is unavailable.
|
|
|
|
=== jlDataOpen
|
|
|
|
[source,c]
|
|
----
|
|
FILE *jlDataOpen(const char *name, const char *mode);
|
|
----
|
|
|
|
Opens a read-only data file. The `DATA/` prefix is prepended automatically.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`name` |`const char *` |Name relative to `DATA/`, for example
|
|
`"levels/title.dat"`.
|
|
|`mode` |`const char *` |Standard `fopen` mode string.
|
|
|===
|
|
|
|
*Returns:* a `FILE *`, or `NULL` if the path would overflow the internal buffer
|
|
or the file cannot be opened.
|
|
|
|
=== jlSaveOpen
|
|
|
|
[source,c]
|
|
----
|
|
FILE *jlSaveOpen(const char *name, const char *mode);
|
|
----
|
|
|
|
Opens a save file for streaming. For write and append modes the `SAVES/`
|
|
directory is created on demand. Use this for large or incremental saves; for a
|
|
whole-file blob prefer `jlSaveWrite` and `jlSaveRead`.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`name` |`const char *` |Name relative to `SAVES/`, for example `"hero.sav"`.
|
|
|`mode` |`const char *` |Standard `fopen` mode string.
|
|
|===
|
|
|
|
*Returns:* a `FILE *`, or `NULL` on failure.
|
|
|
|
=== jlSaveWrite
|
|
|
|
[source,c]
|
|
----
|
|
bool jlSaveWrite(const char *name, const void *buf, uint32_t len);
|
|
----
|
|
|
|
Writes a whole save file, replacing any existing contents.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`name` |`const char *` |Name relative to `SAVES/`.
|
|
|`buf` |`const void *` |Data to write.
|
|
|`len` |`uint32_t` |Byte count.
|
|
|===
|
|
|
|
*Returns:* `true` only if all `len` bytes were written.
|
|
|
|
=== jlSaveRead
|
|
|
|
[source,c]
|
|
----
|
|
uint32_t jlSaveRead(const char *name, void *buf, uint32_t max);
|
|
----
|
|
|
|
Reads a whole save file.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`name` |`const char *` |Name relative to `SAVES/`.
|
|
|`buf` |`void *` |Destination buffer.
|
|
|`max` |`uint32_t` |Buffer capacity.
|
|
|===
|
|
|
|
*Returns:* the number of bytes read; 0 if the file is missing or empty.
|
|
|
|
=== jlSaveExists
|
|
|
|
[source,c]
|
|
----
|
|
bool jlSaveExists(const char *name);
|
|
----
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`name` |`const char *` |Name relative to `SAVES/`.
|
|
|===
|
|
|
|
*Returns:* `true` if the file exists and can be opened for reading.
|
|
|
|
=== jlSaveDelete
|
|
|
|
[source,c]
|
|
----
|
|
bool jlSaveDelete(const char *name);
|
|
----
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`name` |`const char *` |Name relative to `SAVES/`.
|
|
|===
|
|
|
|
*Returns:* `true` if the file was removed.
|
|
|
|
=== jlDiskFree
|
|
|
|
[source,c]
|
|
----
|
|
uint32_t jlDiskFree(void);
|
|
----
|
|
|
|
*Parameters:* none.
|
|
|
|
*Returns:* free space in bytes on the volume holding `SAVES/`. Returns 0 if it
|
|
cannot be determined -- some ports have no query for it -- and saturates at
|
|
`UINT32_MAX` on volumes larger than 4 GB.
|
|
|
|
[source,c]
|
|
----
|
|
// Check before writing a large save on a floppy-based target.
|
|
if (jlDiskFree() < neededBytes) {
|
|
showMessage("Disk full");
|
|
}
|
|
----
|