Tastudio - support "out of order savestating" using saveslot states. Experiemental, could have bugs particularly off by one issues

This commit is contained in:
adelikat 2014-11-15 21:49:58 +00:00
parent eb292eddcc
commit 5349affbc4
5 changed files with 175 additions and 14 deletions

View File

@ -9,7 +9,7 @@ namespace BizHawk.Client.Common
public partial class Bk2Movie public partial class Bk2Movie
{ {
protected List<string> _log = new List<string>(); protected List<string> _log = new List<string>();
private string _logKey = string.Empty; protected string LogKey = string.Empty;
public string GetInputLog() public string GetInputLog()
{ {
@ -22,7 +22,7 @@ namespace BizHawk.Client.Common
return sb.ToString(); return sb.ToString();
} }
public bool ExtractInputLog(TextReader reader, out string errorMessage) public virtual bool ExtractInputLog(TextReader reader, out string errorMessage)
{ {
errorMessage = string.Empty; errorMessage = string.Empty;
int? stateFrame = null; int? stateFrame = null;
@ -30,10 +30,10 @@ namespace BizHawk.Client.Common
// We are in record mode so replace the movie log with the one from the savestate // We are in record mode so replace the movie log with the one from the savestate
if (!Global.MovieSession.MultiTrack.IsActive) if (!Global.MovieSession.MultiTrack.IsActive)
{ {
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Any()) if (Global.Config.EnableBackupMovies && MakeBackup && _log.Any())
{ {
SaveBackup(); SaveBackup();
_makeBackup = false; MakeBackup = false;
} }
_log.Clear(); _log.Clear();
@ -72,7 +72,7 @@ namespace BizHawk.Client.Common
} }
else if (line.StartsWith("LogKey:")) else if (line.StartsWith("LogKey:"))
{ {
_logKey = line.Replace("LogKey:", ""); LogKey = line.Replace("LogKey:", "");
} }
else if (line[0] == '|') else if (line[0] == '|')
{ {
@ -119,7 +119,7 @@ namespace BizHawk.Client.Common
} }
else if (line.StartsWith("LogKey:")) else if (line.StartsWith("LogKey:"))
{ {
_logKey = line.Replace("LogKey:", ""); LogKey = line.Replace("LogKey:", "");
} }
else if (line.StartsWith("|")) else if (line.StartsWith("|"))
{ {
@ -265,7 +265,7 @@ namespace BizHawk.Client.Common
protected StringBuilder RawInputLog() protected StringBuilder RawInputLog()
{ {
var lg = new Bk2LogEntryGenerator(_logKey); var lg = new Bk2LogEntryGenerator(LogKey);
lg.SetSource(Global.MovieOutputHardpoint); lg.SetSource(Global.MovieOutputHardpoint);
var sb = new StringBuilder(); var sb = new StringBuilder();

View File

@ -30,10 +30,10 @@ namespace BizHawk.Client.Common
public virtual void StartNewRecording() public virtual void StartNewRecording()
{ {
_mode = Moviemode.Record; _mode = Moviemode.Record;
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Any()) if (Global.Config.EnableBackupMovies && MakeBackup && _log.Any())
{ {
SaveBackup(); SaveBackup();
_makeBackup = false; MakeBackup = false;
} }
_log.Clear(); _log.Clear();

View File

@ -7,7 +7,7 @@ namespace BizHawk.Client.Common
{ {
public partial class Bk2Movie : IMovie public partial class Bk2Movie : IMovie
{ {
private bool _makeBackup = true; protected bool MakeBackup = true;
public Bk2Movie(string filename) public Bk2Movie(string filename)
: this() : this()
@ -24,7 +24,7 @@ namespace BizHawk.Client.Common
Filename = string.Empty; Filename = string.Empty;
IsCountingRerecords = true; IsCountingRerecords = true;
_mode = Moviemode.Inactive; _mode = Moviemode.Inactive;
_makeBackup = true; MakeBackup = true;
Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0.0"; Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0.0";
} }
@ -52,7 +52,7 @@ namespace BizHawk.Client.Common
public ILogEntryGenerator LogGeneratorInstance() public ILogEntryGenerator LogGeneratorInstance()
{ {
return new Bk2LogEntryGenerator(_logKey); return new Bk2LogEntryGenerator(LogKey);
} }
public double FrameCount public double FrameCount
@ -168,7 +168,7 @@ namespace BizHawk.Client.Common
#endregion #endregion
private void SetFrameAt(int frameNum, string frame) protected void SetFrameAt(int frameNum, string frame)
{ {
if (_log.Count > frameNum) if (_log.Count > frameNum)
{ {

View File

@ -141,7 +141,7 @@ namespace BizHawk.Client.Common
} }
}); });
bl.GetLump(BinaryStateLump.Input, true, delegate(TextReader tr) 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; var errorMessage = string.Empty;
IsCountingRerecords = false; IsCountingRerecords = false;

View File

@ -7,6 +7,7 @@ using System.Text;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using System.ComponentModel; using System.ComponentModel;
using System.Globalization;
namespace BizHawk.Client.Common namespace BizHawk.Client.Common
{ {
@ -335,5 +336,165 @@ namespace BizHawk.Client.Common
{ {
return _log; return _log;
} }
private int? TimelineBranchFrame = null;
// TODO: this is 99% copy pasting of bad code
public override bool ExtractInputLog(TextReader reader, out string errorMessage)
{
errorMessage = string.Empty;
int? stateFrame = null;
var newLog = new List<string>();
// We are in record mode so replace the movie log with the one from the savestate
if (!Global.MovieSession.MultiTrack.IsActive)
{
TimelineBranchFrame = null;
if (Global.Config.EnableBackupMovies && MakeBackup && _log.Any())
{
SaveBackup();
MakeBackup = false;
}
int counter = 0;
while (true)
{
var line = reader.ReadLine();
if (string.IsNullOrEmpty(line))
{
break;
}
else if (line.Contains("Frame 0x")) // NES stores frame count in hex, yay
{
var strs = line.Split('x');
try
{
stateFrame = int.Parse(strs[1], NumberStyles.HexNumber);
}
catch
{
errorMessage = "Savestate Frame number failed to parse";
return false;
}
}
else if (line.Contains("Frame "))
{
var strs = line.Split(' ');
try
{
stateFrame = int.Parse(strs[1]);
}
catch
{
errorMessage = "Savestate Frame number failed to parse";
return false;
}
}
else if (line.StartsWith("LogKey:"))
{
LogKey = line.Replace("LogKey:", "");
}
else if (line[0] == '|')
{
newLog.Add(line);
if (!TimelineBranchFrame.HasValue && line != _log[counter])
{
TimelineBranchFrame = counter;
}
counter++;
}
}
_log.Clear();
_log.AddRange(newLog);
}
else //Multitrack mode
{
// TODO: consider TimelineBranchFrame here, my thinking is that there's never a scenario to invalidate state/lag data during multitrack
var i = 0;
while (true)
{
var line = reader.ReadLine();
if (line == null)
{
break;
}
if (line.Contains("Frame 0x")) // NES stores frame count in hex, yay
{
var strs = line.Split('x');
try
{
stateFrame = int.Parse(strs[1], NumberStyles.HexNumber);
}
catch
{
errorMessage = "Savestate Frame number failed to parse";
return false;
}
}
else if (line.Contains("Frame "))
{
var strs = line.Split(' ');
try
{
stateFrame = int.Parse(strs[1]);
}
catch
{
errorMessage = "Savestate Frame number failed to parse";
return false;
}
}
else if (line.StartsWith("LogKey:"))
{
LogKey = line.Replace("LogKey:", "");
}
else if (line.StartsWith("|"))
{
SetFrameAt(i, line);
i++;
}
}
}
if (!stateFrame.HasValue)
{
errorMessage = "Savestate Frame number failed to parse";
}
var stateFramei = stateFrame ?? 0;
if (stateFramei > 0 && stateFramei < _log.Count)
{
if (!Global.Config.VBAStyleMovieLoadState)
{
Truncate(stateFramei);
}
}
else if (stateFramei > _log.Count) // Post movie savestate
{
if (!Global.Config.VBAStyleMovieLoadState)
{
Truncate(_log.Count);
}
_mode = Moviemode.Finished;
}
if (IsCountingRerecords)
{
Rerecords++;
}
if (TimelineBranchFrame.HasValue)
{
LagLog.RemoveFrom(TimelineBranchFrame.Value);
TasStateManager.Invalidate(TimelineBranchFrame.Value);
}
return true;
}
} }
} }