diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index 99ff3d0770..9fb96e3b70 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -208,10 +208,10 @@ Bk2Movie.cs - - - - + + + + diff --git a/BizHawk.Client.Common/movie/bkm/BkmControllerAdapter.cs b/BizHawk.Client.Common/movie/import/bkm/BkmControllerAdapter.cs similarity index 95% rename from BizHawk.Client.Common/movie/bkm/BkmControllerAdapter.cs rename to BizHawk.Client.Common/movie/import/bkm/BkmControllerAdapter.cs index 504db375b5..c729276ca5 100644 --- a/BizHawk.Client.Common/movie/bkm/BkmControllerAdapter.cs +++ b/BizHawk.Client.Common/movie/import/bkm/BkmControllerAdapter.cs @@ -1,632 +1,632 @@ -using System; - -using BizHawk.Common; -using BizHawk.Emulation.Common; - -namespace BizHawk.Client.Common -{ - internal class BkmControllerAdapter : IController - { - #region IController Implementation - - public ControllerDefinition Definition { get; set; } - - public bool IsPressed(string button) - { - return _myBoolButtons[button]; - } - - public float GetFloat(string name) - { - return _myFloatControls[name]; - } - - #endregion - - /// - /// latches all buttons from the supplied mnemonic string - /// - public void SetControllersAsMnemonic(string mnemonic) - { - if (ControlType == "Null Controller") - { - return; - } - - if (ControlType == "Lynx Controller") - { - SetLynxControllersAsMnemonic(mnemonic); - return; - } - - if (ControlType == "SNES Controller") - { - SetSNESControllersAsMnemonic(mnemonic); - return; - } - - if (ControlType == "Commodore 64 Controller") - { - SetC64ControllersAsMnemonic(mnemonic); - return; - } - - if (ControlType == "GBA Controller") - { - SetGBAControllersAsMnemonic(mnemonic); - return; - } - - if (ControlType == "Atari 7800 ProLine Joystick Controller") - { - SetAtari7800AsMnemonic(mnemonic); - return; - } - - if (ControlType == "Dual Gameboy Controller") - { - SetDualGameBoyControllerAsMnemonic(mnemonic); - return; - } - - if (ControlType == "WonderSwan Controller") - { - SetWonderSwanControllerAsMnemonic(mnemonic); - return; - } - - if (ControlType == "Nintendo 64 Controller") - { - SetN64ControllersAsMnemonic(mnemonic); - return; - } - - if (ControlType == "Saturn Controller") - { - SetSaturnControllersAsMnemonic(mnemonic); - return; - } - - if (ControlType == "PSP Controller") - { - // TODO - return; - } - - if (ControlType == "GPGX Genesis Controller") - { - if (IsGenesis6Button()) - { - SetGenesis6ControllersAsMnemonic(mnemonic); - } - else - { - SetGenesis3ControllersAsMnemonic(mnemonic); - } - - return; - } - - var c = new MnemonicChecker(mnemonic); - - _myBoolButtons.Clear(); - - int start = 3; - if (ControlType == "NES Controller") - { - if (mnemonic.Length < 2) - { - return; - } - else if (mnemonic[1] == 'P') - { - Force("Power", true); - } - else if (mnemonic[1] == 'E') - { - Force("FDS Eject", true); - } - else if (mnemonic[1] == '0') - { - Force("FDS Insert 0", true); - } - else if (mnemonic[1] == '1') - { - Force("FDS Insert 1", true); - } - else if (mnemonic[1] == '2') - { - Force("FDS Insert 2", true); - } - else if (mnemonic[1] == '3') - { - Force("FDS Insert 3", true); - } - else if (mnemonic[1] == 'c') - { - Force("VS Coin 1", true); - } - else if (mnemonic[1] == 'C') - { - Force("VS Coin 2", true); - } - else if (mnemonic[1] != '.') - { - Force("Reset", true); - } - } - - if (ControlType == "Gameboy Controller") - { - if (mnemonic.Length < 2) - { - return; - } - - Force("Power", mnemonic[1] != '.'); - } - - if (ControlType == "Genesis 3-Button Controller") - { - if (mnemonic.Length < 2) - { - return; - } - - Force("Reset", mnemonic[1] != '.'); - } - - if (ControlType == "SMS Controller" || ControlType == "TI83 Controller" || ControlType == "ColecoVision Basic Controller") - { - start = 1; - } - - if (ControlType == "Atari 2600 Basic Controller") - { - if (mnemonic.Length < 2) - { - return; - } - - Force("Reset", mnemonic[1] != '.' && mnemonic[1] != '0'); - Force("Select", mnemonic[2] != '.' && mnemonic[2] != '0'); - start = 4; - } - - for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) - { - int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); - int ctr = start; - if (mnemonic.Length < srcindex + ctr + BkmMnemonicConstants.Buttons[ControlType].Count - 1) - { - return; - } - - string prefix = ""; - if (ControlType != "Gameboy Controller" && ControlType != "TI83 Controller") - { - prefix = $"P{player} "; - } - - foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) - { - Force(prefix + button, c[srcindex + ctr++]); - } - } - - if (ControlType == "SMS Controller") - { - int srcindex = BkmMnemonicConstants.Players[ControlType] * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); - int ctr = start; - foreach (var command in BkmMnemonicConstants.Commands[ControlType].Keys) - { - Force(command, c[srcindex + ctr++]); - } - } - } - - private readonly WorkingDictionary _myBoolButtons = new WorkingDictionary(); - private readonly WorkingDictionary _myFloatControls = new WorkingDictionary(); - - private bool IsGenesis6Button() - { - return Definition.BoolButtons.Contains("P1 X"); - } - - private void Force(string button, bool state) - { - _myBoolButtons[button] = state; - } - - private void Force(string name, float state) - { - _myFloatControls[name] = state; - } - - private string ControlType => Definition.Name; - - private void SetGBAControllersAsMnemonic(string mnemonic) - { - MnemonicChecker c = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - if (mnemonic.Length < 2) - { - return; - } - - if (mnemonic[1] == 'P') - { - Force("Power", true); - } - - int start = 3; - foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) - { - Force(button, c[start++]); - } - } - - private void SetGenesis6ControllersAsMnemonic(string mnemonic) - { - MnemonicChecker c = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - - if (mnemonic.Length < 2) - { - return; - } - - if (mnemonic[1] == 'P') - { - Force("Power", true); - } - else if (mnemonic[1] != '.' && mnemonic[1] != '0') - { - Force("Reset", true); - } - - if (mnemonic.Length < 9) - { - return; - } - - for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) - { - int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); - - if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) - { - return; - } - - int start = 3; - foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) - { - Force($"P{player} {button}", c[srcindex + start++]); - } - } - } - - private void SetGenesis3ControllersAsMnemonic(string mnemonic) - { - MnemonicChecker c = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - - if (mnemonic.Length < 2) - { - return; - } - - if (mnemonic[1] == 'P') - { - Force("Power", true); - } - else if (mnemonic[1] != '.' && mnemonic[1] != '0') - { - Force("Reset", true); - } - - if (mnemonic.Length < 9) - { - return; - } - - for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) - { - int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons["GPGX 3-Button Controller"].Count + 1); - - if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons["GPGX 3-Button Controller"].Count - 1) - { - return; - } - - int start = 3; - foreach (string button in BkmMnemonicConstants.Buttons["GPGX 3-Button Controller"].Keys) - { - Force($"P{player} {button}", c[srcindex + start++]); - } - } - } - - private void SetSNESControllersAsMnemonic(string mnemonic) - { - var c = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - - if (mnemonic.Length < 2) - { - return; - } - - if (mnemonic[1] == 'P') - { - Force("Power", true); - } - else if (mnemonic[1] != '.' && mnemonic[1] != '0') - { - Force("Reset", true); - } - - for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) - { - int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); - - if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) - { - return; - } - - int start = 3; - foreach (var button in BkmMnemonicConstants.Buttons[ControlType].Keys) - { - Force($"P{player} {button}", c[srcindex + start++]); - } - } - } - - private void SetLynxControllersAsMnemonic(string mnemonic) - { - var c = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - - if (mnemonic.Length < 2) - { - return; - } - - if (mnemonic[1] == 'P') - { - Force("Power", true); - } - - for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) - { - int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); - - if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) - { - return; - } - - int start = 3; - foreach (var button in BkmMnemonicConstants.Buttons[ControlType].Keys) - { - Force(button, c[srcindex + start++]); - } - } - } - - private void SetN64ControllersAsMnemonic(string mnemonic) - { - MnemonicChecker c = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - - if (mnemonic.Length < 2) - { - return; - } - - if (mnemonic[1] == 'P') - { - Force("Power", true); - } - else if (mnemonic[1] != '.' && mnemonic[1] != '0') - { - Force("Reset", true); - } - - for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) - { - int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + (BkmMnemonicConstants.Analogs[ControlType].Count * 4) + 1 + 1); - - if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) - { - return; - } - - int start = 3; - foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) - { - Force($"P{player} {button}", c[srcindex + start++]); - } - - foreach (string name in BkmMnemonicConstants.Analogs[ControlType].Keys) - { - Force($"P{player} {name}", int.Parse(mnemonic.Substring(srcindex + start, 4))); - start += 5; - } - } - } - - private void SetSaturnControllersAsMnemonic(string mnemonic) - { - MnemonicChecker c = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - - if (mnemonic.Length < 2) - { - return; - } - - if (mnemonic[1] == 'P') - { - Force("Power", true); - } - else if (mnemonic[1] != '.' && mnemonic[1] != '0') - { - Force("Reset", true); - } - - for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) - { - int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); - - if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) - { - return; - } - - int start = 3; - foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) - { - Force($"P{player} {button}", c[srcindex + start++]); - } - } - } - - private void SetAtari7800AsMnemonic(string mnemonic) - { - MnemonicChecker c = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - - if (mnemonic.Length < 5) - { - return; - } - - if (mnemonic[1] == 'P') - { - Force("Power", true); - } - - if (mnemonic[2] == 'r') - { - Force("Reset", true); - } - - if (mnemonic[3] == 's') - { - Force("Select", true); - } - - if (mnemonic[4] == 'p') - { - Force("Pause", true); - } - - for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) - { - int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); - int start = 6; - if (mnemonic.Length < srcindex + start + BkmMnemonicConstants.Buttons[ControlType].Count) - { - return; - } - - foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) - { - Force($"P{player} {button}", c[srcindex + start++]); - } - } - } - - private void SetDualGameBoyControllerAsMnemonic(string mnemonic) - { - var checker = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - for (int i = 0; i < BkmMnemonicConstants.DgbMnemonic.Length; i++) - { - var t = BkmMnemonicConstants.DgbMnemonic[i]; - if (t.Item1 != null) - { - Force(t.Item1, checker[i]); - } - } - } - - private void SetWonderSwanControllerAsMnemonic(string mnemonic) - { - var checker = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - for (int i = 0; i < BkmMnemonicConstants.WsMnemonic.Length; i++) - { - var t = BkmMnemonicConstants.WsMnemonic[i]; - if (t.Item1 != null) - { - Force(t.Item1, checker[i]); - } - } - } - - private void SetC64ControllersAsMnemonic(string mnemonic) - { - var c = new MnemonicChecker(mnemonic); - _myBoolButtons.Clear(); - - for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) - { - int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); - - if (mnemonic.Length < srcindex + 1 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) - { - return; - } - - int start = 1; - foreach (var button in BkmMnemonicConstants.Buttons[ControlType].Keys) - { - Force($"P{player} {button}", c[srcindex + start++]); - } - } - - int startk = 13; - foreach (string button in BkmMnemonicConstants.Buttons["Commodore 64 Keyboard"].Keys) - { - Force(button, c[startk++]); - } - } - - private sealed class MnemonicChecker - { - private readonly string _mnemonic; - - public MnemonicChecker(string mnemonic) - { - _mnemonic = mnemonic; - } - - public bool this[int c] - { - get - { - if (string.IsNullOrEmpty(_mnemonic)) - { - return false; - } - - if (_mnemonic[c] == '.') - { - return false; - } - - if (_mnemonic[c] == '?') - { - return new Random((int)DateTime.Now.Ticks).Next(0, 10) > 5; - } - - return true; - } - } - } - } -} +using System; + +using BizHawk.Common; +using BizHawk.Emulation.Common; + +namespace BizHawk.Client.Common +{ + internal class BkmControllerAdapter : IController + { + #region IController Implementation + + public ControllerDefinition Definition { get; set; } + + public bool IsPressed(string button) + { + return _myBoolButtons[button]; + } + + public float GetFloat(string name) + { + return _myFloatControls[name]; + } + + #endregion + + /// + /// latches all buttons from the supplied mnemonic string + /// + public void SetControllersAsMnemonic(string mnemonic) + { + if (ControlType == "Null Controller") + { + return; + } + + if (ControlType == "Lynx Controller") + { + SetLynxControllersAsMnemonic(mnemonic); + return; + } + + if (ControlType == "SNES Controller") + { + SetSNESControllersAsMnemonic(mnemonic); + return; + } + + if (ControlType == "Commodore 64 Controller") + { + SetC64ControllersAsMnemonic(mnemonic); + return; + } + + if (ControlType == "GBA Controller") + { + SetGBAControllersAsMnemonic(mnemonic); + return; + } + + if (ControlType == "Atari 7800 ProLine Joystick Controller") + { + SetAtari7800AsMnemonic(mnemonic); + return; + } + + if (ControlType == "Dual Gameboy Controller") + { + SetDualGameBoyControllerAsMnemonic(mnemonic); + return; + } + + if (ControlType == "WonderSwan Controller") + { + SetWonderSwanControllerAsMnemonic(mnemonic); + return; + } + + if (ControlType == "Nintendo 64 Controller") + { + SetN64ControllersAsMnemonic(mnemonic); + return; + } + + if (ControlType == "Saturn Controller") + { + SetSaturnControllersAsMnemonic(mnemonic); + return; + } + + if (ControlType == "PSP Controller") + { + // TODO + return; + } + + if (ControlType == "GPGX Genesis Controller") + { + if (IsGenesis6Button()) + { + SetGenesis6ControllersAsMnemonic(mnemonic); + } + else + { + SetGenesis3ControllersAsMnemonic(mnemonic); + } + + return; + } + + var c = new MnemonicChecker(mnemonic); + + _myBoolButtons.Clear(); + + int start = 3; + if (ControlType == "NES Controller") + { + if (mnemonic.Length < 2) + { + return; + } + else if (mnemonic[1] == 'P') + { + Force("Power", true); + } + else if (mnemonic[1] == 'E') + { + Force("FDS Eject", true); + } + else if (mnemonic[1] == '0') + { + Force("FDS Insert 0", true); + } + else if (mnemonic[1] == '1') + { + Force("FDS Insert 1", true); + } + else if (mnemonic[1] == '2') + { + Force("FDS Insert 2", true); + } + else if (mnemonic[1] == '3') + { + Force("FDS Insert 3", true); + } + else if (mnemonic[1] == 'c') + { + Force("VS Coin 1", true); + } + else if (mnemonic[1] == 'C') + { + Force("VS Coin 2", true); + } + else if (mnemonic[1] != '.') + { + Force("Reset", true); + } + } + + if (ControlType == "Gameboy Controller") + { + if (mnemonic.Length < 2) + { + return; + } + + Force("Power", mnemonic[1] != '.'); + } + + if (ControlType == "Genesis 3-Button Controller") + { + if (mnemonic.Length < 2) + { + return; + } + + Force("Reset", mnemonic[1] != '.'); + } + + if (ControlType == "SMS Controller" || ControlType == "TI83 Controller" || ControlType == "ColecoVision Basic Controller") + { + start = 1; + } + + if (ControlType == "Atari 2600 Basic Controller") + { + if (mnemonic.Length < 2) + { + return; + } + + Force("Reset", mnemonic[1] != '.' && mnemonic[1] != '0'); + Force("Select", mnemonic[2] != '.' && mnemonic[2] != '0'); + start = 4; + } + + for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) + { + int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); + int ctr = start; + if (mnemonic.Length < srcindex + ctr + BkmMnemonicConstants.Buttons[ControlType].Count - 1) + { + return; + } + + string prefix = ""; + if (ControlType != "Gameboy Controller" && ControlType != "TI83 Controller") + { + prefix = $"P{player} "; + } + + foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) + { + Force(prefix + button, c[srcindex + ctr++]); + } + } + + if (ControlType == "SMS Controller") + { + int srcindex = BkmMnemonicConstants.Players[ControlType] * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); + int ctr = start; + foreach (var command in BkmMnemonicConstants.Commands[ControlType].Keys) + { + Force(command, c[srcindex + ctr++]); + } + } + } + + private readonly WorkingDictionary _myBoolButtons = new WorkingDictionary(); + private readonly WorkingDictionary _myFloatControls = new WorkingDictionary(); + + private bool IsGenesis6Button() + { + return Definition.BoolButtons.Contains("P1 X"); + } + + private void Force(string button, bool state) + { + _myBoolButtons[button] = state; + } + + private void Force(string name, float state) + { + _myFloatControls[name] = state; + } + + private string ControlType => Definition.Name; + + private void SetGBAControllersAsMnemonic(string mnemonic) + { + MnemonicChecker c = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + if (mnemonic.Length < 2) + { + return; + } + + if (mnemonic[1] == 'P') + { + Force("Power", true); + } + + int start = 3; + foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) + { + Force(button, c[start++]); + } + } + + private void SetGenesis6ControllersAsMnemonic(string mnemonic) + { + MnemonicChecker c = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + + if (mnemonic.Length < 2) + { + return; + } + + if (mnemonic[1] == 'P') + { + Force("Power", true); + } + else if (mnemonic[1] != '.' && mnemonic[1] != '0') + { + Force("Reset", true); + } + + if (mnemonic.Length < 9) + { + return; + } + + for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) + { + int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); + + if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) + { + return; + } + + int start = 3; + foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) + { + Force($"P{player} {button}", c[srcindex + start++]); + } + } + } + + private void SetGenesis3ControllersAsMnemonic(string mnemonic) + { + MnemonicChecker c = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + + if (mnemonic.Length < 2) + { + return; + } + + if (mnemonic[1] == 'P') + { + Force("Power", true); + } + else if (mnemonic[1] != '.' && mnemonic[1] != '0') + { + Force("Reset", true); + } + + if (mnemonic.Length < 9) + { + return; + } + + for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) + { + int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons["GPGX 3-Button Controller"].Count + 1); + + if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons["GPGX 3-Button Controller"].Count - 1) + { + return; + } + + int start = 3; + foreach (string button in BkmMnemonicConstants.Buttons["GPGX 3-Button Controller"].Keys) + { + Force($"P{player} {button}", c[srcindex + start++]); + } + } + } + + private void SetSNESControllersAsMnemonic(string mnemonic) + { + var c = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + + if (mnemonic.Length < 2) + { + return; + } + + if (mnemonic[1] == 'P') + { + Force("Power", true); + } + else if (mnemonic[1] != '.' && mnemonic[1] != '0') + { + Force("Reset", true); + } + + for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) + { + int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); + + if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) + { + return; + } + + int start = 3; + foreach (var button in BkmMnemonicConstants.Buttons[ControlType].Keys) + { + Force($"P{player} {button}", c[srcindex + start++]); + } + } + } + + private void SetLynxControllersAsMnemonic(string mnemonic) + { + var c = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + + if (mnemonic.Length < 2) + { + return; + } + + if (mnemonic[1] == 'P') + { + Force("Power", true); + } + + for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) + { + int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); + + if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) + { + return; + } + + int start = 3; + foreach (var button in BkmMnemonicConstants.Buttons[ControlType].Keys) + { + Force(button, c[srcindex + start++]); + } + } + } + + private void SetN64ControllersAsMnemonic(string mnemonic) + { + MnemonicChecker c = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + + if (mnemonic.Length < 2) + { + return; + } + + if (mnemonic[1] == 'P') + { + Force("Power", true); + } + else if (mnemonic[1] != '.' && mnemonic[1] != '0') + { + Force("Reset", true); + } + + for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) + { + int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + (BkmMnemonicConstants.Analogs[ControlType].Count * 4) + 1 + 1); + + if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) + { + return; + } + + int start = 3; + foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) + { + Force($"P{player} {button}", c[srcindex + start++]); + } + + foreach (string name in BkmMnemonicConstants.Analogs[ControlType].Keys) + { + Force($"P{player} {name}", int.Parse(mnemonic.Substring(srcindex + start, 4))); + start += 5; + } + } + } + + private void SetSaturnControllersAsMnemonic(string mnemonic) + { + MnemonicChecker c = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + + if (mnemonic.Length < 2) + { + return; + } + + if (mnemonic[1] == 'P') + { + Force("Power", true); + } + else if (mnemonic[1] != '.' && mnemonic[1] != '0') + { + Force("Reset", true); + } + + for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) + { + int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); + + if (mnemonic.Length < srcindex + 3 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) + { + return; + } + + int start = 3; + foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) + { + Force($"P{player} {button}", c[srcindex + start++]); + } + } + } + + private void SetAtari7800AsMnemonic(string mnemonic) + { + MnemonicChecker c = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + + if (mnemonic.Length < 5) + { + return; + } + + if (mnemonic[1] == 'P') + { + Force("Power", true); + } + + if (mnemonic[2] == 'r') + { + Force("Reset", true); + } + + if (mnemonic[3] == 's') + { + Force("Select", true); + } + + if (mnemonic[4] == 'p') + { + Force("Pause", true); + } + + for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) + { + int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); + int start = 6; + if (mnemonic.Length < srcindex + start + BkmMnemonicConstants.Buttons[ControlType].Count) + { + return; + } + + foreach (string button in BkmMnemonicConstants.Buttons[ControlType].Keys) + { + Force($"P{player} {button}", c[srcindex + start++]); + } + } + } + + private void SetDualGameBoyControllerAsMnemonic(string mnemonic) + { + var checker = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + for (int i = 0; i < BkmMnemonicConstants.DgbMnemonic.Length; i++) + { + var t = BkmMnemonicConstants.DgbMnemonic[i]; + if (t.Item1 != null) + { + Force(t.Item1, checker[i]); + } + } + } + + private void SetWonderSwanControllerAsMnemonic(string mnemonic) + { + var checker = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + for (int i = 0; i < BkmMnemonicConstants.WsMnemonic.Length; i++) + { + var t = BkmMnemonicConstants.WsMnemonic[i]; + if (t.Item1 != null) + { + Force(t.Item1, checker[i]); + } + } + } + + private void SetC64ControllersAsMnemonic(string mnemonic) + { + var c = new MnemonicChecker(mnemonic); + _myBoolButtons.Clear(); + + for (int player = 1; player <= BkmMnemonicConstants.Players[ControlType]; player++) + { + int srcindex = (player - 1) * (BkmMnemonicConstants.Buttons[ControlType].Count + 1); + + if (mnemonic.Length < srcindex + 1 + BkmMnemonicConstants.Buttons[ControlType].Count - 1) + { + return; + } + + int start = 1; + foreach (var button in BkmMnemonicConstants.Buttons[ControlType].Keys) + { + Force($"P{player} {button}", c[srcindex + start++]); + } + } + + int startk = 13; + foreach (string button in BkmMnemonicConstants.Buttons["Commodore 64 Keyboard"].Keys) + { + Force(button, c[startk++]); + } + } + + private sealed class MnemonicChecker + { + private readonly string _mnemonic; + + public MnemonicChecker(string mnemonic) + { + _mnemonic = mnemonic; + } + + public bool this[int c] + { + get + { + if (string.IsNullOrEmpty(_mnemonic)) + { + return false; + } + + if (_mnemonic[c] == '.') + { + return false; + } + + if (_mnemonic[c] == '?') + { + return new Random((int)DateTime.Now.Ticks).Next(0, 10) > 5; + } + + return true; + } + } + } + } +} diff --git a/BizHawk.Client.Common/movie/bkm/BkmHeader.cs b/BizHawk.Client.Common/movie/import/bkm/BkmHeader.cs similarity index 94% rename from BizHawk.Client.Common/movie/bkm/BkmHeader.cs rename to BizHawk.Client.Common/movie/import/bkm/BkmHeader.cs index 40afd68d62..001fdf65bb 100644 --- a/BizHawk.Client.Common/movie/bkm/BkmHeader.cs +++ b/BizHawk.Client.Common/movie/import/bkm/BkmHeader.cs @@ -1,118 +1,118 @@ -using System.Collections.Generic; -using System.Text; - -namespace BizHawk.Client.Common -{ - internal class BkmHeader : Dictionary - { - public BkmHeader() - { - Comments = new List(); - Subtitles = new SubtitleList(); - - this[HeaderKeys.EMULATIONVERSION] = VersionInfo.GetEmuVersion(); - this[HeaderKeys.PLATFORM] = Global.Emulator != null ? Global.Emulator.SystemId : ""; - this[HeaderKeys.GAMENAME] = ""; - this[HeaderKeys.AUTHOR] = ""; - this[HeaderKeys.RERECORDS] = "0"; - } - - public List Comments { get; } - public SubtitleList Subtitles { get; } - - public string SavestateBinaryBase64Blob - { - get - { - if (ContainsKey(HeaderKeys.SAVESTATEBINARYBASE64BLOB)) - { - return this[HeaderKeys.SAVESTATEBINARYBASE64BLOB]; - } - - return null; - } - - set - { - if (value == null) - { - Remove(HeaderKeys.SAVESTATEBINARYBASE64BLOB); - } - else - { - Add(HeaderKeys.SAVESTATEBINARYBASE64BLOB, value); - } - } - } - - public new string this[string key] - { - get => ContainsKey(key) ? base[key] : ""; - - set - { - if (ContainsKey(key)) - { - base[key] = value; - } - else - { - Add(key, value); - } - } - } - - public new void Clear() - { - Comments.Clear(); - Subtitles.Clear(); - base.Clear(); - } - - public override string ToString() - { - var sb = new StringBuilder(); - - foreach (var kvp in this) - { - sb - .Append(kvp.Key) - .Append(' ') - .Append(kvp.Value) - .AppendLine(); - } - - sb.Append(Subtitles); - Comments.ForEach(comment => sb.AppendLine(comment)); - - return sb.ToString(); - } - - public bool ParseLineFromFile(string line) - { - if (!string.IsNullOrWhiteSpace(line)) - { - var splitLine = line.Split(new[] { ' ' }, 2); - - if (HeaderKeys.Contains(splitLine[0]) && !ContainsKey(splitLine[0])) - { - Add(splitLine[0], splitLine[1]); - } - else if (line.StartsWith("subtitle") || line.StartsWith("sub")) - { - Subtitles.AddFromString(line); - } - else if (line.StartsWith("comment")) - { - Comments.Add(line.Substring(8, line.Length - 8)); - } - else if (line.StartsWith("|")) - { - return false; - } - } - - return true; - } - } -} +using System.Collections.Generic; +using System.Text; + +namespace BizHawk.Client.Common +{ + internal class BkmHeader : Dictionary + { + public BkmHeader() + { + Comments = new List(); + Subtitles = new SubtitleList(); + + this[HeaderKeys.EMULATIONVERSION] = VersionInfo.GetEmuVersion(); + this[HeaderKeys.PLATFORM] = Global.Emulator != null ? Global.Emulator.SystemId : ""; + this[HeaderKeys.GAMENAME] = ""; + this[HeaderKeys.AUTHOR] = ""; + this[HeaderKeys.RERECORDS] = "0"; + } + + public List Comments { get; } + public SubtitleList Subtitles { get; } + + public string SavestateBinaryBase64Blob + { + get + { + if (ContainsKey(HeaderKeys.SAVESTATEBINARYBASE64BLOB)) + { + return this[HeaderKeys.SAVESTATEBINARYBASE64BLOB]; + } + + return null; + } + + set + { + if (value == null) + { + Remove(HeaderKeys.SAVESTATEBINARYBASE64BLOB); + } + else + { + Add(HeaderKeys.SAVESTATEBINARYBASE64BLOB, value); + } + } + } + + public new string this[string key] + { + get => ContainsKey(key) ? base[key] : ""; + + set + { + if (ContainsKey(key)) + { + base[key] = value; + } + else + { + Add(key, value); + } + } + } + + public new void Clear() + { + Comments.Clear(); + Subtitles.Clear(); + base.Clear(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + + foreach (var kvp in this) + { + sb + .Append(kvp.Key) + .Append(' ') + .Append(kvp.Value) + .AppendLine(); + } + + sb.Append(Subtitles); + Comments.ForEach(comment => sb.AppendLine(comment)); + + return sb.ToString(); + } + + public bool ParseLineFromFile(string line) + { + if (!string.IsNullOrWhiteSpace(line)) + { + var splitLine = line.Split(new[] { ' ' }, 2); + + if (HeaderKeys.Contains(splitLine[0]) && !ContainsKey(splitLine[0])) + { + Add(splitLine[0], splitLine[1]); + } + else if (line.StartsWith("subtitle") || line.StartsWith("sub")) + { + Subtitles.AddFromString(line); + } + else if (line.StartsWith("comment")) + { + Comments.Add(line.Substring(8, line.Length - 8)); + } + else if (line.StartsWith("|")) + { + return false; + } + } + + return true; + } + } +} diff --git a/BizHawk.Client.Common/movie/bkm/BkmMnemonicConstants.cs b/BizHawk.Client.Common/movie/import/bkm/BkmMnemonicConstants.cs similarity index 97% rename from BizHawk.Client.Common/movie/bkm/BkmMnemonicConstants.cs rename to BizHawk.Client.Common/movie/import/bkm/BkmMnemonicConstants.cs index 24c28b26a6..8336d2ec98 100644 --- a/BizHawk.Client.Common/movie/bkm/BkmMnemonicConstants.cs +++ b/BizHawk.Client.Common/movie/import/bkm/BkmMnemonicConstants.cs @@ -1,237 +1,237 @@ -using System; -using System.Collections.Generic; - -namespace BizHawk.Client.Common -{ - internal static class BkmMnemonicConstants - { - public static readonly Dictionary> Buttons = new Dictionary> - { - { - "Gameboy Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, { "A", "A" } - } - }, - { - "Lynx Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, { "A", "A" } - } - }, - { - "GBA Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, - { "A", "A" }, { "L", "L" }, { "R", "R" } - } - }, - { - "Genesis 3-Button Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Start", "S" }, { "A", "A" }, { "B", "B" }, - { "C", "C" } - } - }, - { - "GPGX Genesis Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "A", "A" }, { "B", "B" }, { "C", "C" }, - { "Start", "S" }, { "X", "X" }, { "Y", "Y" }, { "Z", "Z" }, { "Mode", "M" } - } - }, - { - "GPGX 3-Button Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "A", "A" }, { "B", "B" }, - { "C", "C" }, { "Start", "S" }, - } - }, - { - "NES Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, - { "A", "A" } - } - }, - { - "SNES Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, - { "A", "A" }, { "X", "X" }, { "Y", "Y" }, { "L", "L" }, { "R", "R" } - } - }, - { - "PC Engine Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Run", "r" }, { "B2", "2" }, - { "B1", "1" } - } - }, - { - "SMS Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "B1", "1" }, { "B2", "2" } - } - }, - { - "TI83 Controller", new Dictionary - { - { "0", "0" }, { "1", "1" }, { "2", "2" }, { "3", "3" }, { "4", "4" }, { "5", "5" }, { "6", "6" }, { "7", "7" }, - { "8", "8" }, { "9", "9" }, { "DOT", "`" }, { "ON", "O" }, { "ENTER", "=" }, { "UP", "U" }, { "DOWN", "D" }, - { "LEFT", "L" }, { "RIGHT", "R" }, { "PLUS", "+" }, { "MINUS", "_" }, { "MULTIPLY", "*" }, { "DIVIDE", "/" }, - { "CLEAR", "c" }, { "EXP", "^" }, { "DASH", "-" }, { "PARAOPEN", "(" }, { "PARACLOSE", ")" }, { "TAN", "T" }, - { "VARS", "V" }, { "COS", "C" }, { "PRGM", "P" }, { "STAT", "s" }, { "MATRIX", "m" }, { "X", "X" }, { "STO", ">" }, - { "LN", "n" }, { "LOG", "L" }, { "SQUARED", "2" }, { "NEG1", "1" }, { "MATH", "H" }, { "ALPHA", "A" }, - { "GRAPH", "G" }, { "TRACE", "t" }, { "ZOOM", "Z" }, { "WINDOW", "W" }, { "Y", "Y" }, { "2ND", "&" }, { "MODE", "O" }, - { "DEL", "D" }, { "COMMA", "," }, { "SIN", "S" } - } - }, - { - "Atari 2600 Basic Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Button", "B" } - } - }, - { - "Atari 7800 ProLine Joystick Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Trigger", "1" }, { "Trigger 2", "2" } - } - }, - { - "Commodore 64 Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Button", "B" } - } - }, - { - "Commodore 64 Keyboard", new Dictionary - { - { "Key F1", "1" }, { "Key F3", "3" }, { "Key F5", "5" }, { "Key F7", "7" }, - { "Key Left Arrow", "l" }, { "Key 1", "1" }, { "Key 2", "2" }, { "Key 3", "3" }, { "Key 4", "4" }, { "Key 5", "5" }, { "Key 6", "6" }, { "Key 7", "7" }, { "Key 8", "8" }, { "Key 9", "9" }, { "Key 0", "0" }, { "Key Plus", "+" }, { "Key Minus", "-" }, { "Key Pound", "l" }, { "Key Clear/Home", "c" }, { "Key Insert/Delete", "i" }, - { "Key Control", "c" }, { "Key Q", "Q" }, { "Key W", "W" }, { "Key E", "E" }, { "Key R", "R" }, { "Key T", "T" }, { "Key Y", "Y" }, { "Key U", "U" }, { "Key I", "I" }, { "Key O", "O" }, { "Key P", "P" }, { "Key At", "@" }, { "Key Asterisk", "*" }, { "Key Up Arrow", "u" }, { "Key Restore", "r" }, - { "Key Run/Stop", "s" }, { "Key Lck", "k" }, { "Key A", "A" }, { "Key S", "S" }, { "Key D", "D" }, { "Key F", "F" }, { "Key G", "G" }, { "Key H", "H" }, { "Key J", "J" }, { "Key K", "K" }, { "Key L", "L" }, { "Key Colon", ":" }, { "Key Semicolon", ";" }, { "Key Equal", "=" }, { "Key Return", "e" }, - { "Key Commodore", "o" }, { "Key Left Shift", "s" }, { "Key Z", "Z" }, { "Key X", "X" }, { "Key C", "C" }, { "Key V", "V" }, { "Key B", "B" }, { "Key N", "N" }, { "Key M", "M" }, { "Key Comma", "," }, { "Key Period", ">" }, { "Key Slash", "/" }, { "Key Right Shift", "s" }, { "Key Cursor Up/Down", "u" }, { "Key Cursor Left/Right", "l" }, - { "Key Space", "_" } - } - }, - { - "ColecoVision Basic Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "L", "l" }, { "R", "r" }, - { "Key1", "1" }, { "Key2", "2" }, { "Key3", "3" }, { "Key4", "4" }, { "Key5", "5" }, { "Key6", "6" }, - { "Key7", "7" }, { "Key8", "8" }, { "Key9", "9" }, { "Star", "*" }, { "Key0", "0" }, { "Pound", "#" } - } - }, - { - "Nintendo 64 Controller", new Dictionary - { - { "DPad U", "U" }, { "DPad D", "D" }, { "DPad L", "L" }, { "DPad R", "R" }, - { "B", "B" }, { "A", "A" }, { "Z", "Z" }, { "Start", "S" }, { "L", "L" }, { "R", "R" }, - { "C Up", "u" }, { "C Down", "d" }, { "C Left", "l" }, { "C Right", "r" } - } - }, - { - "Saturn Controller", new Dictionary - { - { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, - { "Start", "S" }, { "X", "X" }, { "Y", "Y" }, { "Z", "Z" }, { "A", "A" }, { "B", "B" }, { "C", "C" }, - { "L", "l" }, { "R", "r" }, - } - } - }; - - public static readonly Dictionary> Analogs = new Dictionary> - { - { "Nintendo 64 Controller", new Dictionary { { "X Axis", "X" }, { "Y Axis", "Y" } } } - }; - - public static readonly Dictionary> Commands = new Dictionary> - { - { "Atari 2600 Basic Controller", new Dictionary { { "Reset", "r" }, { "Select", "s" } } }, - { "Atari 7800 ProLine Joystick Controller", new Dictionary { { "Reset", "r" }, { "Select", "s" } } }, - { "Gameboy Controller", new Dictionary { { "Power", "P" } } }, - { "GBA Controller", new Dictionary { { "Power", "P" } } }, - { "Genesis 3-Button Controller", new Dictionary { { "Reset", "r" } } }, - { "GPGX Genesis Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } }, - { "NES Controller", new Dictionary { { "Reset", "r" }, { "Power", "P" }, { "FDS Eject", "E" }, { "FDS Insert 0", "0" }, { "FDS Insert 1", "1" }, { "VS Coin 1", "c" }, { "VS Coin 2", "C" } } }, - { "SNES Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } }, - { "PC Engine Controller", new Dictionary() }, - { "SMS Controller", new Dictionary { { "Pause", "p" }, { "Reset", "r" } } }, - { "TI83 Controller", new Dictionary() }, - { "Nintendo 64 Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } }, - { "Saturn Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } }, - { "GPGX 3-Button Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } } - }; - - public static readonly Dictionary Players = new Dictionary - { - { "Gameboy Controller", 1 }, { "GBA Controller", 1 }, { "Genesis 3-Button Controller", 2 }, { "GPGX Genesis Controller", 2 }, { "NES Controller", 4 }, - { "SNES Controller", 4 }, { "PC Engine Controller", 5 }, { "SMS Controller", 2 }, { "TI83 Controller", 1 }, { "Atari 2600 Basic Controller", 2 }, { "Atari 7800 ProLine Joystick Controller", 2 }, - { "ColecoVision Basic Controller", 2 }, { "Commodore 64 Controller", 2 }, { "Nintendo 64 Controller", 4 }, { "Saturn Controller", 2 }, - { "GPGX 3-Button Controller", 2 }, { "Lynx Controller", 1 } - }; - - // just experimenting with different possibly more painful ways to handle mnemonics - // |P|UDLRsSBA| - public static readonly Tuple[] DgbMnemonic = - { - new Tuple(null, '|'), - new Tuple("P1 Power", 'P'), - new Tuple(null, '|'), - new Tuple("P1 Up", 'U'), - new Tuple("P1 Down", 'D'), - new Tuple("P1 Left", 'L'), - new Tuple("P1 Right", 'R'), - new Tuple("P1 Select", 's'), - new Tuple("P1 Start", 'S'), - new Tuple("P1 B", 'B'), - new Tuple("P1 A", 'A'), - new Tuple(null, '|'), - new Tuple("P2 Power", 'P'), - new Tuple(null, '|'), - new Tuple("P2 Up", 'U'), - new Tuple("P2 Down", 'D'), - new Tuple("P2 Left", 'L'), - new Tuple("P2 Right", 'R'), - new Tuple("P2 Select", 's'), - new Tuple("P2 Start", 'S'), - new Tuple("P2 B", 'B'), - new Tuple("P2 A", 'A'), - new Tuple(null, '|') - }; - - public static readonly Tuple[] WsMnemonic = - { - new Tuple(null, '|'), - new Tuple("P1 X1", '1'), - new Tuple("P1 X3", '3'), - new Tuple("P1 X4", '4'), - new Tuple("P1 X2", '2'), - new Tuple("P1 Y1", '1'), - new Tuple("P1 Y3", '3'), - new Tuple("P1 Y4", '4'), - new Tuple("P1 Y2", '2'), - new Tuple("P1 Start", 'S'), - new Tuple("P1 B", 'B'), - new Tuple("P1 A", 'A'), - new Tuple(null, '|'), - new Tuple("P2 X1", '1'), - new Tuple("P2 X3", '3'), - new Tuple("P2 X4", '4'), - new Tuple("P2 X2", '2'), - new Tuple("P2 Y1", '1'), - new Tuple("P2 Y3", '3'), - new Tuple("P2 Y4", '4'), - new Tuple("P2 Y2", '2'), - new Tuple("P2 Start", 'S'), - new Tuple("P2 B", 'B'), - new Tuple("P2 A", 'A'), - new Tuple(null, '|'), - new Tuple("Power", 'P'), - new Tuple("Rotate", 'R'), - new Tuple(null, '|') - }; - } -} +using System; +using System.Collections.Generic; + +namespace BizHawk.Client.Common +{ + internal static class BkmMnemonicConstants + { + public static readonly Dictionary> Buttons = new Dictionary> + { + { + "Gameboy Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, { "A", "A" } + } + }, + { + "Lynx Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, { "A", "A" } + } + }, + { + "GBA Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, + { "A", "A" }, { "L", "L" }, { "R", "R" } + } + }, + { + "Genesis 3-Button Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Start", "S" }, { "A", "A" }, { "B", "B" }, + { "C", "C" } + } + }, + { + "GPGX Genesis Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "A", "A" }, { "B", "B" }, { "C", "C" }, + { "Start", "S" }, { "X", "X" }, { "Y", "Y" }, { "Z", "Z" }, { "Mode", "M" } + } + }, + { + "GPGX 3-Button Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "A", "A" }, { "B", "B" }, + { "C", "C" }, { "Start", "S" }, + } + }, + { + "NES Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, + { "A", "A" } + } + }, + { + "SNES Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Start", "S" }, { "B", "B" }, + { "A", "A" }, { "X", "X" }, { "Y", "Y" }, { "L", "L" }, { "R", "R" } + } + }, + { + "PC Engine Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Select", "s" }, { "Run", "r" }, { "B2", "2" }, + { "B1", "1" } + } + }, + { + "SMS Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "B1", "1" }, { "B2", "2" } + } + }, + { + "TI83 Controller", new Dictionary + { + { "0", "0" }, { "1", "1" }, { "2", "2" }, { "3", "3" }, { "4", "4" }, { "5", "5" }, { "6", "6" }, { "7", "7" }, + { "8", "8" }, { "9", "9" }, { "DOT", "`" }, { "ON", "O" }, { "ENTER", "=" }, { "UP", "U" }, { "DOWN", "D" }, + { "LEFT", "L" }, { "RIGHT", "R" }, { "PLUS", "+" }, { "MINUS", "_" }, { "MULTIPLY", "*" }, { "DIVIDE", "/" }, + { "CLEAR", "c" }, { "EXP", "^" }, { "DASH", "-" }, { "PARAOPEN", "(" }, { "PARACLOSE", ")" }, { "TAN", "T" }, + { "VARS", "V" }, { "COS", "C" }, { "PRGM", "P" }, { "STAT", "s" }, { "MATRIX", "m" }, { "X", "X" }, { "STO", ">" }, + { "LN", "n" }, { "LOG", "L" }, { "SQUARED", "2" }, { "NEG1", "1" }, { "MATH", "H" }, { "ALPHA", "A" }, + { "GRAPH", "G" }, { "TRACE", "t" }, { "ZOOM", "Z" }, { "WINDOW", "W" }, { "Y", "Y" }, { "2ND", "&" }, { "MODE", "O" }, + { "DEL", "D" }, { "COMMA", "," }, { "SIN", "S" } + } + }, + { + "Atari 2600 Basic Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Button", "B" } + } + }, + { + "Atari 7800 ProLine Joystick Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Trigger", "1" }, { "Trigger 2", "2" } + } + }, + { + "Commodore 64 Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "Button", "B" } + } + }, + { + "Commodore 64 Keyboard", new Dictionary + { + { "Key F1", "1" }, { "Key F3", "3" }, { "Key F5", "5" }, { "Key F7", "7" }, + { "Key Left Arrow", "l" }, { "Key 1", "1" }, { "Key 2", "2" }, { "Key 3", "3" }, { "Key 4", "4" }, { "Key 5", "5" }, { "Key 6", "6" }, { "Key 7", "7" }, { "Key 8", "8" }, { "Key 9", "9" }, { "Key 0", "0" }, { "Key Plus", "+" }, { "Key Minus", "-" }, { "Key Pound", "l" }, { "Key Clear/Home", "c" }, { "Key Insert/Delete", "i" }, + { "Key Control", "c" }, { "Key Q", "Q" }, { "Key W", "W" }, { "Key E", "E" }, { "Key R", "R" }, { "Key T", "T" }, { "Key Y", "Y" }, { "Key U", "U" }, { "Key I", "I" }, { "Key O", "O" }, { "Key P", "P" }, { "Key At", "@" }, { "Key Asterisk", "*" }, { "Key Up Arrow", "u" }, { "Key Restore", "r" }, + { "Key Run/Stop", "s" }, { "Key Lck", "k" }, { "Key A", "A" }, { "Key S", "S" }, { "Key D", "D" }, { "Key F", "F" }, { "Key G", "G" }, { "Key H", "H" }, { "Key J", "J" }, { "Key K", "K" }, { "Key L", "L" }, { "Key Colon", ":" }, { "Key Semicolon", ";" }, { "Key Equal", "=" }, { "Key Return", "e" }, + { "Key Commodore", "o" }, { "Key Left Shift", "s" }, { "Key Z", "Z" }, { "Key X", "X" }, { "Key C", "C" }, { "Key V", "V" }, { "Key B", "B" }, { "Key N", "N" }, { "Key M", "M" }, { "Key Comma", "," }, { "Key Period", ">" }, { "Key Slash", "/" }, { "Key Right Shift", "s" }, { "Key Cursor Up/Down", "u" }, { "Key Cursor Left/Right", "l" }, + { "Key Space", "_" } + } + }, + { + "ColecoVision Basic Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, { "L", "l" }, { "R", "r" }, + { "Key1", "1" }, { "Key2", "2" }, { "Key3", "3" }, { "Key4", "4" }, { "Key5", "5" }, { "Key6", "6" }, + { "Key7", "7" }, { "Key8", "8" }, { "Key9", "9" }, { "Star", "*" }, { "Key0", "0" }, { "Pound", "#" } + } + }, + { + "Nintendo 64 Controller", new Dictionary + { + { "DPad U", "U" }, { "DPad D", "D" }, { "DPad L", "L" }, { "DPad R", "R" }, + { "B", "B" }, { "A", "A" }, { "Z", "Z" }, { "Start", "S" }, { "L", "L" }, { "R", "R" }, + { "C Up", "u" }, { "C Down", "d" }, { "C Left", "l" }, { "C Right", "r" } + } + }, + { + "Saturn Controller", new Dictionary + { + { "Up", "U" }, { "Down", "D" }, { "Left", "L" }, { "Right", "R" }, + { "Start", "S" }, { "X", "X" }, { "Y", "Y" }, { "Z", "Z" }, { "A", "A" }, { "B", "B" }, { "C", "C" }, + { "L", "l" }, { "R", "r" }, + } + } + }; + + public static readonly Dictionary> Analogs = new Dictionary> + { + { "Nintendo 64 Controller", new Dictionary { { "X Axis", "X" }, { "Y Axis", "Y" } } } + }; + + public static readonly Dictionary> Commands = new Dictionary> + { + { "Atari 2600 Basic Controller", new Dictionary { { "Reset", "r" }, { "Select", "s" } } }, + { "Atari 7800 ProLine Joystick Controller", new Dictionary { { "Reset", "r" }, { "Select", "s" } } }, + { "Gameboy Controller", new Dictionary { { "Power", "P" } } }, + { "GBA Controller", new Dictionary { { "Power", "P" } } }, + { "Genesis 3-Button Controller", new Dictionary { { "Reset", "r" } } }, + { "GPGX Genesis Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } }, + { "NES Controller", new Dictionary { { "Reset", "r" }, { "Power", "P" }, { "FDS Eject", "E" }, { "FDS Insert 0", "0" }, { "FDS Insert 1", "1" }, { "VS Coin 1", "c" }, { "VS Coin 2", "C" } } }, + { "SNES Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } }, + { "PC Engine Controller", new Dictionary() }, + { "SMS Controller", new Dictionary { { "Pause", "p" }, { "Reset", "r" } } }, + { "TI83 Controller", new Dictionary() }, + { "Nintendo 64 Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } }, + { "Saturn Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } }, + { "GPGX 3-Button Controller", new Dictionary { { "Power", "P" }, { "Reset", "r" } } } + }; + + public static readonly Dictionary Players = new Dictionary + { + { "Gameboy Controller", 1 }, { "GBA Controller", 1 }, { "Genesis 3-Button Controller", 2 }, { "GPGX Genesis Controller", 2 }, { "NES Controller", 4 }, + { "SNES Controller", 4 }, { "PC Engine Controller", 5 }, { "SMS Controller", 2 }, { "TI83 Controller", 1 }, { "Atari 2600 Basic Controller", 2 }, { "Atari 7800 ProLine Joystick Controller", 2 }, + { "ColecoVision Basic Controller", 2 }, { "Commodore 64 Controller", 2 }, { "Nintendo 64 Controller", 4 }, { "Saturn Controller", 2 }, + { "GPGX 3-Button Controller", 2 }, { "Lynx Controller", 1 } + }; + + // just experimenting with different possibly more painful ways to handle mnemonics + // |P|UDLRsSBA| + public static readonly Tuple[] DgbMnemonic = + { + new Tuple(null, '|'), + new Tuple("P1 Power", 'P'), + new Tuple(null, '|'), + new Tuple("P1 Up", 'U'), + new Tuple("P1 Down", 'D'), + new Tuple("P1 Left", 'L'), + new Tuple("P1 Right", 'R'), + new Tuple("P1 Select", 's'), + new Tuple("P1 Start", 'S'), + new Tuple("P1 B", 'B'), + new Tuple("P1 A", 'A'), + new Tuple(null, '|'), + new Tuple("P2 Power", 'P'), + new Tuple(null, '|'), + new Tuple("P2 Up", 'U'), + new Tuple("P2 Down", 'D'), + new Tuple("P2 Left", 'L'), + new Tuple("P2 Right", 'R'), + new Tuple("P2 Select", 's'), + new Tuple("P2 Start", 'S'), + new Tuple("P2 B", 'B'), + new Tuple("P2 A", 'A'), + new Tuple(null, '|') + }; + + public static readonly Tuple[] WsMnemonic = + { + new Tuple(null, '|'), + new Tuple("P1 X1", '1'), + new Tuple("P1 X3", '3'), + new Tuple("P1 X4", '4'), + new Tuple("P1 X2", '2'), + new Tuple("P1 Y1", '1'), + new Tuple("P1 Y3", '3'), + new Tuple("P1 Y4", '4'), + new Tuple("P1 Y2", '2'), + new Tuple("P1 Start", 'S'), + new Tuple("P1 B", 'B'), + new Tuple("P1 A", 'A'), + new Tuple(null, '|'), + new Tuple("P2 X1", '1'), + new Tuple("P2 X3", '3'), + new Tuple("P2 X4", '4'), + new Tuple("P2 X2", '2'), + new Tuple("P2 Y1", '1'), + new Tuple("P2 Y3", '3'), + new Tuple("P2 Y4", '4'), + new Tuple("P2 Y2", '2'), + new Tuple("P2 Start", 'S'), + new Tuple("P2 B", 'B'), + new Tuple("P2 A", 'A'), + new Tuple(null, '|'), + new Tuple("Power", 'P'), + new Tuple("Rotate", 'R'), + new Tuple(null, '|') + }; + } +} diff --git a/BizHawk.Client.Common/movie/bkm/BkmMovie.cs b/BizHawk.Client.Common/movie/import/bkm/BkmMovie.cs similarity index 94% rename from BizHawk.Client.Common/movie/bkm/BkmMovie.cs rename to BizHawk.Client.Common/movie/import/bkm/BkmMovie.cs index 41d736fc14..185d403053 100644 --- a/BizHawk.Client.Common/movie/bkm/BkmMovie.cs +++ b/BizHawk.Client.Common/movie/import/bkm/BkmMovie.cs @@ -1,150 +1,150 @@ -using System; -using System.Collections.Generic; -using System.IO; - -namespace BizHawk.Client.Common -{ - internal class BkmMovie - { - private readonly List _log = new List(); - private int? _loopOffset; - - public BkmMovie() - { - Header = new BkmHeader { [HeaderKeys.MOVIEVERSION] = "BizHawk v0.0.1" }; - } - - public string PreferredExtension => "bkm"; - - public BkmHeader Header { get; } - public string Filename { get; set; } = ""; - public bool Loaded { get; private set; } - - public int InputLogLength => _log.Count; - - public double FrameCount - { - get - { - if (_loopOffset.HasValue) - { - return double.PositiveInfinity; - } - - if (Loaded) - { - return _log.Count; - } - - return 0; - } - } - - public BkmControllerAdapter GetInputState(int frame) - { - if (frame < FrameCount && frame >= 0) - { - int getFrame; - - if (_loopOffset.HasValue) - { - if (frame < _log.Count) - { - getFrame = frame; - } - else - { - getFrame = ((frame - _loopOffset.Value) % (_log.Count - _loopOffset.Value)) + _loopOffset.Value; - } - } - else - { - getFrame = frame; - } - - var adapter = new BkmControllerAdapter - { - Definition = Global.MovieSession.MovieControllerAdapter.Definition - }; - adapter.SetControllersAsMnemonic(_log[getFrame]); - return adapter; - } - - return null; - } - - public IDictionary HeaderEntries => Header; - - public SubtitleList Subtitles => Header.Subtitles; - - public IList Comments => Header.Comments; - - public string SyncSettingsJson - { - get => Header[HeaderKeys.SYNCSETTINGS]; - set => Header[HeaderKeys.SYNCSETTINGS] = value; - } - - public string TextSavestate { get; set; } - public byte[] BinarySavestate { get; set; } - - public bool Load() - { - 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; - return true; - } - } +using System; +using System.Collections.Generic; +using System.IO; + +namespace BizHawk.Client.Common +{ + internal class BkmMovie + { + private readonly List _log = new List(); + private int? _loopOffset; + + public BkmMovie() + { + Header = new BkmHeader { [HeaderKeys.MOVIEVERSION] = "BizHawk v0.0.1" }; + } + + public string PreferredExtension => "bkm"; + + public BkmHeader Header { get; } + public string Filename { get; set; } = ""; + public bool Loaded { get; private set; } + + public int InputLogLength => _log.Count; + + public double FrameCount + { + get + { + if (_loopOffset.HasValue) + { + return double.PositiveInfinity; + } + + if (Loaded) + { + return _log.Count; + } + + return 0; + } + } + + public BkmControllerAdapter GetInputState(int frame) + { + if (frame < FrameCount && frame >= 0) + { + int getFrame; + + if (_loopOffset.HasValue) + { + if (frame < _log.Count) + { + getFrame = frame; + } + else + { + getFrame = ((frame - _loopOffset.Value) % (_log.Count - _loopOffset.Value)) + _loopOffset.Value; + } + } + else + { + getFrame = frame; + } + + var adapter = new BkmControllerAdapter + { + Definition = Global.MovieSession.MovieControllerAdapter.Definition + }; + adapter.SetControllersAsMnemonic(_log[getFrame]); + return adapter; + } + + return null; + } + + public IDictionary HeaderEntries => Header; + + public SubtitleList Subtitles => Header.Subtitles; + + public IList Comments => Header.Comments; + + public string SyncSettingsJson + { + get => Header[HeaderKeys.SYNCSETTINGS]; + set => Header[HeaderKeys.SYNCSETTINGS] = value; + } + + public string TextSavestate { get; set; } + public byte[] BinarySavestate { get; set; } + + public bool Load() + { + 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; + return true; + } + } } \ No newline at end of file