From 4ebe71bfccbef17268c8941bed8d428d445268ca Mon Sep 17 00:00:00 2001 From: Reonu Date: Sun, 26 May 2024 16:38:58 +0100 Subject: [PATCH] Automatic save backup system (#260) * Made errors print to console as well --------- Co-authored-by: Mr-Wiseguy --- src/recomp/pi.cpp | 33 ++++++++++++++++++++++++++++----- src/ui/ui_renderer.cpp | 1 + 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/recomp/pi.cpp b/src/recomp/pi.cpp index 0c8a09d..224e7b0 100644 --- a/src/recomp/pi.cpp +++ b/src/recomp/pi.cpp @@ -96,20 +96,36 @@ struct { const std::u8string save_folder = u8"saves"; const std::u8string save_filename = std::u8string{recomp::mm_game_id} + u8".bin"; +const std::u8string save_filename_temp = std::u8string{recomp::mm_game_id} + u8".bin.temp"; +const std::u8string save_filename_backup = std::u8string{recomp::mm_game_id} + u8".bin.bak"; std::filesystem::path get_save_file_path() { return recomp::get_app_folder_path() / save_folder / save_filename; } +std::filesystem::path get_save_file_path_temp() { + return recomp::get_app_folder_path() / save_folder / save_filename_temp; +} + +std::filesystem::path get_save_file_path_backup() { + return recomp::get_app_folder_path() / save_folder / save_filename_backup; +} + void update_save_file() { - std::ofstream save_file{ get_save_file_path(), std::ios_base::binary }; + std::ofstream save_file{ get_save_file_path_temp(), std::ios_base::binary }; if (save_file.good()) { std::lock_guard lock{ save_context.save_buffer_mutex }; save_file.write(save_context.save_buffer.data(), save_context.save_buffer.size()); + if (std::filesystem::exists(get_save_file_path())) { + std::filesystem::rename(get_save_file_path(),get_save_file_path_backup()); + } else { + printf("\nSavefile doesn't exist. Skip renaming."); + } + std::filesystem::rename(get_save_file_path_temp(),get_save_file_path()); } else { - fprintf(stderr, "Failed to save!\n"); - std::exit(EXIT_FAILURE); + recomp::message_box("Failed to write to the save file. Check your file permissions. If you have moved your appdata folder to Dropbox or similar, this can cause issues."); + //std::exit(EXIT_FAILURE); } } @@ -176,6 +192,7 @@ void save_clear(uint32_t start, uint32_t size, char value) { void ultramodern::init_saving(RDRAM_ARG1) { std::filesystem::path save_file_path = get_save_file_path(); + std::filesystem::path save_file_path_backup = get_save_file_path_backup(); // Ensure the save file directory exists. std::filesystem::create_directories(save_file_path.parent_path()); @@ -185,8 +202,14 @@ void ultramodern::init_saving(RDRAM_ARG1) { if (save_file.good()) { save_file.read(save_context.save_buffer.data(), save_context.save_buffer.size()); } else { - // Otherwise clear the save file to all zeroes. - save_context.save_buffer.fill(0); + // Reading the save file faield, so try to read the backup save file. + std::ifstream save_file_backup{ save_file_path_backup, std::ios_base::binary }; + if (save_file_backup.good()) { + save_file_backup.read(save_context.save_buffer.data(), save_context.save_buffer.size()); + } else { + // Otherwise clear the save file to all zeroes. + save_context.save_buffer.fill(0); + } } save_context.saving_thread = std::thread{saving_thread_func, PASS_RDRAM}; diff --git a/src/ui/ui_renderer.cpp b/src/ui/ui_renderer.cpp index 4b4e950..c5ad2d3 100644 --- a/src/ui/ui_renderer.cpp +++ b/src/ui/ui_renderer.cpp @@ -1477,4 +1477,5 @@ recomp::Menu recomp::get_current_menu() { void recomp::message_box(const char* msg) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, recomp::program_name.data(), msg, nullptr); + printf("[ERROR] %s\n", msg); }