diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
index 6240abbc74..602220cc5c 100644
--- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj
+++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
@@ -180,21 +180,8 @@
-
-
- BkmMovie.cs
-
-
- BkmMovie.cs
-
-
- BkmMovie.cs
-
-
- BkmMovie.cs
-
diff --git a/BizHawk.Client.Common/movie/bkm/BkmControllerAdapter.cs b/BizHawk.Client.Common/movie/bkm/BkmControllerAdapter.cs
index 8a1ee67237..4e87e6d1b9 100644
--- a/BizHawk.Client.Common/movie/bkm/BkmControllerAdapter.cs
+++ b/BizHawk.Client.Common/movie/bkm/BkmControllerAdapter.cs
@@ -5,7 +5,7 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
{
- public class BkmControllerAdapter : IMovieController
+ internal class BkmControllerAdapter : IController
{
#region IController Implementation
@@ -23,54 +23,6 @@ namespace BizHawk.Client.Common
#endregion
- #region IMovieController Implementation
-
- ///
- /// latches one player from the source
- ///
- public void LatchPlayerFromSource(IController playerSource, int playerNum)
- {
- foreach (var button in playerSource.Definition.BoolButtons)
- {
- var bnp = ButtonNameParser.Parse(button);
-
- if (bnp?.PlayerNum != playerNum)
- {
- continue;
- }
-
- var val = playerSource.IsPressed(button);
- _myBoolButtons[button] = val;
- }
- }
-
- ///
- /// latches all buttons from the provided source
- ///
- public void LatchFromSource(IController source)
- {
- foreach (var button in Definition.BoolButtons)
- {
- _myBoolButtons[button] = source.IsPressed(button);
- }
-
- foreach (var name in Definition.FloatControls)
- {
- _myFloatControls[name] = source.GetFloat(name);
- }
- }
-
- ///
- /// latches sticky buttons from Global.AutofireStickyXORAdapter
- ///
- public void LatchSticky()
- {
- foreach (var button in Definition.BoolButtons)
- {
- _myBoolButtons[button] = Global.AutofireStickyXORAdapter.IsSticky(button);
- }
- }
-
///
/// latches all buttons from the supplied mnemonic string
///
@@ -273,8 +225,6 @@ namespace BizHawk.Client.Common
}
}
- #endregion
-
private readonly WorkingDictionary _myBoolButtons = new WorkingDictionary();
private readonly WorkingDictionary _myFloatControls = new WorkingDictionary();
diff --git a/BizHawk.Client.Common/movie/bkm/BkmHeader.cs b/BizHawk.Client.Common/movie/bkm/BkmHeader.cs
index e33895a0e6..40afd68d62 100644
--- a/BizHawk.Client.Common/movie/bkm/BkmHeader.cs
+++ b/BizHawk.Client.Common/movie/bkm/BkmHeader.cs
@@ -3,7 +3,7 @@ using System.Text;
namespace BizHawk.Client.Common
{
- public class BkmHeader : Dictionary
+ internal class BkmHeader : Dictionary
{
public BkmHeader()
{
@@ -45,91 +45,9 @@ namespace BizHawk.Client.Common
}
}
- public ulong Rerecords
- {
- get
- {
- if (!ContainsKey(HeaderKeys.RERECORDS))
- {
- this[HeaderKeys.RERECORDS] = "0";
- }
-
- return ulong.Parse(this[HeaderKeys.RERECORDS]);
- }
-
- set
- {
- this[HeaderKeys.RERECORDS] = value.ToString();
- }
- }
-
- public bool StartsFromSavestate
- {
- get
- {
- if (ContainsKey(HeaderKeys.STARTSFROMSAVESTATE))
- {
- return bool.Parse(this[HeaderKeys.STARTSFROMSAVESTATE]);
- }
-
- return false;
- }
-
- set
- {
- if (value)
- {
- Add(HeaderKeys.STARTSFROMSAVESTATE, "True");
- }
- else
- {
- Remove(HeaderKeys.STARTSFROMSAVESTATE);
- }
- }
- }
-
- public string GameName
- {
- get
- {
- if (ContainsKey(HeaderKeys.GAMENAME))
- {
- return this[HeaderKeys.GAMENAME];
- }
-
- return "";
- }
-
- set
- {
- this[HeaderKeys.GAMENAME] = value;
- }
- }
-
- public string SystemId
- {
- get
- {
- if (ContainsKey(HeaderKeys.PLATFORM))
- {
- return this[HeaderKeys.PLATFORM];
- }
-
- return "";
- }
-
- set
- {
- this[HeaderKeys.PLATFORM] = value;
- }
- }
-
public new string this[string key]
{
- get
- {
- return ContainsKey(key) ? base[key] : "";
- }
+ get => ContainsKey(key) ? base[key] : "";
set
{
diff --git a/BizHawk.Client.Common/movie/bkm/BkmLogEntryGenerator.cs b/BizHawk.Client.Common/movie/bkm/BkmLogEntryGenerator.cs
deleted file mode 100644
index 721fdd3ae6..0000000000
--- a/BizHawk.Client.Common/movie/bkm/BkmLogEntryGenerator.cs
+++ /dev/null
@@ -1,610 +0,0 @@
-using System.Text;
-
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Client.Common
-{
- public class BkmLogEntryGenerator : ILogEntryGenerator
- {
- private IController _source;
-
- public void SetSource(IController source)
- {
- _source = source;
- _controlType = source.Definition.Name;
- }
-
- public string GenerateLogEntry()
- {
- if (_controlType == "Null Controller")
- {
- return "|.|";
- }
-
- if (_controlType == "Lynx Controller")
- {
- return GetLynxControllersAsMnemonic();
- }
-
- if (_controlType == "Atari 7800 ProLine Joystick Controller")
- {
- return GetA78ControllersAsMnemonic();
- }
-
- if (_controlType == "SNES Controller")
- {
- return GetSNESControllersAsMnemonic();
- }
-
- if (_controlType == "Commodore 64 Controller")
- {
- return GetC64ControllersAsMnemonic();
- }
-
- if (_controlType == "GBA Controller")
- {
- return GetGBAControllersAsMnemonic();
- }
-
- if (_controlType == "Dual Gameboy Controller")
- {
- return GetDualGameBoyControllerAsMnemonic();
- }
-
- if (_controlType == "WonderSwan Controller")
- {
- return GetWonderSwanControllerAsMnemonic();
- }
-
- if (_controlType == "Nintento 64 Controller")
- {
- return GetN64ControllersAsMnemonic();
- }
-
- if (_controlType == "Saturn Controller")
- {
- return GetSaturnControllersAsMnemonic();
- }
-
- if (_controlType == "PSP Controller")
- {
- return "|.|"; // TODO
- }
-
- if (_controlType == "GPGX Genesis Controller")
- {
- return GetGeneis6ButtonControllersAsMnemonic();
- }
-
- if (_controlType == "GPGX 3-Button Controller")
- {
- return GetGeneis3ButtonControllersAsMnemonic();
- }
-
- var input = new StringBuilder("|");
-
- if (_controlType == "PC Engine Controller")
- {
- input.Append(".");
- }
- else if (_controlType == "Atari 2600 Basic Controller")
- {
- input.Append(IsBasePressed("Reset") ? "r" : ".");
- input.Append(IsBasePressed("Select") ? "s" : ".");
- }
- else if (_controlType == "NES Controller")
- {
- if (IsBasePressed("Power"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Power"]);
- }
- else if (IsBasePressed("Reset"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Reset"]);
- }
- else if (IsBasePressed("FDS Eject"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["FDS Eject"]);
- }
- else if (IsBasePressed("FDS Insert 0"))
- {
- input.Append("0");
- }
- else if (IsBasePressed("FDS Insert 1"))
- {
- input.Append("1");
- }
- else if (IsBasePressed("FDS Insert 2"))
- {
- input.Append("2");
- }
- else if (IsBasePressed("FDS Insert 3"))
- {
- input.Append("3");
- }
- else if (IsBasePressed("VS Coin 1"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["VS Coin 1"]);
- }
- else if (IsBasePressed("VS Coin 2"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["VS Coin 2"]);
- }
- else
- {
- input.Append('.');
- }
- }
- else if (_controlType == "Genesis 3-Button Controller")
- {
- if (IsBasePressed("Power"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Power"]);
- }
- else if (IsBasePressed("Reset"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Reset"]);
- }
- else
- {
- input.Append('.');
- }
- }
- else if (_controlType == "Gameboy Controller")
- {
- input.Append(IsBasePressed("Power") ? BkmMnemonicConstants.Commands[_controlType]["Power"] : ".");
- }
-
- if (_controlType != "SMS Controller" && _controlType != "TI83 Controller" && _controlType != "ColecoVision Basic Controller")
- {
- input.Append("|");
- }
-
- for (int player = 1; player <= BkmMnemonicConstants.Players[_controlType]; player++)
- {
- var prefix = "";
- if (_controlType != "Gameboy Controller" && _controlType != "TI83 Controller")
- {
- prefix = $"P{player} ";
- }
-
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed(prefix + button) ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- input.Append("|");
- }
-
- if (_controlType == "SMS Controller")
- {
- foreach (var command in BkmMnemonicConstants.Commands[_controlType].Keys)
- {
- input.Append(IsBasePressed(command) ? BkmMnemonicConstants.Commands[_controlType][command] : ".");
- }
-
- input.Append("|");
- }
-
- if (_controlType == "TI83 Controller")
- {
- input.Append(".|"); // TODO: perhaps ON should go here?
- }
-
- return input.ToString();
- }
-
- public string GenerateInputDisplay()
- {
- return GenerateLogEntry()
- .Replace(".", " ")
- .Replace("|", "")
- .Replace(" 000, 000", " ");
- }
-
- public bool IsEmpty => EmptyEntry == GenerateLogEntry();
-
- public string EmptyEntry
- {
- get
- {
- switch (Global.Emulator.SystemId)
- {
- default:
- case "NULL":
- return "|.|";
- case "A26":
- return "|..|.....|.....|";
- case "A78":
- return "|....|......|......|";
- case "TI83":
- return "|..................................................|.|";
- case "NES":
- return "|.|........|........|........|........|";
- case "SNES":
- return "|.|............|............|............|............|";
- case "SMS":
- case "GG":
- case "SG":
- return "|......|......|..|";
- case "GEN":
- return "|.|........|........|";
- case "GB":
- return "|.|........|";
- case "DGB":
- return "|.|........|.|........|";
- case "PCE":
- case "PCECD":
- case "SGX":
- return "|.|........|........|........|........|........|";
- case "Coleco":
- return "|..................|..................|";
- case "C64":
- return "|.....|.....|..................................................................|";
- case "GBA":
- return "|.|..........|";
- case "N64":
- return "|.|............|............|............|............|";
- case "SAT":
- return "|.|.............|.............|";
- case "WSWAN":
- return "|...........|...........|..|";
- }
- }
- }
-
- public IMovieController MovieControllerAdapter => new BkmControllerAdapter();
-
- #region Privates
-
- private bool IsBasePressed(string name)
- {
- return _source.IsPressed(name);
- }
-
- private float GetBaseFloat(string name)
- {
- return _source.GetFloat(name);
- }
-
- private string _controlType;
-
- private string GetGBAControllersAsMnemonic()
- {
- var input = new StringBuilder("|");
- if (IsBasePressed("Power"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Power"]);
- }
- else
- {
- input.Append(".");
- }
-
- input.Append("|");
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed(button) ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- input.Append("|");
- return input.ToString();
- }
-
- private string GetSNESControllersAsMnemonic()
- {
- var input = new StringBuilder("|");
-
- if (IsBasePressed("Power"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Power"]);
- }
- else if (IsBasePressed("Reset"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Reset"]);
- }
- else
- {
- input.Append('.');
- }
-
- input.Append("|");
- for (int player = 1; player <= BkmMnemonicConstants.Players[_controlType]; player++)
- {
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed($"P{player} {button}") ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- input.Append("|");
- }
-
- return input.ToString();
- }
-
- private string GetC64ControllersAsMnemonic()
- {
- var input = new StringBuilder("|");
-
- for (int player = 1; player <= BkmMnemonicConstants.Players[_controlType]; player++)
- {
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed($"P{player} {button}") ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- input.Append('|');
- }
-
- foreach (var button in BkmMnemonicConstants.Buttons["Commodore 64 Keyboard"].Keys)
- {
- input.Append(IsBasePressed(button) ? BkmMnemonicConstants.Buttons["Commodore 64 Keyboard"][button] : ".");
- }
-
- input.Append('|');
- return input.ToString();
- }
-
- private string GetDualGameBoyControllerAsMnemonic()
- {
- // |.|........|.|........|
- var input = new StringBuilder();
-
- foreach (var t in BkmMnemonicConstants.DgbMnemonic)
- {
- if (t.Item1 != null)
- {
- input.Append(IsBasePressed(t.Item1) ? t.Item2 : '.');
- }
- else
- {
- input.Append(t.Item2); // Separator
- }
- }
-
- return input.ToString();
- }
-
- private string GetWonderSwanControllerAsMnemonic()
- {
- // |....|....|...|
- var input = new StringBuilder();
-
- foreach (var t in BkmMnemonicConstants.WsMnemonic)
- {
- if (t.Item1 != null)
- {
- input.Append(IsBasePressed(t.Item1) ? t.Item2 : '.');
- }
- else
- {
- input.Append(t.Item2); // Separator
- }
- }
-
- return input.ToString();
- }
-
- private string GetA78ControllersAsMnemonic()
- {
- var input = new StringBuilder("|");
- input.Append(IsBasePressed("Power") ? 'P' : '.');
- input.Append(IsBasePressed("Reset") ? 'r' : '.');
- input.Append(IsBasePressed("Select") ? 's' : '.');
- input.Append(IsBasePressed("Pause") ? 'p' : '.');
- input.Append('|');
-
- for (int player = 1; player <= BkmMnemonicConstants.Players[_controlType]; player++)
- {
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed($"P{player} {button}") ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- input.Append('|');
- }
-
- return input.ToString();
- }
-
- private string GetLynxControllersAsMnemonic()
- {
- var input = new StringBuilder("|");
- input.Append(IsBasePressed("Power") ? 'P' : '.');
- input.Append('|');
-
- for (int player = 1; player <= BkmMnemonicConstants.Players[_controlType]; player++)
- {
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed(button) ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- input.Append('|');
- }
-
- return input.ToString();
- }
-
- private string GetN64ControllersAsMnemonic()
- {
- var input = new StringBuilder("|");
- if (IsBasePressed("Power"))
- {
- input.Append('P');
- }
- else if (IsBasePressed("Reset"))
- {
- input.Append('r');
- }
- else
- {
- input.Append('.');
- }
-
- input.Append('|');
-
- for (int player = 1; player <= BkmMnemonicConstants.Players[_controlType]; player++)
- {
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed($"P{player} {button}") ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- if (BkmMnemonicConstants.Analogs[_controlType].Keys.Count > 0)
- {
- foreach (var name in BkmMnemonicConstants.Analogs[_controlType].Keys)
- {
- int val;
-
- // Nasty hackery
- if (name == "Y Axis")
- {
- if (IsBasePressed($"P{player} A Up"))
- {
- val = 127;
- }
- else if (IsBasePressed($"P{player} A Down"))
- {
- val = -127;
- }
- else
- {
- val = (int)GetBaseFloat($"P{player} {name}");
- }
- }
- else if (name == "X Axis")
- {
- if (IsBasePressed($"P{player} A Left"))
- {
- val = -127;
- }
- else if (IsBasePressed($"P{player} A Right"))
- {
- val = 127;
- }
- else
- {
- val = (int)GetBaseFloat($"P{player} {name}");
- }
- }
- else
- {
- val = (int)GetBaseFloat($"P{player} {name}");
- }
-
- if (val >= 0)
- {
- input.Append(' ');
- }
-
- input.Append($"{val:000}").Append(',');
- }
-
- input.Remove(input.Length - 1, 1);
- }
-
- input.Append('|');
- }
-
- return input.ToString();
- }
-
- private string GetSaturnControllersAsMnemonic()
- {
- var input = new StringBuilder("|");
- if (IsBasePressed("Power"))
- {
- input.Append('P');
- }
- else if (IsBasePressed("Reset"))
- {
- input.Append('r');
- }
- else
- {
- input.Append('.');
- }
-
- input.Append('|');
-
- for (int player = 1; player <= BkmMnemonicConstants.Players[_controlType]; player++)
- {
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed($"P{player} {button}") ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- input.Append('|');
- }
-
- return input.ToString();
- }
-
- private string GetGeneis6ButtonControllersAsMnemonic()
- {
- var input = new StringBuilder("|");
-
- if (IsBasePressed("Power"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Power"]);
- }
- else if (IsBasePressed("Reset"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Reset"]);
- }
- else
- {
- input.Append('.');
- }
-
- input.Append("|");
- for (int player = 1; player <= BkmMnemonicConstants.Players[_controlType]; player++)
- {
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed($"P{player} {button}") ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- input.Append("|");
- }
-
- input.Append("|");
- return input.ToString();
- }
-
- private string GetGeneis3ButtonControllersAsMnemonic()
- {
- var input = new StringBuilder("|");
-
- if (IsBasePressed("Power"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Power"]);
- }
- else if (IsBasePressed("Reset"))
- {
- input.Append(BkmMnemonicConstants.Commands[_controlType]["Reset"]);
- }
- else
- {
- input.Append('.');
- }
-
- input.Append("|");
- for (int player = 1; player <= BkmMnemonicConstants.Players[_controlType]; player++)
- {
- foreach (var button in BkmMnemonicConstants.Buttons[_controlType].Keys)
- {
- input.Append(IsBasePressed($"P{player} {button}") ? BkmMnemonicConstants.Buttons[_controlType][button] : ".");
- }
-
- input.Append("|");
- }
-
- input.Append("|");
- return input.ToString();
- }
-
- #endregion
- }
-}
diff --git a/BizHawk.Client.Common/movie/bkm/BkmMnemonicConstants.cs b/BizHawk.Client.Common/movie/bkm/BkmMnemonicConstants.cs
index 720050e329..078176da88 100644
--- a/BizHawk.Client.Common/movie/bkm/BkmMnemonicConstants.cs
+++ b/BizHawk.Client.Common/movie/bkm/BkmMnemonicConstants.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace BizHawk.Client.Common
{
- public static class BkmMnemonicConstants
+ internal static class BkmMnemonicConstants
{
public static readonly Dictionary> Buttons = new Dictionary>
{
diff --git a/BizHawk.Client.Common/movie/bkm/BkmMovie.HeaderApi.cs b/BizHawk.Client.Common/movie/bkm/BkmMovie.HeaderApi.cs
deleted file mode 100644
index e4329a2280..0000000000
--- a/BizHawk.Client.Common/movie/bkm/BkmMovie.HeaderApi.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System.Collections.Generic;
-
-namespace BizHawk.Client.Common
-{
- public partial class BkmMovie
- {
- public IDictionary HeaderEntries => Header;
-
- public SubtitleList Subtitles => Header.Subtitles;
-
- public IList Comments => Header.Comments;
-
- public string SyncSettingsJson
- {
- get { return Header[HeaderKeys.SYNCSETTINGS]; }
- set { Header[HeaderKeys.SYNCSETTINGS] = value; }
- }
-
- public ulong Rerecords
- {
- get { return Header.Rerecords; }
- set { Header.Rerecords = value; }
- }
-
- public bool StartsFromSavestate
- {
- get { return Header.StartsFromSavestate; }
- set { Header.StartsFromSavestate = value; }
- }
-
- // Bkm doesn't support saveram anchored movies
- public bool StartsFromSaveRam
- {
- get { return false; } set { }
- }
-
- public string GameName
- {
- get { return Header.GameName; }
- set { Header.GameName = value; }
- }
-
- public string SystemID
- {
- get { return Header.SystemId; }
- set { Header.SystemId = value; }
- }
-
- public string Hash
- {
- get { return Header[HeaderKeys.SHA1]; }
- set { Header[HeaderKeys.SHA1] = value; }
- }
-
- public string Author
- {
- get { return Header[HeaderKeys.AUTHOR]; }
- set { Header[HeaderKeys.AUTHOR] = value; }
- }
-
- public string Core
- {
- get { return Header[HeaderKeys.CORE]; }
- set { Header[HeaderKeys.CORE] = value; }
- }
-
- public string BoardName
- {
- get { return Header[HeaderKeys.BOARDNAME]; }
- set { Header[HeaderKeys.BOARDNAME] = value; }
- }
-
- public string EmulatorVersion
- {
- get { return Header[HeaderKeys.EMULATIONVERSION]; }
- set { Header[HeaderKeys.EMULATIONVERSION] = value; }
- }
-
- public string FirmwareHash
- {
- get { return Header[HeaderKeys.FIRMWARESHA1]; }
- set { Header[HeaderKeys.FIRMWARESHA1] = value; }
- }
-
- public string TextSavestate { get; set; }
- public byte[] BinarySavestate { get; set; }
- public int[] SavestateFramebuffer { get { return null; } set { } } // eat and ignore framebuffers
- public byte[] SaveRam { get { return null; } set { } } // Bkm does not support Saveram anchored movies
- }
-}
diff --git a/BizHawk.Client.Common/movie/bkm/BkmMovie.IO.cs b/BizHawk.Client.Common/movie/bkm/BkmMovie.IO.cs
deleted file mode 100644
index d296be8d35..0000000000
--- a/BizHawk.Client.Common/movie/bkm/BkmMovie.IO.cs
+++ /dev/null
@@ -1,281 +0,0 @@
-using System;
-using System.IO;
-using System.Text;
-
-using BizHawk.Common;
-
-namespace BizHawk.Client.Common
-{
- public partial class BkmMovie
- {
- private int _preloadFramecount; // Not a a reliable number, used for preloading (when no log has yet been loaded), this is only for quick stat compilation for dialogs such as play movie
-
- public void SaveAs(string path)
- {
- Filename = path;
- if (!Loaded)
- {
- return;
- }
-
- var directoryInfo = new FileInfo(Filename).Directory;
- if (directoryInfo != null)
- {
- Directory.CreateDirectory(directoryInfo.FullName);
- }
-
- Write(Filename);
- }
-
- public void Save()
- {
- if (!Loaded || string.IsNullOrWhiteSpace(Filename))
- {
- return;
- }
-
- SaveAs(Filename);
- _changes = false;
- }
-
- public void SaveBackup()
- {
- if (!Loaded || string.IsNullOrWhiteSpace(Filename))
- {
- return;
- }
-
- var backupName = Filename;
- backupName = backupName.Insert(Filename.LastIndexOf("."), $".{DateTime.Now:yyyy-MM-dd HH.mm.ss}");
- backupName = Path.Combine(Global.Config.PathEntries["Global", "Movie backups"].Path, Path.GetFileName(backupName));
-
- var directoryInfo = new FileInfo(backupName).Directory;
- if (directoryInfo != null)
- {
- Directory.CreateDirectory(directoryInfo.FullName);
- }
-
- Write(backupName);
- }
-
- public bool Load(bool preload)
- {
- var file = new FileInfo(Filename);
-
- if (file.Exists == false)
- {
- Loaded = false;
- return false;
- }
-
- Header.Clear();
- _log.Clear();
-
- using (var sr = file.OpenText())
- {
- string line;
-
- while ((line = sr.ReadLine()) != null)
- {
- if (line == "")
- {
- continue;
- }
-
- if (line.Contains("LoopOffset"))
- {
- try
- {
- _loopOffset = int.Parse(line.Split(new[] { ' ' }, 2)[1]);
- }
- catch (Exception)
- {
- continue;
- }
- }
- else if (Header.ParseLineFromFile(line))
- {
- continue;
- }
- else if (line.StartsWith("|"))
- {
- _log.Add(line);
- }
- else
- {
- Header.Comments.Add(line);
- }
- }
- }
-
- if (Header.SavestateBinaryBase64Blob != null)
- {
- BinarySavestate = Convert.FromBase64String(Header.SavestateBinaryBase64Blob);
- }
-
- Loaded = true;
- _changes = false;
- return true;
- }
-
- ///
- /// Load Header information only for displaying file information in dialogs such as play movie
- /// TODO - consider not loading the SavestateBinaryBase64Blob key?
- ///
- public bool PreLoadHeaderAndLength(HawkFile hawkFile)
- {
- Loaded = false;
- var file = new FileInfo(hawkFile.CanonicalFullPath);
-
- if (file.Exists == false)
- {
- return false;
- }
-
- Header.Clear();
- _log.Clear();
-
- var origStreamPosn = hawkFile.GetStream().Position;
- hawkFile.GetStream().Position = 0; // Reset to start
-
- // No using block because we're sharing the stream and need to give it back undisposed.
- var sr = new StreamReader(hawkFile.GetStream());
-
- for (;;)
- {
- // read to first space (key/value delimeter), or pipe, or EOF
- int first = sr.Read();
-
- if (first == -1)
- {
- break;
- } // EOF
-
- if (first == '|') // pipe: begin input log
- {
- // NOTE - this code is a bit convoluted due to its predating the basic outline of the parser which was upgraded in may 2014
- var line = '|' + sr.ReadLine();
-
- // how many bytes are left, total?
- long remain = sr.BaseStream.Length - sr.BaseStream.Position;
-
- // try to find out whether we use \r\n or \n
- // but only look for 1K characters.
- bool usesR = false;
- for (int i = 0; i < 1024; i++)
- {
- int c = sr.Read();
- if (c == -1)
- {
- break;
- }
-
- if (c == '\r')
- {
- usesR = true;
- break;
- }
-
- if (c == '\n')
- {
- break;
- }
- }
-
- int lineLen = line.Length + 1; // account for \n
- if (usesR)
- {
- lineLen++; // account for \r
- }
-
- _preloadFramecount = (int)(remain / lineLen); // length is remaining bytes / length per line
- _preloadFramecount++; // account for the current line
- break;
- }
- else
- {
- // a header line. finish reading key token, to make sure it isn't one of the FORBIDDEN keys
- var sbLine = new StringBuilder();
- sbLine.Append((char)first);
- for (;;)
- {
- int c = sr.Read();
- if (c == -1 || c == '\n' || c == ' ')
- {
- break;
- }
-
- sbLine.Append((char)c);
- }
-
- var line = sbLine.ToString();
-
- // ignore these suckers, theyre way too big for preloading. seriously, we will get out of memory errors.
- var skip = line == HeaderKeys.SAVESTATEBINARYBASE64BLOB;
-
- if (skip)
- {
- // skip remainder of the line
- sr.DiscardBufferedData();
- var stream = sr.BaseStream;
- for (;;)
- {
- int c = stream.ReadByte();
- if (c == -1 || c == '\n')
- {
- break;
- }
- }
-
- // proceed to next line
- continue;
- }
-
- var remainder = sr.ReadLine();
- sbLine.Append(' ');
- sbLine.Append(remainder);
- line = sbLine.ToString();
-
- if (string.IsNullOrWhiteSpace(line) || Header.ParseLineFromFile(line))
- {
- continue;
- }
-
- Header.Comments.Add(line);
- }
- }
-
- hawkFile.GetStream().Position = origStreamPosn;
-
- return true;
- }
-
- private void Write(string fn)
- {
- Header.SavestateBinaryBase64Blob = BinarySavestate != null
- ? Convert.ToBase64String(BinarySavestate)
- : null;
-
- using (var fs = new FileStream(fn, FileMode.Create, FileAccess.Write, FileShare.Read))
- {
- using (var sw = new StreamWriter(fs))
- {
- sw.Write(Header.ToString());
-
- // TODO: clean this up
- if (_loopOffset.HasValue)
- {
- sw.WriteLine($"LoopOffset {_loopOffset}");
- }
-
- foreach (var input in _log)
- {
- sw.WriteLine(input);
- }
- }
- }
-
- _changes = false;
- }
- }
-}
diff --git a/BizHawk.Client.Common/movie/bkm/BkmMovie.InputLog.cs b/BizHawk.Client.Common/movie/bkm/BkmMovie.InputLog.cs
deleted file mode 100644
index eb5cf0d4ad..0000000000
--- a/BizHawk.Client.Common/movie/bkm/BkmMovie.InputLog.cs
+++ /dev/null
@@ -1,291 +0,0 @@
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-
-namespace BizHawk.Client.Common
-{
- public partial class BkmMovie
- {
- private readonly List _log = new List();
-
- public void WriteInputLog(TextWriter writer)
- {
- writer.WriteLine("[Input]");
-
- foreach (var record in _log)
- {
- writer.WriteLine(record);
- }
-
- writer.WriteLine("[/Input]");
- }
-
- public string GetInputLogEntry(int frame)
- {
- if (frame < FrameCount && frame >= 0)
- {
- return _log[frame];
- }
-
- return "";
- }
-
- public bool ExtractInputLog(TextReader reader, out string errorMessage)
- {
- errorMessage = "";
- 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.Any())
- {
- SaveBackup();
- _makeBackup = false;
- }
-
- _log.Clear();
- while (true)
- {
- var line = reader.ReadLine();
- if (line == null)
- {
- break;
- }
-
- if (line.Trim() == "" || 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.Add(line);
- }
- }
- }
- else
- {
- var i = 0;
- while (true)
- {
- var line = reader.ReadLine();
- if (line == null)
- {
- break;
- }
-
- if (line.Trim() == "" || 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("|"))
- {
- 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++;
- }
-
- return true;
- }
-
- public bool CheckTimeLines(TextReader reader, out string errorMessage)
- {
- // This function will compare the movie data to the savestate movie data to see if they match
- errorMessage = "";
- var log = new List();
- var stateFrame = 0;
- while (true)
- {
- var line = reader.ReadLine();
- if (line == null)
- {
- return false;
- }
-
- if (line.Trim() == "")
- {
- 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.Add(line);
- }
- }
-
- if (stateFrame == 0)
- {
- stateFrame = log.Count; // In case the frame count failed to parse, revert to using the entire state input log
- }
-
- if (_log.Count < stateFrame)
- {
- if (IsFinished)
- {
- return true;
- }
-
- errorMessage = $"The savestate is from frame {log.Count} which is greater than the current movie length of {_log.Count}";
-
- 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.Count) // 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;
- }
- }
-}
diff --git a/BizHawk.Client.Common/movie/bkm/BkmMovie.ModeApi.cs b/BizHawk.Client.Common/movie/bkm/BkmMovie.ModeApi.cs
deleted file mode 100644
index 437ea64e68..0000000000
--- a/BizHawk.Client.Common/movie/bkm/BkmMovie.ModeApi.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System.Linq;
-
-namespace BizHawk.Client.Common
-{
- public partial class BkmMovie
- {
- private enum Moviemode
- {
- Inactive, Play, Record, Finished
- }
-
- private Moviemode _mode = Moviemode.Inactive;
-
- public bool IsPlaying => _mode == Moviemode.Play || _mode == Moviemode.Finished;
-
- public bool IsRecording => _mode == Moviemode.Record;
-
- public bool IsActive => _mode != Moviemode.Inactive;
-
- public bool IsFinished => _mode == Moviemode.Finished;
-
- public void StartNewRecording()
- {
- _mode = Moviemode.Record;
- if (Global.Config.EnableBackupMovies && _makeBackup && _log.Any())
- {
- SaveBackup();
- _makeBackup = false;
- }
-
- _log.Clear();
- }
-
- public void StartNewPlayback()
- {
- _mode = Moviemode.Play;
- }
-
- public void SwitchToRecord()
- {
- _mode = Moviemode.Record;
- }
-
- public void SwitchToPlay()
- {
- _mode = Moviemode.Play;
- Save();
- }
-
- public bool Stop(bool saveChanges = true)
- {
- bool saved = false;
- if (saveChanges)
- {
- if (_mode == Moviemode.Record || _changes)
- {
- Save();
- saved = true;
- }
- }
-
- _changes = false;
- _mode = Moviemode.Inactive;
-
- return saved;
- }
-
- public void FinishedMode()
- {
- _mode = Moviemode.Finished;
- }
- }
-}
diff --git a/BizHawk.Client.Common/movie/bkm/BkmMovie.cs b/BizHawk.Client.Common/movie/bkm/BkmMovie.cs
index 32003a7030..41d736fc14 100644
--- a/BizHawk.Client.Common/movie/bkm/BkmMovie.cs
+++ b/BizHawk.Client.Common/movie/bkm/BkmMovie.cs
@@ -1,52 +1,27 @@
-using BizHawk.Emulation.Common;
+using System;
+using System.Collections.Generic;
+using System.IO;
namespace BizHawk.Client.Common
{
- public partial class BkmMovie : IMovie
+ internal class BkmMovie
{
- private bool _makeBackup;
- private bool _changes;
+ private readonly List _log = new List();
private int? _loopOffset;
- public BkmMovie(string filename)
- : this()
- {
- Rerecords = 0;
- Filename = filename;
- Loaded = !string.IsNullOrWhiteSpace(filename);
- }
-
public BkmMovie()
{
Header = new BkmHeader { [HeaderKeys.MOVIEVERSION] = "BizHawk v0.0.1" };
- Filename = "";
- _preloadFramecount = 0;
-
- IsCountingRerecords = true;
- _mode = Moviemode.Inactive;
- _makeBackup = true;
}
- #region Properties
-
- public ILogEntryGenerator LogGeneratorInstance()
- {
- return new BkmLogEntryGenerator();
- }
-
- public string PreferredExtension => Extension;
-
- public const string Extension = "bkm";
+ public string PreferredExtension => "bkm";
public BkmHeader Header { get; }
- public string Filename { get; set; }
- public bool IsCountingRerecords { get; set; }
+ public string Filename { get; set; } = "";
public bool Loaded { get; private set; }
public int InputLogLength => _log.Count;
- public int TimeLength => _log.Count;
-
public double FrameCount
{
get
@@ -61,114 +36,115 @@ namespace BizHawk.Client.Common
return _log.Count;
}
- return _preloadFramecount;
+ return 0;
}
}
- public bool Changes => _changes;
-
- #endregion
-
- #region Public Log Editing
-
- public IController GetInputState(int frame)
+ public BkmControllerAdapter GetInputState(int frame)
{
if (frame < FrameCount && frame >= 0)
{
- int getframe;
+ int getFrame;
if (_loopOffset.HasValue)
{
if (frame < _log.Count)
{
- getframe = frame;
+ getFrame = frame;
}
else
{
- getframe = ((frame - _loopOffset.Value) % (_log.Count - _loopOffset.Value)) + _loopOffset.Value;
+ getFrame = ((frame - _loopOffset.Value) % (_log.Count - _loopOffset.Value)) + _loopOffset.Value;
}
}
else
{
- getframe = frame;
+ getFrame = frame;
}
var adapter = new BkmControllerAdapter
{
Definition = Global.MovieSession.MovieControllerAdapter.Definition
};
- adapter.SetControllersAsMnemonic(_log[getframe]);
+ adapter.SetControllersAsMnemonic(_log[getFrame]);
return adapter;
}
return null;
}
- public void ClearFrame(int frame)
+ public IDictionary HeaderEntries => Header;
+
+ public SubtitleList Subtitles => Header.Subtitles;
+
+ public IList Comments => Header.Comments;
+
+ public string SyncSettingsJson
{
- var lg = LogGeneratorInstance();
- SetFrameAt(frame, lg.EmptyEntry);
- _changes = true;
+ get => Header[HeaderKeys.SYNCSETTINGS];
+ set => Header[HeaderKeys.SYNCSETTINGS] = value;
}
- public void AppendFrame(IController source)
- {
- var lg = LogGeneratorInstance();
- lg.SetSource(source);
- _log.Add(lg.GenerateLogEntry());
- _changes = true;
- }
+ public string TextSavestate { get; set; }
+ public byte[] BinarySavestate { get; set; }
- public void Truncate(int frame)
+ public bool Load()
{
- if (frame < _log.Count)
+ var file = new FileInfo(Filename);
+
+ if (file.Exists == false)
{
- _log.RemoveRange(frame, _log.Count - frame);
- _changes = true;
+ Loaded = false;
+ return false;
}
- }
- public void PokeFrame(int frame, IController source)
- {
- var lg = LogGeneratorInstance();
- lg.SetSource(source);
+ Header.Clear();
+ _log.Clear();
- _changes = true;
- SetFrameAt(frame, lg.GenerateLogEntry());
- }
-
- public void RecordFrame(int frame, IController source)
- {
- // 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"
- if (Global.Config.VBAStyleMovieLoadState)
+ using (var sr = file.OpenText())
{
- if (Global.Emulator.Frame < _log.Count)
+ string line;
+
+ while ((line = sr.ReadLine()) != null)
{
- Truncate(Global.Emulator.Frame);
+ if (line == "")
+ {
+ continue;
+ }
+
+ if (line.Contains("LoopOffset"))
+ {
+ try
+ {
+ _loopOffset = int.Parse(line.Split(new[] { ' ' }, 2)[1]);
+ }
+ catch (Exception)
+ {
+ continue;
+ }
+ }
+ else if (Header.ParseLineFromFile(line))
+ {
+ continue;
+ }
+ else if (line.StartsWith("|"))
+ {
+ _log.Add(line);
+ }
+ else
+ {
+ Header.Comments.Add(line);
+ }
}
}
- var lg = LogGeneratorInstance();
- lg.SetSource(source);
- SetFrameAt(frame, lg.GenerateLogEntry());
-
- _changes = true;
- }
-
- #endregion
-
- private void SetFrameAt(int frameNum, string frame)
- {
- if (_log.Count > frameNum)
+ if (Header.SavestateBinaryBase64Blob != null)
{
- _log[frameNum] = frame;
- }
- else
- {
- _log.Add(frame);
+ BinarySavestate = Convert.FromBase64String(Header.SavestateBinaryBase64Blob);
}
+
+ Loaded = true;
+ return true;
}
}
}
\ No newline at end of file
diff --git a/BizHawk.Client.Common/movie/import/BkmImport.cs b/BizHawk.Client.Common/movie/import/BkmImport.cs
index ac1fb715cc..8c51cf7ea4 100644
--- a/BizHawk.Client.Common/movie/import/BkmImport.cs
+++ b/BizHawk.Client.Common/movie/import/BkmImport.cs
@@ -13,8 +13,46 @@ namespace BizHawk.Client.Common.movie.import
Filename = SourceFile.FullName
};
- movie.Load(false);
- Result.Movie = movie.ToBk2();
+ movie.Load();
+ Result.Movie = ToBk2(movie);
+ }
+
+ public static Bk2Movie ToBk2(BkmMovie old)
+ {
+ var bk2 = new Bk2Movie(old.Filename.Replace(old.PreferredExtension, Bk2Movie.Extension));
+
+ for (var i = 0; i < old.InputLogLength; i++)
+ {
+ var input = old.GetInputState(i);
+ bk2.AppendFrame(input);
+ }
+
+ bk2.HeaderEntries.Clear();
+ foreach (var kvp in old.HeaderEntries)
+ {
+ bk2.HeaderEntries[kvp.Key] = kvp.Value;
+ }
+
+ bk2.SyncSettingsJson = old.SyncSettingsJson;
+
+ bk2.Comments.Clear();
+ foreach (var comment in old.Comments)
+ {
+ bk2.Comments.Add(comment);
+ }
+
+ bk2.Subtitles.Clear();
+ foreach (var sub in old.Subtitles)
+ {
+ bk2.Subtitles.Add(sub);
+ }
+
+ bk2.TextSavestate = old.TextSavestate;
+ bk2.BinarySavestate = old.BinarySavestate;
+
+ bk2.Save();
+
+ return bk2;
}
}
}