Accept .srm save file extension - #2741
Open
Davey-Hughes wants to merge 2 commits into
Open
Davey-Hughes wants to merge 2 commits into
Davey-Hughes wants to merge 2 commits into
Conversation
RetroArch writes DS cart saves as <romname>.srm, byte-identical to the .sav melonDS writes, so a shared save directory ends up holding two copies of the same data under two names with no way to make melonDS use the other one. Add a per-instance SaveFileExtension setting, selectable in path settings, and fall back to reading the other extension when the configured one has no file. Writes always use the configured extension. Reading and writing different files is not new here: for instance 2 melonDS already reads game.sav and writes game.sav.2. This applies the same idea to a second axis, and warns when it happens so a stale file isn't a surprise. The warning can be dismissed permanently. Applying a save path or extension change retargets the live SaveManager, which flushes the in-memory save to the new path and truncates whatever is already there. Confirm by name before doing that, since it destroys a save. The writability check now targets the file actually written rather than the unsuffixed path, which the old code only ever read from.
Switching the save file extension otherwise means the mismatch warning fires on every game in a library until each has been written once under the new name. Add a Convert button that renames the existing save files in the save directory, listing up front exactly what will be renamed and what will be skipped and why, and rewriting that list with the outcome afterwards. std::filesystem::rename is used rather than copying: it is atomic within a filesystem and never touches the file's data. It does replace an existing destination silently, so the destination is checked immediately before each rename and the file skipped if anything is there at all, a dangling symlink included. Symlinks, collisions and unreadable entries are skipped, never renamed. The multi-instance suffix is handled, so game.sav.2 becomes game.srm.2. A successful conversion saves the extension setting with it, since the rename cannot be undone and the two must not disagree, and says up front that the running game will be restarted. Also adds a button to open the save directory.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I use both the standalone melonDS as well as the RetroArch core, and realized the
.savfiles melonDS creates and the.srmfiles RA uses are the same files, just with a different extension. For my personal usage I don't really mind setting up softlinks but it is a bit annoying and from researching this online it's confusing for others who have to manually rename files.This PR has 2 parts, and I think many of the UX decisions I'm very open to changing based on feedback.
Part 1: .srm selection
The first commit allows a user to set
.srmas the save file extension. From a fresh setup with zero saves, this basically just equates to allowing users to point their melonDS save path to the same as where RA saves, and if you set.srmthen you can seamlessly use the same saves (assuming the ROM name matches as well).The decision this opens which I think is very much a UX decision that can change is whether to read the other file extension if it exists. Say a
.srmfile exists but you are using.savthen should this be detected and prompt the user to help with confusion? The decision I made was a dialogue box to tell the user that they're using a different save file extension than what's detected. (The exact wording is a result of Part 2)Part 2: file conversion
"File conversion" is really just file extension renaming, and it's done using
fs::renamewhich is an atomic operation and should be the safest way to perform this operation. I think this is both a nice UX as well as prevents file renaming mistakes. This does open some other questions about what to do when there's name collisions, such as if you had an existingfilename.savandfilename.srm, and the decision here is to show in the dialogue that these files will be skipped.The other thing this handles properly is when you use the multiple instance feature of melonDS, where files like
filename.sav.2will be properly renamed asfilename.srm.2,A small last detail is that an "open folder" option is added to give a convenient UX to manually copy/fix saves.
Testing
All four CI platforms build, and tested the rename semantics on Linux, Windows, and MacOS including case-insensitive collision (
filename.srmandFILENAME.srm).I tested this the most with the Qt Linux build, but I will update this when I am able to build and test manually in Windows. I also made a github actions test file to test some of the platform differences, but I'm not sure if we want that to be included in this PR or not. I'm happy to share it if it's helpful.