fix .bkm import
- closes #3909 Effectively best-effort for now, may or may not work for some movies.
This commit is contained in:
parent
d3362f5e0c
commit
85e2d18780
|
@ -1,8 +1,9 @@
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores;
|
||||
|
||||
namespace BizHawk.Client.Common.movie.import
|
||||
{
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
[ImporterFor("BizHawk", ".bkm")]
|
||||
internal class BkmImport : MovieImporter
|
||||
{
|
||||
|
@ -13,15 +14,20 @@ namespace BizHawk.Client.Common.movie.import
|
|||
|
||||
for (var i = 0; i < bkm.InputLogLength; i++)
|
||||
{
|
||||
// TODO: this is currently broken because Result.Movie.Emulator is no longer getting set,
|
||||
// however using that was sketchy anyway because it relied on the currently loaded core for import
|
||||
var input = bkm.GetInputState(i, Result.Movie.Emulator.ControllerDefinition, bkm.Header[HeaderKeys.Platform]);
|
||||
var input = bkm.GetInputState(i, bkm.Header[HeaderKeys.Platform]);
|
||||
Result.Movie.AppendFrame(input);
|
||||
}
|
||||
|
||||
Result.Movie.LogKey = bkm.GenerateLogKey;
|
||||
|
||||
Result.Movie.HeaderEntries.Clear();
|
||||
foreach (var (k, v) in bkm.Header) Result.Movie.HeaderEntries[k] = v;
|
||||
|
||||
// migrate some stuff, probably incomplete
|
||||
if (Result.Movie.HeaderEntries[HeaderKeys.Core] is "QuickNes") Result.Movie.HeaderEntries[HeaderKeys.Core] = CoreNames.QuickNes;
|
||||
if (Result.Movie.HeaderEntries[HeaderKeys.Core] is "EMU7800") Result.Movie.HeaderEntries[HeaderKeys.Core] = CoreNames.A7800Hawk;
|
||||
if (Result.Movie.HeaderEntries[HeaderKeys.Platform] is "DGB") Result.Movie.HeaderEntries[HeaderKeys.Platform] = VSystemID.Raw.GBL;
|
||||
|
||||
Result.Movie.SyncSettingsJson = bkm.SyncSettingsJson;
|
||||
|
||||
Result.Movie.Comments.Clear();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common.CollectionExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
@ -7,32 +8,10 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
internal class BkmControllerAdapter : IController
|
||||
{
|
||||
public BkmControllerAdapter(ControllerDefinition definition, string systemId)
|
||||
public BkmControllerAdapter(string systemId)
|
||||
{
|
||||
// We do need to map the definition name to the legacy
|
||||
// controller names that were used back in the bkm days
|
||||
var name = systemId switch
|
||||
{
|
||||
"Lynx" => "Lynx Controller",
|
||||
"SNES" => "SNES Controller",
|
||||
"C64" => "Commodore 64 Controller",
|
||||
"GBA" => "GBA Controller",
|
||||
"A78" => "Atari 7800 ProLine Joystick Controller",
|
||||
"DGB" => "Dual Gameboy Controller",
|
||||
"WSWAN" => "WonderSwan Controller",
|
||||
"N64" => "Nintendo 64 Controller",
|
||||
"SAT" => "Saturn Controller",
|
||||
"GEN" => "GPGX Genesis Controller",
|
||||
"NES" => "NES Controller",
|
||||
"GB" => "Gameboy Controller",
|
||||
"A26" => "Atari 2600 Basic Controller",
|
||||
"TI83" => "TI83 Controller",
|
||||
"Coleco" => "ColecoVision Basic Controller",
|
||||
"SMS Controller" => "SMS",
|
||||
_ => "Null Controller",
|
||||
};
|
||||
Definition = new(copyFrom: definition, withName: name);
|
||||
Definition.BuildMnemonicsCache(systemId); //TODO these aren't the same...
|
||||
Definition = BkmMnemonicConstants.ControllerDefinitions[systemId];
|
||||
Definition.BuildMnemonicsCache(systemId);
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition { get; set; }
|
||||
|
@ -43,167 +22,126 @@ namespace BizHawk.Client.Common
|
|||
public int AxisValue(string name)
|
||||
=> _myAxisControls.GetValueOrDefault(name);
|
||||
|
||||
public IReadOnlyCollection<(string Name, int Strength)> GetHapticsSnapshot() => throw new NotImplementedException(); // no idea --yoshi
|
||||
public IReadOnlyCollection<(string Name, int Strength)> GetHapticsSnapshot() => throw new NotSupportedException();
|
||||
|
||||
public void SetHapticChannelStrength(string name, int strength) => throw new NotImplementedException(); // no idea --yoshi
|
||||
public void SetHapticChannelStrength(string name, int strength) => throw new NotSupportedException();
|
||||
|
||||
private void SetFromMnemonic(ReadOnlySpan<char> mnemonic)
|
||||
{
|
||||
if (mnemonic.IsEmpty) return;
|
||||
var iterator = 0;
|
||||
|
||||
foreach ((string buttonName, AxisSpec? axisSpec) in Definition.ControlsOrdered.Skip(1).SelectMany(static x => x))
|
||||
{
|
||||
while (mnemonic[iterator] == '|') iterator++;
|
||||
|
||||
if (axisSpec.HasValue)
|
||||
{
|
||||
var separatorIndex = iterator + mnemonic[iterator..].IndexOfAny(',', '|');
|
||||
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
|
||||
var val = int.Parse(mnemonic[iterator..separatorIndex]);
|
||||
#else
|
||||
var axisValueString = mnemonic[iterator..separatorIndex].ToString();
|
||||
var val = int.Parse(axisValueString);
|
||||
#endif
|
||||
_myAxisControls[buttonName] = val;
|
||||
|
||||
iterator = separatorIndex + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_myBoolButtons[buttonName] = mnemonic[iterator] != '.';
|
||||
iterator++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// latches all buttons from the supplied mnemonic string
|
||||
/// </summary>
|
||||
public void SetControllersAsMnemonic(string mnemonic)
|
||||
{
|
||||
switch (ControlType)
|
||||
// _myBoolButtons.Clear();
|
||||
|
||||
switch (Definition.Name)
|
||||
{
|
||||
case "Null Controller":
|
||||
return;
|
||||
case "Lynx Controller":
|
||||
SetLynxControllersAsMnemonic(mnemonic);
|
||||
return;
|
||||
case "SNES Controller":
|
||||
SetSNESControllersAsMnemonic(mnemonic);
|
||||
return;
|
||||
case "Commodore 64 Controller":
|
||||
SetC64ControllersAsMnemonic(mnemonic);
|
||||
return;
|
||||
case "Gameboy Controller":
|
||||
Force("Power", mnemonic[1] == 'P');
|
||||
SetFromMnemonic(mnemonic.AsSpan(3));
|
||||
break;
|
||||
case "GBA Controller":
|
||||
SetGBAControllersAsMnemonic(mnemonic);
|
||||
return;
|
||||
case "Atari 7800 ProLine Joystick Controller":
|
||||
SetAtari7800AsMnemonic(mnemonic);
|
||||
return;
|
||||
case "Dual Gameboy Controller":
|
||||
SetDualGameBoyControllerAsMnemonic(mnemonic);
|
||||
return;
|
||||
case "WonderSwan Controller":
|
||||
SetWonderSwanControllerAsMnemonic(mnemonic);
|
||||
return;
|
||||
case "Nintendo 64 Controller":
|
||||
SetN64ControllersAsMnemonic(mnemonic);
|
||||
return;
|
||||
case "Saturn Controller":
|
||||
SetSaturnControllersAsMnemonic(mnemonic);
|
||||
return;
|
||||
Force("Power", mnemonic[1] == 'P');
|
||||
SetFromMnemonic(mnemonic.AsSpan(3));
|
||||
break;
|
||||
case "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;
|
||||
}
|
||||
|
||||
switch (mnemonic[1])
|
||||
{
|
||||
case 'P':
|
||||
Force("Power", true);
|
||||
break;
|
||||
case 'E':
|
||||
Force("FDS Eject", true);
|
||||
break;
|
||||
case '0':
|
||||
Force("FDS Insert 0", true);
|
||||
break;
|
||||
case '1':
|
||||
Force("FDS Insert 1", true);
|
||||
break;
|
||||
case '2':
|
||||
Force("FDS Insert 2", true);
|
||||
break;
|
||||
case '3':
|
||||
Force("FDS Insert 3", true);
|
||||
break;
|
||||
case 'c':
|
||||
Force("VS Coin 1", true);
|
||||
break;
|
||||
case 'C':
|
||||
Force("VS Coin 2", true);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (mnemonic[1] != '.')
|
||||
{
|
||||
Force("Reset", true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ControlType == "Gameboy Controller")
|
||||
{
|
||||
if (mnemonic.Length < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Force("Power", 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++]);
|
||||
}
|
||||
Force("Power", mnemonic[1] == 'P');
|
||||
Force("Reset", mnemonic[1] == 'r');
|
||||
SetFromMnemonic(mnemonic.AsSpan(3));
|
||||
break;
|
||||
case "NES Controller":
|
||||
Force("Power", mnemonic[1] == 'P');
|
||||
Force("Reset", mnemonic[1] == 'r');
|
||||
Force("FDS Eject", mnemonic[1] == 'E');
|
||||
Force("FDS Insert 0", mnemonic[1] == '0');
|
||||
Force("FDS Insert 1", mnemonic[1] == '1');
|
||||
Force("FDS Insert 2", mnemonic[1] == '2');
|
||||
Force("FDS Insert 3", mnemonic[1] == '3');
|
||||
Force("VS Coin 1", mnemonic[1] == 'c');
|
||||
Force("VS Coin 2", mnemonic[1] == 'C');
|
||||
SetFromMnemonic(mnemonic.AsSpan(3));
|
||||
break;
|
||||
case "SNES Controller":
|
||||
Force("Power", mnemonic[1] == 'P');
|
||||
Force("Reset", mnemonic[1] == 'r');
|
||||
SetFromMnemonic(mnemonic.AsSpan(3));
|
||||
break;
|
||||
case "PC Engine Controller":
|
||||
SetFromMnemonic(mnemonic.AsSpan(3));
|
||||
break;
|
||||
case "SMS Controller":
|
||||
SetFromMnemonic(mnemonic.AsSpan(1));
|
||||
Force("Power", mnemonic[^3] == 'P');
|
||||
Force("Reset", mnemonic[^2] == 'r');
|
||||
break;
|
||||
case "TI83 Controller":
|
||||
SetFromMnemonic(mnemonic.AsSpan(1));
|
||||
break;
|
||||
case "Atari 2600 Basic Controller":
|
||||
Force("Reset", mnemonic[1] == 'r');
|
||||
Force("Select", mnemonic[2] == 's');
|
||||
SetFromMnemonic(mnemonic.AsSpan(4));
|
||||
break;
|
||||
case "Atari 7800 ProLine Joystick Controller":
|
||||
Force("Power", mnemonic[1] == 'P');
|
||||
Force("Reset", mnemonic[2] == 'r');
|
||||
Force("Select", mnemonic[3] == 's');
|
||||
Force("Pause", mnemonic[4] == 'p');
|
||||
SetFromMnemonic(mnemonic.AsSpan(6));
|
||||
break;
|
||||
case "Commodore 64 Controller":
|
||||
SetFromMnemonic(mnemonic.AsSpan(1));
|
||||
break;
|
||||
case "ColecoVision Basic Controller":
|
||||
SetFromMnemonic(mnemonic.AsSpan(1));
|
||||
break;
|
||||
case "Nintento 64 Controller":
|
||||
Force("Power", mnemonic[1] == 'P');
|
||||
Force("Reset", mnemonic[1] == 'r');
|
||||
SetFromMnemonic(mnemonic.AsSpan(3));
|
||||
break;
|
||||
case "Saturn Controller":
|
||||
Force("Power", mnemonic[1] == 'P');
|
||||
Force("Reset", mnemonic[1] == 'r');
|
||||
SetFromMnemonic(mnemonic.AsSpan(3));
|
||||
break;
|
||||
case "Dual Gameboy Controller":
|
||||
SetFromMnemonic(mnemonic.AsSpan());
|
||||
break;
|
||||
case "WonderSwan Controller":
|
||||
SetFromMnemonic(mnemonic.AsSpan(1));
|
||||
Force("Power", mnemonic[^3] == 'P');
|
||||
Force("Rotate", mnemonic[^2] == 'R');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,381 +149,9 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private readonly Dictionary<string, bool> _myBoolButtons = new();
|
||||
|
||||
private bool IsGenesis6Button() => Definition.BoolButtons.Contains("P1 X");
|
||||
|
||||
private void Force(string button, bool state)
|
||||
{
|
||||
_myBoolButtons[button] = state;
|
||||
}
|
||||
|
||||
private void Force(string name, int state)
|
||||
{
|
||||
_myAxisControls[name] = state;
|
||||
}
|
||||
|
||||
private string ControlType => Definition.Name;
|
||||
|
||||
private void SetGBAControllersAsMnemonic(string mnemonic)
|
||||
{
|
||||
var 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 + (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)
|
||||
{
|
||||
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 (string button in BkmMnemonicConstants.Buttons[ControlType].Keys)
|
||||
{
|
||||
Force($"P{player} {button}", c[srcIndex + start++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetAtari7800AsMnemonic(string mnemonic)
|
||||
{
|
||||
var 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 startKey = 13;
|
||||
foreach (string button in BkmMnemonicConstants.Buttons["Commodore 64 Keyboard"].Keys)
|
||||
{
|
||||
Force(button, c[startKey++]);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class MnemonicChecker
|
||||
{
|
||||
private readonly string _mnemonic;
|
||||
|
||||
public MnemonicChecker(string mnemonic)
|
||||
{
|
||||
_mnemonic = mnemonic;
|
||||
}
|
||||
|
||||
public bool this[int c] => !string.IsNullOrEmpty(_mnemonic) && _mnemonic[c] != '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
using System.Collections.Generic;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
internal class BkmControllerDefinition(string name) : ControllerDefinition(name)
|
||||
{
|
||||
// same as ControllerDefinition.GenOrderedControls, just with Axes after BoolButtons
|
||||
protected override IReadOnlyList<IReadOnlyList<(string Name, AxisSpec? AxisSpec)>> GenOrderedControls()
|
||||
{
|
||||
var ret = new List<(string, AxisSpec?)>[PlayerCount + 1];
|
||||
for (var i = 0; i < ret.Length; i++) ret[i] = new();
|
||||
foreach (var btn in BoolButtons) ret[PlayerNumber(btn)].Add((btn, null));
|
||||
foreach ((string buttonName, var axisSpec) in Axes) ret[PlayerNumber(buttonName)].Add((buttonName, axisSpec));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,203 +1,156 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
internal static class BkmMnemonicConstants
|
||||
{
|
||||
public static readonly IReadOnlyDictionary<string, IReadOnlyDictionary<string, string>> Buttons = new Dictionary<string, IReadOnlyDictionary<string, string>>
|
||||
public static readonly IReadOnlyDictionary<string, ControllerDefinition> ControllerDefinitions = new Dictionary<string, ControllerDefinition>
|
||||
{
|
||||
["Gameboy Controller"] = new Dictionary<string, string>
|
||||
[VSystemID.Raw.GB] = new BkmControllerDefinition("Gameboy Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["Select"] = "s", ["Start"] = "S", ["B"] = "B", ["A"] = "A"
|
||||
},
|
||||
["Lynx Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = new[] { "Up", "Down", "Left", "Right", "Select", "Start", "B", "A" }.Select(b => $"P1 {b}")
|
||||
.Append("Power")
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.GBA] = new BkmControllerDefinition("GBA Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["Select"] = "s", ["Start"] = "S", ["B"] = "B", ["A"] = "A"
|
||||
},
|
||||
["GBA Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = new[] { "Up", "Down", "Left", "Right", "Select", "Start", "B", "A", "L", "R" }.Select(b => $"P1 {b}")
|
||||
.Append("Power")
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.GEN] = new BkmControllerDefinition("GPGX Genesis Controller")
|
||||
{
|
||||
["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<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 2)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "A", "B", "C", "Start", "X", "Y", "Z", "Mode" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Reset", "Power" ])
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.NES] = new BkmControllerDefinition("NES Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["Start"] = "S", ["A"] = "A", ["B"] = "B", ["C"] = "C"
|
||||
},
|
||||
["GPGX Genesis Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 4)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "Select", "Start", "B", "A" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Reset", "Power", "FDS Eject", "FDS Insert 0", "FDS Insert 1", "FDS Insert 2", "FDS Insert 3", "VS Coin 1", "VS Coin 2" ])
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.SNES] = new BkmControllerDefinition("SNES Controller")
|
||||
{
|
||||
["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<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 4)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "Select", "Start", "B", "A", "X", "Y", "L", "R" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Reset", "Power" ])
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.PCE] = new BkmControllerDefinition("PC Engine Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["A"] = "A", ["B"] = "B", ["C"] = "C", ["Start"] = "S"
|
||||
},
|
||||
["NES Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 5)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "Select", "Run", "B2", "B1" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.SMS] = new BkmControllerDefinition("SMS Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["Select"] = "s", ["Start"] = "S", ["B"] = "B", ["A"] = "A"
|
||||
},
|
||||
["SNES Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 2)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "B1", "B2" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Pause", "Reset" ])
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.TI83] = new BkmControllerDefinition("TI83 Controller")
|
||||
{
|
||||
["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<string, string>
|
||||
BoolButtons = new[] {
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "DOT", "ON", "ENTER",
|
||||
"UP", "DOWN", "LEFT", "RIGHT", "PLUS", "MINUS", "MULTIPLY", "DIVIDE",
|
||||
"CLEAR", "EXP", "DASH", "PARAOPEN", "PARACLOSE", "TAN", "VARS", "COS",
|
||||
"PRGM", "STAT", "MATRIX", "X", "STO", "LN", "LOG", "SQUARED", "NEG1",
|
||||
"MATH", "ALPHA", "GRAPH", "TRACE", "ZOOM", "WINDOW", "Y", "2ND", "MODE"
|
||||
}.Select(b => $"P1 {b}")
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.A26] = new BkmControllerDefinition("Atari 2600 Basic Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["Select"] = "s", ["Run"] = "r", ["B2"] = "2", ["B1"] = "1"
|
||||
},
|
||||
["SMS Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 2)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "Button" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Reset", "Select" ])
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.A78] = new BkmControllerDefinition("Atari 7800 ProLine Joystick Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["B1"] = "1", ["B2"] = "2"
|
||||
},
|
||||
["TI83 Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 2)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "Trigger", "Trigger 2" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Reset", "Power", "Select", "Pause" ])
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.C64] = new BkmControllerDefinition("Commodore 64 Controller")
|
||||
{
|
||||
["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"
|
||||
},
|
||||
["Atari 2600 Basic Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 2)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "Button" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Key F1", "Key F3", "Key F5", "Key F7", "Key Left Arrow", "Key 1",
|
||||
"Key 2", "Key 3", "Key 4", "Key 5", "Key 6", "Key 7", "Key 8", "Key 9", "Key 0", "Key Plus",
|
||||
"Key Minus", "Key Pound", "Key Clear/Home", "Key Insert/Delete", "Key Control", "Key Q", "Key W", "Key E",
|
||||
"Key R", "Key T", "Key Y", "Key U", "Key I", "Key O", "Key P", "Key At", "Key Asterisk", "Key Up Arrow",
|
||||
"Key Restore", "Key Run/Stop", "Key Lck", "Key A", "Key S", "Key D", "Key F", "Key G", "Key H", "Key J",
|
||||
"Key K", "Key L", "Key Colon", "Key Semicolon", "Key Equal", "Key Return", "Key Commodore", "Key Left Shift",
|
||||
"Key Z", "Key X", "Key C", "Key V", "Key B", "Key N", "Key M", "Key Comma", "Key Period",
|
||||
"Key Slash", "Key Right Shift", "Key Cursor Up/Down", "Key Cursor Left/Right", "Key Space"
|
||||
])
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.Coleco] = new BkmControllerDefinition("ColecoVision Basic Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["Button"] = "B"
|
||||
},
|
||||
["Atari 7800 ProLine Joystick Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 2)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "L", "R",
|
||||
"Key1", "Key2", "Key3", "Key4", "Key5", "Key6",
|
||||
"Key7", "Key8", "Key9", "Star", "Key0", "Pound"
|
||||
}.Select(b => $"P{i} {b}"))
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.N64] = new BkmControllerDefinition("Nintento 64 Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["Trigger"] = "1", ["Trigger 2"] = "2"
|
||||
},
|
||||
["Commodore 64 Controller"] = new Dictionary<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 4)
|
||||
.SelectMany(i => new[] {
|
||||
"DPad U", "DPad D", "DPad L", "DPad R",
|
||||
"B", "A", "Z", "Start", "L", "R",
|
||||
"C Up", "C Down", "C Left", "C Right"
|
||||
}.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Reset", "Power" ])
|
||||
.ToArray()
|
||||
}.AddXYPair("P1 {0} Axis", AxisPairOrientation.RightAndUp, (-128).RangeTo(127), 0)
|
||||
.AddXYPair("P2 {0} Axis", AxisPairOrientation.RightAndUp, (-128).RangeTo(127), 0)
|
||||
.AddXYPair("P3 {0} Axis", AxisPairOrientation.RightAndUp, (-128).RangeTo(127), 0)
|
||||
.AddXYPair("P4 {0} Axis", AxisPairOrientation.RightAndUp, (-128).RangeTo(127), 0)
|
||||
.MakeImmutable(),
|
||||
[VSystemID.Raw.SAT] = new BkmControllerDefinition("Saturn Controller")
|
||||
{
|
||||
["Up"] = "U", ["Down"] = "D", ["Left"] = "L", ["Right"] = "R", ["Button"] = "B"
|
||||
},
|
||||
["Commodore 64 Keyboard"] = new Dictionary<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 2)
|
||||
.SelectMany(i => new[] { "Up", "Down", "Left", "Right", "Start", "X", "Y", "Z", "A", "B", "C", "L", "R" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Reset", "Power" ])
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
["DGB"] = new BkmControllerDefinition("Dual Gameboy Controller")
|
||||
{
|
||||
["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<string, string>
|
||||
BoolButtons = Enumerable.Range(1, 2)
|
||||
.SelectMany(i => new[] { "Power", "Up", "Down", "Left", "Right", "Select", "Start", "B", "A" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.ToArray()
|
||||
}.MakeImmutable(),
|
||||
[VSystemID.Raw.WSWAN] = new BkmControllerDefinition("WonderSwan Controller")
|
||||
{
|
||||
["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<string, string>
|
||||
{
|
||||
["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<string, string>
|
||||
{
|
||||
["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 IReadOnlyDictionary<string, IReadOnlyDictionary<string, string>> Analogs = new Dictionary<string, IReadOnlyDictionary<string, string>>
|
||||
{
|
||||
["Nintendo 64 Controller"] = new Dictionary<string, string> { ["X Axis"] = "X" , ["Y Axis"] = "Y" }
|
||||
};
|
||||
|
||||
public static readonly IReadOnlyDictionary<string, IReadOnlyDictionary<string, string>> Commands = new Dictionary<string, IReadOnlyDictionary<string, string>>
|
||||
{
|
||||
["Atari 2600 Basic Controller"] = new Dictionary<string, string> { ["Reset"] = "r", ["Select"] = "s" },
|
||||
["Atari 7800 ProLine Joystick Controller"] = new Dictionary<string, string> { ["Reset"] = "r", ["Select"] = "s" },
|
||||
["Gameboy Controller"] = new Dictionary<string, string> { ["Power"] = "P" },
|
||||
["GBA Controller"] = new Dictionary<string, string> { ["Power"] = "P" },
|
||||
["Genesis 3-Button Controller"] = new Dictionary<string, string> { ["Reset"] = "r" },
|
||||
["GPGX Genesis Controller"] = new Dictionary<string, string> { ["Power"] = "P", ["Reset"] = "r" },
|
||||
["NES Controller"] = new Dictionary<string, string> { ["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<string, string> { ["Power"] = "P", ["Reset"] = "r" },
|
||||
["PC Engine Controller"] = new Dictionary<string, string>(),
|
||||
["SMS Controller"] = new Dictionary<string, string> { ["Pause"] = "p", ["Reset"] = "r" },
|
||||
["TI83 Controller"] = new Dictionary<string, string>(),
|
||||
["Nintendo 64 Controller"] = new Dictionary<string, string> { ["Power"] = "P", ["Reset"] = "r" },
|
||||
["Saturn Controller"] = new Dictionary<string, string> { ["Power"] = "P", ["Reset"] = "r" },
|
||||
["GPGX 3-Button Controller"] = new Dictionary<string, string> { ["Power"] = "P", ["Reset"] = "r" }
|
||||
};
|
||||
|
||||
public static readonly IReadOnlyDictionary<string, int> Players = new Dictionary<string, int>
|
||||
{
|
||||
["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 (string, char)[] DgbMnemonic =
|
||||
{
|
||||
(null, '|'),
|
||||
("P1 Power", 'P'),
|
||||
(null, '|'),
|
||||
("P1 Up", 'U'),
|
||||
("P1 Down", 'D'),
|
||||
("P1 Left", 'L'),
|
||||
("P1 Right", 'R'),
|
||||
("P1 Select", 's'),
|
||||
("P1 Start", 'S'),
|
||||
("P1 B", 'B'),
|
||||
("P1 A", 'A'),
|
||||
(null, '|'),
|
||||
("P2 Power", 'P'),
|
||||
(null, '|'),
|
||||
("P2 Up", 'U'),
|
||||
("P2 Down", 'D'),
|
||||
("P2 Left", 'L'),
|
||||
("P2 Right", 'R'),
|
||||
("P2 Select", 's'),
|
||||
("P2 Start", 'S'),
|
||||
("P2 B", 'B'),
|
||||
("P2 A", 'A'),
|
||||
(null, '|')
|
||||
};
|
||||
|
||||
public static readonly (string, char)[] WsMnemonic =
|
||||
{
|
||||
(null, '|'),
|
||||
("P1 X1", '1'),
|
||||
("P1 X3", '3'),
|
||||
("P1 X4", '4'),
|
||||
("P1 X2", '2'),
|
||||
("P1 Y1", '1'),
|
||||
("P1 Y3", '3'),
|
||||
("P1 Y4", '4'),
|
||||
("P1 Y2", '2'),
|
||||
("P1 Start", 'S'),
|
||||
("P1 B", 'B'),
|
||||
("P1 A", 'A'),
|
||||
(null, '|'),
|
||||
("P2 X1", '1'),
|
||||
("P2 X3", '3'),
|
||||
("P2 X4", '4'),
|
||||
("P2 X2", '2'),
|
||||
("P2 Y1", '1'),
|
||||
("P2 Y3", '3'),
|
||||
("P2 Y4", '4'),
|
||||
("P2 Y2", '2'),
|
||||
("P2 Start", 'S'),
|
||||
("P2 B", 'B'),
|
||||
("P2 A", 'A'),
|
||||
(null, '|'),
|
||||
("Power", 'P'),
|
||||
("Rotate", 'R'),
|
||||
(null, '|')
|
||||
BoolButtons = Enumerable.Range(1, 2)
|
||||
.SelectMany(i => new[] { "X1", "X3", "X4", "X2", "Y1", "Y3", "Y4", "Y2", "Start", "B", "A" }
|
||||
.Select(b => $"P{i} {b}"))
|
||||
.Concat([ "Power", "Rotate" ])
|
||||
.ToArray()
|
||||
}.MakeImmutable()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,25 +2,26 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
internal class BkmMovie
|
||||
{
|
||||
private BkmControllerAdapter _adapter;
|
||||
|
||||
private readonly List<string> _log = new List<string>();
|
||||
public BkmHeader Header { get; } = new BkmHeader();
|
||||
public string Filename { get; set; } = "";
|
||||
public bool Loaded { get; private set; }
|
||||
public int InputLogLength => Loaded ? _log.Count : 0;
|
||||
|
||||
public BkmControllerAdapter GetInputState(int frame, ControllerDefinition definition, string sytemId)
|
||||
public BkmControllerAdapter GetInputState(int frame, string sytemId)
|
||||
{
|
||||
if (frame < InputLogLength && frame >= 0)
|
||||
{
|
||||
var adapter = new BkmControllerAdapter(definition, sytemId);
|
||||
adapter.SetControllersAsMnemonic(_log[frame]);
|
||||
return adapter;
|
||||
_adapter ??= new BkmControllerAdapter(sytemId);
|
||||
_adapter.SetControllersAsMnemonic(_log[frame]);
|
||||
return _adapter;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -30,6 +31,8 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public IList<string> Comments => Header.Comments;
|
||||
|
||||
public string GenerateLogKey => Bk2LogEntryGenerator.GenerateLogKey(_adapter.Definition);
|
||||
|
||||
public string SyncSettingsJson
|
||||
{
|
||||
get => Header[HeaderKeys.SyncSettings];
|
||||
|
|
Loading…
Reference in New Issue