3.0 KiB
Save & Locale
Save system (src/dusk/save/)
Slot-based persistent storage. Currently disabled in engine init (commented out in engine.c) — the system is fully implemented but not yet wired up.
Slots
Up to SAVE_FILE_COUNT_MAX (3) save slots. The global SAVE holds all slots:
saveInit();
saveExists(slot); // bool_t — check before load
saveLoad(slot); // read from platform storage → SAVE.files[slot]
saveWrite(slot); // write SAVE.files[slot] → platform storage
saveDelete(slot);
savefile_t *f = saveGet(slot);
saveDispose();
Save file format
savefile_t is the serialized struct stored per slot. Currently minimal:
typedef struct {
char_t header[3]; // "DSK"
uint32_t version; // SAVE_FILE_VERSION = 1
bool_t exists;
} savefile_t;
Extend this struct to add game-specific save data (player position, story flags, etc.).
Stream serialization (save/savestream.h)
savestream_t is a cursor used to read/write a save slot's bytes. It CRC32-checksums all data written through it and verifies the checksum on read.
Write a save:
savestream_t stream;
// (platform opens stream for slot)
saveFileWriteHeader(&stream, SAVE_FILE_HEADER);
saveFileWriteVersion(&stream, SAVE_FILE_VERSION);
saveFileWriteBool(&stream, myFlag);
saveFileWriteInt32(&stream, myInt);
saveFileWriteString(&stream, myString, sizeof(myString));
saveStreamFinalizeWriteImpl(&stream); // writes CRC
Read a save:
saveFileReadHeader(&stream, headerBuf);
saveFileReadVersion(&stream, &version);
saveFileReadBool(&stream, &myFlag);
saveFileReadInt32(&stream, &myInt);
saveFileReadString(&stream, myString, sizeof(myString));
saveStreamVerifyChecksumImpl(&stream, slot); // returns error if CRC mismatch
All multi-byte values are stored in little-endian byte order. The saveFile* macros are thin wrappers over the *Impl functions that integrate errorChain — always use the macros.
Platform backends
Each src/dusk{platform}/save/ provides saveplatform_t (e.g. a file path on Linux, a memory-card handle on GameCube). The stream implementations (savestream{platform}.c) do the actual I/O.
Locale / i18n (src/dusk/locale/)
Translations are stored as GNU .po files in assets/locale/. Only en_US.po currently exists.
Loading
localemanager_t LOCALE tracks the active locale and its in-progress asset entry:
localeManagerInit(); // loads en_US by default
localeManagerSetLocale(&LOCALE_EN_US); // switch locale (async load)
localeManagerDispose();
LOCALE_EN_US is a predefined localeinfo_t constant (name = "en-US", file = "locale/en_US.po").
Looking up strings
char_t buf[128];
localeManagerGetText("my.key", buf, sizeof(buf), 1, /* format args */ );
The macro handles plural forms and printf-style format arguments. Pass plural 1 for singular, any other value for plural.
assetlocaleloader.c parses the .po format (msgid / msgstr pairs) into a key→string table during the async asset load phase.