From a9c686a6afaea2393929e5e333e7a536161aeafa Mon Sep 17 00:00:00 2001 From: Reonu Date: Wed, 22 May 2024 21:16:29 +0100 Subject: [PATCH] init automatic save backup system --- src/recomp/pi.cpp | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 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};