public static void SaveStateFile(string filename, string name) { var core = Global.Emulator.AsStatable(); // the old method of text savestate save is now gone. // a text savestate is just like a binary savestate, but with a different core lump using (var bs = new BinaryStateSaver(filename)) { if (Global.Config.SaveStateType == Config.SaveStateTypeE.Text || (Global.Config.SaveStateType == Config.SaveStateTypeE.Default && !core.BinarySaveStatesPreferred)) { // text savestate format using (new SimpleTime("Save Core")) bs.PutLump(BinaryStateLump.CorestateText, (tw) => core.SaveStateText(tw)); } else { // binary core lump format using (new SimpleTime("Save Core")) bs.PutLump(BinaryStateLump.Corestate, bw => core.SaveStateBinary(bw)); } if (Global.Config.SaveScreenshotWithStates) { var vp = Global.Emulator.VideoProvider(); var buff = vp.GetVideoBuffer(); int out_w = vp.BufferWidth; int out_h = vp.BufferHeight; // if buffer is too big, scale down screenshot if (!Global.Config.NoLowResLargeScreenshotWithStates && buff.Length >= Global.Config.BigScreenshotSize) { out_w /= 2; out_h /= 2; } using (new SimpleTime("Save Framebuffer")) bs.PutLump(BinaryStateLump.Framebuffer, (s) => QuickBmpFile.Save(Global.Emulator.VideoProvider(), s, out_w, out_h)); } if (Global.MovieSession.Movie.IsActive) { bs.PutLump(BinaryStateLump.Input, delegate(TextWriter tw) { // this never should have been a core's responsibility tw.WriteLine("Frame {0}", Global.Emulator.Frame); Global.MovieSession.HandleMovieSaveState(tw); }); } } }
public void Save(BinaryStateSaver bs) { var nheader = new IndexedStateLump(BinaryStateLump.BranchHeader); var ncore = new IndexedStateLump(BinaryStateLump.BranchCoreData); var ninput = new IndexedStateLump(BinaryStateLump.BranchInputLog); var nframebuffer = new IndexedStateLump(BinaryStateLump.BranchFrameBuffer); var nlaglog = new IndexedStateLump(BinaryStateLump.BranchLagLog); foreach (var b in this) { bs.PutLump(nheader, delegate(TextWriter tw) { // if this header needs more stuff in it, handle it sensibly tw.WriteLine(JsonConvert.SerializeObject(new { Frame = b.Frame, TimeStamp = b.TimeStamp })); }); bs.PutLump(ncore, delegate(Stream s) { s.Write(b.CoreData, 0, b.CoreData.Length); }); bs.PutLump(ninput, delegate(TextWriter tw) { foreach (var line in b.InputLog) { tw.WriteLine(line); } }); bs.PutLump(nframebuffer, delegate(Stream s) { var vp = new BitmapBufferVideoProvider(b.OSDFrameBuffer); QuickBmpFile.Save(vp, s, b.OSDFrameBuffer.Width, b.OSDFrameBuffer.Height); }); bs.PutLump(nlaglog, delegate(BinaryWriter bw) { b.LagLog.Save(bw); }); nheader.Increment(); ncore.Increment(); ninput.Increment(); nframebuffer.Increment(); nlaglog.Increment(); } }
public static void SaveStateFile(string filename, string name) { var core = Global.Emulator.AsStatable(); // the old method of text savestate save is now gone. // a text savestate is just like a binary savestate, but with a different core lump using var bs = new BinaryStateSaver(filename); if (Global.Config.SaveStateType == SaveStateTypeE.Text || (Global.Config.SaveStateType == SaveStateTypeE.Default && !core.BinarySaveStatesPreferred)) { // text savestate format using (new SimpleTime("Save Core")) { bs.PutLump(BinaryStateLump.CorestateText, tw => core.SaveStateText(tw)); } } else { // binary core lump format using (new SimpleTime("Save Core")) { bs.PutLump(BinaryStateLump.Corestate, bw => core.SaveStateBinary(bw)); } } if (Global.Config.SaveScreenshotWithStates && Global.Emulator.HasVideoProvider()) { var vp = Global.Emulator.AsVideoProvider(); var buff = vp.GetVideoBuffer(); if (buff.Length == 1) { // is a hacky opengl texture ID. can't handle this now! // need to discuss options // 1. cores must be able to provide a pixels VideoProvider in addition to a texture ID, on command (not very hard overall but interface changing and work per core) // 2. SavestateManager must be setup with a mechanism for resolving texture IDs (even less work, but sloppy) // There are additional problems with AVWriting. They depend on VideoProvider providing pixels. } else { int outWidth = vp.BufferWidth; int outHeight = vp.BufferHeight; // if buffer is too big, scale down screenshot if (!Global.Config.NoLowResLargeScreenshotWithStates && buff.Length >= Global.Config.BigScreenshotSize) { outWidth /= 2; outHeight /= 2; } using (new SimpleTime("Save Framebuffer")) { bs.PutLump(BinaryStateLump.Framebuffer, s => QuickBmpFile.Save(Global.Emulator.AsVideoProvider(), s, outWidth, outHeight)); } } } if (Global.MovieSession.Movie.IsActive()) { bs.PutLump(BinaryStateLump.Input, delegate(TextWriter tw) { // this never should have been a core's responsibility tw.WriteLine("Frame {0}", Global.Emulator.Frame); Global.MovieSession.HandleMovieSaveState(tw); }); } if (Global.UserBag.Any()) { bs.PutLump(BinaryStateLump.UserData, delegate(TextWriter tw) { var data = ConfigService.SaveWithType(Global.UserBag); tw.WriteLine(data); }); } if (Global.MovieSession.Movie.IsActive() && Global.MovieSession.Movie is TasMovie) { bs.PutLump(BinaryStateLump.LagLog, delegate(TextWriter tw) { ((TasMovie)Global.MovieSession.Movie).TasLagLog.Save(tw); }); } }
public void Save(BinaryStateSaver bs) { var nheader = new IndexedStateLump(BinaryStateLump.BranchHeader); var ncore = new IndexedStateLump(BinaryStateLump.BranchCoreData); var ninput = new IndexedStateLump(BinaryStateLump.BranchInputLog); var nframebuffer = new IndexedStateLump(BinaryStateLump.BranchFrameBuffer); var ncoreframebuffer = new IndexedStateLump(BinaryStateLump.BranchCoreFrameBuffer); var nmarkers = new IndexedStateLump(BinaryStateLump.BranchMarkers); var nusertext = new IndexedStateLump(BinaryStateLump.BranchUserText); foreach (var b in this) { bs.PutLump(nheader, delegate(TextWriter tw) { // if this header needs more stuff in it, handle it sensibly tw.WriteLine(JsonConvert.SerializeObject(new { b.Frame, b.TimeStamp, b.UniqueIdentifier })); }); bs.PutLump(ncore, delegate(Stream s) { s.Write(b.CoreData, 0, b.CoreData.Length); }); bs.PutLump(ninput, delegate(TextWriter tw) { int todo = b.InputLog.Count; for (int i = 0; i < todo; i++) { tw.WriteLine(b.InputLog[i]); } }); bs.PutLump(nframebuffer, delegate(Stream s) { var vp = new BitmapBufferVideoProvider(b.OSDFrameBuffer); QuickBmpFile.Save(vp, s, b.OSDFrameBuffer.Width, b.OSDFrameBuffer.Height); }); bs.PutLump(ncoreframebuffer, delegate(Stream s) { var vp = new BitmapBufferVideoProvider(b.CoreFrameBuffer); QuickBmpFile.Save(vp, s, b.CoreFrameBuffer.Width, b.CoreFrameBuffer.Height); }); bs.PutLump(nmarkers, delegate(TextWriter tw) { tw.WriteLine(b.Markers.ToString()); }); bs.PutLump(nusertext, delegate(TextWriter tw) { tw.WriteLine(b.UserText); }); nheader.Increment(); ncore.Increment(); ninput.Increment(); nframebuffer.Increment(); ncoreframebuffer.Increment(); nmarkers.Increment(); nusertext.Increment(); } }
public void Create(string filename, SaveStateConfig config) { // the old method of text savestate save is now gone. // a text savestate is just like a binary savestate, but with a different core lump using var bs = new ZipStateSaver(filename, config.CompressionLevelNormal); bs.PutVersionLumps(); using (new SimpleTime("Save Core")) { if (config.Type == SaveStateType.Text) { bs.PutLump(BinaryStateLump.CorestateText, tw => _statable.SaveStateText(tw)); } else { bs.PutLump(BinaryStateLump.Corestate, bw => _statable.SaveStateBinary(bw)); } } if (config.SaveScreenshot && _videoProvider != null) { var buff = _videoProvider.GetVideoBuffer(); if (buff.Length == 1) { // is a hacky opengl texture ID. can't handle this now! // need to discuss options // 1. cores must be able to provide a pixels VideoProvider in addition to a texture ID, on command (not very hard overall but interface changing and work per core) // 2. SavestateManager must be setup with a mechanism for resolving texture IDs (even less work, but sloppy) // There are additional problems with AVWriting. They depend on VideoProvider providing pixels. } else { int outWidth = _videoProvider.BufferWidth; int outHeight = _videoProvider.BufferHeight; // if buffer is too big, scale down screenshot if (!config.NoLowResLargeScreenshots && buff.Length >= config.BigScreenshotSize) { outWidth /= 2; outHeight /= 2; } using (new SimpleTime("Save Framebuffer")) { bs.PutLump(BinaryStateLump.Framebuffer, s => QuickBmpFile.Save(_videoProvider, s, outWidth, outHeight)); } } } if (_movieSession.Movie.IsActive()) { bs.PutLump(BinaryStateLump.Input, delegate(TextWriter tw) { // this never should have been a core's responsibility tw.WriteLine("Frame {0}", _emulator.Frame); _movieSession.HandleSaveState(tw); }); } if (_userBag.Any()) { bs.PutLump(BinaryStateLump.UserData, delegate(TextWriter tw) { var data = ConfigService.SaveWithType(_userBag); tw.WriteLine(data); }); } if (_movieSession.Movie.IsActive() && _movieSession.Movie is ITasMovie) { bs.PutLump(BinaryStateLump.LagLog, delegate(TextWriter tw) { ((ITasMovie)_movieSession.Movie).LagLog.Save(tw); }); } }