protected void AddBk2Lumps(ZipStateSaver bs) { 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)); } }
protected virtual void Write(string fn, bool isBackup = false) { if (Emulator is Emulation.Cores.Nintendo.SubNESHawk.SubNESHawk subNes) { Header[HeaderKeys.VBlankCount] = subNes.VblankCount.ToString(); } else if (Emulator is Emulation.Cores.Nintendo.Gameboy.Gameboy gameboy) { Header[HeaderKeys.CycleCount] = gameboy.CycleCount.ToString(); } else if (Emulator is Emulation.Cores.Nintendo.SubGBHawk.SubGBHawk subGb) { Header[HeaderKeys.CycleCount] = subGb.CycleCount.ToString(); } var file = new FileInfo(fn); if (!file.Directory.Exists) { Directory.CreateDirectory(file.Directory.ToString()); } using var bs = new ZipStateSaver(fn, Global.Config.Savestates.MovieCompressionLevel); 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 (!isBackup) { Changes = false; } }
private void AddTasProjLumps(ZipStateSaver bs, bool isBackup = false) { var settings = JsonConvert.SerializeObject(TasStateManager.Settings); bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(settings)); bs.PutLump(BinaryStateLump.LagLog, tw => LagLog.Save(tw)); bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString())); 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(VerificationLog.ToInputLog())); } if (Branches.Any()) { Branches.Save(bs); } bs.PutLump(BinaryStateLump.Session, tw => tw.WriteLine(JsonConvert.SerializeObject(TasSession))); if (TasStateManager.Settings.SaveStateHistory && !isBackup) { bs.PutLump(BinaryStateLump.StateHistory, bw => TasStateManager.Save(bw)); } }
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); }); } }
protected override void Write(string fn, bool isBackup = false) { if (Emulator is Emulation.Cores.Nintendo.SubNESHawk.SubNESHawk subNes) { Header[HeaderKeys.VBlankCount] = subNes.VblankCount.ToString(); } else if (Emulator is Emulation.Cores.Nintendo.Gameboy.Gameboy gameboy) { Header[HeaderKeys.CycleCount] = gameboy.CycleCount.ToString(); } else if (Emulator is Emulation.Cores.Nintendo.SubGBHawk.SubGBHawk subGb) { Header[HeaderKeys.CycleCount] = subGb.CycleCount.ToString(); } var file = new FileInfo(fn); if (file.Directory != null && !file.Directory.Exists) { Directory.CreateDirectory(file.Directory.ToString()); } using var bs = new ZipStateSaver(fn, Global.Config.Savestates.MovieCompressionLevel); 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); // TasProj extras var settings = JsonConvert.SerializeObject(TasStateManager.Settings); bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(settings)); bs.PutLump(BinaryStateLump.LagLog, tw => LagLog.Save(tw)); 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(VerificationLog.ToInputLog())); } if (Branches.Any()) { Branches.Save(bs); } bs.PutLump(BinaryStateLump.Session, tw => tw.WriteLine(JsonConvert.SerializeObject(TasSession))); if (TasStateManager.Settings.SaveStateHistory && !isBackup) { bs.PutLump(BinaryStateLump.StateHistory, bw => TasStateManager.Save(bw)); } if (!isBackup) { Changes = false; } }