diff --git a/BizHawk.Client.Common/SavestateManager.cs b/BizHawk.Client.Common/SavestateManager.cs index 945141c890..5fbefb1bd3 100644 --- a/BizHawk.Client.Common/SavestateManager.cs +++ b/BizHawk.Client.Common/SavestateManager.cs @@ -37,7 +37,7 @@ namespace BizHawk.Client.Common if (Global.Config.SaveLargeScreenshotWithStates || buff.Length < Global.Config.BigScreenshotSize) { using (new SimpleTime("Save Framebuffer")) - bs.PutLump(BinaryStateLump.Framebuffer, (BinaryWriter bw) => bw.Write(buff)); + bs.PutLump(BinaryStateLump.Framebuffer, DumpFramebuffer); } } @@ -54,6 +54,25 @@ namespace BizHawk.Client.Common } } + public static void PopulateFramebuffer(BinaryReader br) + { + var buff = Global.Emulator.VideoProvider.GetVideoBuffer(); + try + { + for (int i = 0; i < buff.Length; i++) + { + int j = br.ReadInt32(); + buff[i] = j; + } + } + catch (EndOfStreamException) { } + } + + public static void DumpFramebuffer(BinaryWriter bw) + { + bw.Write(Global.Emulator.VideoProvider.GetVideoBuffer()); + } + public static bool LoadStateFile(string path, string name) { // try to detect binary first @@ -77,20 +96,7 @@ namespace BizHawk.Client.Common using (new SimpleTime("Load Core")) bl.GetCoreState(br => Global.Emulator.LoadStateBinary(br), tr => Global.Emulator.LoadStateText(tr)); - bl.GetLump(BinaryStateLump.Framebuffer, false, - delegate(BinaryReader br) - { - var buff = Global.Emulator.VideoProvider.GetVideoBuffer(); - try - { - for (int i = 0; i < buff.Length; i++) - { - int j = br.ReadInt32(); - buff[i] = j; - } - } - catch (EndOfStreamException) { } - }); + bl.GetLump(BinaryStateLump.Framebuffer, false, PopulateFramebuffer); } catch { diff --git a/BizHawk.Client.Common/movie/bk2/Bk2Movie.HeaderApi.cs b/BizHawk.Client.Common/movie/bk2/Bk2Movie.HeaderApi.cs index b8f7771412..1e8ddce528 100644 --- a/BizHawk.Client.Common/movie/bk2/Bk2Movie.HeaderApi.cs +++ b/BizHawk.Client.Common/movie/bk2/Bk2Movie.HeaderApi.cs @@ -238,5 +238,6 @@ namespace BizHawk.Client.Common public string TextSavestate { get; set; } public byte[] BinarySavestate { get; set; } + public int[] SavestateFramebuffer { get; set; } } } diff --git a/BizHawk.Client.Common/movie/bk2/Bk2Movie.IO.cs b/BizHawk.Client.Common/movie/bk2/Bk2Movie.IO.cs index 1d2b58050b..66afb5d7b5 100644 --- a/BizHawk.Client.Common/movie/bk2/Bk2Movie.IO.cs +++ b/BizHawk.Client.Common/movie/bk2/Bk2Movie.IO.cs @@ -119,6 +119,13 @@ namespace BizHawk.Client.Common { TextSavestate = tr.ReadToEnd(); }); + bl.GetLump(BinaryStateLump.Framebuffer, false, + delegate(BinaryReader br, long length) + { + SavestateFramebuffer = new int[length / sizeof(int)]; + for (int i = 0; i < SavestateFramebuffer.Length; i++) + SavestateFramebuffer[i] = br.ReadInt32(); + }); } } @@ -166,6 +173,11 @@ namespace BizHawk.Client.Common { bs.PutLump(BinaryStateLump.Corestate, (BinaryWriter bw) => bw.Write(BinarySavestate)); } + if (SavestateFramebuffer != null) + { + bs.PutLump(BinaryStateLump.Framebuffer, + (BinaryWriter bw) => BizHawk.Common.IOExtensions.IOExtensions.Write(bw, SavestateFramebuffer)); + } } } diff --git a/BizHawk.Client.Common/movie/bkm/BkmMovie.HeaderApi.cs b/BizHawk.Client.Common/movie/bkm/BkmMovie.HeaderApi.cs index 684aa6b5ca..d46e816cdb 100644 --- a/BizHawk.Client.Common/movie/bkm/BkmMovie.HeaderApi.cs +++ b/BizHawk.Client.Common/movie/bkm/BkmMovie.HeaderApi.cs @@ -90,5 +90,6 @@ namespace BizHawk.Client.Common public string TextSavestate { get; set; } public byte[] BinarySavestate { get; set; } + public int[] SavestateFramebuffer { get { return null; } set { } } // eat and ignore framebuffers } } diff --git a/BizHawk.Client.Common/movie/interfaces/IMovie.cs b/BizHawk.Client.Common/movie/interfaces/IMovie.cs index e4f393ef0c..31fd9eea66 100644 --- a/BizHawk.Client.Common/movie/interfaces/IMovie.cs +++ b/BizHawk.Client.Common/movie/interfaces/IMovie.cs @@ -50,6 +50,7 @@ namespace BizHawk.Client.Common // savestate anchor. string TextSavestate { get; set; } byte[] BinarySavestate { get; set; } + int[] SavestateFramebuffer { get; set; } ulong Rerecords { get; set; } bool StartsFromSavestate { get; set; } diff --git a/BizHawk.Client.EmuHawk/MainForm.Movie.cs b/BizHawk.Client.EmuHawk/MainForm.Movie.cs index e0d733d511..ca8509bd69 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Movie.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Movie.cs @@ -44,7 +44,16 @@ namespace BizHawk.Client.EmuHawk { Global.Emulator.LoadStateBinary(new BinaryReader(new MemoryStream(movie.BinarySavestate, false))); } - + if (movie.SavestateFramebuffer != null) + { + var b1 = movie.SavestateFramebuffer; + var b2 = Global.Emulator.VideoProvider.GetVideoBuffer(); + int len = Math.Min(b1.Length, b2.Length); + for (int i = 0; i < len; i++) + { + b2[i] = b1[i]; + } + } Global.Emulator.ResetCounters(); } diff --git a/BizHawk.Client.EmuHawk/movie/RecordMovie.cs b/BizHawk.Client.EmuHawk/movie/RecordMovie.cs index 78d2c90148..939cfbfab6 100644 --- a/BizHawk.Client.EmuHawk/movie/RecordMovie.cs +++ b/BizHawk.Client.EmuHawk/movie/RecordMovie.cs @@ -83,6 +83,17 @@ namespace BizHawk.Client.EmuHawk movieToRecord.TextSavestate = sw.ToString(); } } + // TODO: do we want to support optionally not saving this? + if (true) + { + // hack: some IMovies eat the framebuffer, so don't bother with them + movieToRecord.SavestateFramebuffer = new int[0]; + if (movieToRecord.SavestateFramebuffer != null) + { + + movieToRecord.SavestateFramebuffer = (int[])Global.Emulator.VideoProvider.GetVideoBuffer().Clone(); + } + } } movieToRecord.PopulateWithDefaultHeaderValues(AuthorBox.Text);