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; }