Tastudio - support "out of order savestating" using saveslot states. Experiemental, could have bugs particularly off by one issues
This commit is contained in:
parent
eb292eddcc
commit
5349affbc4
|
@ -9,7 +9,7 @@ namespace BizHawk.Client.Common
|
|||
public partial class Bk2Movie
|
||||
{
|
||||
protected List<string> _log = new List<string>();
|
||||
private string _logKey = string.Empty;
|
||||
protected string LogKey = string.Empty;
|
||||
|
||||
public string GetInputLog()
|
||||
{
|
||||
|
@ -22,7 +22,7 @@ namespace BizHawk.Client.Common
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
public bool ExtractInputLog(TextReader reader, out string errorMessage)
|
||||
public virtual bool ExtractInputLog(TextReader reader, out string errorMessage)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
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
|
||||
if (!Global.MovieSession.MultiTrack.IsActive)
|
||||
{
|
||||
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Any())
|
||||
if (Global.Config.EnableBackupMovies && MakeBackup && _log.Any())
|
||||
{
|
||||
SaveBackup();
|
||||
_makeBackup = false;
|
||||
MakeBackup = false;
|
||||
}
|
||||
|
||||
_log.Clear();
|
||||
|
@ -72,7 +72,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
else if (line.StartsWith("LogKey:"))
|
||||
{
|
||||
_logKey = line.Replace("LogKey:", "");
|
||||
LogKey = line.Replace("LogKey:", "");
|
||||
}
|
||||
else if (line[0] == '|')
|
||||
{
|
||||
|
@ -119,7 +119,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
else if (line.StartsWith("LogKey:"))
|
||||
{
|
||||
_logKey = line.Replace("LogKey:", "");
|
||||
LogKey = line.Replace("LogKey:", "");
|
||||
}
|
||||
else if (line.StartsWith("|"))
|
||||
{
|
||||
|
@ -265,7 +265,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
protected StringBuilder RawInputLog()
|
||||
{
|
||||
var lg = new Bk2LogEntryGenerator(_logKey);
|
||||
var lg = new Bk2LogEntryGenerator(LogKey);
|
||||
lg.SetSource(Global.MovieOutputHardpoint);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
|
|
@ -30,10 +30,10 @@ namespace BizHawk.Client.Common
|
|||
public virtual void StartNewRecording()
|
||||
{
|
||||
_mode = Moviemode.Record;
|
||||
if (Global.Config.EnableBackupMovies && _makeBackup && _log.Any())
|
||||
if (Global.Config.EnableBackupMovies && MakeBackup && _log.Any())
|
||||
{
|
||||
SaveBackup();
|
||||
_makeBackup = false;
|
||||
MakeBackup = false;
|
||||
}
|
||||
|
||||
_log.Clear();
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public partial class Bk2Movie : IMovie
|
||||
{
|
||||
private bool _makeBackup = true;
|
||||
protected bool MakeBackup = true;
|
||||
|
||||
public Bk2Movie(string filename)
|
||||
: this()
|
||||
|
@ -24,7 +24,7 @@ namespace BizHawk.Client.Common
|
|||
Filename = string.Empty;
|
||||
IsCountingRerecords = true;
|
||||
_mode = Moviemode.Inactive;
|
||||
_makeBackup = true;
|
||||
MakeBackup = true;
|
||||
|
||||
Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0.0";
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public ILogEntryGenerator LogGeneratorInstance()
|
||||
{
|
||||
return new Bk2LogEntryGenerator(_logKey);
|
||||
return new Bk2LogEntryGenerator(LogKey);
|
||||
}
|
||||
|
||||
public double FrameCount
|
||||
|
@ -168,7 +168,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
#endregion
|
||||
|
||||
private void SetFrameAt(int frameNum, string frame)
|
||||
protected void SetFrameAt(int frameNum, string frame)
|
||||
{
|
||||
if (_log.Count > frameNum)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
IsCountingRerecords = false;
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Text;
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
@ -335,5 +336,165 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue