Refactor InputDisplayGenerator + LogEntryGenerator + ControllerDefinition (#3782)
* refactor InputDisplayGenerator and LogEntryGenerator handling * Fix NRE in Tastudio. I can already see this avalanching into 100 different bugs * cba, revert 48f4e13de and bring back bullshit dummy default MovieController * Refactor MnemonicCache + make Bk2LogEntryGenerator and Bk2InputDisplayGenerator static. This should simplify stuff and make the logic clearer
This commit is contained in:
parent
08bd14e800
commit
a0800862b3
|
@ -50,9 +50,7 @@ namespace BizHawk.Client.Common
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lg = _movieSession.Movie.LogGeneratorInstance(
|
return Bk2LogEntryGenerator.GenerateLogEntry(_movieSession.Movie.GetInputState(frame));
|
||||||
_movieSession.Movie.GetInputState(frame));
|
|
||||||
return lg.GenerateLogEntry();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(string filename)
|
public void Save(string filename)
|
||||||
|
|
|
@ -9,8 +9,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public class Controller : IController
|
public class Controller : IController
|
||||||
{
|
{
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public Controller(ControllerDefinition definition)
|
public Controller(ControllerDefinition definition)
|
||||||
{
|
{
|
||||||
Definition = definition;
|
Definition = definition;
|
||||||
|
@ -186,4 +184,4 @@ namespace BizHawk.Client.Common
|
||||||
.Select(kvp => kvp.Key)
|
.Select(kvp => kvp.Key)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _emulator.Frame.ToString();
|
return _emulator.Frame.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,10 +172,10 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
public string InputStrMovie()
|
public string InputStrMovie()
|
||||||
=> MakeStringFor(_movieSession.MovieController, cache: true);
|
=> MakeStringFor(_movieSession.MovieController);
|
||||||
|
|
||||||
public string InputStrImmediate()
|
public string InputStrImmediate()
|
||||||
=> MakeStringFor(_inputManager.AutofireStickyXorAdapter, cache: true);
|
=> MakeStringFor(_inputManager.AutofireStickyXorAdapter);
|
||||||
|
|
||||||
public string InputPrevious()
|
public string InputPrevious()
|
||||||
{
|
{
|
||||||
|
@ -196,15 +196,9 @@ namespace BizHawk.Client.Common
|
||||||
? MakeStringFor(_inputManager.AutofireStickyXorAdapter.Or(_movieSession.Movie.GetInputState(_emulator.Frame - 1)))
|
? MakeStringFor(_inputManager.AutofireStickyXorAdapter.Or(_movieSession.Movie.GetInputState(_emulator.Frame - 1)))
|
||||||
: InputStrImmediate();
|
: InputStrImmediate();
|
||||||
|
|
||||||
private string MakeStringFor(IController controller, bool cache = false)
|
private static string MakeStringFor(IController controller)
|
||||||
{
|
{
|
||||||
var idg = controller.InputDisplayGenerator;
|
return Bk2InputDisplayGenerator.Generate(controller);
|
||||||
if (idg is null)
|
|
||||||
{
|
|
||||||
idg = new Bk2InputDisplayGenerator(_emulator.SystemId, controller);
|
|
||||||
if (cache) controller.InputDisplayGenerator = idg;
|
|
||||||
}
|
|
||||||
return idg.Generate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string MakeIntersectImmediatePrevious()
|
public string MakeIntersectImmediatePrevious()
|
||||||
|
@ -292,7 +286,7 @@ namespace BizHawk.Client.Common
|
||||||
// in order to achieve this we want to avoid drawing anything pink that isn't actually held down right now
|
// in order to achieve this we want to avoid drawing anything pink that isn't actually held down right now
|
||||||
// so we make an AND adapter and combine it using immediate & sticky
|
// so we make an AND adapter and combine it using immediate & sticky
|
||||||
// (adapter creation moved to InputManager)
|
// (adapter creation moved to InputManager)
|
||||||
var autoString = MakeStringFor(_inputManager.WeirdStickyControllerForInputDisplay, cache: true);
|
var autoString = MakeStringFor(_inputManager.WeirdStickyControllerForInputDisplay);
|
||||||
g.DrawString(autoString, autoColor, point.X, point.Y);
|
g.DrawString(autoString, autoColor, point.X, point.Y);
|
||||||
|
|
||||||
//recolor everything that's changed from the previous input
|
//recolor everything that's changed from the previous input
|
||||||
|
|
|
@ -9,8 +9,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public class AutofireController : IController
|
public class AutofireController : IController
|
||||||
{
|
{
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public AutofireController(IEmulator emulator, int on, int off)
|
public AutofireController(IEmulator emulator, int on, int off)
|
||||||
{
|
{
|
||||||
On = on < 1 ? 0 : on;
|
On = on < 1 ? 0 : on;
|
||||||
|
|
|
@ -14,8 +14,6 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
public ControllerDefinition Definition { get; set; }
|
public ControllerDefinition Definition { get; set; }
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public bool IsPressed(string button) => _pressed.Contains(button);
|
public bool IsPressed(string button) => _pressed.Contains(button);
|
||||||
|
|
||||||
public int AxisValue(string name) => 0;
|
public int AxisValue(string name) => 0;
|
||||||
|
|
|
@ -13,8 +13,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public ControllerDefinition Definition { get; }
|
public ControllerDefinition Definition { get; }
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
protected Dictionary<string, int> Axes { get; private set; } = new();
|
protected Dictionary<string, int> Axes { get; private set; } = new();
|
||||||
|
|
||||||
protected Dictionary<string, bool> Buttons { get; private set; } = new();
|
protected Dictionary<string, bool> Buttons { get; private set; } = new();
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using BizHawk.Emulation.Common;
|
|
||||||
|
|
||||||
namespace BizHawk.Client.Common
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An implementation of <see cref="IInputDisplayGenerator"/> that
|
|
||||||
/// uses .bk2 mnemonics as the basis for display
|
|
||||||
/// </summary>
|
|
||||||
public class Bk2InputDisplayGenerator : IInputDisplayGenerator
|
|
||||||
{
|
|
||||||
/// <remarks>either <c>Range</c> or <c>Mnemonic</c> is always non-null</remarks>
|
|
||||||
private readonly IReadOnlyList<(string Name, AxisSpec? Range, char? Mnemonic)> _cachedInputSpecs;
|
|
||||||
|
|
||||||
private readonly IController _source;
|
|
||||||
|
|
||||||
public Bk2InputDisplayGenerator(string systemId, IController source)
|
|
||||||
{
|
|
||||||
const string ERR_MSG = nameof(ControllerDefinition.OrderedControlsFlat) + "/" + nameof(ControllerDefinition.ControlsOrdered) + " contains an input name which is neither a button nor an axis";
|
|
||||||
_cachedInputSpecs = source.Definition.OrderedControlsFlat.Select(button =>
|
|
||||||
{
|
|
||||||
if (source.Definition.Axes.TryGetValue(button, out var range)) return (button, range, null);
|
|
||||||
if (source.Definition.BoolButtons.Contains(button)) return (button, (AxisSpec?) null, (char?) Bk2MnemonicLookup.Lookup(button, systemId));
|
|
||||||
throw new Exception(ERR_MSG);
|
|
||||||
}).ToList();
|
|
||||||
_source = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Generate()
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
foreach (var (button, range, mnemonicChar) in _cachedInputSpecs)
|
|
||||||
{
|
|
||||||
if (range is not null)
|
|
||||||
{
|
|
||||||
var val = _source.AxisValue(button);
|
|
||||||
|
|
||||||
if (val == range.Value.Neutral)
|
|
||||||
{
|
|
||||||
sb.Append(" ");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.Append(val.ToString().PadLeft(5, ' ')).Append(',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.Append(_source.IsPressed(button)
|
|
||||||
? mnemonicChar.Value
|
|
||||||
: ' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
|
namespace BizHawk.Client.Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a display friendly version of the input log entry
|
||||||
|
/// using .bk2 mnemonics as the basis for display
|
||||||
|
/// </summary>
|
||||||
|
public static class Bk2InputDisplayGenerator
|
||||||
|
{
|
||||||
|
public static string Generate(IController source)
|
||||||
|
{
|
||||||
|
if (source.Definition.MnemonicsCache is null)
|
||||||
|
throw new InvalidOperationException("Can't generate input display string with empty mnemonics cache");
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
foreach ((string buttonName, AxisSpec? axisSpec) in source.Definition.ControlsOrdered.SelectMany(x => x))
|
||||||
|
{
|
||||||
|
if (axisSpec.HasValue)
|
||||||
|
{
|
||||||
|
int val = source.AxisValue(buttonName);
|
||||||
|
|
||||||
|
if (val == axisSpec.Value.Neutral)
|
||||||
|
{
|
||||||
|
sb.Append(" ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append(val.ToString().PadLeft(5, ' ')).Append(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append(source.IsPressed(buttonName)
|
||||||
|
? source.Definition.MnemonicsCache[buttonName]
|
||||||
|
: ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,8 +8,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public ControllerDefinition Definition => Source.Definition;
|
public ControllerDefinition Definition => Source.Definition;
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public bool IsPressed(string button)
|
public bool IsPressed(string button)
|
||||||
{
|
{
|
||||||
if (Source != null && SourceAnd != null)
|
if (Source != null && SourceAnd != null)
|
||||||
|
@ -36,8 +34,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public ControllerDefinition Definition => Source.Definition;
|
public ControllerDefinition Definition => Source.Definition;
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public bool IsPressed(string button)
|
public bool IsPressed(string button)
|
||||||
{
|
{
|
||||||
if (Source != null && SourceXor != null)
|
if (Source != null && SourceXor != null)
|
||||||
|
@ -64,8 +60,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public ControllerDefinition Definition => Source.Definition;
|
public ControllerDefinition Definition => Source.Definition;
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public bool IsPressed(string button)
|
public bool IsPressed(string button)
|
||||||
{
|
{
|
||||||
return (Source?.IsPressed(button) ?? false)
|
return (Source?.IsPressed(button) ?? false)
|
||||||
|
|
|
@ -11,8 +11,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public ControllerDefinition Definition => Curr.Definition;
|
public ControllerDefinition Definition => Curr.Definition;
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public bool IsPressed(string button) => Curr.IsPressed(button);
|
public bool IsPressed(string button) => Curr.IsPressed(button);
|
||||||
|
|
||||||
public int AxisValue(string name) => Curr.AxisValue(name);
|
public int AxisValue(string name) => Curr.AxisValue(name);
|
||||||
|
|
|
@ -54,13 +54,14 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
public void ResetMainControllers(AutofireController nullAutofireController)
|
public void ResetMainControllers(AutofireController nullAutofireController)
|
||||||
{
|
{
|
||||||
ActiveController = new(NullController.Instance.Definition);
|
ActiveController = new Controller(NullController.Instance.Definition);
|
||||||
AutoFireController = nullAutofireController;
|
AutoFireController = nullAutofireController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SyncControls(IEmulator emulator, IMovieSession session, Config config)
|
public void SyncControls(IEmulator emulator, IMovieSession session, Config config)
|
||||||
{
|
{
|
||||||
var def = emulator.ControllerDefinition;
|
var def = emulator.ControllerDefinition;
|
||||||
|
def.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(emulator.SystemId));
|
||||||
|
|
||||||
ActiveController = BindToDefinition(def, config.AllTrollers, config.AllTrollersAnalog, config.AllTrollersFeedbacks);
|
ActiveController = BindToDefinition(def, config.AllTrollers, config.AllTrollersAnalog, config.AllTrollersFeedbacks);
|
||||||
AutoFireController = BindToDefinitionAF(emulator, config.AllTrollersAutoFire, config.AutofireOn, config.AutofireOff);
|
AutoFireController = BindToDefinitionAF(emulator, config.AllTrollersAutoFire, config.AutofireOn, config.AutofireOff);
|
||||||
|
@ -157,4 +158,4 @@ namespace BizHawk.Client.Common
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public ControllerDefinition Definition { get; private set; }
|
public ControllerDefinition Definition { get; private set; }
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
private readonly Dictionary<string, bool> _overrides = new Dictionary<string, bool>();
|
private readonly Dictionary<string, bool> _overrides = new Dictionary<string, bool>();
|
||||||
private readonly Dictionary<string, int> _axisOverrides = new Dictionary<string, int>();
|
private readonly Dictionary<string, int> _axisOverrides = new Dictionary<string, int>();
|
||||||
private readonly List<string> _inverses = new List<string>();
|
private readonly List<string> _inverses = new List<string>();
|
||||||
|
|
|
@ -14,8 +14,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public ControllerDefinition Definition => Source.Definition;
|
public ControllerDefinition Definition => Source.Definition;
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public bool IsPressed(string button)
|
public bool IsPressed(string button)
|
||||||
{
|
{
|
||||||
var source = Source.IsPressed(button);
|
var source = Source.IsPressed(button);
|
||||||
|
@ -110,8 +108,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public ControllerDefinition Definition => Source.Definition;
|
public ControllerDefinition Definition => Source.Definition;
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public bool IsPressed(string button)
|
public bool IsPressed(string button)
|
||||||
{
|
{
|
||||||
var source = Source.IsPressed(button);
|
var source = Source.IsPressed(button);
|
||||||
|
@ -216,4 +212,4 @@ namespace BizHawk.Client.Common
|
||||||
_justPressed = buttons;
|
_justPressed = buttons;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
public ControllerDefinition Definition => Source.Definition;
|
public ControllerDefinition Definition => Source.Definition;
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public OpposingDirPolicy OpposingDirPolicy { get; set; }
|
public OpposingDirPolicy OpposingDirPolicy { get; set; }
|
||||||
|
|
||||||
public bool IsPressed(string button)
|
public bool IsPressed(string button)
|
||||||
|
|
|
@ -52,12 +52,13 @@ namespace BizHawk.Client.Common
|
||||||
public IInputAdapter MovieOut { get; } = new CopyControllerAdapter();
|
public IInputAdapter MovieOut { get; } = new CopyControllerAdapter();
|
||||||
public IStickyAdapter StickySource { get; set; }
|
public IStickyAdapter StickySource { get; set; }
|
||||||
|
|
||||||
public IMovieController MovieController { get; private set; } = new Bk2Controller("", NullController.Instance.Definition);
|
public IMovieController MovieController { get; private set; } = new Bk2Controller(NullController.Instance.Definition);
|
||||||
|
|
||||||
public IMovieController GenerateMovieController(ControllerDefinition definition = null)
|
public IMovieController GenerateMovieController(ControllerDefinition definition = null, string logKey = null)
|
||||||
{
|
{
|
||||||
// TODO: expose Movie.LogKey and pass in here
|
// TODO: should this fallback to Movie.LogKey?
|
||||||
return new Bk2Controller("", definition ?? MovieController.Definition);
|
// this function is kinda weird
|
||||||
|
return new Bk2Controller(definition ?? MovieController.Definition, logKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleFrameBefore()
|
public void HandleFrameBefore()
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using BizHawk.Common;
|
using BizHawk.Common;
|
||||||
|
@ -14,38 +13,22 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
private readonly Dictionary<string, bool> _myBoolButtons = new();
|
private readonly Dictionary<string, bool> _myBoolButtons = new();
|
||||||
|
|
||||||
private readonly Bk2ControllerDefinition _type;
|
public Bk2Controller(ControllerDefinition definition, string logKey) : this(definition)
|
||||||
|
|
||||||
private IReadOnlyList<ControlMap> _controlsOrdered;
|
|
||||||
|
|
||||||
private IReadOnlyList<ControlMap> ControlsOrdered
|
|
||||||
=> _controlsOrdered
|
|
||||||
??= _type.OrderedControlsFlat.Select(name => new ControlMap(name, _type)).ToArray();
|
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public Bk2Controller(string key, ControllerDefinition definition) : this(definition)
|
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(key))
|
if (!string.IsNullOrEmpty(logKey))
|
||||||
{
|
Definition = new Bk2ControllerDefinition(definition, logKey);
|
||||||
var groups = key.Split(new[] { "#" }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
|
|
||||||
_type.ControlsFromLog = groups
|
|
||||||
.Select(group => group.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries).ToList())
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bk2Controller(ControllerDefinition definition)
|
public Bk2Controller(ControllerDefinition definition)
|
||||||
{
|
{
|
||||||
_type = new Bk2ControllerDefinition(definition);
|
Definition = definition;
|
||||||
foreach ((string axisName, AxisSpec range) in definition.Axes)
|
foreach ((string axisName, AxisSpec range) in definition.Axes)
|
||||||
{
|
{
|
||||||
_myAxisControls[axisName] = range.Neutral;
|
_myAxisControls[axisName] = range.Neutral;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControllerDefinition Definition => _type;
|
public ControllerDefinition Definition { get; }
|
||||||
|
|
||||||
public int AxisValue(string name)
|
public int AxisValue(string name)
|
||||||
=> _myAxisControls.GetValueOrDefault(name);
|
=> _myAxisControls.GetValueOrDefault(name);
|
||||||
|
@ -87,16 +70,12 @@ namespace BizHawk.Client.Common
|
||||||
if (string.IsNullOrWhiteSpace(mnemonic)) return;
|
if (string.IsNullOrWhiteSpace(mnemonic)) return;
|
||||||
var iterator = 0;
|
var iterator = 0;
|
||||||
|
|
||||||
foreach (var key in ControlsOrdered)
|
foreach (var playerControls in Definition.ControlsOrdered)
|
||||||
|
foreach ((string buttonName, AxisSpec? axisSpec) in playerControls)
|
||||||
{
|
{
|
||||||
while (mnemonic[iterator] == '|') iterator++;
|
while (mnemonic[iterator] == '|') iterator++;
|
||||||
|
|
||||||
if (key.IsBool)
|
if (axisSpec.HasValue)
|
||||||
{
|
|
||||||
_myBoolButtons[key.Name] = mnemonic[iterator] != '.';
|
|
||||||
iterator++;
|
|
||||||
}
|
|
||||||
else if (key.IsAxis)
|
|
||||||
{
|
{
|
||||||
var commaIndex = mnemonic.IndexOf(',', iterator);
|
var commaIndex = mnemonic.IndexOf(',', iterator);
|
||||||
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
|
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
|
||||||
|
@ -105,10 +84,15 @@ namespace BizHawk.Client.Common
|
||||||
var axisValueString = mnemonic.Substring(startIndex: iterator, length: commaIndex - iterator);
|
var axisValueString = mnemonic.Substring(startIndex: iterator, length: commaIndex - iterator);
|
||||||
var val = int.Parse(axisValueString);
|
var val = int.Parse(axisValueString);
|
||||||
#endif
|
#endif
|
||||||
_myAxisControls[key.Name] = val;
|
_myAxisControls[buttonName] = val;
|
||||||
|
|
||||||
iterator = commaIndex + 1;
|
iterator = commaIndex + 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_myBoolButtons[buttonName] = mnemonic[iterator] != '.';
|
||||||
|
iterator++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,40 +106,23 @@ namespace BizHawk.Client.Common
|
||||||
_myAxisControls[buttonName] = value;
|
_myAxisControls[buttonName] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly struct ControlMap
|
|
||||||
{
|
|
||||||
public readonly bool IsAxis;
|
|
||||||
|
|
||||||
public readonly bool IsBool;
|
|
||||||
|
|
||||||
public readonly string Name;
|
|
||||||
|
|
||||||
public ControlMap(string name, bool isButton, bool isAxis)
|
|
||||||
{
|
|
||||||
Debug.Assert(isButton ^ isAxis, "axis conflicts with button of the same name?");
|
|
||||||
Name = name;
|
|
||||||
IsBool = isButton;
|
|
||||||
IsAxis = isAxis;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ControlMap(string name, ControllerDefinition def)
|
|
||||||
: this(
|
|
||||||
name: name,
|
|
||||||
isButton: def.BoolButtons.Contains(name),
|
|
||||||
isAxis: def.Axes.ContainsKey(name)) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Bk2ControllerDefinition : ControllerDefinition
|
private class Bk2ControllerDefinition : ControllerDefinition
|
||||||
{
|
{
|
||||||
public IReadOnlyList<IReadOnlyList<string>> ControlsFromLog = null;
|
private readonly IReadOnlyList<IReadOnlyList<(string, AxisSpec?)>> _controlsFromLogKey;
|
||||||
|
|
||||||
public Bk2ControllerDefinition(ControllerDefinition source)
|
public Bk2ControllerDefinition(ControllerDefinition sourceDefinition, string logKey)
|
||||||
: base(source)
|
: base(sourceDefinition)
|
||||||
{
|
{
|
||||||
|
var groups = logKey.Split(new[] { "#" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
_controlsFromLogKey = groups
|
||||||
|
.Select(group => group.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(buttonname => (buttonname, sourceDefinition.Axes.TryGetValue(buttonname, out var axisSpec) ? axisSpec : (AxisSpec?)null))
|
||||||
|
.ToArray())
|
||||||
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyList<IReadOnlyList<string>> GenOrderedControls()
|
protected override IReadOnlyList<IReadOnlyList<(string Name, AxisSpec? AxisSpec)>> GenOrderedControls() => _controlsFromLogKey;
|
||||||
=> ControlsFromLog is not null && ControlsFromLog.Count is not 0 ? ControlsFromLog : base.GenOrderedControls();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
@ -6,43 +5,17 @@ using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
namespace BizHawk.Client.Common
|
namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
// Designed to be able to last the lifetime of an IMovie
|
public static class Bk2LogEntryGenerator
|
||||||
public sealed class Bk2LogEntryGenerator
|
|
||||||
{
|
{
|
||||||
private readonly string _systemId;
|
/// <summary>
|
||||||
private readonly IController _source;
|
/// Gets an input log entry that is considered empty. (booleans will be false, axes will be neutral)
|
||||||
|
/// </summary>
|
||||||
private readonly Dictionary<string, char> _mnemonics = new();
|
public static string EmptyEntry(IController source) => CreateLogEntry(source, createEmpty: true);
|
||||||
private readonly List<IReadOnlyList<string>> _controlsOrdered;
|
|
||||||
|
|
||||||
public Bk2LogEntryGenerator(string systemId, IController source)
|
|
||||||
{
|
|
||||||
_systemId = systemId;
|
|
||||||
_source = source;
|
|
||||||
_controlsOrdered = _source.Definition.ControlsOrdered.Where(static c => c.Count is not 0).ToList();
|
|
||||||
foreach (var group in _controlsOrdered) foreach (var button in group)
|
|
||||||
{
|
|
||||||
var found = Bk2MnemonicLookup.Lookup(button, _systemId);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_mnemonics.Add(button, found);
|
|
||||||
}
|
|
||||||
catch (ArgumentException e)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(innerException: e, paramName: nameof(source), message: $"duplicate KEY {button} in input log mnemonic cache (was {_mnemonics[button]}, attempting to set {found})");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an input log entry that is considered empty. (booleans will be false, axes will be 0)
|
/// Generates an input log entry for the current state of source
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string EmptyEntry => CreateLogEntry(createEmpty: true);
|
public static string GenerateLogEntry(IController source) => CreateLogEntry(source);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generates an input log entry for the current state of Source
|
|
||||||
/// </summary>
|
|
||||||
public string GenerateLogEntry() => CreateLogEntry();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a human readable key that will specify the names of the
|
/// Generates a human readable key that will specify the names of the
|
||||||
|
@ -57,55 +30,37 @@ namespace BizHawk.Client.Common
|
||||||
foreach (var group in definition.ControlsOrdered.Where(static c => c.Count is not 0))
|
foreach (var group in definition.ControlsOrdered.Where(static c => c.Count is not 0))
|
||||||
{
|
{
|
||||||
sb.Append('#');
|
sb.Append('#');
|
||||||
foreach (var button in group)
|
foreach ((string buttonName, _) in group)
|
||||||
{
|
{
|
||||||
sb.Append(button).Append('|');
|
sb.Append(buttonName).Append('|');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private static string CreateLogEntry(IController source, bool createEmpty = false)
|
||||||
/// Generates a dictionary of button names to their corresponding mnemonic values
|
|
||||||
/// </summary>
|
|
||||||
public IDictionary<string, string> Map()
|
|
||||||
{
|
{
|
||||||
var dict = new Dictionary<string, string>();
|
if (!createEmpty && source.Definition.MnemonicsCache is null)
|
||||||
foreach (var button in _source.Definition.OrderedControlsFlat)
|
throw new InvalidOperationException("Can't generate log entry with empty mnemonics cache");
|
||||||
{
|
|
||||||
if (_source.Definition.BoolButtons.Contains(button))
|
|
||||||
{
|
|
||||||
dict.Add(button, Bk2MnemonicLookup.Lookup(button, _systemId).ToString());
|
|
||||||
}
|
|
||||||
else if (_source.Definition.Axes.ContainsKey(button))
|
|
||||||
{
|
|
||||||
dict.Add(button, Bk2MnemonicLookup.LookupAxis(button, _systemId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string CreateLogEntry(bool createEmpty = false)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
sb.Append('|');
|
sb.Append('|');
|
||||||
|
|
||||||
foreach (var group in _controlsOrdered)
|
foreach (var group in source.Definition.ControlsOrdered)
|
||||||
{
|
{
|
||||||
foreach (var button in group)
|
foreach ((string buttonName, var axisSpec) in group)
|
||||||
{
|
{
|
||||||
if (_source.Definition.Axes.TryGetValue(button, out var range))
|
if (axisSpec.HasValue)
|
||||||
{
|
{
|
||||||
var val = createEmpty ? range.Neutral : _source.AxisValue(button);
|
var val = createEmpty ? axisSpec.Value.Neutral : source.AxisValue(buttonName);
|
||||||
sb.Append(val.ToString().PadLeft(5, ' ')).Append(',');
|
sb.Append(val.ToString().PadLeft(5, ' ')).Append(',');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sb.Append(!createEmpty && _source.IsPressed(button)
|
sb.Append(!createEmpty && source.IsPressed(buttonName)
|
||||||
? _mnemonics[button]
|
? source.Definition.MnemonicsCache[buttonName]
|
||||||
: '.');
|
: '.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using BizHawk.Common.StringExtensions;
|
using BizHawk.Common.StringExtensions;
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
using BizHawk.Emulation.Cores.Libretro;
|
using BizHawk.Emulation.Cores.Libretro;
|
||||||
|
|
||||||
// ReSharper disable StyleCop.SA1509
|
|
||||||
namespace BizHawk.Client.Common
|
namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
internal static class Bk2MnemonicLookup
|
public static class Bk2MnemonicLookup
|
||||||
{
|
{
|
||||||
public static char Lookup(string button, string systemId)
|
public static char Lookup(string button, string systemId)
|
||||||
{
|
{
|
||||||
|
@ -65,6 +63,8 @@ namespace BizHawk.Client.Common
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Func<string, char> MnemonicFunc(string systemId) => buttonName => Lookup(buttonName, systemId);
|
||||||
|
|
||||||
private static readonly Dictionary<string, char> BaseMnemonicLookupTable = new Dictionary<string, char>
|
private static readonly Dictionary<string, char> BaseMnemonicLookupTable = new Dictionary<string, char>
|
||||||
{
|
{
|
||||||
["Power"] = 'P',
|
["Power"] = 'P',
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace BizHawk.Client.Common
|
||||||
public partial class Bk2Movie : BasicMovieInfo, IMovie
|
public partial class Bk2Movie : BasicMovieInfo, IMovie
|
||||||
{
|
{
|
||||||
private Bk2Controller _adapter;
|
private Bk2Controller _adapter;
|
||||||
//private Bk2LogEntryGenerator _logGenerator;
|
|
||||||
public Bk2Movie(IMovieSession session, string filename) : base(filename)
|
public Bk2Movie(IMovieSession session, string filename) : base(filename)
|
||||||
{
|
{
|
||||||
Session = session;
|
Session = session;
|
||||||
|
@ -32,18 +32,6 @@ namespace BizHawk.Client.Common
|
||||||
public virtual bool Changes { get; protected set; }
|
public virtual bool Changes { get; protected set; }
|
||||||
public bool IsCountingRerecords { get; set; } = true;
|
public bool IsCountingRerecords { get; set; } = true;
|
||||||
|
|
||||||
public Bk2LogEntryGenerator LogGeneratorInstance(IController source)
|
|
||||||
{
|
|
||||||
// Hack because initial movie loading is a mess, and you will immediate create a file with an undefined controller
|
|
||||||
//if (!source.Definition.Any())
|
|
||||||
{
|
|
||||||
return new Bk2LogEntryGenerator(Emulator?.SystemId ?? SystemID, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
//_logGenerator ??= new Bk2LogEntryGenerator(Emulator?.SystemId ?? SystemID, source);
|
|
||||||
//return _logGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int FrameCount => Log.Count;
|
public override int FrameCount => Log.Count;
|
||||||
public int InputLogLength => Log.Count;
|
public int InputLogLength => Log.Count;
|
||||||
|
|
||||||
|
@ -60,8 +48,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
public void AppendFrame(IController source)
|
public void AppendFrame(IController source)
|
||||||
{
|
{
|
||||||
var lg = LogGeneratorInstance(source);
|
Log.Add(Bk2LogEntryGenerator.GenerateLogEntry(source));
|
||||||
Log.Add(lg.GenerateLogEntry());
|
|
||||||
Changes = true;
|
Changes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +62,7 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(source);
|
SetFrameAt(frame, Bk2LogEntryGenerator.GenerateLogEntry(source));
|
||||||
SetFrameAt(frame, lg.GenerateLogEntry());
|
|
||||||
|
|
||||||
Changes = true;
|
Changes = true;
|
||||||
}
|
}
|
||||||
|
@ -94,8 +80,8 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
if (frame < FrameCount && frame >= -1)
|
if (frame < FrameCount && frame >= -1)
|
||||||
{
|
{
|
||||||
_adapter ??= new Bk2Controller(LogKey, Session.MovieController.Definition);
|
_adapter ??= new Bk2Controller(Session.MovieController.Definition, LogKey);
|
||||||
_adapter.SetFromMnemonic(frame >= 0 ? Log[frame] : Session.Movie.LogGeneratorInstance(Session.MovieController).EmptyEntry);
|
_adapter.SetFromMnemonic(frame >= 0 ? Log[frame] : Bk2LogEntryGenerator.EmptyEntry(_adapter));
|
||||||
return _adapter;
|
return _adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,8 +90,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
public virtual void PokeFrame(int frame, IController source)
|
public virtual void PokeFrame(int frame, IController source)
|
||||||
{
|
{
|
||||||
var lg = LogGeneratorInstance(source);
|
SetFrameAt(frame, Bk2LogEntryGenerator.GenerateLogEntry(source));
|
||||||
SetFrameAt(frame, lg.GenerateLogEntry());
|
|
||||||
Changes = true;
|
Changes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
private void ImportInputFrame(string line)
|
private void ImportInputFrame(string line)
|
||||||
{
|
{
|
||||||
|
DeSmuMEControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
SimpleController controller = new(DeSmuMEControllerDef);
|
SimpleController controller = new(DeSmuMEControllerDef);
|
||||||
|
|
||||||
controller["LidOpen"] = false;
|
controller["LidOpen"] = false;
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
NesRightPort = nameof(ControllerNES)
|
NesRightPort = nameof(ControllerNES)
|
||||||
};
|
};
|
||||||
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
|
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
|
||||||
|
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
|
|
||||||
// 004 4-byte little-endian unsigned int: version number, must be 2
|
// 004 4-byte little-endian unsigned int: version number, must be 2
|
||||||
uint version = r.ReadUInt32();
|
uint version = r.ReadUInt32();
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace BizHawk.Client.Common
|
||||||
};
|
};
|
||||||
|
|
||||||
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
|
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
|
||||||
|
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
|
|
||||||
Result.Movie.HeaderEntries[HeaderKeys.Platform] = platform;
|
Result.Movie.HeaderEntries[HeaderKeys.Platform] = platform;
|
||||||
|
|
||||||
|
@ -120,6 +121,7 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
controllerSettings.NesLeftPort = nameof(ControllerNES);
|
controllerSettings.NesLeftPort = nameof(ControllerNES);
|
||||||
_deck = controllerSettings.Instantiate((x, y) => false).AddSystemToControllerDef();
|
_deck = controllerSettings.Instantiate((x, y) => false).AddSystemToControllerDef();
|
||||||
|
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (line.StartsWith("port1", StringComparison.OrdinalIgnoreCase))
|
else if (line.StartsWith("port1", StringComparison.OrdinalIgnoreCase))
|
||||||
|
@ -128,6 +130,7 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
controllerSettings.NesRightPort = nameof(ControllerNES);
|
controllerSettings.NesRightPort = nameof(ControllerNES);
|
||||||
_deck = controllerSettings.Instantiate((x, y) => false).AddSystemToControllerDef();
|
_deck = controllerSettings.Instantiate((x, y) => false).AddSystemToControllerDef();
|
||||||
|
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (line.StartsWith("port2", StringComparison.OrdinalIgnoreCase))
|
else if (line.StartsWith("port2", StringComparison.OrdinalIgnoreCase))
|
||||||
|
@ -148,6 +151,7 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
_deck = controllerSettings.Instantiate((x, y) => false)/*.AddSystemToControllerDef()*/; //TODO call omitted on purpose? --yoshi
|
_deck = controllerSettings.Instantiate((x, y) => false)/*.AddSystemToControllerDef()*/; //TODO call omitted on purpose? --yoshi
|
||||||
|
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -157,6 +161,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
syncSettings.Controls = controllerSettings;
|
syncSettings.Controls = controllerSettings;
|
||||||
Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(syncSettings);
|
Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(syncSettings);
|
||||||
|
Result.Movie.LogKey = Bk2LogEntryGenerator.GenerateLogKey(_deck.ControllerDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IControllerDeck _deck;
|
private IControllerDeck _deck;
|
||||||
|
|
|
@ -94,6 +94,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
NesRightPort = controller2 ? nameof(ControllerNES) : nameof(UnpluggedNES)
|
NesRightPort = controller2 ? nameof(ControllerNES) : nameof(UnpluggedNES)
|
||||||
};
|
};
|
||||||
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
|
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
|
||||||
|
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
syncSettings.Controls.NesLeftPort = controllerSettings.NesLeftPort;
|
syncSettings.Controls.NesLeftPort = controllerSettings.NesLeftPort;
|
||||||
syncSettings.Controls.NesRightPort = controllerSettings.NesRightPort;
|
syncSettings.Controls.NesRightPort = controllerSettings.NesRightPort;
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,8 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
}
|
}
|
||||||
|
|
||||||
GPGXControlConverter controlConverter = new(input, systemId: VSystemID.Raw.GEN, cdButtons: false);
|
GPGXControlConverter controlConverter = new(input, systemId: VSystemID.Raw.GEN, cdButtons: false);
|
||||||
|
|
||||||
|
controlConverter.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
SimpleController controller = new(controlConverter.ControllerDef);
|
SimpleController controller = new(controlConverter.ControllerDef);
|
||||||
|
|
||||||
// Unknown.
|
// Unknown.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -21,9 +20,9 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
private SimpleController _controller;
|
private SimpleController _controller;
|
||||||
private SimpleController _emptyController;
|
private SimpleController _emptyController;
|
||||||
|
|
||||||
private readonly string[][] _lsnesGamepadButtons = Enumerable.Range(1, 8)
|
private readonly (string, AxisSpec?)[][] _lsnesGamepadButtons = Enumerable.Range(1, 8)
|
||||||
.Select(player => new[] { "B", "Y", "Select", "Start", "Up", "Down", "Left", "Right", "A", "X", "L", "R" }
|
.Select(player => new[] { "B", "Y", "Select", "Start", "Up", "Down", "Left", "Right", "A", "X", "L", "R" }
|
||||||
.Select(button => $"P{player} {button}").ToArray())
|
.Select(button => ($"P{player} {button}", (AxisSpec?)null)).ToArray())
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
protected override void RunImport()
|
protected override void RunImport()
|
||||||
|
@ -85,6 +84,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerDefinition controllerDefinition = new BsnesControllers(ss, true).Definition;
|
ControllerDefinition controllerDefinition = new BsnesControllers(ss, true).Definition;
|
||||||
|
controllerDefinition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.SNES));
|
||||||
_emptyController = new SimpleController(controllerDefinition);
|
_emptyController = new SimpleController(controllerDefinition);
|
||||||
_controller = new SimpleController(controllerDefinition);
|
_controller = new SimpleController(controllerDefinition);
|
||||||
_playerCount = controllerDefinition.PlayerCount;
|
_playerCount = controllerDefinition.PlayerCount;
|
||||||
|
@ -312,8 +312,8 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
{
|
{
|
||||||
if (player > _playerCount) break;
|
if (player > _playerCount) break;
|
||||||
|
|
||||||
IReadOnlyList<string> buttons = _controller.Definition.ControlsOrdered[player];
|
var buttons = _controller.Definition.ControlsOrdered[player];
|
||||||
if (buttons[0].EndsWithOrdinal("Up")) // hack to identify gamepad / multitap which have a different button order in bizhawk compared to lsnes
|
if (buttons[0].Name.EndsWithOrdinal("Up")) // hack to identify gamepad / multitap which have a different button order in bizhawk compared to lsnes
|
||||||
{
|
{
|
||||||
buttons = _lsnesGamepadButtons[player - 1];
|
buttons = _lsnesGamepadButtons[player - 1];
|
||||||
}
|
}
|
||||||
|
@ -323,7 +323,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
for (int button = 0; button < buttons.Count; button++)
|
for (int button = 0; button < buttons.Count; button++)
|
||||||
{
|
{
|
||||||
// Consider the button pressed so long as its spot is not occupied by a ".".
|
// Consider the button pressed so long as its spot is not occupied by a ".".
|
||||||
_controller[buttons[button]] = sections[player][button] != '.';
|
_controller[buttons[button].Name] = sections[player][button] != '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
{
|
{
|
||||||
var buttons = new[] { "Up", "Down", "Left", "Right", "B1", "B2", "Run", "Select" };
|
var buttons = new[] { "Up", "Down", "Left", "Right", "B1", "B2", "Run", "Select" };
|
||||||
|
|
||||||
|
_deck.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
SimpleController controllers = new(_deck.Definition);
|
SimpleController controllers = new(_deck.Definition);
|
||||||
|
|
||||||
// Split up the sections of the frame.
|
// Split up the sections of the frame.
|
||||||
|
|
|
@ -95,6 +95,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
|
|
||||||
var ss = new SMS.SmsSyncSettings();
|
var ss = new SMS.SmsSyncSettings();
|
||||||
var cd = new SMSControllerDeck(ss.Port1, ss.Port2, isGameGear, ss.UseKeyboard);
|
var cd = new SMSControllerDeck(ss.Port1, ss.Port2, isGameGear, ss.UseKeyboard);
|
||||||
|
cd.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
SimpleController controllers = new(cd.Definition);
|
SimpleController controllers = new(cd.Definition);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -181,6 +181,7 @@ namespace BizHawk.Client.Common
|
||||||
OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None
|
OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None
|
||||||
};
|
};
|
||||||
SimpleController controllers = new(Octoshock.CreateControllerDefinition(settings));
|
SimpleController controllers = new(Octoshock.CreateControllerDefinition(settings));
|
||||||
|
controllers.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
|
|
||||||
string[] buttons =
|
string[] buttons =
|
||||||
{
|
{
|
||||||
|
@ -291,6 +292,7 @@ namespace BizHawk.Client.Common
|
||||||
OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None
|
OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None
|
||||||
};
|
};
|
||||||
SimpleController controllers = new(Octoshock.CreateControllerDefinition(settings));
|
SimpleController controllers = new(Octoshock.CreateControllerDefinition(settings));
|
||||||
|
controllers.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
|
|
||||||
string[] buttons =
|
string[] buttons =
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result.Movie.HeaderEntries[HeaderKeys.Platform] = VSystemID.Raw.SNES;
|
Result.Movie.SystemID = VSystemID.Raw.SNES;
|
||||||
|
|
||||||
// 004 4-byte little-endian unsigned int: version number
|
// 004 4-byte little-endian unsigned int: version number
|
||||||
uint versionNumber = r.ReadUInt32();
|
uint versionNumber = r.ReadUInt32();
|
||||||
|
@ -189,6 +189,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerDefinition definition = new Snes9xControllers(ss).ControllerDefinition;
|
ControllerDefinition definition = new Snes9xControllers(ss).ControllerDefinition;
|
||||||
|
definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
SimpleController controllers = new(definition);
|
SimpleController controllers = new(definition);
|
||||||
|
|
||||||
Result.Movie.LogKey = Bk2LogEntryGenerator.GenerateLogKey(definition);
|
Result.Movie.LogKey = Bk2LogEntryGenerator.GenerateLogKey(definition);
|
||||||
|
|
|
@ -203,6 +203,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
SimpleController controllers = isGBA
|
SimpleController controllers = isGBA
|
||||||
? GbaController()
|
? GbaController()
|
||||||
: GbController();
|
: GbController();
|
||||||
|
controllers.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(isGBA ? VSystemID.Raw.GBA : VSystemID.Raw.GB));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 01 00 A
|
* 01 00 A
|
||||||
|
|
|
@ -106,6 +106,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
"Reset", "Power", "Previous Disk", "Next Disk", "P1 Left", "P1 Right", "P1 Up", "P1 Down", "P1 Start", "P1 A", "P1 B", "P1 C", "P1 X", "P1 Y", "P1 Z", "P1 L", "P1 R"
|
"Reset", "Power", "Previous Disk", "Next Disk", "P1 Left", "P1 Right", "P1 Up", "P1 Down", "P1 Start", "P1 A", "P1 B", "P1 C", "P1 X", "P1 Y", "P1 Z", "P1 L", "P1 R"
|
||||||
}
|
}
|
||||||
}.MakeImmutable());
|
}.MakeImmutable());
|
||||||
|
controllers.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||||
|
|
||||||
// Split up the sections of the frame.
|
// Split up the sections of the frame.
|
||||||
var sections = line.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
|
var sections = line.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
@ -128,7 +129,7 @@ namespace BizHawk.Client.Common.movie.import
|
||||||
for (int button = 0; button < buttonNames.Count; button++)
|
for (int button = 0; button < buttonNames.Count; button++)
|
||||||
{
|
{
|
||||||
// Consider the button pressed so long as its spot is not occupied by a ".".
|
// Consider the button pressed so long as its spot is not occupied by a ".".
|
||||||
controllers[buttonNames[button]] = sections[1][button] != '.';
|
controllers[buttonNames[button].Name] = sections[1][button] != '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,6 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
internal class BkmControllerAdapter : IController
|
internal class BkmControllerAdapter : IController
|
||||||
{
|
{
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public BkmControllerAdapter(ControllerDefinition definition, string systemId)
|
public BkmControllerAdapter(ControllerDefinition definition, string systemId)
|
||||||
{
|
{
|
||||||
// We do need to map the definition name to the legacy
|
// We do need to map the definition name to the legacy
|
||||||
|
@ -34,6 +32,7 @@ namespace BizHawk.Client.Common
|
||||||
_ => "Null Controller",
|
_ => "Null Controller",
|
||||||
};
|
};
|
||||||
Definition = new(copyFrom: definition, withName: name);
|
Definition = new(copyFrom: definition, withName: name);
|
||||||
|
Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(systemId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControllerDefinition Definition { get; set; }
|
public ControllerDefinition Definition { get; set; }
|
||||||
|
|
|
@ -74,11 +74,6 @@ namespace BizHawk.Client.Common
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SaveBackup();
|
void SaveBackup();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a log generator using the given input source
|
|
||||||
/// </summary>
|
|
||||||
Bk2LogEntryGenerator LogGeneratorInstance(IController source);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instructs the movie to save the current contents to Filename
|
/// Instructs the movie to save the current contents to Filename
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -48,11 +48,10 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a <see cref="IMovieController" /> instance based on the
|
/// Creates a <see cref="IMovieController" /> instance based on the
|
||||||
/// given button definition if provided else the
|
/// given button definition if provided else the current
|
||||||
/// current <see cref="MovieController" /> button definition
|
/// <see cref="MovieController"/>s button definition will be used
|
||||||
/// will be used
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IMovieController GenerateMovieController(ControllerDefinition definition = null);
|
IMovieController GenerateMovieController(ControllerDefinition definition = null, string logKey = null);
|
||||||
|
|
||||||
void HandleFrameBefore();
|
void HandleFrameBefore();
|
||||||
void HandleFrameAfter();
|
void HandleFrameAfter();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
namespace BizHawk.Client.Common
|
namespace BizHawk.Client.Common
|
||||||
|
|
|
@ -20,8 +20,7 @@ namespace BizHawk.Client.Common
|
||||||
ChangeLog.AddGeneralUndo(frame - 1, frame - 1, $"Record Frame: {frame}");
|
ChangeLog.AddGeneralUndo(frame - 1, frame - 1, $"Record Frame: {frame}");
|
||||||
}
|
}
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(source);
|
SetFrameAt(frame, Bk2LogEntryGenerator.GenerateLogEntry(source));
|
||||||
SetFrameAt(frame, lg.GenerateLogEntry());
|
|
||||||
|
|
||||||
Changes = true;
|
Changes = true;
|
||||||
|
|
||||||
|
@ -86,8 +85,7 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
ChangeLog.AddGeneralUndo(frame, frame, $"Clear Frame: {frame}");
|
ChangeLog.AddGeneralUndo(frame, frame, $"Clear Frame: {frame}");
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(Session.MovieController);
|
SetFrameAt(frame, Bk2LogEntryGenerator.EmptyEntry(Session.MovieController));
|
||||||
SetFrameAt(frame, lg.EmptyEntry);
|
|
||||||
Changes = true;
|
Changes = true;
|
||||||
|
|
||||||
InvalidateAfter(frame);
|
InvalidateAfter(frame);
|
||||||
|
@ -210,8 +208,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
foreach (var input in inputStates)
|
foreach (var input in inputStates)
|
||||||
{
|
{
|
||||||
var lg = LogGeneratorInstance(input);
|
inputLog.Add(Bk2LogEntryGenerator.GenerateLogEntry(input));
|
||||||
inputLog.Add(lg.GenerateLogEntry());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertInput(frame, inputLog); // Sets the ChangeLog
|
InsertInput(frame, inputLog); // Sets the ChangeLog
|
||||||
|
@ -238,8 +235,7 @@ namespace BizHawk.Client.Common
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(states[i]);
|
var entry = Bk2LogEntryGenerator.GenerateLogEntry(states[i]);
|
||||||
var entry = lg.GenerateLogEntry();
|
|
||||||
if (firstChangedFrame == -1 && Log[frame + i] != entry)
|
if (firstChangedFrame == -1 && Log[frame + i] != entry)
|
||||||
{
|
{
|
||||||
firstChangedFrame = frame + i;
|
firstChangedFrame = frame + i;
|
||||||
|
@ -260,8 +256,7 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
frame = Math.Min(frame, Log.Count);
|
frame = Math.Min(frame, Log.Count);
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(Session.MovieController);
|
Log.InsertRange(frame, Enumerable.Repeat(Bk2LogEntryGenerator.EmptyEntry(Session.MovieController), count));
|
||||||
Log.InsertRange(frame, Enumerable.Repeat(lg.EmptyEntry, count).ToList());
|
|
||||||
|
|
||||||
ShiftBindedMarkers(frame, count);
|
ShiftBindedMarkers(frame, count);
|
||||||
|
|
||||||
|
@ -280,11 +275,9 @@ namespace BizHawk.Client.Common
|
||||||
Session.MovieController.SetFromSticky(Session.StickySource);
|
Session.MovieController.SetFromSticky(Session.StickySource);
|
||||||
|
|
||||||
// account for autohold. needs autohold pattern to be already recorded in the current frame
|
// account for autohold. needs autohold pattern to be already recorded in the current frame
|
||||||
var lg = LogGeneratorInstance(Session.MovieController);
|
|
||||||
|
|
||||||
for (int i = 0; i < numFrames; i++)
|
for (int i = 0; i < numFrames; i++)
|
||||||
{
|
{
|
||||||
Log.Add(lg.GenerateLogEntry());
|
Log.Add(Bk2LogEntryGenerator.GenerateLogEntry(Session.MovieController));
|
||||||
}
|
}
|
||||||
|
|
||||||
Changes = true;
|
Changes = true;
|
||||||
|
@ -306,8 +299,7 @@ namespace BizHawk.Client.Common
|
||||||
var adapter = GetInputState(frame);
|
var adapter = GetInputState(frame);
|
||||||
adapter.SetBool(buttonName, !adapter.IsPressed(buttonName));
|
adapter.SetBool(buttonName, !adapter.IsPressed(buttonName));
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(adapter);
|
Log[frame] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||||
Log[frame] = lg.GenerateLogEntry();
|
|
||||||
Changes = true;
|
Changes = true;
|
||||||
InvalidateAfter(frame);
|
InvalidateAfter(frame);
|
||||||
|
|
||||||
|
@ -325,8 +317,7 @@ namespace BizHawk.Client.Common
|
||||||
var old = adapter.IsPressed(buttonName);
|
var old = adapter.IsPressed(buttonName);
|
||||||
adapter.SetBool(buttonName, val);
|
adapter.SetBool(buttonName, val);
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(adapter);
|
Log[frame] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||||
Log[frame] = lg.GenerateLogEntry();
|
|
||||||
|
|
||||||
if (old != val)
|
if (old != val)
|
||||||
{
|
{
|
||||||
|
@ -352,8 +343,7 @@ namespace BizHawk.Client.Common
|
||||||
bool old = adapter.IsPressed(buttonName);
|
bool old = adapter.IsPressed(buttonName);
|
||||||
adapter.SetBool(buttonName, val);
|
adapter.SetBool(buttonName, val);
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(adapter);
|
Log[frame + i] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||||
Log[frame + i] = lg.GenerateLogEntry();
|
|
||||||
|
|
||||||
if (changed == -1 && old != val)
|
if (changed == -1 && old != val)
|
||||||
{
|
{
|
||||||
|
@ -381,8 +371,7 @@ namespace BizHawk.Client.Common
|
||||||
var old = adapter.AxisValue(buttonName);
|
var old = adapter.AxisValue(buttonName);
|
||||||
adapter.SetAxis(buttonName, val);
|
adapter.SetAxis(buttonName, val);
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(adapter);
|
Log[frame] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||||
Log[frame] = lg.GenerateLogEntry();
|
|
||||||
|
|
||||||
if (old != val)
|
if (old != val)
|
||||||
{
|
{
|
||||||
|
@ -408,8 +397,7 @@ namespace BizHawk.Client.Common
|
||||||
var old = adapter.AxisValue(buttonName);
|
var old = adapter.AxisValue(buttonName);
|
||||||
adapter.SetAxis(buttonName, val);
|
adapter.SetAxis(buttonName, val);
|
||||||
|
|
||||||
var lg = LogGeneratorInstance(adapter);
|
Log[frame + i] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||||
Log[frame + i] = lg.GenerateLogEntry();
|
|
||||||
|
|
||||||
if (changed == -1 && old != val)
|
if (changed == -1 && old != val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,15 +56,8 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Attach(emulator);
|
base.Attach(emulator);
|
||||||
|
|
||||||
foreach (var button in emulator.ControllerDefinition.BoolButtons)
|
|
||||||
{
|
|
||||||
_mnemonicCache[button] = Bk2MnemonicLookup.Lookup(button, emulator.SystemId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Dictionary<string, char> _mnemonicCache = new Dictionary<string, char>();
|
|
||||||
|
|
||||||
public override bool StartsFromSavestate
|
public override bool StartsFromSavestate
|
||||||
{
|
{
|
||||||
get => base.StartsFromSavestate;
|
get => base.StartsFromSavestate;
|
||||||
|
@ -146,7 +139,7 @@ namespace BizHawk.Client.Common
|
||||||
public void InvalidateEntireGreenzone()
|
public void InvalidateEntireGreenzone()
|
||||||
=> InvalidateAfter(0);
|
=> InvalidateAfter(0);
|
||||||
|
|
||||||
private (int Frame, IMovieController Controller) _displayCache = (-1, new Bk2Controller("", NullController.Instance.Definition));
|
private (int Frame, IMovieController Controller) _displayCache = (-1, new Bk2Controller(NullController.Instance.Definition));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the mnemonic value for boolean buttons, and actual value for axes,
|
/// Returns the mnemonic value for boolean buttons, and actual value for axes,
|
||||||
|
@ -162,12 +155,14 @@ namespace BizHawk.Client.Common
|
||||||
return CreateDisplayValueForButton(_displayCache.Controller, buttonName);
|
return CreateDisplayValueForButton(_displayCache.Controller, buttonName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CreateDisplayValueForButton(IController adapter, string buttonName)
|
private static string CreateDisplayValueForButton(IController adapter, string buttonName)
|
||||||
{
|
{
|
||||||
|
// those Contains checks could be avoided by passing in the button type
|
||||||
|
// this should be considered if this becomes a significant performance issue
|
||||||
if (adapter.Definition.BoolButtons.Contains(buttonName))
|
if (adapter.Definition.BoolButtons.Contains(buttonName))
|
||||||
{
|
{
|
||||||
return adapter.IsPressed(buttonName)
|
return adapter.IsPressed(buttonName)
|
||||||
? _mnemonicCache[buttonName].ToString()
|
? adapter.Definition.MnemonicsCache![buttonName].ToString()
|
||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
private int _dataSize;
|
private int _dataSize;
|
||||||
|
|
||||||
private Dictionary<string, double> _cachedControlProbabilities;
|
private Dictionary<string, double> _cachedControlProbabilities;
|
||||||
private Bk2LogEntryGenerator _logGenerator;
|
|
||||||
|
|
||||||
private bool _previousDisplayMessage;
|
private bool _previousDisplayMessage;
|
||||||
private bool _previousInvisibleEmulation;
|
private bool _previousInvisibleEmulation;
|
||||||
|
@ -1001,7 +1000,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
InputManager.SyncControls(Emulator, MovieSession, Config);
|
InputManager.SyncControls(Emulator, MovieSession, Config);
|
||||||
|
|
||||||
if (clear_log) { _currentBotAttempt.Log.Clear(); }
|
if (clear_log) { _currentBotAttempt.Log.Clear(); }
|
||||||
_currentBotAttempt.Log.Add(_logGenerator.GenerateLogEntry());
|
_currentBotAttempt.Log.Add(Bk2LogEntryGenerator.GenerateLogEntry(InputManager.ClickyVirtualPadController));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartBot()
|
private void StartBot()
|
||||||
|
@ -1027,7 +1026,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
MovieSession.Movie.IsCountingRerecords = false;
|
MovieSession.Movie.IsCountingRerecords = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logGenerator = MovieSession.Movie.LogGeneratorInstance(InputManager.ClickyVirtualPadController);
|
|
||||||
_cachedControlProbabilities = ControlProbabilities;
|
_cachedControlProbabilities = ControlProbabilities;
|
||||||
|
|
||||||
_doNotUpdateValues = true;
|
_doNotUpdateValues = true;
|
||||||
|
|
|
@ -34,8 +34,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
// Get a IController that only contains buttons in key.
|
// Get a IController that only contains buttons in key.
|
||||||
InitController(_inputKey);
|
InitController(_inputKey);
|
||||||
|
|
||||||
var logGenerator = movieSession.Movie.LogGeneratorInstance(_controller);
|
|
||||||
|
|
||||||
string movieKey = Bk2LogEntryGenerator.GenerateLogKey(_controller.Definition).Replace("#", "");
|
string movieKey = Bk2LogEntryGenerator.GenerateLogKey(_controller.Definition).Replace("#", "");
|
||||||
movieKey = movieKey.Substring(startIndex: 0, length: movieKey.Length - 1); // drop last char
|
movieKey = movieKey.Substring(startIndex: 0, length: movieKey.Length - 1); // drop last char
|
||||||
if (key == movieKey)
|
if (key == movieKey)
|
||||||
|
@ -50,7 +48,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
_controller.SetFrom(movieSession.Movie.GetInputState(i + start));
|
_controller.SetFrom(movieSession.Movie.GetInputState(i + start));
|
||||||
_log[i] = logGenerator.GenerateLogEntry();
|
_log[i] = Bk2LogEntryGenerator.GenerateLogEntry(_controller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,18 +113,15 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
|
|
||||||
var newController = _movieSession.GenerateMovieController(d.MakeImmutable());
|
var newController = _movieSession.GenerateMovieController(d.MakeImmutable());
|
||||||
var logGenerator = _movieSession.Movie.LogGeneratorInstance(newController);
|
|
||||||
logGenerator.GenerateLogEntry(); // Reference and create all buttons.
|
|
||||||
|
|
||||||
// Reset all buttons in targetController (it may still have buttons that aren't being set here set true)
|
// Reset all buttons in targetController (it may still have buttons that aren't being set here set true)
|
||||||
var tC = _movieSession.Movie.LogGeneratorInstance(_targetController);
|
_targetController.SetFromMnemonic(Bk2LogEntryGenerator.EmptyEntry(_targetController));
|
||||||
_targetController.SetFromMnemonic(tC.EmptyEntry);
|
|
||||||
for (int i = 0; i < Length; i++)
|
for (int i = 0; i < Length; i++)
|
||||||
{
|
{
|
||||||
_controller.SetFromMnemonic(_log[i]);
|
_controller.SetFromMnemonic(_log[i]);
|
||||||
LatchFromSourceButtons(_targetController, _controller);
|
LatchFromSourceButtons(_targetController, _controller);
|
||||||
newController.SetFrom(_targetController);
|
newController.SetFrom(_targetController);
|
||||||
_log[i] = logGenerator.GenerateLogEntry();
|
_log[i] = Bk2LogEntryGenerator.GenerateLogEntry(newController);
|
||||||
}
|
}
|
||||||
|
|
||||||
_controller = newController;
|
_controller = newController;
|
||||||
|
|
|
@ -418,7 +418,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
|
|
||||||
_tasClipboard.Add(new TasClipboardEntry(index, input));
|
_tasClipboard.Add(new TasClipboardEntry(index, input));
|
||||||
var logEntry = CurrentTasMovie.LogGeneratorInstance(input).GenerateLogEntry();
|
var logEntry = Bk2LogEntryGenerator.GenerateLogEntry(input);
|
||||||
sb.AppendLine(Settings.CopyIncludesFrameNo ? $"{FrameToStringPadded(index)} {logEntry}" : logEntry);
|
sb.AppendLine(Settings.CopyIncludesFrameNo ? $"{FrameToStringPadded(index)} {logEntry}" : logEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,8 +537,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
|
|
||||||
_tasClipboard.Add(new TasClipboardEntry(index, input));
|
_tasClipboard.Add(new TasClipboardEntry(index, input));
|
||||||
var lg = CurrentTasMovie.LogGeneratorInstance(input);
|
sb.AppendLine(Bk2LogEntryGenerator.GenerateLogEntry(input));
|
||||||
sb.AppendLine(lg.GenerateLogEntry());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Clipboard.SetDataObject(sb.ToString());
|
Clipboard.SetDataObject(sb.ToString());
|
||||||
|
|
|
@ -7,7 +7,6 @@ using System.ComponentModel;
|
||||||
using BizHawk.Client.Common;
|
using BizHawk.Client.Common;
|
||||||
using BizHawk.Client.EmuHawk.ToolExtensions;
|
using BizHawk.Client.EmuHawk.ToolExtensions;
|
||||||
using BizHawk.Client.EmuHawk.Properties;
|
using BizHawk.Client.EmuHawk.Properties;
|
||||||
using BizHawk.Common;
|
|
||||||
using BizHawk.Common.StringExtensions;
|
using BizHawk.Common.StringExtensions;
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
|
@ -351,31 +350,17 @@ namespace BizHawk.Client.EmuHawk
|
||||||
Rotatable = true,
|
Rotatable = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
var columnNames = MovieSession.Movie
|
foreach ((string name, string mnemonic0, int maxLength) in MnemonicMap())
|
||||||
.LogGeneratorInstance(MovieSession.MovieController)
|
|
||||||
.Map();
|
|
||||||
|
|
||||||
foreach (var (name, mnemonic0) in columnNames)
|
|
||||||
{
|
{
|
||||||
var mnemonic = Emulator.SystemId is VSystemID.Raw.N64 && N64CButtonSuffixes.Any(name.EndsWithOrdinal)
|
var mnemonic = Emulator.SystemId is VSystemID.Raw.N64 && N64CButtonSuffixes.Any(name.EndsWithOrdinal)
|
||||||
? $"c{mnemonic0.ToUpperInvariant()}" // prepend 'c' to differentiate from L/R buttons -- this only affects the column headers
|
? $"c{mnemonic0.ToUpperInvariant()}" // prepend 'c' to differentiate from L/R buttons -- this only affects the column headers
|
||||||
: mnemonic0;
|
: mnemonic0;
|
||||||
ColumnType type;
|
|
||||||
int digits;
|
var type = ControllerType.Axes.ContainsKey(name) ? ColumnType.Axis : ColumnType.Boolean;
|
||||||
if (ControllerType.Axes.TryGetValue(name, out var range))
|
|
||||||
{
|
|
||||||
type = ColumnType.Axis;
|
|
||||||
digits = Math.Max(mnemonic.Length, range.MaxDigits);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
type = ColumnType.Boolean;
|
|
||||||
digits = mnemonic.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
TasView.AllColumns.Add(new(
|
TasView.AllColumns.Add(new(
|
||||||
name: name,
|
name: name,
|
||||||
widthUnscaled: (digits * 6) + 14, // magic numbers reused in EditBranchTextPopUp() --feos // not since eb63fa5a9 (before 2.3.3) --yoshi
|
widthUnscaled: (maxLength * 6) + 14, // magic numbers reused in EditBranchTextPopUp() --feos // not since eb63fa5a9 (before 2.3.3) --yoshi
|
||||||
type: type,
|
type: type,
|
||||||
text: mnemonic));
|
text: mnemonic));
|
||||||
}
|
}
|
||||||
|
@ -497,8 +482,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var lg = CurrentTasMovie.LogGeneratorInstance(MovieSession.MovieController);
|
var empty = Bk2LogEntryGenerator.EmptyEntry(MovieSession.MovieController);
|
||||||
var empty = lg.EmptyEntry;
|
|
||||||
foreach (var row in TasView.SelectedRows)
|
foreach (var row in TasView.SelectedRows)
|
||||||
{
|
{
|
||||||
if (CurrentTasMovie[row].LogEntry != empty)
|
if (CurrentTasMovie[row].LogEntry != empty)
|
||||||
|
@ -1258,5 +1242,27 @@ namespace BizHawk.Client.EmuHawk
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<(string Name, string Mnemonic, int MaxLength)> MnemonicMap()
|
||||||
|
{
|
||||||
|
if (MovieSession.MovieController.Definition.MnemonicsCache is null)
|
||||||
|
throw new InvalidOperationException("Can't build mnemonic map with empty mnemonics cache");
|
||||||
|
|
||||||
|
foreach (var playerControls in MovieSession.MovieController.Definition.ControlsOrdered)
|
||||||
|
{
|
||||||
|
foreach ((string name, AxisSpec? axisSpec) in playerControls)
|
||||||
|
{
|
||||||
|
if (axisSpec.HasValue)
|
||||||
|
{
|
||||||
|
string mnemonic = Bk2MnemonicLookup.LookupAxis(name, MovieSession.Movie.SystemID);
|
||||||
|
yield return (name, mnemonic, Math.Max(mnemonic.Length, axisSpec.Value.MaxDigits));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yield return (name, MovieSession.MovieController.Definition.MnemonicsCache[name].ToString(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
#nullable disable
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
@ -21,38 +19,48 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
private bool _mutable = true;
|
private bool _mutable = true;
|
||||||
|
|
||||||
private IReadOnlyList<IReadOnlyList<string>> _orderedControls = null;
|
private IReadOnlyList<IReadOnlyList<(string, AxisSpec?)>>? _orderedControls;
|
||||||
|
|
||||||
private IReadOnlyList<string> _orderedControlsFlat = null;
|
|
||||||
|
|
||||||
/// <summary>starts with console buttons, then each player's buttons individually</summary>
|
/// <summary>starts with console buttons, then each player's buttons individually</summary>
|
||||||
public IReadOnlyList<IReadOnlyList<string>> ControlsOrdered
|
public IReadOnlyList<IReadOnlyList<(string Name, AxisSpec? AxisSpec)>> ControlsOrdered
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_orderedControls is not null) return _orderedControls;
|
if (_orderedControls is not null) return _orderedControls;
|
||||||
if (!_mutable) return _orderedControls = GenOrderedControls();
|
if (!_mutable) return _orderedControls = GenOrderedControls();
|
||||||
const string ERR_MSG = "this " + nameof(ControllerDefinition) + " has not yet been built and sealed, so it is not safe to enumerate this while it could still be mutated";
|
const string ERR_MSG = $"this {nameof(ControllerDefinition)} has not yet been built and sealed, so it is not safe to enumerate this while it could still be mutated";
|
||||||
throw new InvalidOperationException(ERR_MSG);
|
throw new InvalidOperationException(ERR_MSG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
|
|
||||||
public IReadOnlyList<string> OrderedControlsFlat => _orderedControlsFlat ??= ControlsOrdered.SelectMany(static s => s).ToList();
|
private Dictionary<string, char>? _mnemonicsCache;
|
||||||
|
public IReadOnlyDictionary<string, char>? MnemonicsCache => _mnemonicsCache;
|
||||||
|
|
||||||
|
/// <remarks>
|
||||||
|
/// TODO: this should probably be called in <see cref="MakeImmutable"/>,
|
||||||
|
/// but the needed Bk2MnemonicsLookup is in Client.Common
|
||||||
|
/// </remarks>
|
||||||
|
public void BuildMnemonicsCache(Func<string, char> mnemonicFunc)
|
||||||
|
{
|
||||||
|
if (_mutable)
|
||||||
|
throw new InvalidOperationException($"this {nameof(ControllerDefinition)} has not yet been built and sealed; can't build mnemonics cache");
|
||||||
|
|
||||||
|
_mnemonicsCache ??= BoolButtons.ToDictionary(buttonName => buttonName, mnemonicFunc);
|
||||||
|
}
|
||||||
|
|
||||||
public ControllerDefinition(string name)
|
public ControllerDefinition(string name)
|
||||||
=> Name = name;
|
=> Name = name;
|
||||||
|
|
||||||
public ControllerDefinition(ControllerDefinition copyFrom, string withName = null)
|
public ControllerDefinition(ControllerDefinition copyFrom, string? withName = null)
|
||||||
: this(withName ?? copyFrom.Name)
|
: this(withName ?? copyFrom.Name)
|
||||||
{
|
{
|
||||||
BoolButtons.AddRange(copyFrom.BoolButtons);
|
BoolButtons.AddRange(copyFrom.BoolButtons);
|
||||||
foreach (var kvp in copyFrom.Axes) Axes.Add(kvp);
|
foreach (var kvp in copyFrom.Axes) Axes.Add(kvp);
|
||||||
HapticsChannels.AddRange(copyFrom.HapticsChannels);
|
HapticsChannels.AddRange(copyFrom.HapticsChannels);
|
||||||
CategoryLabels = copyFrom.CategoryLabels;
|
CategoryLabels = copyFrom.CategoryLabels;
|
||||||
// Do not clone _orderedControls, as GenOrderedControls may be overridden by the derived class
|
_mnemonicsCache = copyFrom._mnemonicsCache;
|
||||||
// _orderedControls = copyFrom._orderedControls;
|
|
||||||
MakeImmutable();
|
MakeImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,11 +113,12 @@ namespace BizHawk.Emulation.Common
|
||||||
if (!_mutable) throw new InvalidOperationException(ERR_MSG);
|
if (!_mutable) throw new InvalidOperationException(ERR_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual IReadOnlyList<IReadOnlyList<string>> GenOrderedControls()
|
protected virtual IReadOnlyList<IReadOnlyList<(string Name, AxisSpec? AxisSpec)>> GenOrderedControls()
|
||||||
{
|
{
|
||||||
var ret = new List<string>[PlayerCount + 1];
|
var ret = new List<(string, AxisSpec?)>[PlayerCount + 1];
|
||||||
for (var i = 0; i < ret.Length; i++) ret[i] = new();
|
for (var i = 0; i < ret.Length; i++) ret[i] = new();
|
||||||
foreach (var btn in Axes.Keys.Concat(BoolButtons)) ret[PlayerNumber(btn)].Add(btn);
|
foreach ((string buttonName, var axisSpec) in Axes) ret[PlayerNumber(buttonName)].Add((buttonName, axisSpec));
|
||||||
|
foreach (var btn in BoolButtons) ret[PlayerNumber(btn)].Add((btn, null));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,6 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
public ControllerDefinition Definition { get; } = new ControllerDefinition("Null Controller").MakeImmutable();
|
public ControllerDefinition Definition { get; } = new ControllerDefinition("Null Controller").MakeImmutable();
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public bool IsPressed(string button) => false;
|
public bool IsPressed(string button) => false;
|
||||||
|
|
||||||
public int AxisValue(string name) => 0;
|
public int AxisValue(string name) => 0;
|
||||||
|
@ -23,6 +21,7 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
public void SetHapticChannelStrength(string name, int strength) {}
|
public void SetHapticChannelStrength(string name, int strength) {}
|
||||||
|
|
||||||
public static readonly NullController Instance = new NullController();
|
public static readonly NullController Instance = new();
|
||||||
|
private NullController() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,8 +69,6 @@ namespace BizHawk.Emulation.Common
|
||||||
|
|
||||||
private readonly IController _src;
|
private readonly IController _src;
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public DummyController(
|
public DummyController(
|
||||||
IController src,
|
IController src,
|
||||||
IReadOnlyDictionary<string, string> buttonAxisRemaps)
|
IReadOnlyDictionary<string, string> buttonAxisRemaps)
|
||||||
|
|
|
@ -11,9 +11,6 @@ namespace BizHawk.Emulation.Common
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ControllerDefinition Definition { get; }
|
ControllerDefinition Definition { get; }
|
||||||
|
|
||||||
/// <summary>used as cache by frontend; implement as autoprop w/ initial value <see langword="null"/></summary>
|
|
||||||
IInputDisplayGenerator InputDisplayGenerator { get; set; }
|
|
||||||
|
|
||||||
/// <seealso cref="SetHapticChannelStrength"/>
|
/// <seealso cref="SetHapticChannelStrength"/>
|
||||||
IReadOnlyCollection<(string Name, int Strength)> GetHapticsSnapshot();
|
IReadOnlyCollection<(string Name, int Strength)> GetHapticsSnapshot();
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
namespace BizHawk.Emulation.Common
|
|
||||||
{
|
|
||||||
public interface IInputDisplayGenerator
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Generates a display friendly version of the input log entry
|
|
||||||
/// </summary>
|
|
||||||
string Generate();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,8 +15,6 @@ namespace BizHawk.Emulation.Common
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, int> _buttons = new();
|
private readonly Dictionary<string, int> _buttons = new();
|
||||||
|
|
||||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
|
||||||
|
|
||||||
public SaveController()
|
public SaveController()
|
||||||
{
|
{
|
||||||
Definition = null;
|
Definition = null;
|
||||||
|
|
|
@ -112,18 +112,18 @@ namespace BizHawk.Emulation.Cores.Libretro
|
||||||
MakeImmutable();
|
MakeImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyList<IReadOnlyList<string>> GenOrderedControls()
|
protected override IReadOnlyList<IReadOnlyList<(string Name, AxisSpec? AxisSpec)>> GenOrderedControls()
|
||||||
{
|
{
|
||||||
// all this is to remove the keyboard buttons from P0 and put them in P3 so they appear at the end of the input display
|
// all this is to remove the keyboard buttons from P0 and put them in P3 so they appear at the end of the input display
|
||||||
var players = base.GenOrderedControls().ToList();
|
var players = base.GenOrderedControls().ToList();
|
||||||
List<string> retroKeyboard = new();
|
List<(string, AxisSpec?)> retroKeyboard = new();
|
||||||
var p0 = (List<string>) players[0];
|
var p0 = (List<(string, AxisSpec?)>) players[0];
|
||||||
for (var i = 0; i < p0.Count; /* incremented in body */)
|
for (var i = 0; i < p0.Count; /* incremented in body */)
|
||||||
{
|
{
|
||||||
var buttonName = p0[i];
|
(string ButtonName, AxisSpec?) button = p0[i];
|
||||||
if (CategoryLabels.TryGetValue(buttonName, out var v) && v is CAT_KEYBOARD)
|
if (CategoryLabels.TryGetValue(button.ButtonName, out var v) && v is CAT_KEYBOARD)
|
||||||
{
|
{
|
||||||
retroKeyboard.Add(buttonName);
|
retroKeyboard.Add(button);
|
||||||
p0.RemoveAt(i);
|
p0.RemoveAt(i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -15,18 +15,19 @@ namespace BizHawk.Tests.Client.Common.Display
|
||||||
public void Initializer()
|
public void Initializer()
|
||||||
{
|
{
|
||||||
_boolController = new(new ControllerDefinition("Dummy Gamepad") { BoolButtons = { "A" } }.MakeImmutable());
|
_boolController = new(new ControllerDefinition("Dummy Gamepad") { BoolButtons = { "A" } }.MakeImmutable());
|
||||||
|
_boolController.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.NULL));
|
||||||
_axisController = new(
|
_axisController = new(
|
||||||
new ControllerDefinition("Dummy Gamepad")
|
new ControllerDefinition("Dummy Gamepad")
|
||||||
.AddXYPair("Stick{0}", AxisPairOrientation.RightAndUp, 0.RangeTo(200), MidValue)
|
.AddXYPair("Stick{0}", AxisPairOrientation.RightAndUp, 0.RangeTo(200), MidValue)
|
||||||
.MakeImmutable());
|
.MakeImmutable());
|
||||||
|
_axisController.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Generate_BoolPressed_GeneratesMnemonic()
|
public void Generate_BoolPressed_GeneratesMnemonic()
|
||||||
{
|
{
|
||||||
_boolController["A"] = true;
|
_boolController["A"] = true;
|
||||||
var displayGenerator = new Bk2InputDisplayGenerator("NES", _boolController);
|
var actual = Bk2InputDisplayGenerator.Generate(_boolController);
|
||||||
var actual = displayGenerator.Generate();
|
|
||||||
Assert.AreEqual("A", actual);
|
Assert.AreEqual("A", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,16 +35,14 @@ namespace BizHawk.Tests.Client.Common.Display
|
||||||
public void Generate_BoolUnPressed_GeneratesSpace()
|
public void Generate_BoolUnPressed_GeneratesSpace()
|
||||||
{
|
{
|
||||||
_boolController["A"] = false;
|
_boolController["A"] = false;
|
||||||
var displayGenerator = new Bk2InputDisplayGenerator("NES", _boolController);
|
var actual = Bk2InputDisplayGenerator.Generate(_boolController);
|
||||||
var actual = displayGenerator.Generate();
|
|
||||||
Assert.AreEqual(" ", actual);
|
Assert.AreEqual(" ", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Generate_Floats()
|
public void Generate_Floats()
|
||||||
{
|
{
|
||||||
var displayGenerator = new Bk2InputDisplayGenerator("NES", _axisController);
|
var actual = Bk2InputDisplayGenerator.Generate(_axisController);
|
||||||
var actual = displayGenerator.Generate();
|
|
||||||
Assert.AreEqual(" 0, 0,", actual);
|
Assert.AreEqual(" 0, 0,", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +50,7 @@ namespace BizHawk.Tests.Client.Common.Display
|
||||||
public void Generate_MidRangeDisplaysEmpty()
|
public void Generate_MidRangeDisplaysEmpty()
|
||||||
{
|
{
|
||||||
_axisController.AcceptNewAxis("StickX", MidValue);
|
_axisController.AcceptNewAxis("StickX", MidValue);
|
||||||
var displayGenerator = new Bk2InputDisplayGenerator("NES", _axisController);
|
var actual = Bk2InputDisplayGenerator.Generate(_axisController);
|
||||||
var actual = displayGenerator.Generate();
|
|
||||||
Assert.AreEqual(" 0,", actual);
|
Assert.AreEqual(" 0,", actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,19 +14,21 @@ namespace BizHawk.Tests.Client.Common.Movie
|
||||||
public void Initializer()
|
public void Initializer()
|
||||||
{
|
{
|
||||||
_boolController = new(new ControllerDefinition("Dummy Gamepad") { BoolButtons = { "A" } }.MakeImmutable());
|
_boolController = new(new ControllerDefinition("Dummy Gamepad") { BoolButtons = { "A" } }.MakeImmutable());
|
||||||
|
_boolController.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.NES));
|
||||||
_axisController = new(
|
_axisController = new(
|
||||||
new ControllerDefinition("Dummy Gamepad")
|
new ControllerDefinition("Dummy Gamepad")
|
||||||
.AddXYPair("Stick{0}", AxisPairOrientation.RightAndUp, 0.RangeTo(200), 100)
|
.AddXYPair("Stick{0}", AxisPairOrientation.RightAndUp, 0.RangeTo(200), 100)
|
||||||
.MakeImmutable());
|
.MakeImmutable());
|
||||||
|
_axisController.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.NES));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void GenerateLogEntry_ExclamationForUnknownButtons()
|
public void GenerateLogEntry_ExclamationForUnknownButtons()
|
||||||
{
|
{
|
||||||
SimpleController controller = new(new ControllerDefinition("Dummy Gamepad") { BoolButtons = { "Unknown Button" } }.MakeImmutable());
|
SimpleController controller = new(new ControllerDefinition("Dummy Gamepad") { BoolButtons = { "Unknown Button" } }.MakeImmutable());
|
||||||
var lg = new Bk2LogEntryGenerator("NES", controller);
|
controller.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.NES));
|
||||||
controller["Unknown Button"] = true;
|
controller["Unknown Button"] = true;
|
||||||
var actual = lg.GenerateLogEntry();
|
var actual = Bk2LogEntryGenerator.GenerateLogEntry(controller);
|
||||||
Assert.AreEqual("|!|", actual);
|
Assert.AreEqual("|!|", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +36,7 @@ namespace BizHawk.Tests.Client.Common.Movie
|
||||||
public void GenerateLogEntry_BoolPressed_GeneratesMnemonic()
|
public void GenerateLogEntry_BoolPressed_GeneratesMnemonic()
|
||||||
{
|
{
|
||||||
_boolController["A"] = true;
|
_boolController["A"] = true;
|
||||||
var lg = new Bk2LogEntryGenerator("NES", _boolController);
|
var actual = Bk2LogEntryGenerator.GenerateLogEntry(_boolController);
|
||||||
var actual = lg.GenerateLogEntry();
|
|
||||||
Assert.AreEqual("|A|", actual);
|
Assert.AreEqual("|A|", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,17 +44,15 @@ namespace BizHawk.Tests.Client.Common.Movie
|
||||||
public void GenerateLogEntry_BoolUnPressed_GeneratesPeriod()
|
public void GenerateLogEntry_BoolUnPressed_GeneratesPeriod()
|
||||||
{
|
{
|
||||||
_boolController["A"] = false;
|
_boolController["A"] = false;
|
||||||
var lg = new Bk2LogEntryGenerator("NES", _boolController);
|
var actual = Bk2LogEntryGenerator.GenerateLogEntry(_boolController);
|
||||||
var actual = lg.GenerateLogEntry();
|
|
||||||
Assert.AreEqual("|.|", actual);
|
Assert.AreEqual("|.|", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void GenerateLogEntry_Floats()
|
public void GenerateLogEntry_Floats()
|
||||||
{
|
{
|
||||||
var lg = new Bk2LogEntryGenerator("NES", _axisController);
|
var actual = Bk2LogEntryGenerator.GenerateLogEntry(_axisController);
|
||||||
var actual = lg.GenerateLogEntry();
|
|
||||||
Assert.AreEqual("| 0, 0,|", actual);
|
Assert.AreEqual("| 0, 0,|", actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue