one-saves-cli 0.6.1

The 1saves command-line tool: convert emulator saves and memory cards to and from the Universal Saves Format
# one-saves-cli

The `1saves` command-line tool: move retro saves and memory cards in and out of the
[Universal Saves Format][spec].

```console
$ cargo install one-saves-cli
```

## Commands

```console
$ 1saves convert card.mcr --from duckstation
card.mcr -> card.1saves (PS1 memory card, 3 save(s), 25525 bytes)

$ 1saves convert pokemon.srm --from mgba --rom pokemon_red.gb --dat No-Intro_GB.dat
identified as "Pokemon - Red Version (USA, Europe)"

$ 1saves inspect card.1saves     # everything it says, down to each save on a card
$ 1saves verify card.1saves      # structure, every digest, and the encoding
$ 1saves hash card.1saves        # content hash and file hash
$ 1saves extract card.1saves     # write it back out as the card it came from
$ 1saves extract card.1saves --part 1   # pull one save out as its own bundle
$ 1saves profiles                # what --from accepts
```

`new` makes an empty, formatted card, written as the file an emulator or a flash cart loads:

```console
$ 1saves new gc MemoryCardA.USA.raw --size 1019
empty GameCube memory card -> MemoryCardA.USA.raw (1019 blocks, 64 Mbit, 8388608 bytes)

$ 1saves new ps2 Mcd002.ps2              # Sony's 8 MB card, spare areas and all
$ 1saves new gc MemoryCardA.JAP.raw --shift-jis   # for a Japanese console
$ 1saves new saturn cart.bcr --size 512K --layout wide   # as Yabause keeps a cart
$ 1saves new neogeo game.sav --layout mister   # as the MiSTer core keeps a card
$ 1saves new vmu blank.1saves            # a bundle holding the card, rather than the card
```

`--from` names either a producer (`mgba`, `duckstation`, `pcsx2`, or any of the apps and 200 cores
in the registry) or an input format (`ps1`, `raw`). A producer says who wrote the bytes; the format
is still detected from the bytes themselves.

A bundle's `source` names three layers: the app, the core it ran, and the platform under it.
`--from retroarch` names only the app, so add the rest when you know them:

```console
$ 1saves convert crystal.srm --from retroarch --core gambatte --platform muos
```

Each is written as its registry slug, whatever it was called on the command line, and checked: a
core the app cannot run is refused. A producer neither registry lists — a flash cartridge, a
cartridge reader — is left out of `source` rather than given a reverse-DNS name `1saves` does not
own, so its profile settles only the device kind and the system. `1saves profiles` shows which is
which.

`--rom` reads a ROM's header for a title and product code and hashes it; `--dat` resolves that
digest against a No-Intro, Redump or TOSEC catalog to get a canonical name.

## Features

All on by default. Turning one off drops what it carries, and the dependencies under it, from the
binary.

| Feature | What it carries | What comes off |
| ------- | --------------- | -------------- |
| `cards` | all seven card formats | the seven crates below |
| `ps1` `n64` `gc` `vmu` `ps2` `neogeo` `saturn` | one card format each | that format's crate, and nothing else |
| `dat` | `--dat FILE` | `datary` and the XML reader, derive macro and proc-macro chain under it |
| `dat-cmpro` | the ClrMamePro syntax for `--dat` | `winnow` |
| `rom` | `--rom FILE` | `crc32fast`, `md-5`, `sha1` |
| `zstd` | — | `zstd` and the C library it compiles |

`dat` implies `rom`: a catalog is looked up by the ROM's digest, so `--dat` has nothing to resolve
without `--rom`. With `zstd` off, `hash` and `verify` report a content hash as unavailable on a
bundle whose payload is compressed rather than computing one.

A card format that is off is still **named**. `inspect`, `verify` and `hash` read a bundle of it
unchanged, and `convert` and `extract` refuse in these words rather than guessing:

```console
$ 1saves convert card.mcr
1saves: this is a PS1 memory card, and this build has the `ps1` feature off, so it can
        name the format and not read or write it
```

What such a build cannot do is tell that format's dump from a flat save when the extension is
ambiguous — `.bin`, `.srm` — because the reader that knows the signature is what came off.

```console
$ cargo install one-saves-cli --no-default-features --features ps1,zstd
```

[spec]: https://docs.1retro.com/specifications/universal-saves-format/