BizHawk/BizHawk.Client.Common/movie/bkm/BkmMovie.cs

198 lines
4.0 KiB
C#
Raw Normal View History

2013-10-25 00:59:34 +00:00
using System;
using BizHawk.Emulation.Common;
2013-10-25 00:59:34 +00:00
namespace BizHawk.Client.Common
{
2014-06-13 00:15:55 +00:00
public partial class BkmMovie : IMovie
2013-10-25 00:59:34 +00:00
{
2014-04-06 19:01:00 +00:00
private readonly PlatformFrameRates _frameRates = new PlatformFrameRates();
private bool _makeBackup = true;
2014-04-06 19:01:00 +00:00
private bool _changes;
private int? _loopOffset;
2013-10-25 00:59:34 +00:00
2014-06-14 20:17:07 +00:00
public BkmMovie(string filename)
: this()
2013-10-25 00:59:34 +00:00
{
Rerecords = 0;
2013-10-25 00:59:34 +00:00
Filename = filename;
2014-04-06 19:01:00 +00:00
Loaded = !string.IsNullOrWhiteSpace(filename);
2013-10-25 00:59:34 +00:00
}
2014-06-14 20:17:07 +00:00
public BkmMovie()
2013-10-25 00:59:34 +00:00
{
2014-06-13 00:43:55 +00:00
Header = new BkmHeader();
2014-06-12 20:42:46 +00:00
Header[HeaderKeys.MOVIEVERSION] = "BizHawk v0.0.1";
2014-04-06 19:01:00 +00:00
Filename = string.Empty;
_preloadFramecount = 0;
2014-06-12 23:57:23 +00:00
2013-10-25 00:59:34 +00:00
IsCountingRerecords = true;
_mode = Moviemode.Inactive;
_makeBackup = true;
2013-10-25 00:59:34 +00:00
}
#region Properties
public ILogEntryGenerator LogGeneratorInstance()
{
return new BkmLogEntryGenerator();
}
public string PreferredExtension { get { return "bkm"; } }
2014-06-13 00:43:55 +00:00
public BkmHeader Header { get; private set; }
public string Filename { get; set; }
public bool IsCountingRerecords { get; set; }
2013-10-25 00:59:34 +00:00
public bool Loaded { get; private set; }
2014-06-12 23:57:23 +00:00
public int InputLogLength
2013-10-25 00:59:34 +00:00
{
get { return _log.Count; }
2013-10-25 00:59:34 +00:00
}
public double FrameCount
2013-10-25 00:59:34 +00:00
{
get
{
if (_loopOffset.HasValue)
2013-10-25 00:59:34 +00:00
{
return double.PositiveInfinity;
}
2014-04-06 19:01:00 +00:00
if (Loaded)
{
return _log.Count;
2013-10-25 00:59:34 +00:00
}
2014-04-06 19:01:00 +00:00
return _preloadFramecount;
2013-10-25 00:59:34 +00:00
}
}
public bool Changes
2013-10-25 00:59:34 +00:00
{
get { return _changes; }
2013-10-25 00:59:34 +00:00
}
2014-06-14 14:04:54 +00:00
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.Count : _preloadFramecount);
2014-06-14 14:04:54 +00:00
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);
}
}
2013-10-25 00:59:34 +00:00
#endregion
#region Public Log Editing
public string GetInput(int frame)
{
2014-06-14 14:04:54 +00:00
if (frame < FrameCount && frame >= 0)
2013-10-25 00:59:34 +00:00
{
2014-06-14 14:04:54 +00:00
int getframe;
if (_loopOffset.HasValue)
{
if (frame < _log.Count)
{
2014-06-14 14:04:54 +00:00
getframe = frame;
}
else
{
getframe = ((frame - _loopOffset.Value) % (_log.Count - _loopOffset.Value)) + _loopOffset.Value;
}
2013-10-25 00:59:34 +00:00
}
2014-06-14 14:04:54 +00:00
else
{
getframe = frame;
}
return _log[getframe];
2013-10-25 00:59:34 +00:00
}
2014-06-14 14:04:54 +00:00
2014-04-06 19:01:00 +00:00
Finish();
return string.Empty;
2013-10-25 00:59:34 +00:00
}
public void ClearFrame(int frame)
{
var lg = LogGeneratorInstance();
_log.SetFrameAt(frame, lg.EmptyEntry);
_changes = true;
2013-10-25 00:59:34 +00:00
}
public void AppendFrame(IController source)
2013-10-25 00:59:34 +00:00
{
var lg = LogGeneratorInstance();
lg.SetSource(source);
_log.Add(lg.GenerateLogEntry());
_changes = true;
2013-10-25 00:59:34 +00:00
}
public void Truncate(int frame)
2013-10-25 00:59:34 +00:00
{
2014-06-14 21:41:11 +00:00
_log.Truncate(frame);
_changes = true;
2013-10-25 00:59:34 +00:00
}
public void PokeFrame(int frame, IController source)
2013-10-25 00:59:34 +00:00
{
var lg = LogGeneratorInstance();
lg.SetSource(source);
_changes = true;
_log.SetFrameAt(frame, lg.GenerateLogEntry());
2013-10-25 00:59:34 +00:00
}
public void RecordFrame(int frame, IController source)
2013-10-25 00:59:34 +00:00
{
2013-11-30 02:20:34 +00:00
// Note: Truncation here instead of loadstate will make VBA style loadstates
// (Where an entire movie is loaded then truncated on the next frame
// this allows users to restore a movie with any savestate from that "timeline"
2013-10-25 00:59:34 +00:00
if (Global.Config.VBAStyleMovieLoadState)
{
if (Global.Emulator.Frame < _log.Count)
2013-10-25 00:59:34 +00:00
{
2014-06-14 21:41:11 +00:00
_log.Truncate(Global.Emulator.Frame);
2013-10-25 00:59:34 +00:00
}
}
2013-11-30 02:20:34 +00:00
var lg = LogGeneratorInstance();
lg.SetSource(source);
_log.SetFrameAt(frame, lg.GenerateLogEntry());
_changes = true;
2013-10-25 00:59:34 +00:00
}
#endregion
private double GetSeconds(int frameCount)
{
double frames = frameCount;
if (frames < 1)
{
return 0;
}
2014-06-14 14:04:54 +00:00
return frames / Fps;
}
2013-10-25 00:59:34 +00:00
}
}