Automatic save backup system (#260)

* Made errors print to console as well

---------

Co-authored-by: Mr-Wiseguy <mrwiseguyromhacking@gmail.com>
This commit is contained in:
Reonu 2024-05-26 16:38:58 +01:00 committed by GitHub
parent d4898f2316
commit 4ebe71bfcc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 5 deletions

View File

@ -96,20 +96,36 @@ struct {
const std::u8string save_folder = u8"saves"; 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 = 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() { std::filesystem::path get_save_file_path() {
return recomp::get_app_folder_path() / save_folder / save_filename; 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() { 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()) { if (save_file.good()) {
std::lock_guard lock{ save_context.save_buffer_mutex }; std::lock_guard lock{ save_context.save_buffer_mutex };
save_file.write(save_context.save_buffer.data(), save_context.save_buffer.size()); 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 { } else {
fprintf(stderr, "Failed to save!\n"); printf("\nSavefile doesn't exist. Skip renaming.");
std::exit(EXIT_FAILURE); }
std::filesystem::rename(get_save_file_path_temp(),get_save_file_path());
} else {
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) { void ultramodern::init_saving(RDRAM_ARG1) {
std::filesystem::path save_file_path = get_save_file_path(); 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. // Ensure the save file directory exists.
std::filesystem::create_directories(save_file_path.parent_path()); std::filesystem::create_directories(save_file_path.parent_path());
@ -184,10 +201,16 @@ void ultramodern::init_saving(RDRAM_ARG1) {
std::ifstream save_file{ save_file_path, std::ios_base::binary }; std::ifstream save_file{ save_file_path, std::ios_base::binary };
if (save_file.good()) { if (save_file.good()) {
save_file.read(save_context.save_buffer.data(), save_context.save_buffer.size()); save_file.read(save_context.save_buffer.data(), save_context.save_buffer.size());
} else {
// 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 { } else {
// Otherwise clear the save file to all zeroes. // Otherwise clear the save file to all zeroes.
save_context.save_buffer.fill(0); save_context.save_buffer.fill(0);
} }
}
save_context.saving_thread = std::thread{saving_thread_func, PASS_RDRAM}; save_context.saving_thread = std::thread{saving_thread_func, PASS_RDRAM};
} }

View File

@ -1477,4 +1477,5 @@ recomp::Menu recomp::get_current_menu() {
void recomp::message_box(const char* msg) { void recomp::message_box(const char* msg) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, recomp::program_name.data(), msg, nullptr); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, recomp::program_name.data(), msg, nullptr);
printf("[ERROR] %s\n", msg);
} }