Satiator menu replacement with image support written using jo-engine. Currently loads .iso and .cue / .bin format (.wav should work but not tested). Some games may not work due to vdp1 not being cleared. Region free is different to the official menu as it is done by actually patching the files on your SD card. Therefore there is a confirmation screen before launching which can be turned off in options.
This is a proof-of-concept change that adds MemCardPro-style per-game dedicated save ram functionality to any games started from Satiator-Rings.
This feature is dependent on @slinga-homebrew's Save-Game-Copier project. In its current state, SGC does not have a lib that can be imported by prospective projects so parts of its codebase have been manually added to the Rings project for this feature.
Summary of Operation
Each game is given a dedicated folder on the SD card that represents its SRAM state.
When a game is launched, the original state of the SRAM is saved to the _BACKUP folder.
The SRAM is cleared.
If the game has been launched before, the contents of its folder are copied into the SRAM.
A SAVRING marker save file is added to the SRAM that indicates the current game's GameID string.
When Rings is launched, the SRAM saves are listed out to search for a marker save.
If a marker save is found, the GameID string is used to create a new folder or open existing folder for this game, and replace its current contents with the ones found in the SRAM.
Afterwards, Rings erases the SRAM once more and adds all the saves found in the _BACKUP folder to allow users to disable this feature, switch to the legacy satiator menu, or start a CD game with no impact to previous behavior
Usage Instructions:
To use this feature:
Enable "Per-Game Saves" in the options pane
Launch any title
Observe that the title has (almost) the entire 32kb of Internal save memory space available to it.
Restart the console back into the rings menu to ensure the per-game saves are stored to the SD card.
To play games from CD
If the console was not restarted after the previous gaming session start Rings and ensure you reach the directory listing screen.
Place CD into console
Restart Console and launch game
Observe that the CD title has access to the original state of your internal save memory prior to enabling the per-save feature.
To modify per-game saves on the SD card
Ensure that all per-game saves have been committed to the SD card by restarting back into Rings after a previous gaming session.
Mount SD card to computer
Observe the satiator-saves folder and its per-game (denoted by the Sega gameid given to each title) subdirectories.
Modify or add additional *.BUP save files to each game while ensuring that each per-game folder does not go above 32kb
Implementation notes and callouts
The folder and marker names and certain attributes of the marker save's metadata are in DEFINE's that can be modified to suit tastes and needs.
To avoid any compatibility issues, I opted NOT to create a 0 byte SAVE entry and instead used a really small 52 byte save I found an original Title had used. Its not clear to me if this was necessary after all.
Most of the changes in this feature were isolated to the save* files, but certain changes were made to satiatorVerifyPatchDescFileImage to extract the gameID from the CD image along with the region code extraction that was done already. This gameid is set to a global value to match behavior in other parts of Rings
Satiator-Rings does not currently have an OSS license associated with it and SGC uses GPL3, this discrepancy will need to be resolved
This is not the most efficient way to do these bulk save operations. I favored using SGC in a clean manner than to modify its codebase and add more efficient bulk operation procedures (such as listing and deleting items in the same loop).
This save functionality allocates a full 32kb of space in RAM to parse and copy save contents from one device to the other. Even disabling this feature does not currently free this memory (Save init has to occur even if the feature is disabled to ensure we handle certain edge cases)
Error codes and enum handling could be done better if all error codes in Rings were combined into one enum
This was tested with a variety of titles over the course of a week, but please exercise caution around saves you care about.
Future work
Clean up Save-Game-Copier dependency
Save-Game-Copier's codebase had to be heavily commented out and culled to match this feature. To better maintain this codebase, a proposed libSave-Game-Copier would greatly improve maintainability of this feature. The SGC code also had certain changes done to it to ensure it functioned correctly within Rings. This included commenting out of all error and UI code, and removal of Satiator directory change calls (as Rings would perform the correct operations before handing control to SGC)
Multiple Save ram slots per-game
The SAVRING save file has metadata that can be used to indicate save slot number. UI work would be required to allow users to select between slots.
UI to tell users not to shut off their saturns during a save operation that could corrupt sram state
"If you see this icon, please do not turn off your console as it may lead to data loss"
Additional error and diagnosis in the UI
This would be useful for explaining to the user if the SRAM or SD card is out of space.
If initialization errors occur in the Save subsystem, disable the in-game save feature and direct the user to resolve any issues
Rebootless saves to SD card
Currently we do not control code execution after the title has been launched. This makes it hard to build a per-game system that ensures writes to the SRAM are copied to the SD card and therefore requires a reboot to commit the changes to disk. However, patching of the game's binary/binaries (certain titles launch multiple executables, US Saturn Bomberman for example) to divert SRAM save logic to instead save directly to the Satiator or a patched AR cart may be possible, but could introduce great compat risk (switching between CD mode and SD card mode while a game is running sounds very risky to me),
One possible middle ground: a future patched AR cart image could replicate the Save Init functionality so that users wouldn't need to restart into Rings to save their previous session to SD card and reimage their SRAM to _BACKUP state.
This is a proof-of-concept change that adds MemCardPro-style per-game dedicated save ram functionality to any games started from Satiator-Rings.
This feature is dependent on @slinga-homebrew's Save-Game-Copier project. In its current state, SGC does not have a lib that can be imported by prospective projects so parts of its codebase have been manually added to the Rings project for this feature.
Summary of Operation
SAVRING
marker save file is added to the SRAM that indicates the current game's GameID string.Usage Instructions:
To use this feature:
To play games from CD
To modify per-game saves on the SD card
satiator-saves
folder and its per-game (denoted by the Sega gameid given to each title) subdirectories.Implementation notes and callouts
satiatorVerifyPatchDescFileImage
to extract the gameID from the CD image along with the region code extraction that was done already. This gameid is set to a global value to match behavior in other parts of RingsFuture work