TasMovie - more reorg and restore state and lag capturing

This commit is contained in:
adelikat 2014-07-07 18:40:42 +00:00
parent c019ec3bf0
commit 6d61db045f
5 changed files with 126 additions and 10 deletions

View File

@ -166,8 +166,10 @@
<Compile Include="movie\PlatformFrameRates.cs" />
<Compile Include="movie\Subtitle.cs" />
<Compile Include="movie\SubtitleList.cs" />
<Compile Include="movie\tasproj\TasMovie.Editing.cs" />
<Compile Include="movie\tasproj\TasMovie.IO.cs" />
<Compile Include="movie\tasproj\TasMovie.cs" />
<Compile Include="movie\tasproj\TasStateManager.cs" />
<Compile Include="movie\tasproj\TasMovieRecord.cs" />
<Compile Include="NESGameGenieEncoderDecoder.cs" />
<Compile Include="PathManager.cs" />

View File

@ -70,7 +70,7 @@ namespace BizHawk.Client.Common
Changes = true;
}
public void RecordFrame(int frame, IController source)
public virtual void RecordFrame(int frame, IController source)
{
if (Global.Config.VBAStyleMovieLoadState)
{
@ -87,7 +87,7 @@ namespace BizHawk.Client.Common
Changes = true;
}
public void Truncate(int frame)
public virtual void Truncate(int frame)
{
if (frame < _log.Count)
{
@ -162,7 +162,7 @@ namespace BizHawk.Client.Common
return null;
}
public void PokeFrame(int frame, IController source)
public virtual void PokeFrame(int frame, IController source)
{
var lg = LogGeneratorInstance();
lg.SetSource(source);
@ -171,9 +171,10 @@ namespace BizHawk.Client.Common
SetFrameAt(frame, lg.GenerateLogEntry());
}
public void ClearFrame(int frame)
public virtual void ClearFrame(int frame)
{
SetFrameAt(frame, LogGeneratorInstance().EmptyEntry);
Changes = true;
}
#endregion

View File

@ -0,0 +1,47 @@
using System;
using System.IO;
using System.Linq;
using BizHawk.Common;
namespace BizHawk.Client.Common
{
public partial class TasMovie
{
// TODO: all these
public override void RecordFrame(int frame, Emulation.Common.IController source)
{
base.RecordFrame(frame, source);
LagLog.RemoveRange(frame, LagLog.Count - frame);
LagLog.Add(Global.Emulator.IsLagFrame);
StateManager.Invalidate(frame);
StateManager.Capture();
}
public override void Truncate(int frame)
{
base.Truncate(frame);
LagLog.RemoveRange(frame + 2, LagLog.Count - frame - 1);
StateManager.Invalidate(frame + 1);
}
public override void PokeFrame(int frame, Emulation.Common.IController source)
{
base.PokeFrame(frame, source);
LagLog.RemoveRange(frame, LagLog.Count - frame);
StateManager.Invalidate(frame);
}
public override void ClearFrame(int frame)
{
base.ClearFrame(frame);
LagLog.RemoveRange(frame + 1, LagLog.Count - frame - 1);
StateManager.Invalidate(frame + 1);
}
}
}

View File

@ -12,6 +12,7 @@ namespace BizHawk.Client.Common
public sealed partial class TasMovie : Bk2Movie
{
private readonly List<bool> LagLog = new List<bool>();
private readonly TasStateManager StateManager = new TasStateManager();
public TasMovie(string path) : base(path) { }
@ -32,15 +33,13 @@ namespace BizHawk.Client.Common
{
get
{
return new TasMovieRecord // TODO
return new TasMovieRecord
{
State = null,
LogEntry = "",
Lagged = false
State = StateManager[index],
LogEntry = GetInput(index),
Lagged = LagLog[index]
};
}
}
// _state = (byte[])Global.Emulator.SaveStateBinary().Clone();
}
}

View File

@ -0,0 +1,67 @@
using System.Collections.Generic;
using System.Linq;
namespace BizHawk.Client.Common
{
/// <summary>
/// Captures savestates and manages the logic of adding, retrieving,
/// invalidating/clearing of states. Also does memory management and limiting of states
/// </summary>
public class TasStateManager
{
private readonly Dictionary<int, byte[]> States = new Dictionary<int, byte[]>();
/// <summary>
/// Retrieves the savestate for the given frame,
/// If this frame does not have a state currently, will return an empty array
/// </summary>
/// <returns>A savestate for the given frame or an empty array if there isn't one</returns>
public byte[] this[int frame]
{
get
{
if (States.ContainsKey(frame))
{
return States[frame];
}
return new byte[0];
}
}
/// <summary>
/// Requests that the current emulator state be captured
/// </summary>
public void Capture()
{
var frame = Global.Emulator.Frame;
var state = (byte[])Global.Emulator.SaveStateBinary().Clone();
if (States.ContainsKey(frame))
{
States[frame] = state;
}
else
{
States.Add(frame, state);
}
}
/// <summary>
/// Clears out all savestates after the given frame number
/// </summary>
public void Invalidate(int frame)
{
// TODO be more efficient, this could get slow
var toRemove = States
.Where(x => x.Key > frame)
.Select(x => x.Key)
.ToList();
foreach (var f in toRemove)
{
States.Remove(f);
}
}
}
}