A native C library that reads the game-native title id out of a ROM
(ULUS10064, SLUS-20152, 0100ABCD12345000), finds the save files an
emulator keeps for that game, and moves them between the emulator and a
RomM server. A client pairs a local save with the right game record by
the platform's own id instead of guessing from file names, archives and
hashes the save the way RomM does, and syncs it back without touching
other games' saves.
The client always tells sigil which emulator runs the game and where that
emulator keeps its saves; sigil never searches the drive. Each column
reads yes (sigil does it), no (the system needs it and sigil doesn't
do it yet) or n/a (the system has nothing of that kind).
- Game id: sigil reads the system's own id out of the ROM.
n/awhere the cart or disc carries none and emulators name saves after the file. - Save files: sigil knows which files in the save folder are this game's, for each emulator it lists. The client can upload them as they are (members).
- Shared card: the emulator can keep every game's saves on one memory
card or backup RAM file, and sigil takes one game's saves out of it and
puts them back without touching the others.
n/awhere each game's saves are already files of their own. - Unit: what travels to RomM: one file, several files zipped, or the game's save folders zipped. "single or multi" depends on the emulator or the cart (a clock file, a second card).
- Collect and restore: sigil builds the unit, writes a downloaded one
back and tracks what changed since the last sync
(sync). Where it's
no, the client uploads the save files as they are.
| System | Game id | Save files | Shared card | Unit | Collect and restore |
|---|---|---|---|---|---|
| PlayStation | yes | yes | yes | single | yes |
| PlayStation 2 | yes | yes | yes | single | yes |
| PSP | yes | yes | n/a | folder | yes |
| PS Vita | yes | yes | n/a | folder | yes |
| PlayStation 3 | yes | yes | n/a | folder | yes |
| Game Boy / Color | n/a | yes | n/a | single or multi | yes |
| Game Boy Advance | no | yes | n/a | single or multi | no |
| Super Nintendo | n/a | yes | n/a | single or multi | no |
| Famicom Disk System | no | yes | n/a | single | no |
| Nintendo DS | no | yes | n/a | single | no |
| Nintendo 3DS | yes | yes | n/a | folder | yes |
| Nintendo 64 | yes | yes | n/a | multi | yes |
| GameCube | yes | yes | yes | single or multi | yes |
| Wii | yes | yes | n/a | folder | yes |
| Wii U | yes | yes | n/a | folder | yes |
| Switch | yes | yes | n/a | folder | yes |
| Mega Drive, 32X, Master System, Game Gear | no | yes | n/a | single | no |
| Sega CD | no | yes | yes | single or multi | yes |
| Saturn | no | yes | yes | single or multi | yes |
| Dreamcast | yes | yes | yes | single or multi | yes |
| Xbox | yes | no | n/a | folder | no |
| Xbox 360 | yes | no | n/a | folder | no |
| Arcade | n/a | yes | no | single or multi | no |
| Neo Geo | no | yes | no | single or multi | no |
| Neo Geo Pocket | no | yes | n/a | single | no |
| PC Engine | n/a | yes | n/a | single | no |
| WonderSwan | no | yes | n/a | single | no |
| Lynx | n/a | yes | n/a | single | no |
| Jaguar | n/a | yes | no | single | no |
| Pokémon Mini | no | yes | n/a | single | no |
| 3DO | n/a | yes | no | single | no |
| DOS | n/a | yes | n/a | single | no |
| CD-i | n/a | yes | n/a | folder | no |
docs/platforms/ lists every system, the emulators each one covers, and the ones still in development. Formats and containers sigil reads: identification, containers.
- C: include/sigil.h. Guide: C.
- Kotlin/Java (Android, JNI):
bindings/android/. Guide: Kotlin. - Go (cgo):
bindings/go/. Guide: Go. - Python (cffi):
bindings/python/. Guide: Python.
Every binding exposes the same operations, options and fields. Each guide walks the three steps (identify the game, locate its saves, hash or sync them) with what each call requires, takes optionally, and returns.
cmake -B build -S . && cmake --build buildIdentify a game:
#include <sigil.h>
#include <stdio.h>
int main(void) {
sigil_result r;
int rc = sigil_extract_from_path("/path/to/game.iso",
SIGIL_PLATFORM_AUTO, NULL, &r);
if (rc != SIGIL_OK) {
fprintf(stderr, "sigil: %s\n", sigil_strerror(rc));
return 1;
}
printf("platform=%s\n", sigil_platform_to_slug(r.platform));
printf("title_id=%s\n", r.title_id); /* game identity, persist this */
printf("save_id=%s\n", r.save_id); /* on-disk save folder/file name */
printf("raw_serial=%s\n", r.raw_serial); /* as it appears in the binary */
printf("source=%s\n", r.source == SIGIL_SOURCE_BINARY ? "binary" : "filename");
/* r.usage: SIGIL_USAGE_FOLDER_EXACT | _FOLDER_PREFIX | _FILE_EXACT | _FILE_PREFIX | _FOLDER_SPLIT */
return 0;
}Collect a game's saves and put them back, in Python:
import sigil
game = sigil.extract("Chrono Cross (USA).chd", "psx")
unit = sigil.collect(game, "pcsx_rearmed", "Chrono Cross (USA).cue", "/saves/psx")
# upload unit.data as unit.artifact, store unit.state
sigil.restore(unit.data, game, "pcsx_rearmed", "Chrono Cross (USA).cue", "/saves/psx", state=unit.state)More: identification (the fields and what to
do with save_id), save units (which files belong
to a game, how they're hashed), sync (collect, restore,
conflicts), CLI, building and testing.
Pre-1.0. The API may evolve before 1.0. Every public struct has a
struct_version field so new fields can be added without breaking
existing consumers, but the function signatures and existing field
layouts can still change. Consumers vendoring sigil should pin a
specific commit; once 1.0 ships the C ABI freezes.
Report bugs and platform gaps in the GitHub issues, with the platform, the emulator, and the title id or the file that fails. A save sample helps most; tests/fixtures/saves/README.md explains how samples are added.
PRs welcome. See TRADEMARKS.md for the naming
policy: forks-for-contribution (standard fork → PR-upstream flow)
are encouraged; forks-and-republish-as-a-separate-project under the
argosy-sigil name are not.
MPL-2.0. See LICENSE for the full text and TRADEMARKS.md for the project naming policy. Anyone can use sigil in any application (proprietary or open); modifications to sigil's own files must remain MPL-2.0.
The Sega CD backup RAM reader (src/card_segacd.c) takes its ECC layout
table and format-block bytes from superctr/buram, Copyright (c) 2022 Ian
Karlsson, used under the MIT license; the notice is in
licenses/buram-MIT.txt.