Despite having an API that creates save state data into an user-provided buffer, some Libretro cores still create additional data as files. Additionally, Libretro save states don't feature a screenshot of the video frame buffer at the time the save state is created, making it impossible to preview the save state or restore the frame buffer when the save state is loaded back.
We also want to save data to completely restore the emulation state, like the core name and version, core options values, and any other data needed by the application.
To make it easier to put all this data into a single file, we'll use the RIFF format. RIFF is a chunked format, allowing us to save everything we need in an organized way.
All integers and float-point numbers are written in little-endian, and strings are null-terminated.
Save states will have one main chunk, HCSV
, with the following subchunks to hold the data:
HC
:HASH
: Thegit
commit hash when the app was builtOPTS
: A chunk with the application options, each option is serialized as:- A string with an application option key
- A string with an application option value that was selected at the time the save state was created
- The list terminates with an empty option key (length is 0)
TIME
: ISO-8601 data and time when the file was createdREM
: A string with any notes that the user wanted to save along with the save stateFRMB
: Frame buffer contentsAVNF
: A copy of theretro_system_av_info
structure contents at the time the save state was created. All values must be serialized in little-endian, without any padding, in the same order as they appear in the structure.PXFM
: A 32-bit unsigned integer with the pixel format as specified with theretro_pixel_format
enumerationPIXL
: Pixel data using the format specified in thePXFM
chunk and dimensions specified inAVNF
, compressed withzlib
SAVE
: The data obtained with a call toretro_serialize
FILE
: If the core creates files to persist additional data, they are added to this chunk, which is repeated for each filePATH
: A 32-bit unsigned integer specifying where the file must be put in the file system so the core can find it- 0: System folder
- 1: Same folder as the core
- 2: Core assets folder
- 3: Save folder
NAME
: a string with the file name, without the pathUNSZ
: A 32-bit unsigned integer with the size ofDATA
when uncompressedDATA
: The contents of the file compressed withzlib
CORE
: A chunk with core informationNAME
: A string with the library name fromretro_system_info
VERS
: A string with the library version also fromretro_system_info
OPTS
: A chunk with the core options, same format as the application options