Fix Bk2 playback, also rip out a bunch of junk from the Old Movie Log class from the first attempt at TAStudio and some half-baked notion of an input log class

This commit is contained in:
adelikat 2014-06-14 21:37:51 +00:00
parent d27df7816d
commit 70baceb6c8
11 changed files with 61 additions and 278 deletions

View File

@ -104,7 +104,7 @@ namespace BizHawk.Client.Common
Console.WriteLine("Read a zipstate of version {0}", _ver);
}
public static BinaryStateLoader LoadAndDetect(string filename)
public static BinaryStateLoader LoadAndDetect(string filename, bool isMovieLoad = false)
{
var ret = new BinaryStateLoader();
@ -126,7 +126,8 @@ namespace BizHawk.Client.Common
try
{
ret._zip = new ZipFile(filename);
if (!ret.GetLump(BinaryStateLump.Versiontag, false, ret.ReadVersion))
if (!isMovieLoad && !ret.GetLump(BinaryStateLump.Versiontag, false, ret.ReadVersion))
{
ret._zip.Close();
return null;

View File

@ -149,11 +149,6 @@
<Compile Include="movie\HeaderKeys.cs" />
<Compile Include="movie\InputAdapters.cs" />
<Compile Include="movie\interfaces\IMovie.cs" />
<Compile Include="movie\MnemonicGenerators\BooleanControllerMnemonicGenerator.cs" />
<Compile Include="movie\MnemonicGenerators\IMnemonicGenerator.cs" />
<Compile Include="movie\MnemonicGenerators\IMnemonicPorts.cs" />
<Compile Include="movie\MnemonicGenerators\MnemonicGeneratorFactory.cs" />
<Compile Include="movie\MnemonicGenerators\NesMnemonicGenerator.cs" />
<Compile Include="movie\MnemonicsGenerator.cs" />
<Compile Include="movie\MovieImport.cs" />
<Compile Include="movie\MovieMnemonics.cs" />

View File

@ -43,7 +43,7 @@ namespace BizHawk.Client.Common
return false;
}
using (BinaryStateLoader bl = BinaryStateLoader.LoadAndDetect(Filename))
using (BinaryStateLoader bl = BinaryStateLoader.LoadAndDetect(Filename, true))
{
if (bl == null)
{
@ -108,7 +108,7 @@ namespace BizHawk.Client.Common
{
if (line != null && line.StartsWith("|"))
{
_log.AppendFrame(line);
_log.Add(line);
}
}
});

View File

@ -30,7 +30,7 @@ namespace BizHawk.Client.Common
// We are in record mode so replace the movie log with the one from the savestate
if (!Global.MovieSession.MultiTrack.IsActive)
{
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Length > 0)
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Any())
{
SaveBackup();
_makeBackup = false;
@ -83,7 +83,7 @@ namespace BizHawk.Client.Common
}
else if (line[0] == '|')
{
_log.AppendFrame(line);
_log.Add(line);
}
}
}
@ -149,20 +149,18 @@ namespace BizHawk.Client.Common
var stateFramei = stateFrame ?? 0;
if (stateFramei > 0 && stateFramei < _log.Length)
if (stateFramei > 0 && stateFramei < _log.Count)
{
if (!Global.Config.VBAStyleMovieLoadState)
{
_log.TruncateStates(stateFramei);
_log.TruncateMovie(stateFramei);
}
}
else if (stateFramei > _log.Length) // Post movie savestate
else if (stateFramei > _log.Count) // Post movie savestate
{
if (!Global.Config.VBAStyleMovieLoadState)
{
_log.TruncateStates(_log.Length);
_log.TruncateMovie(_log.Length);
_log.TruncateMovie(_log.Count);
}
_mode = Moviemode.Finished;
@ -180,7 +178,7 @@ namespace BizHawk.Client.Common
{
// This function will compare the movie data to the savestate movie data to see if they match
errorMessage = string.Empty;
var log = new BkmLog();
var newLog = new BkmLog();
var stateFrame = 0;
while (true)
{
@ -231,16 +229,16 @@ namespace BizHawk.Client.Common
}
else if (line[0] == '|')
{
log.AppendFrame(line);
newLog.Add(line);
}
}
if (stateFrame == 0)
{
stateFrame = log.Length; // In case the frame count failed to parse, revert to using the entire state input log
stateFrame = newLog.Count; // In case the frame count failed to parse, revert to using the entire state input log
}
if (_log.Length < stateFrame)
if (_log.Count < stateFrame)
{
if (IsFinished)
{
@ -248,16 +246,16 @@ namespace BizHawk.Client.Common
}
errorMessage = "The savestate is from frame "
+ log.Length
+ newLog.Count
+ " which is greater than the current movie length of "
+ _log.Length;
+ _log.Count;
return false;
}
for (var i = 0; i < stateFrame; i++)
{
if (_log[i] != log[i])
if (_log[i] != newLog[i])
{
errorMessage = "The savestate input does not match the movie input at frame "
+ (i + 1)
@ -267,7 +265,7 @@ namespace BizHawk.Client.Common
}
}
if (stateFrame > log.Length) // stateFrame is greater than state input log, so movie finished mode
if (stateFrame > newLog.Count) // stateFrame is greater than state input log, so movie finished mode
{
if (_mode == Moviemode.Play || _mode == Moviemode.Finished)
{

View File

@ -50,7 +50,7 @@ namespace BizHawk.Client.Common
return double.PositiveInfinity;
}
return _log.Length;
return _log.Count;
}
}
@ -70,7 +70,7 @@ namespace BizHawk.Client.Common
{
get
{
var dblseconds = GetSeconds(_log.Length);
var dblseconds = GetSeconds(_log.Count);
var seconds = (int)(dblseconds % 60);
var days = seconds / 86400;
var hours = seconds / 3600;
@ -82,7 +82,7 @@ namespace BizHawk.Client.Common
public int InputLogLength
{
get { return _log.Length; }
get { return _log.Count; }
}
#region Log Editing
@ -91,7 +91,7 @@ namespace BizHawk.Client.Common
{
var mg = new MnemonicsGenerator();
mg.SetSource(source);
_log.AppendFrame(mg.GetControllersAsMnemonic());
_log.Add(mg.GetControllersAsMnemonic());
Changes = true;
}
@ -99,7 +99,7 @@ namespace BizHawk.Client.Common
{
if (Global.Config.VBAStyleMovieLoadState)
{
if (Global.Emulator.Frame < _log.Length)
if (Global.Emulator.Frame < _log.Count)
{
_log.TruncateMovie(Global.Emulator.Frame);
}
@ -127,13 +127,13 @@ namespace BizHawk.Client.Common
if (LoopOffset.HasValue)
{
if (frame < _log.Length)
if (frame < _log.Count)
{
getframe = frame;
}
else
{
getframe = ((frame - LoopOffset.Value) % (_log.Length - LoopOffset.Value)) + LoopOffset.Value;
getframe = ((frame - LoopOffset.Value) % (_log.Count - LoopOffset.Value)) + LoopOffset.Value;
}
}
else

View File

@ -5,242 +5,34 @@ using System.Linq;
namespace BizHawk.Client.Common
{
// TODO: what is this object really trying to accomplish? COnsider making it a collection (ICollection, IEnumerable perhaps)
/// <summary>
/// Represents the controller key presses of a movie
/// </summary>
public class BkmLog : IEnumerable<string>
public class BkmLog : List<string>
{
public IEnumerator<string> GetEnumerator()
{
return _movieRecords.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#region Properties
public byte[] InitState { get; private set; }
public int StateCount
{
get
{
return _state_records.Count;
}
}
public int Length
{
get
{
return _movieRecords.Count;
}
}
public int StateFirstIndex
{
get
{
return (_state_records.Count == 0) ? -1 : _state_records[0].Index;
}
}
public int StateLastIndex
{
get
{
return (_state_records.Count == 0) ? -1 : _state_records[_state_records.Count - 1].Index;
}
}
public int StateSizeInBytes
{
get
{
return _state_records.Any() ? StateCount * _state_records[0].State.Length : 0;
}
}
#endregion
#region Public Methods
public void Clear()
{
_movieRecords.Clear();
_state_records.Clear();
}
public void ClearStates()
{
_state_records.Clear();
}
public void AppendFrame(string frame)
{
_movieRecords.Add(frame);
}
public void AddState(byte[] state)
{
if (Global.Emulator.Frame == 0)
{
InitState = state;
}
if (Global.Emulator.Frame < StateFirstIndex)
{
_state_records.Clear();
_state_records.Add(new StateRecord(Global.Emulator.Frame, state));
}
if (Global.Emulator.Frame > StateLastIndex)
{
if (StateSizeInBytes + state.Length > MAXSTATERECORDSIZE)
{
// Discard the oldest state to save space.
_state_records.RemoveAt(0);
}
_state_records.Add(new StateRecord(Global.Emulator.Frame,state));
}
}
public void SetFrameAt(int frameNum, string frame)
{
if (frameNum < StateLastIndex && (frameNum < StateFirstIndex || frame != _movieRecords[frameNum]))
if (this.Count > frameNum)
{
TruncateStates(frameNum + 1);
}
if (_movieRecords.Count > frameNum)
{
_movieRecords[frameNum] = frame;
this[frameNum] = frame;
}
else
{
_movieRecords.Add(frame);
this.Add(frame);
}
}
public void AddFrameAt(int frame, string record)
{
_movieRecords.Insert(frame, record);
if (frame <= StateLastIndex)
{
if (frame <= StateFirstIndex)
{
_state_records.Clear();
}
else
{
_state_records.RemoveRange(frame - StateFirstIndex, StateLastIndex - frame + 1);
}
}
}
public byte[] GetState(int frame)
{
return _state_records[frame - StateFirstIndex].State;
}
public void DeleteFrame(int frame)
{
_movieRecords.RemoveAt(frame);
if (frame <= StateLastIndex)
{
if (frame <= StateFirstIndex)
{
_state_records.Clear();
}
else
{
_state_records.RemoveRange(frame - StateFirstIndex, StateLastIndex - frame + 1);
}
}
}
public void TruncateStates(int frame)
{
if (frame >= 0)
{
if (frame < StateFirstIndex)
{
_state_records.Clear();
}
else if (frame <= StateLastIndex)
{
_state_records.RemoveRange(frame - StateFirstIndex, StateLastIndex - frame + 1);
}
}
}
public string this[int frame]
{
get
{
return _movieRecords[frame];
}
this.RemoveAt(frame);
}
public void TruncateMovie(int frame)
{
if (frame < _movieRecords.Count)
if (frame < this.Count)
{
_movieRecords.RemoveRange(frame, _movieRecords.Count - frame);
TruncateStates(frame);
this.RemoveRange(frame, this.Count - frame);
}
}
public bool FrameLagged(int frame)
{
if (frame >= StateFirstIndex && frame <= StateLastIndex && frame <= _state_records.Count)
{
if (frame < _state_records.Count)
{
return _state_records[frame].Lagged;
}
else
{
return false;
}
}
else
{
return false;
}
}
#endregion
#region private fields
private sealed class StateRecord
{
public StateRecord(int index, byte[] state)
{
Index = index;
State = state;
Lagged = Global.Emulator.IsLagFrame;
}
public int Index { get; private set; }
public byte[] State { get; private set; }
public bool Lagged { get; private set; }
}
private readonly List<string> _movieRecords = new List<string>();
private readonly List<StateRecord> _state_records = new List<StateRecord>();
// TODO: Make this size limit configurable by the user
private const int MAXSTATERECORDSIZE = 512 * 1024 * 1024; //To limit memory usage.
#endregion
}
}

View File

@ -99,7 +99,7 @@ namespace BizHawk.Client.Common
}
else if (line.StartsWith("|"))
{
_log.AppendFrame(line);
_log.Add(line);
}
else
{

View File

@ -1,5 +1,6 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
namespace BizHawk.Client.Common
@ -32,7 +33,7 @@ namespace BizHawk.Client.Common
// We are in record mode so replace the movie log with the one from the savestate
if (!Global.MovieSession.MultiTrack.IsActive)
{
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Length > 0)
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Any())
{
SaveBackup();
_makeBackup = false;
@ -85,7 +86,7 @@ namespace BizHawk.Client.Common
}
else if (line[0] == '|')
{
_log.AppendFrame(line);
_log.Add(line);
}
}
}
@ -151,20 +152,18 @@ namespace BizHawk.Client.Common
var stateFramei = stateFrame ?? 0;
if (stateFramei > 0 && stateFramei < _log.Length)
if (stateFramei > 0 && stateFramei < _log.Count)
{
if (!Global.Config.VBAStyleMovieLoadState)
{
_log.TruncateStates(stateFramei);
_log.TruncateMovie(stateFramei);
}
}
else if (stateFramei > _log.Length) // Post movie savestate
else if (stateFramei > _log.Count) // Post movie savestate
{
if (!Global.Config.VBAStyleMovieLoadState)
{
_log.TruncateStates(_log.Length);
_log.TruncateMovie(_log.Length);
_log.TruncateMovie(_log.Count);
}
_mode = Moviemode.Finished;
@ -233,16 +232,16 @@ namespace BizHawk.Client.Common
}
else if (line[0] == '|')
{
log.AppendFrame(line);
log.Add(line);
}
}
if (stateFrame == 0)
{
stateFrame = log.Length; // In case the frame count failed to parse, revert to using the entire state input log
stateFrame = log.Count; // In case the frame count failed to parse, revert to using the entire state input log
}
if (_log.Length < stateFrame)
if (_log.Count < stateFrame)
{
if (IsFinished)
{
@ -250,9 +249,9 @@ namespace BizHawk.Client.Common
}
errorMessage = "The savestate is from frame "
+ log.Length
+ log.Count
+ " which is greater than the current movie length of "
+ _log.Length;
+ _log.Count;
return false;
}
@ -269,7 +268,7 @@ namespace BizHawk.Client.Common
}
}
if (stateFrame > log.Length) // stateFrame is greater than state input log, so movie finished mode
if (stateFrame > log.Count) // stateFrame is greater than state input log, so movie finished mode
{
if (_mode == Moviemode.Play || _mode == Moviemode.Finished)
{

View File

@ -1,4 +1,6 @@
namespace BizHawk.Client.Common
using System.Linq;
namespace BizHawk.Client.Common
{
public partial class BkmMovie : IMovie
{
@ -38,7 +40,7 @@
}
_mode = Moviemode.Record;
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Length > 0)
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Any())
{
SaveBackup();
_makeBackup = false;

View File

@ -40,7 +40,7 @@ namespace BizHawk.Client.Common
public int InputLogLength
{
get { return _log.Length; }
get { return _log.Count; }
}
public double FrameCount
@ -54,7 +54,7 @@ namespace BizHawk.Client.Common
if (Loaded)
{
return _log.Length;
return _log.Count;
}
return _preloadFramecount;
@ -82,7 +82,7 @@ namespace BizHawk.Client.Common
{
get
{
var dblseconds = GetSeconds(Loaded ? _log.Length : _preloadFramecount);
var dblseconds = GetSeconds(Loaded ? _log.Count : _preloadFramecount);
var seconds = (int)(dblseconds % 60);
var days = seconds / 86400;
var hours = seconds / 3600;
@ -105,13 +105,13 @@ namespace BizHawk.Client.Common
if (_loopOffset.HasValue)
{
if (frame < _log.Length)
if (frame < _log.Count)
{
getframe = frame;
}
else
{
getframe = ((frame - _loopOffset.Value) % (_log.Length - _loopOffset.Value)) + _loopOffset.Value;
getframe = ((frame - _loopOffset.Value) % (_log.Count - _loopOffset.Value)) + _loopOffset.Value;
}
}
else
@ -136,14 +136,13 @@ namespace BizHawk.Client.Common
{
var mg = new MnemonicsGenerator();
mg.SetSource(source);
_log.AppendFrame(mg.GetControllersAsMnemonic());
_log.Add(mg.GetControllersAsMnemonic());
_changes = true;
}
public void Truncate(int frame)
{
_log.TruncateMovie(frame);
_log.TruncateStates(frame);
_changes = true;
}
@ -163,7 +162,7 @@ namespace BizHawk.Client.Common
// this allows users to restore a movie with any savestate from that "timeline"
if (Global.Config.VBAStyleMovieLoadState)
{
if (Global.Emulator.Frame < _log.Length)
if (Global.Emulator.Frame < _log.Count)
{
_log.TruncateMovie(Global.Emulator.Frame);
}

View File

@ -71,7 +71,6 @@ namespace BizHawk.Client.EmuHawk
}
else if (result == DialogResult.No)
{
_tas.Changes = false;
return true;
}
else if (result == DialogResult.Cancel)
@ -166,7 +165,7 @@ namespace BizHawk.Client.EmuHawk
{
if (Global.MovieSession.Movie.IsActive)
{
var result = MessageBox.Show("Warning, Tastudio doesn't support .bkm movie files at this time, opening this will cause you to lose your work, proceed? If you have unsaved changes you should cancel this, and savebefore opening TAStudio", "Unsupported movie", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
var result = MessageBox.Show("Warning, Tastudio doesn't support regular movie files at this time, opening this will cause you to lose your work, proceed? If you have unsaved changes you should cancel this, and savebefore opening TAStudio", "Unsupported movie", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (result != DialogResult.Yes)
{
Close();
@ -185,8 +184,6 @@ namespace BizHawk.Client.EmuHawk
EngageTasStudio();
}
_tas.ActivePlayers = new List<string> { "Player 1" }; // TODO
SetUpColumns();
LoadConfigSettings();
}
@ -218,7 +215,7 @@ namespace BizHawk.Client.EmuHawk
AddColumn(MarkerColumnName, String.Empty, 18);
AddColumn(FrameColumnName, "Frame#", 68);
foreach (var kvp in _tas.AvailableMnemonics)
foreach (var kvp in _tas.ColumnNames)
{
AddColumn(kvp.Key, kvp.Value.ToString(), 20);
}
@ -492,11 +489,11 @@ namespace BizHawk.Client.EmuHawk
}
else
{
_tas.ToggleButton(TasView.PointedCell.Row.Value, TasView.PointedCell.Column);
//_tas.ToggleButton(TasView.PointedCell.Row.Value, TasView.PointedCell.Column);
TasView.Refresh();
_startDrawColumn = TasView.PointedCell.Column;
_startOn = _tas.IsPressed(TasView.PointedCell.Row.Value, TasView.PointedCell.Column);
//_startOn = _tas.IsPressed(TasView.PointedCell.Row.Value, TasView.PointedCell.Column);
}
}
}
@ -541,7 +538,7 @@ namespace BizHawk.Client.EmuHawk
}
else if (TasView.IsPaintDown && e.NewCell.Row.HasValue && !string.IsNullOrEmpty(_startDrawColumn))
{
_tas.SetButton(e.NewCell.Row.Value, _startDrawColumn, _startOn); // Notice it uses new row, old column, you can only paint across a single column
_tas.SetBoolButton(e.NewCell.Row.Value, _startDrawColumn, _startOn); // Notice it uses new row, old column, you can only paint across a single column
TasView.Refresh();
}
}