From 291dd80c27a7924666ae7800d81f91c4b90dba08 Mon Sep 17 00:00:00 2001 From: Morilli <35152647+Morilli@users.noreply.github.com> Date: Wed, 4 Jun 2025 21:23:55 +0200 Subject: [PATCH] refactor LoadSaveRam The code will now consider both autosaveram and normal saveram files on load. Normal saveram is preferred unless an autosave exists that is more recent than the normal save, in which case the user is prompted to select which saveram to load. --- src/BizHawk.Client.EmuHawk/MainForm.cs | 71 ++++++++++++++------------ 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index d79a1418d8..4c2e8fa770 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -2012,48 +2012,62 @@ namespace BizHawk.Client.EmuHawk { if (Emulator.HasSaveRam()) { - try // zero says: this is sort of sketchy... but this is no time for rearchitecting - { - var saveRamPath = Config.PathEntries.SaveRamAbsolutePath(Game, MovieSession.Movie); - if (Config.AutosaveSaveRAM) - { - var saveram = new FileInfo(saveRamPath); - var autosave = new FileInfo(Config.PathEntries.AutoSaveRamAbsolutePath(Game, MovieSession.Movie)); - if (autosave.Exists && autosave.LastWriteTime > saveram.LastWriteTime) - { - AddOnScreenMessage("AutoSaveRAM is newer than last saved SaveRAM"); - } - } + var saveRam = new FileInfo(Config.PathEntries.SaveRamAbsolutePath(Game, MovieSession.Movie)); + var autoSaveRam = new FileInfo(Config.PathEntries.AutoSaveRamAbsolutePath(Game, MovieSession.Movie)); + FileInfo saveramToLoad; + if (saveRam.Exists && (!autoSaveRam.Exists || autoSaveRam.LastWriteTimeUtc <= saveRam.LastWriteTimeUtc)) + { + saveramToLoad = saveRam; + } + else if (autoSaveRam.Exists && !saveRam.Exists) + { + AddOnScreenMessage("SaveRAM missing! Loading autosaved SaveRAM instead.", 5); + saveramToLoad = autoSaveRam; + } + else if (saveRam.Exists && autoSaveRam.Exists) + { + bool result = ShowMessageBox2( + owner: this, + "The autosaved SaveRAM is more recent than the normal SaveRAM.\n" + + "This could happen due to a crash or because files were manually modified.\n" + + "Do you want to load the autosave instead of the older SaveRAM file?", + "Load autosaved SaveRAM?", + EMsgBoxIcon.Error); + + saveramToLoad = result ? autoSaveRam : saveRam; + } + else + { + // no saveram to load + return; + } + + try + { byte[] sram; // some cores might not know how big the saveram ought to be, so just send it the whole file if (Emulator is AppleII or C64 or DOSBox or MGBAHawk or NeoGeoPort or NES { BoardName: "FDS" }) { - sram = File.ReadAllBytes(saveRamPath); + sram = File.ReadAllBytes(saveramToLoad.FullName); } else { var oldRam = Emulator.AsSaveRam().CloneSaveRam(); - if (oldRam == null) - { - // we're eating this one now. The possible negative consequence is that a user could lose - // their saveram and not know why - // ShowMessageBox(owner: null, "Error: tried to load saveram, but core would not accept it?"); - return; - } + Debug.Assert(oldRam is not null, $"Tried loading existing saveram, but {nameof(ISaveRam.CloneSaveRam)} returned null!"); // why do we silently truncate\pad here instead of warning\erroring? sram = new byte[oldRam.Length]; - using var reader = new BinaryReader(new FileStream(saveRamPath, FileMode.Open, FileAccess.Read)); - reader.Read(sram, 0, sram.Length); + _ = saveramToLoad.OpenRead().Read(sram, 0, sram.Length); } Emulator.AsSaveRam().StoreSaveRam(sram); } - catch (IOException) + catch (IOException e) { AddOnScreenMessage("An error occurred while loading Sram"); + Console.Error.WriteLine(e); } } } @@ -3952,16 +3966,7 @@ namespace BizHawk.Client.EmuHawk // Don't load Save Ram if a movie is being loaded if (!MovieSession.NewMovieQueued) { - if (File.Exists(Config.PathEntries.SaveRamAbsolutePath(loader.Game, MovieSession.Movie))) - { - LoadSaveRam(); - } - else if (Config.AutosaveSaveRAM - && File.Exists(Config.PathEntries.AutoSaveRamAbsolutePath(loader.Game, MovieSession.Movie))) - { - AddOnScreenMessage("AutoSaveRAM found, but SaveRAM was not saved"); - } - + LoadSaveRam(); AutoFlushSaveRamIn = Config.FlushSaveRamFrames; }