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 CopyVerificationLog(IEnumerable <string> log) { foreach (string entry in log) { VerificationLog.Add(entry); } }
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 override bool Load() { var file = new FileInfo(Filename); if (!file.Exists) { return(false); } using (var bl = BinaryStateLoader.LoadAndDetect(Filename, true)) { if (bl == null) { return(false); } ClearBeforeLoad(); ClearTasprojExtras(); bl.GetLump(BinaryStateLump.Movieheader, true, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { var pair = line.Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries); if (pair.Length > 1) { Header.Add(pair[0], pair[1]); } } } }); bl.GetLump(BinaryStateLump.Comments, true, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { Comments.Add(line); } } }); bl.GetLump(BinaryStateLump.Subtitles, true, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { Subtitles.AddFromString(line); } } }); bl.GetLump(BinaryStateLump.SyncSettings, true, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { SyncSettingsJson = line; } } }); bl.GetLump(BinaryStateLump.Input, true, delegate(TextReader tr) // Note: ExtractInputLog will clear Lag and State data potentially, this must come before loading those { var errorMessage = string.Empty; IsCountingRerecords = false; ExtractInputLog(tr, out errorMessage); IsCountingRerecords = true; }); if (StartsFromSavestate) { bl.GetCoreState( delegate(BinaryReader br, long length) { BinarySavestate = br.ReadBytes((int)length); }, delegate(TextReader tr) { TextSavestate = tr.ReadToEnd(); }); } // TasMovie enhanced information if (bl.HasLump(BinaryStateLump.LagLog)) { bl.GetLump(BinaryStateLump.LagLog, false, delegate(BinaryReader br, long length) { LagLog.Load(br); }); } bl.GetLump(BinaryStateLump.StateHistorySettings, false, delegate(TextReader tr) { StateManager.Settings.PopulateFromString(tr.ReadToEnd()); }); if (StateManager.Settings.SaveStateHistory) { bl.GetLump(BinaryStateLump.StateHistory, false, delegate(BinaryReader br, long length) { StateManager.Load(br); }); } // Movie should always have a state at frame 0. if (!this.StartsFromSavestate) { StateManager.Capture(); } bl.GetLump(BinaryStateLump.Markers, false, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { Markers.Add(new TasMovieMarker(line)); } } }); if (GetClientSettingsOnLoad != null && bl.HasLump(BinaryStateLump.ClientSettings)) { string clientSettings = string.Empty; bl.GetLump(BinaryStateLump.ClientSettings, true, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { clientSettings = line; } } }); GetClientSettingsOnLoad(clientSettings); } if (bl.HasLump(BinaryStateLump.VerificationLog)) { bl.GetLump(BinaryStateLump.VerificationLog, true, delegate(TextReader tr) { VerificationLog.Clear(); while (true) { var line = tr.ReadLine(); if (string.IsNullOrEmpty(line)) { break; } if (line.StartsWith("|")) { VerificationLog.Add(line); } } }); } } Changes = false; return(true); }
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; } }
private void LoadTasprojExtras(ZipStateLoader bl, bool preload) { bl.GetLump(BinaryStateLump.LagLog, false, delegate(TextReader tr) { LagLog.Load(tr); }); bl.GetLump(BinaryStateLump.StateHistorySettings, false, delegate(TextReader tr) { var json = tr.ReadToEnd(); try { TasStateManager.Settings = JsonConvert.DeserializeObject <TasStateManagerSettings>(json); } catch { // Do nothing, and use default settings instead } }); bl.GetLump(BinaryStateLump.Markers, false, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { Markers.Add(new TasMovieMarker(line)); } } }); if (GetClientSettingsOnLoad != null) { string clientSettings = ""; bl.GetLump(BinaryStateLump.ClientSettings, false, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { clientSettings = line; } } }); if (!string.IsNullOrWhiteSpace(clientSettings)) { GetClientSettingsOnLoad(clientSettings); } } bl.GetLump(BinaryStateLump.VerificationLog, false, delegate(TextReader tr) { VerificationLog.Clear(); while (true) { var line = tr.ReadLine(); if (string.IsNullOrEmpty(line)) { break; } if (line.StartsWith("|")) { VerificationLog.Add(line); } } }); Branches.Load(bl, this); bl.GetLump(BinaryStateLump.Session, false, delegate(TextReader tr) { var json = tr.ReadToEnd(); try { TasSession = JsonConvert.DeserializeObject <TasSession>(json); } catch { // Do nothing, and use default settings instead } }); if (!preload) { if (TasStateManager.Settings.SaveStateHistory) { bl.GetLump(BinaryStateLump.StateHistory, false, delegate(BinaryReader br, long length) { TasStateManager.Load(br); }); } } }
public override bool Load(bool preload) { var file = new FileInfo(Filename); if (!file.Exists) { return(false); } using (var bl = BinaryStateLoader.LoadAndDetect(Filename, true)) { if (bl == null) { return(false); } ClearBeforeLoad(); ClearTasprojExtras(); bl.GetLump(BinaryStateLump.Movieheader, true, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { var pair = line.Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries); if (pair.Length > 1) { Header.Add(pair[0], pair[1]); } } } }); bl.GetLump(BinaryStateLump.Comments, true, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { Comments.Add(line); } } }); bl.GetLump(BinaryStateLump.Subtitles, true, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { Subtitles.AddFromString(line); } } }); bl.GetLump(BinaryStateLump.SyncSettings, true, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { SyncSettingsJson = line; } } }); bl.GetLump(BinaryStateLump.Input, true, delegate(TextReader tr) // Note: ExtractInputLog will clear Lag and State data potentially, this must come before loading those { IsCountingRerecords = false; ExtractInputLog(tr, out _); IsCountingRerecords = true; }); if (StartsFromSavestate) { bl.GetCoreState( delegate(BinaryReader br, long length) { BinarySavestate = br.ReadBytes((int)length); }, delegate(TextReader tr) { TextSavestate = tr.ReadToEnd(); }); } else if (StartsFromSaveRam) { bl.GetLump(BinaryStateLump.MovieSaveRam, false, delegate(BinaryReader br, long length) { SaveRam = br.ReadBytes((int)length); }); } // TasMovie enhanced information bl.GetLump(BinaryStateLump.LagLog, false, delegate(TextReader tr) { LagLog.Load(tr); }); bl.GetLump(BinaryStateLump.StateHistorySettings, false, delegate(TextReader tr) { var json = tr.ReadToEnd(); try { TasStateManager.Settings = JsonConvert.DeserializeObject <TasStateManagerSettings>(json); } catch { // Do nothing, and use default settings instead } }); bl.GetLump(BinaryStateLump.Markers, false, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { Markers.Add(new TasMovieMarker(line)); } } }); if (GetClientSettingsOnLoad != null) { string clientSettings = ""; bl.GetLump(BinaryStateLump.ClientSettings, false, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { clientSettings = line; } } }); if (!string.IsNullOrWhiteSpace(clientSettings)) { GetClientSettingsOnLoad(clientSettings); } } bl.GetLump(BinaryStateLump.VerificationLog, false, delegate(TextReader tr) { VerificationLog.Clear(); while (true) { var line = tr.ReadLine(); if (string.IsNullOrEmpty(line)) { break; } if (line.StartsWith("|")) { VerificationLog.Add(line); } } }); Branches.Load(bl, this); bl.GetLump(BinaryStateLump.Session, false, delegate(TextReader tr) { var json = tr.ReadToEnd(); try { Session = JsonConvert.DeserializeObject <TasSession>(json); } catch { // Do nothing, and use default settings instead } }); if (!preload) { if (TasStateManager.Settings.SaveStateHistory) { bl.GetLump(BinaryStateLump.StateHistory, false, delegate(BinaryReader br, long length) { TasStateManager.Load(br); }); } } } Changes = false; return(true); }
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; } }
private void LoadTasprojExtras(ZipStateLoader bl) { bl.GetLump(BinaryStateLump.LagLog, false, delegate(TextReader tr) { LagLog.Load(tr); }); bl.GetLump(BinaryStateLump.Markers, false, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { Markers.Add(new TasMovieMarker(line)); } } }); if (GetClientSettingsOnLoad != null) { string clientSettings = ""; bl.GetLump(BinaryStateLump.ClientSettings, false, delegate(TextReader tr) { string line; while ((line = tr.ReadLine()) != null) { if (!string.IsNullOrWhiteSpace(line)) { clientSettings = line; } } }); if (!string.IsNullOrWhiteSpace(clientSettings)) { GetClientSettingsOnLoad(clientSettings); } } bl.GetLump(BinaryStateLump.VerificationLog, false, delegate(TextReader tr) { VerificationLog.Clear(); while (true) { var line = tr.ReadLine(); if (string.IsNullOrEmpty(line)) { break; } if (line.StartsWith("|")) { VerificationLog.Add(line); } } }); Branches.Load(bl, this); bl.GetLump(BinaryStateLump.Session, false, delegate(TextReader tr) { var json = tr.ReadToEnd(); try { TasSession = JsonConvert.DeserializeObject <TasSession>(json); } catch { // Do nothing, and use default settings instead } }); ZwinderStateManagerSettings settings = new ZwinderStateManagerSettings(); bl.GetLump(BinaryStateLump.StateHistorySettings, false, delegate(TextReader tr) { var json = tr.ReadToEnd(); try { settings = JsonConvert.DeserializeObject <ZwinderStateManagerSettings>(json); } catch { // Do nothing, and use default settings instead } }); bl.GetLump(BinaryStateLump.StateHistory, false, delegate(BinaryReader br, long length) { try { TasStateManager?.Dispose(); TasStateManager = ZwinderStateManager.Create(br, settings, IsReserved); } catch { // Continue with a fresh manager. If state history got corrupted, the file is still very much useable // and we would want the user to be able to load, and regenerate their state history // however, we still have an issue of how state history got corrupted TasStateManager = new ZwinderStateManager( Session.Settings.DefaultTasStateManagerSettings, IsReserved); Session.PopupMessage("State history was corrupted, clearing and working with a fresh history."); } }); }