Repository navigation
[develop] Add optional global saves folder #431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
fdf9ba4
d119bfc
96ba84e
61e0774
bbace93
d270ccc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
|
|
||
| #include <string.h> | ||
| #include <libdragon.h> | ||
| #include <fatfs/ff.h> | ||
| #include "cart_load.h" | ||
| #include "ini_parser.h" | ||
| #include "path.h" | ||
|
|
@@ -48,6 +49,50 @@ static bool create_saves_subdirectory (path_t *path) { | |
| return error; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Get the path of a ROM's save in the global saves directory. | ||
| * | ||
| * Every save lives in /saves on the SD card, named after the ROM file ("sd:/any/directory/Game.z64" uses | ||
| * "sd:/saves/Game.sav"), so copies of the same ROM in different directories share one save. | ||
| * With "Migrate Old Saves" on, a save still stored in the ROM's own location (its "saves" subdirectory, or next | ||
| * to the ROM) is moved into the global directory the first time, so existing progress carries over. If that move | ||
| * fails, the existing save is used where it is rather than starting a new, empty one. With it off, saves in the | ||
| * per-folder locations are left untouched. | ||
| * | ||
| * @param menu Pointer to the menu structure. | ||
| * @param save_path The save path next to the ROM (with the "sav" extension already applied). | ||
| * @param save_type The save type (nothing is created or moved when the ROM has no save). | ||
| * @return path_t* The save path to use (to be freed by the caller), or NULL if the directory could not be created. | ||
| */ | ||
| static path_t *global_save_path (menu_t *menu, path_t *save_path, flashcart_save_type_t save_type) { | ||
| path_t *global_save = path_init(menu->storage_prefix, "/" SAVE_DIRECTORY_NAME); | ||
| if ((save_type != FLASHCART_SAVE_TYPE_NONE) && directory_create(path_get(global_save))) { | ||
| path_free(global_save); | ||
| return NULL; | ||
| } | ||
| path_push(global_save, path_last_get(save_path)); | ||
|
|
||
| if (!menu->settings.migrate_saves_to_global_folder || (save_type == FLASHCART_SAVE_TYPE_NONE)) { | ||
| return global_save; | ||
| } | ||
|
|
||
| path_t *local_save = path_clone(save_path); | ||
| if (menu->settings.use_saves_folder) { | ||
| path_push_subdir(local_save, SAVE_DIRECTORY_NAME); | ||
| } | ||
|
Comment on lines
+80
to
+82
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check both legacy save locations before migration. If a user changed Use Saves Folder before enabling migration, this branch checks only the current location. An existing save in the other location remains untouched.
|
||
|
|
||
| if (!path_are_match(global_save, local_save) && !file_exists(path_get(global_save)) && | ||
| file_exists(path_get(local_save))) { | ||
| if (f_rename(strip_fs_prefix(path_get(local_save)), strip_fs_prefix(path_get(global_save))) != FR_OK) { | ||
| path_free(global_save); | ||
| return local_save; | ||
| } | ||
| } | ||
|
|
||
| path_free(local_save); | ||
| return global_save; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Convert the ROM save type to the flashcart save type. | ||
| * | ||
|
|
@@ -113,7 +158,14 @@ cart_load_err_t cart_load_n64_rom_and_save (menu_t *menu, flashcart_progress_cal | |
| } | ||
|
|
||
| path_ext_replace(path, "sav"); | ||
| if (menu->settings.use_saves_folder) { | ||
| if (menu->settings.use_global_saves_folder) { | ||
| path_t *save_path = global_save_path(menu, path, save_type); | ||
| path_free(path); | ||
| if (save_path == NULL) { | ||
| return CART_LOAD_ERR_CREATE_SAVES_SUBDIR_FAIL; | ||
| } | ||
| path = save_path; | ||
| } else if (menu->settings.use_saves_folder) { | ||
| if ((save_type != FLASHCART_SAVE_TYPE_NONE) && create_saves_subdirectory(path)) { | ||
| path_free(path); | ||
| return CART_LOAD_ERR_CREATE_SAVES_SUBDIR_FAIL; | ||
|
|
@@ -359,7 +411,14 @@ cart_load_err_t cart_load_emulator (menu_t *menu, cart_load_emu_type_t emu_type, | |
| } | ||
|
|
||
| path_ext_replace(path, "sav"); | ||
| if (menu->settings.use_saves_folder) { | ||
| if (menu->settings.use_global_saves_folder) { | ||
| path_t *save_path = global_save_path(menu, path, save_type); | ||
| path_free(path); | ||
| if (save_path == NULL) { | ||
| return CART_LOAD_ERR_CREATE_SAVES_SUBDIR_FAIL; | ||
| } | ||
| path = save_path; | ||
| } else if (menu->settings.use_saves_folder) { | ||
| if ((save_type != FLASHCART_SAVE_TYPE_NONE) && create_saves_subdirectory(path)) { | ||
| path_free(path); | ||
| return CART_LOAD_ERR_CREATE_SAVES_SUBDIR_FAIL; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use an existing local save if global directory creation fails.
If migration is enabled and
/savescannot be created, this return occurs before the local save is checked. Both callers then stop the ROM load, even when an existing local save could be used in place. Check for that save and return its path on directory-creation failure; keep the error when no usable save exists. (raw.githubusercontent.com)