Bk2 progress
This commit is contained in:
parent
2774e9c252
commit
d816b1ed20
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -23,12 +24,266 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public bool ExtractInputLog(TextReader reader, out string errorMessage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
errorMessage = string.Empty;
|
||||
int? stateFrame = null;
|
||||
|
||||
// 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)
|
||||
{
|
||||
SaveBackup();
|
||||
_makeBackup = false;
|
||||
}
|
||||
|
||||
_log.Clear();
|
||||
while (true)
|
||||
{
|
||||
var line = reader.ReadLine();
|
||||
if (line == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.Trim() == string.Empty || line == "[Input]")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line == "[/Input]")
|
||||
{
|
||||
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[0] == '|')
|
||||
{
|
||||
_log.AppendFrame(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var i = 0;
|
||||
while (true)
|
||||
{
|
||||
var line = reader.ReadLine();
|
||||
if (line == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.Trim() == string.Empty || line == "[Input]")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line == "[/Input]")
|
||||
{
|
||||
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("|"))
|
||||
{
|
||||
_log.SetFrameAt(i, line);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!stateFrame.HasValue)
|
||||
{
|
||||
errorMessage = "Savestate Frame number failed to parse";
|
||||
}
|
||||
|
||||
var stateFramei = stateFrame ?? 0;
|
||||
|
||||
if (stateFramei > 0 && stateFramei < _log.Length)
|
||||
{
|
||||
if (!Global.Config.VBAStyleMovieLoadState)
|
||||
{
|
||||
_log.TruncateStates(stateFramei);
|
||||
_log.TruncateMovie(stateFramei);
|
||||
}
|
||||
}
|
||||
else if (stateFramei > _log.Length) // Post movie savestate
|
||||
{
|
||||
if (!Global.Config.VBAStyleMovieLoadState)
|
||||
{
|
||||
_log.TruncateStates(_log.Length);
|
||||
_log.TruncateMovie(_log.Length);
|
||||
}
|
||||
|
||||
_mode = Moviemode.Finished;
|
||||
}
|
||||
|
||||
if (IsCountingRerecords)
|
||||
{
|
||||
Rerecords++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CheckTimeLines(TextReader reader, out string errorMessage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// 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 stateFrame = 0;
|
||||
while (true)
|
||||
{
|
||||
var line = reader.ReadLine();
|
||||
if (line == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (line.Trim() == string.Empty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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 == "[Input]")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (line == "[/Input]")
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (line[0] == '|')
|
||||
{
|
||||
log.AppendFrame(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (stateFrame == 0)
|
||||
{
|
||||
stateFrame = log.Length; // In case the frame count failed to parse, revert to using the entire state input log
|
||||
}
|
||||
|
||||
if (_log.Length < stateFrame)
|
||||
{
|
||||
if (IsFinished)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
errorMessage = "The savestate is from frame "
|
||||
+ log.Length
|
||||
+ " which is greater than the current movie length of "
|
||||
+ _log.Length;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < stateFrame; i++)
|
||||
{
|
||||
if (_log[i] != log[i])
|
||||
{
|
||||
errorMessage = "The savestate input does not match the movie input at frame "
|
||||
+ (i + 1)
|
||||
+ ".";
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (stateFrame > log.Length) // stateFrame is greater than state input log, so movie finished mode
|
||||
{
|
||||
if (_mode == Moviemode.Play || _mode == Moviemode.Finished)
|
||||
{
|
||||
_mode = Moviemode.Finished;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_mode == Moviemode.Finished)
|
||||
{
|
||||
_mode = Moviemode.Play;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private StringBuilder RawInputLog()
|
||||
|
|
|
@ -71,5 +71,13 @@ namespace BizHawk.Client.Common
|
|||
Changes = false;
|
||||
_mode = Moviemode.Inactive;
|
||||
}
|
||||
|
||||
private void Finish()
|
||||
{
|
||||
if (_mode == Moviemode.Play)
|
||||
{
|
||||
_mode = Moviemode.Finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
private readonly PlatformFrameRates _frameRates = new PlatformFrameRates();
|
||||
private bool _makeBackup = true;
|
||||
private int? _loopOffset;
|
||||
|
||||
public Bk2Movie(string filename, bool startsFromSavestate = false)
|
||||
: this(startsFromSavestate)
|
||||
|
@ -34,66 +35,134 @@ namespace BizHawk.Client.Common
|
|||
_makeBackup = true;
|
||||
}
|
||||
|
||||
#region Implementation
|
||||
|
||||
public string Filename { get; set; }
|
||||
public string PreferredExtension { get { return "bk2"; } }
|
||||
public bool IsCountingRerecords { get; set; }
|
||||
|
||||
public bool Changes { get; private set; }
|
||||
public bool IsCountingRerecords { get; set; }
|
||||
|
||||
public double FrameCount
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
get
|
||||
{
|
||||
if (_loopOffset.HasValue)
|
||||
{
|
||||
return double.PositiveInfinity;
|
||||
}
|
||||
|
||||
return _log.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public double Fps
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
get
|
||||
{
|
||||
var system = Header[HeaderKeys.PLATFORM];
|
||||
var pal = Header.ContainsKey(HeaderKeys.PAL) &&
|
||||
Header[HeaderKeys.PAL] == "1";
|
||||
|
||||
return _frameRates[system, pal];
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan Time
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
get
|
||||
{
|
||||
var dblseconds = GetSeconds(_log.Length);
|
||||
var seconds = (int)(dblseconds % 60);
|
||||
var days = seconds / 86400;
|
||||
var hours = seconds / 3600;
|
||||
var minutes = (seconds / 60) % 60;
|
||||
var milliseconds = (int)((dblseconds - seconds) * 1000);
|
||||
return new TimeSpan(days, hours, minutes, seconds, milliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
public int InputLogLength
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
get { return _log.Length; }
|
||||
}
|
||||
|
||||
public string Filename
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
#region Log Editing
|
||||
|
||||
public void AppendFrame(IController source)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var mg = new MnemonicsGenerator();
|
||||
mg.SetSource(source);
|
||||
_log.AppendFrame(mg.GetControllersAsMnemonic());
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
public void RecordFrame(int frame, IController source)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (Global.Config.VBAStyleMovieLoadState)
|
||||
{
|
||||
if (Global.Emulator.Frame < _log.Length)
|
||||
{
|
||||
_log.TruncateMovie(Global.Emulator.Frame);
|
||||
}
|
||||
}
|
||||
|
||||
var mg = new MnemonicsGenerator();
|
||||
mg.SetSource(source);
|
||||
|
||||
Changes = true;
|
||||
_log.SetFrameAt(frame, mg.GetControllersAsMnemonic());
|
||||
}
|
||||
|
||||
public void Truncate(int frame)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
_log.TruncateMovie(frame);
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
public string GetInput(int frame)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (frame < FrameCount && frame >= 0)
|
||||
{
|
||||
|
||||
int getframe;
|
||||
|
||||
if (_loopOffset.HasValue)
|
||||
{
|
||||
if (frame < _log.Length)
|
||||
{
|
||||
getframe = frame;
|
||||
}
|
||||
else
|
||||
{
|
||||
getframe = ((frame - _loopOffset.Value) % (_log.Length - _loopOffset.Value)) + _loopOffset.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getframe = frame;
|
||||
}
|
||||
|
||||
return _log[getframe];
|
||||
}
|
||||
|
||||
Finish();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// Probably won't support
|
||||
#endregion
|
||||
|
||||
private double GetSeconds(int frameCount)
|
||||
{
|
||||
double frames = frameCount;
|
||||
|
||||
if (frames < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return frames / Fps;
|
||||
}
|
||||
|
||||
#region Probably won't support
|
||||
|
||||
public void PokeFrame(int frame, IController source)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
|
|
@ -67,40 +67,62 @@ namespace BizHawk.Client.Common
|
|||
get { return _changes; }
|
||||
}
|
||||
|
||||
public double Fps
|
||||
{
|
||||
get
|
||||
{
|
||||
var system = Header[HeaderKeys.PLATFORM];
|
||||
var pal = Header.ContainsKey(HeaderKeys.PAL) &&
|
||||
Header[HeaderKeys.PAL] == "1";
|
||||
|
||||
return _frameRates[system, pal];
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan Time
|
||||
{
|
||||
get
|
||||
{
|
||||
var dblseconds = GetSeconds(Loaded ? _log.Length : _preloadFramecount);
|
||||
var seconds = (int)(dblseconds % 60);
|
||||
var days = seconds / 86400;
|
||||
var hours = seconds / 3600;
|
||||
var minutes = (seconds / 60) % 60;
|
||||
var milliseconds = (int)((dblseconds - seconds) * 1000);
|
||||
return new TimeSpan(days, hours, minutes, seconds, milliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Log Editing
|
||||
|
||||
public string GetInput(int frame)
|
||||
{
|
||||
if (frame < FrameCount)
|
||||
if (frame < FrameCount && frame >= 0)
|
||||
{
|
||||
if (frame >= 0)
|
||||
{
|
||||
int getframe;
|
||||
|
||||
if (_loopOffset.HasValue)
|
||||
{
|
||||
if (frame < _log.Length)
|
||||
{
|
||||
getframe = frame;
|
||||
}
|
||||
else
|
||||
{
|
||||
getframe = ((frame - _loopOffset.Value) % (_log.Length - _loopOffset.Value)) + _loopOffset.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
int getframe;
|
||||
|
||||
if (_loopOffset.HasValue)
|
||||
{
|
||||
if (frame < _log.Length)
|
||||
{
|
||||
getframe = frame;
|
||||
}
|
||||
|
||||
return _log[getframe];
|
||||
else
|
||||
{
|
||||
getframe = ((frame - _loopOffset.Value) % (_log.Length - _loopOffset.Value)) + _loopOffset.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
else
|
||||
{
|
||||
getframe = frame;
|
||||
}
|
||||
|
||||
return _log[getframe];
|
||||
}
|
||||
|
||||
|
||||
Finish();
|
||||
return string.Empty;
|
||||
}
|
||||
|
@ -155,20 +177,6 @@ namespace BizHawk.Client.Common
|
|||
_log.SetFrameAt(frame, mg.GetControllersAsMnemonic());
|
||||
}
|
||||
|
||||
public TimeSpan Time
|
||||
{
|
||||
get
|
||||
{
|
||||
var dblseconds = GetSeconds(Loaded ? _log.Length : _preloadFramecount);
|
||||
var seconds = (int)(dblseconds % 60);
|
||||
var days = seconds / 86400;
|
||||
var hours = seconds / 3600;
|
||||
var minutes = (seconds / 60) % 60;
|
||||
var milliseconds = (int)((dblseconds - seconds) * 1000);
|
||||
return new TimeSpan(days, hours, minutes, seconds, milliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private double GetSeconds(int frameCount)
|
||||
|
@ -180,23 +188,7 @@ namespace BizHawk.Client.Common
|
|||
return 0;
|
||||
}
|
||||
|
||||
var system = Header[HeaderKeys.PLATFORM];
|
||||
var pal = Header.ContainsKey(HeaderKeys.PAL) &&
|
||||
Header[HeaderKeys.PAL] == "1";
|
||||
|
||||
return frames / _frameRates[system, pal];
|
||||
}
|
||||
|
||||
public double Fps
|
||||
{
|
||||
get
|
||||
{
|
||||
var system = Header[HeaderKeys.PLATFORM];
|
||||
var pal = Header.ContainsKey(HeaderKeys.PAL) &&
|
||||
Header[HeaderKeys.PAL] == "1";
|
||||
|
||||
return _frameRates[system, pal];
|
||||
}
|
||||
return frames / Fps;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue