diff --git a/BizHawk.Client.Common/movie/tasproj/TasLagLog.cs b/BizHawk.Client.Common/movie/tasproj/TasLagLog.cs index 4d7fea83b2..e6a4f7e9d9 100644 --- a/BizHawk.Client.Common/movie/tasproj/TasLagLog.cs +++ b/BizHawk.Client.Common/movie/tasproj/TasLagLog.cs @@ -1,37 +1,91 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; namespace BizHawk.Client.Common { - public class TasLagLog : List + public class TasLagLog { + private readonly SortedList LagLog = new SortedList(); + + public bool? this[int frame] + { + get + { + if (LagLog.ContainsKey(frame)) + { + return LagLog[frame]; + } + + return null; + } + + set + { + if (!value.HasValue) + { + LagLog.Remove(frame); + } + else if (frame < 0) + { + return; // Nothing to do + } + else if (LagLog.ContainsKey(frame)) + { + LagLog[frame] = value.Value; + } + else + { + LagLog.Add(frame, value.Value); + } + } + } + + public bool HasLagEntry(int frame) + { + return LagLog.ContainsKey(frame); + } + + public void Clear() + { + LagLog.Clear(); + } + public void RemoveFrom(int frame) { - if (frame > 0 && frame <= this.Count) + if (frame > 0 && frame <= LagLog.Count) { - this.RemoveRange(frame - 1, this.Count - (frame - 1)); + for (int i = LagLog.Count - 1; i > frame; i--) // Reverse order because removing from a sorted list re-indexes the items after the removed item + { + LagLog.RemoveAt(i); + } } else if (frame == 0) { this.Clear(); } + } - public bool? Lagged(int index) + public void Save(BinaryWriter bw) { - // Hacky but effective, we haven't record the lag information for the current frame yet - if (index == Global.Emulator.Frame - 1) + bw.Write(LagLog.Count); + foreach (var kvp in LagLog) { - return Global.Emulator.IsLagFrame; - } - - if (index < this.Count) - { - return this[index]; + bw.Write(kvp.Key); + bw.Write(kvp.Value); } + } - return null; + public void Load(BinaryReader br) + { + LagLog.Clear(); + int length = br.ReadInt32(); + for (int i = 0; i < length; i++) + { + LagLog.Add(br.ReadInt32(), br.ReadBoolean()); + } } } } diff --git a/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs b/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs index cefecf5caf..3d5e591134 100644 --- a/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs +++ b/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs @@ -14,11 +14,8 @@ namespace BizHawk.Client.Common { base.RecordFrame(frame, source); - if (frame > 0) - { - LagLog.RemoveFrom(frame); - LagLog.Add(Global.Emulator.IsLagFrame); - } + LagLog.RemoveFrom(frame); + LagLog[frame] = Global.Emulator.IsLagFrame; StateManager.Capture(); } diff --git a/BizHawk.Client.Common/movie/tasproj/TasMovie.IO.cs b/BizHawk.Client.Common/movie/tasproj/TasMovie.IO.cs index a4dcc21cd8..7f0536f130 100644 --- a/BizHawk.Client.Common/movie/tasproj/TasMovie.IO.cs +++ b/BizHawk.Client.Common/movie/tasproj/TasMovie.IO.cs @@ -40,7 +40,7 @@ namespace BizHawk.Client.Common bs.PutLump(BinaryStateLump.Greenzone, (BinaryWriter bw) => StateManager.Save(bw)); } - bs.PutLump(BinaryStateLump.LagLog, (BinaryWriter bw) => bw.Write(LagLog.ToByteArray())); + bs.PutLump(BinaryStateLump.LagLog, (BinaryWriter bw) => LagLog.Save(bw)); bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString())); if (StartsFromSavestate) @@ -163,10 +163,13 @@ namespace BizHawk.Client.Common } // TasMovie enhanced information - bl.GetLump(BinaryStateLump.LagLog, false, delegate(BinaryReader br, long length) + if (bl.HasLump(BinaryStateLump.LagLog)) { - LagLog.AddRange(br.ReadBytes((int)length).ToBools()); - }); + bl.GetLump(BinaryStateLump.LagLog, false, delegate(BinaryReader br, long length) + { + LagLog.Load(br); + }); + } bl.GetLump(BinaryStateLump.GreenzoneSettings, false, delegate(TextReader tr) { diff --git a/BizHawk.Client.Common/movie/tasproj/TasMovie.cs b/BizHawk.Client.Common/movie/tasproj/TasMovie.cs index 28c0a621ab..b5518ea4fb 100644 --- a/BizHawk.Client.Common/movie/tasproj/TasMovie.cs +++ b/BizHawk.Client.Common/movie/tasproj/TasMovie.cs @@ -63,7 +63,7 @@ namespace BizHawk.Client.Common { State = StateManager[index], LogEntry = GetInputLogEntry(index), - Lagged = LagLog.Lagged(index) + Lagged = LagLog[index] }; } } @@ -287,16 +287,9 @@ namespace BizHawk.Client.Common public override IController GetInputState(int frame) { - if (Global.Emulator.Frame - 1 == frame) - { - if (frame == LagLog.Count) // I intentionally did not do >=, if it were >= we missed some entries somewhere, oops, maybe this shoudl be a dictionary with frame values? - { - LagLog.Add(Global.Emulator.IsLagFrame); - } - } - - if (Global.Emulator.Frame == frame) // Take this opportunity to capture lag and state info if we do not have it + if (frame == Global.Emulator.Frame) // Take this opportunity to capture lag and state info if we do not have it { + LagLog[Global.Emulator.Frame] = Global.Emulator.IsLagFrame; if (!StateManager.HasState(frame)) {