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); }); } } }
protected virtual void Write(string fn, bool backup = false) { if (Global.Emulator is Emulation.Cores.Nintendo.SubNESHawk.SubNESHawk subNes) { Header[HeaderKeys.VBlankCount] = subNes.VBL_CNT.ToString(); } else if (Global.Emulator is Emulation.Cores.Nintendo.Gameboy.Gameboy gameboy) { Header[HeaderKeys.CycleCount] = gameboy.CycleCount.ToString(); } else if (Global.Emulator is Emulation.Cores.Nintendo.SubGBHawk.SubGBHawk subGb) { Header[HeaderKeys.VBlankCount] = subGb.VBL_CNT.ToString(); } var file = new FileInfo(fn); if (!file.Directory.Exists) { Directory.CreateDirectory(file.Directory.ToString()); } using var bs = new BinaryStateSaver(fn, false); bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString())); bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString())); bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString())); bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(_syncSettingsJson)); bs.PutLump(BinaryStateLump.Input, WriteInputLog); if (StartsFromSavestate) { if (TextSavestate != null) { bs.PutLump(BinaryStateLump.CorestateText, (TextWriter tw) => tw.Write(TextSavestate)); } else { bs.PutLump(BinaryStateLump.Corestate, (BinaryWriter bw) => bw.Write(BinarySavestate)); } if (SavestateFramebuffer != null) { bs.PutLump(BinaryStateLump.Framebuffer, (BinaryWriter bw) => bw.Write(SavestateFramebuffer)); } } else if (StartsFromSaveRam) { bs.PutLump(BinaryStateLump.MovieSaveRam, (BinaryWriter bw) => bw.Write(SaveRam)); } if (!backup) { Changes = false; } }
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(); } }
protected virtual void Write(string fn) { var file = new FileInfo(fn); if (!file.Directory.Exists) { Directory.CreateDirectory(file.Directory.ToString()); } using (var fs = new FileStream(fn, FileMode.Create, FileAccess.Write)) using (var bs = new BinaryStateSaver(fs, false)) { bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString())); bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString())); bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString())); bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(_syncSettingsJson)); bs.PutLump(BinaryStateLump.Input, tw => tw.WriteLine(RawInputLog())); if (StartsFromSavestate) { if (TextSavestate != null) { bs.PutLump(BinaryStateLump.CorestateText, (TextWriter tw) => tw.Write(TextSavestate)); } else { bs.PutLump(BinaryStateLump.Corestate, (BinaryWriter bw) => bw.Write(BinarySavestate)); } } } Changes = false; }
public static void SaveStateFile(string filename, string name) { // 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 fs = new FileStream(filename, FileMode.Create, FileAccess.Write)) using (var bs = new BinaryStateSaver(fs)) { if (Global.Config.SaveStateType == Config.SaveStateTypeE.Text || (Global.Config.SaveStateType == Config.SaveStateTypeE.Default && !Global.Emulator.BinarySaveStatesPreferred)) { // text savestate format bs.PutLump(BinaryStateLump.CorestateText, (tw) => Global.Emulator.SaveStateText(tw)); } else { // binary core lump format bs.PutLump(BinaryStateLump.Corestate, bw => Global.Emulator.SaveStateBinary(bw)); } if (Global.Config.SaveScreenshotWithStates) { var buff = Global.Emulator.VideoProvider.GetVideoBuffer(); // If user wants large screenshots, or screenshot is small enough if (Global.Config.SaveLargeScreenshotWithStates || buff.Length < Global.Config.BigScreenshotSize) { bs.PutLump(BinaryStateLump.Framebuffer, (BinaryWriter bw) => bw.Write(buff)); } } 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); }); } } }
protected virtual void Write(string fn, bool backup = false) { var file = new FileInfo(fn); if (!file.Directory.Exists) { Directory.CreateDirectory(file.Directory.ToString()); } using (var bs = new BinaryStateSaver(fn, false)) { bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString())); bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString())); bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString())); bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(_syncSettingsJson)); bs.PutLump(BinaryStateLump.Input, tw => WriteInputLog(tw)); if (StartsFromSavestate) { if (TextSavestate != null) { bs.PutLump(BinaryStateLump.CorestateText, (TextWriter tw) => tw.Write(TextSavestate)); } else { 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)); } } else if (StartsFromSaveRam) { bs.PutLump(BinaryStateLump.MovieSaveRam, (BinaryWriter bw) => bw.Write(SaveRam)); } } if (!backup) { Changes = false; } }
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); }); } }
protected override void Write(string fn) { var file = new FileInfo(fn); if (!file.Directory.Exists) { Directory.CreateDirectory(file.Directory.ToString()); } using (var bs = new BinaryStateSaver(fn, false)) { bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString())); bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString())); bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString())); bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(SyncSettingsJson)); bs.PutLump(BinaryStateLump.Input, tw => tw.WriteLine(RawInputLog())); // TasProj extras bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(StateManager.Settings.ToString())); if (StateManager.Settings.SaveStateHistory) { bs.PutLump(BinaryStateLump.StateHistory, (BinaryWriter bw) => StateManager.Save(bw)); } bs.PutLump(BinaryStateLump.LagLog, (BinaryWriter bw) => LagLog.Save(bw)); bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString())); if (StartsFromSavestate) { if (TextSavestate != null) { bs.PutLump(BinaryStateLump.CorestateText, (TextWriter tw) => tw.Write(TextSavestate)); } else { bs.PutLump(BinaryStateLump.Corestate, (BinaryWriter bw) => bw.Write(BinarySavestate)); } } else if (StartsFromSaveRam) { bs.PutLump(BinaryStateLump.MovieSaveRam, (BinaryWriter bw) => bw.Write(SaveRam)); } if (ClientSettingsForSave != null) { var clientSettingsJson = ClientSettingsForSave(); bs.PutLump(BinaryStateLump.ClientSettings, (TextWriter tw) => tw.Write(clientSettingsJson)); } if (VerificationLog.Any()) { bs.PutLump(BinaryStateLump.VerificationLog, tw => tw.WriteLine(InputLogToString(VerificationLog))); } if (Branches.Any()) { Branches.Save(bs); if (StateManager.Settings.BranchStatesInTasproj) { bs.PutLump(BinaryStateLump.BranchStateHistory, (BinaryWriter bw) => StateManager.SaveBranchStates(bw)); } } bs.PutLump(BinaryStateLump.Session, tw => tw.WriteLine(Session.ToString())); } Changes = false; }
protected virtual void Write(string fn, bool backup = false) { var file = new FileInfo(fn); if (!file.Directory.Exists) { Directory.CreateDirectory(file.Directory.ToString()); } using (var bs = new BinaryStateSaver(fn, false)) { bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString())); bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString())); bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString())); bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(_syncSettingsJson)); bs.PutLump(BinaryStateLump.Input, tw => WriteInputLog(tw)); if (StartsFromSavestate) { if (TextSavestate != null) { bs.PutLump(BinaryStateLump.CorestateText, (TextWriter tw) => tw.Write(TextSavestate)); } else { 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)); } } else if (StartsFromSaveRam) { bs.PutLump(BinaryStateLump.MovieSaveRam, (BinaryWriter bw) => bw.Write(SaveRam)); } } if (!backup) Changes = false; }
protected override void Write(string fn, bool backup = false) { var file = new FileInfo(fn); if (!file.Directory.Exists) { Directory.CreateDirectory(file.Directory.ToString()); } using (var bs = new BinaryStateSaver(fn, false)) { bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString())); bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString())); bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString())); bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(SyncSettingsJson)); bs.PutLump(BinaryStateLump.Input, tw => WriteInputLog(tw)); // TasProj extras bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(StateManager.Settings.ToString())); bs.PutLump(BinaryStateLump.LagLog, (BinaryWriter bw) => LagLog.Save(bw)); bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString())); if (StartsFromSavestate) { if (TextSavestate != null) { bs.PutLump(BinaryStateLump.CorestateText, (TextWriter tw) => tw.Write(TextSavestate)); } else { bs.PutLump(BinaryStateLump.Corestate, (BinaryWriter bw) => bw.Write(BinarySavestate)); } } else if (StartsFromSaveRam) { bs.PutLump(BinaryStateLump.MovieSaveRam, (BinaryWriter bw) => bw.Write(SaveRam)); } if (ClientSettingsForSave != null) { var clientSettingsJson = ClientSettingsForSave(); bs.PutLump(BinaryStateLump.ClientSettings, (TextWriter tw) => tw.Write(clientSettingsJson)); } if (VerificationLog.Any()) { bs.PutLump(BinaryStateLump.VerificationLog, tw => tw.WriteLine(InputLogToString(VerificationLog))); } if (Branches.Any()) { Branches.Save(bs); if (StateManager.Settings.BranchStatesInTasproj) { bs.PutLump(BinaryStateLump.BranchStateHistory, (BinaryWriter bw) => StateManager.SaveBranchStates(bw)); } } bs.PutLump(BinaryStateLump.Session, tw => tw.WriteLine(Session.ToString())); if (StateManager.Settings.SaveStateHistory) { bs.PutLump(BinaryStateLump.StateHistory, (BinaryWriter bw) => StateManager.Save(bw)); } } if (!backup) { Changes = false; } }
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); }); } if (Global.UserBag.Any()) { bs.PutLump(BinaryStateLump.UserData, delegate(TextWriter tw) { var data = ConfigService.SaveWithType(Global.UserBag); tw.WriteLine(data); }); } } }
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(); } }
private void SaveStateFile(string filename, string name) { var core = Emulator.AsStatable(); 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 (true) //Global.Config.SaveScreenshotWithStates) { var vp = 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 (true /* !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(Emulator.VideoProvider(), s, out_w, out_h)); } if (IAmMaster) { 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}", Emulator.Frame); Global.MovieSession.HandleMovieSaveState(tw); }); } } } }
protected override void Write(string fn) { _totalProgress = 0; var file = new FileInfo(fn); if (!file.Directory.Exists) { Directory.CreateDirectory(file.Directory.ToString()); } using (var bs = new BinaryStateSaver(fn, false)) { bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString())); ReportProgress(PROGRESS_STEP); bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString())); ReportProgress(PROGRESS_STEP); bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString())); ReportProgress(PROGRESS_STEP); bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(SyncSettingsJson)); ReportProgress(PROGRESS_STEP); bs.PutLump(BinaryStateLump.Input, tw => tw.WriteLine(RawInputLog())); ReportProgress(PROGRESS_STEP); // TasProj extras bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(StateManager.Settings.ToString())); ReportProgress(PROGRESS_STEP); if (StateManager.Settings.SaveStateHistory) { bs.PutLump(BinaryStateLump.StateHistory, (BinaryWriter bw) => StateManager.Save(bw)); } ReportProgress(PROGRESS_STEP); bs.PutLump(BinaryStateLump.LagLog, (BinaryWriter bw) => LagLog.Save(bw)); ReportProgress(PROGRESS_STEP); bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString())); ReportProgress(PROGRESS_STEP); if (StartsFromSavestate) { if (TextSavestate != null) { bs.PutLump(BinaryStateLump.CorestateText, (TextWriter tw) => tw.Write(TextSavestate)); } else { bs.PutLump(BinaryStateLump.Corestate, (BinaryWriter bw) => bw.Write(BinarySavestate)); } } ReportProgress(PROGRESS_STEP); if (ClientSettingsForSave != null) { var clientSettingsJson = ClientSettingsForSave(); bs.PutLump(BinaryStateLump.ClientSettings, (TextWriter tw) => tw.Write(clientSettingsJson)); } ReportProgress(PROGRESS_STEP); if (VerificationLog.Any()) { bs.PutLump(BinaryStateLump.VerificationLog, tw => tw.WriteLine(InputLogToString(VerificationLog))); } ReportProgress(PROGRESS_STEP); } Changes = false; }
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(); 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 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); }); } 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(BinaryWriter bw) { (Global.MovieSession.Movie as TasMovie).TasLagLog.Save(bw); }); } } }