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;
|
||||
}
|
||||
|
||||
var lg = _movieSession.Movie.LogGeneratorInstance(
|
||||
_movieSession.Movie.GetInputState(frame));
|
||||
return lg.GenerateLogEntry();
|
||||
return Bk2LogEntryGenerator.GenerateLogEntry(_movieSession.Movie.GetInputState(frame));
|
||||
}
|
||||
|
||||
public void Save(string filename)
|
||||
|
|
|
@ -9,8 +9,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public class Controller : IController
|
||||
{
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public Controller(ControllerDefinition definition)
|
||||
{
|
||||
Definition = definition;
|
||||
|
@ -186,4 +184,4 @@ namespace BizHawk.Client.Common
|
|||
.Select(kvp => kvp.Key)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
return _emulator.Frame.ToString();
|
||||
}
|
||||
|
||||
|
@ -172,10 +172,10 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
public string InputStrMovie()
|
||||
=> MakeStringFor(_movieSession.MovieController, cache: true);
|
||||
=> MakeStringFor(_movieSession.MovieController);
|
||||
|
||||
public string InputStrImmediate()
|
||||
=> MakeStringFor(_inputManager.AutofireStickyXorAdapter, cache: true);
|
||||
=> MakeStringFor(_inputManager.AutofireStickyXorAdapter);
|
||||
|
||||
public string InputPrevious()
|
||||
{
|
||||
|
@ -196,15 +196,9 @@ namespace BizHawk.Client.Common
|
|||
? MakeStringFor(_inputManager.AutofireStickyXorAdapter.Or(_movieSession.Movie.GetInputState(_emulator.Frame - 1)))
|
||||
: InputStrImmediate();
|
||||
|
||||
private string MakeStringFor(IController controller, bool cache = false)
|
||||
private static string MakeStringFor(IController controller)
|
||||
{
|
||||
var idg = controller.InputDisplayGenerator;
|
||||
if (idg is null)
|
||||
{
|
||||
idg = new Bk2InputDisplayGenerator(_emulator.SystemId, controller);
|
||||
if (cache) controller.InputDisplayGenerator = idg;
|
||||
}
|
||||
return idg.Generate();
|
||||
return Bk2InputDisplayGenerator.Generate(controller);
|
||||
}
|
||||
|
||||
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
|
||||
// so we make an AND adapter and combine it using immediate & sticky
|
||||
// (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);
|
||||
|
||||
//recolor everything that's changed from the previous input
|
||||
|
|
|
@ -9,8 +9,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public class AutofireController : IController
|
||||
{
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public AutofireController(IEmulator emulator, int on, int off)
|
||||
{
|
||||
On = on < 1 ? 0 : on;
|
||||
|
|
|
@ -14,8 +14,6 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public ControllerDefinition Definition { get; set; }
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public bool IsPressed(string button) => _pressed.Contains(button);
|
||||
|
||||
public int AxisValue(string name) => 0;
|
||||
|
|
|
@ -13,8 +13,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public ControllerDefinition Definition { get; }
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
protected Dictionary<string, int> Axes { 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 IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
if (Source != null && SourceAnd != null)
|
||||
|
@ -36,8 +34,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public ControllerDefinition Definition => Source.Definition;
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
if (Source != null && SourceXor != null)
|
||||
|
@ -64,8 +60,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public ControllerDefinition Definition => Source.Definition;
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return (Source?.IsPressed(button) ?? false)
|
||||
|
|
|
@ -11,8 +11,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public ControllerDefinition Definition => Curr.Definition;
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public bool IsPressed(string button) => Curr.IsPressed(button);
|
||||
|
||||
public int AxisValue(string name) => Curr.AxisValue(name);
|
||||
|
|
|
@ -54,13 +54,14 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void ResetMainControllers(AutofireController nullAutofireController)
|
||||
{
|
||||
ActiveController = new(NullController.Instance.Definition);
|
||||
ActiveController = new Controller(NullController.Instance.Definition);
|
||||
AutoFireController = nullAutofireController;
|
||||
}
|
||||
|
||||
public void SyncControls(IEmulator emulator, IMovieSession session, Config config)
|
||||
{
|
||||
var def = emulator.ControllerDefinition;
|
||||
def.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(emulator.SystemId));
|
||||
|
||||
ActiveController = BindToDefinition(def, config.AllTrollers, config.AllTrollersAnalog, config.AllTrollersFeedbacks);
|
||||
AutoFireController = BindToDefinitionAF(emulator, config.AllTrollersAutoFire, config.AutofireOn, config.AutofireOff);
|
||||
|
@ -157,4 +158,4 @@ namespace BizHawk.Client.Common
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
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, int> _axisOverrides = new Dictionary<string, int>();
|
||||
private readonly List<string> _inverses = new List<string>();
|
||||
|
|
|
@ -14,8 +14,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public ControllerDefinition Definition => Source.Definition;
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
var source = Source.IsPressed(button);
|
||||
|
@ -110,8 +108,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public ControllerDefinition Definition => Source.Definition;
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
var source = Source.IsPressed(button);
|
||||
|
@ -216,4 +212,4 @@ namespace BizHawk.Client.Common
|
|||
_justPressed = buttons;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public ControllerDefinition Definition => Source.Definition;
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public OpposingDirPolicy OpposingDirPolicy { get; set; }
|
||||
|
||||
public bool IsPressed(string button)
|
||||
|
|
|
@ -52,12 +52,13 @@ namespace BizHawk.Client.Common
|
|||
public IInputAdapter MovieOut { get; } = new CopyControllerAdapter();
|
||||
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
|
||||
return new Bk2Controller("", definition ?? MovieController.Definition);
|
||||
// TODO: should this fallback to Movie.LogKey?
|
||||
// this function is kinda weird
|
||||
return new Bk2Controller(definition ?? MovieController.Definition, logKey);
|
||||
}
|
||||
|
||||
public void HandleFrameBefore()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
|
@ -14,38 +13,22 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private readonly Dictionary<string, bool> _myBoolButtons = new();
|
||||
|
||||
private readonly Bk2ControllerDefinition _type;
|
||||
|
||||
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)
|
||||
public Bk2Controller(ControllerDefinition definition, string logKey) : this(definition)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
var groups = key.Split(new[] { "#" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
_type.ControlsFromLog = groups
|
||||
.Select(group => group.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries).ToList())
|
||||
.ToList();
|
||||
}
|
||||
if (!string.IsNullOrEmpty(logKey))
|
||||
Definition = new Bk2ControllerDefinition(definition, logKey);
|
||||
}
|
||||
|
||||
public Bk2Controller(ControllerDefinition definition)
|
||||
{
|
||||
_type = new Bk2ControllerDefinition(definition);
|
||||
Definition = definition;
|
||||
foreach ((string axisName, AxisSpec range) in definition.Axes)
|
||||
{
|
||||
_myAxisControls[axisName] = range.Neutral;
|
||||
}
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition => _type;
|
||||
public ControllerDefinition Definition { get; }
|
||||
|
||||
public int AxisValue(string name)
|
||||
=> _myAxisControls.GetValueOrDefault(name);
|
||||
|
@ -87,16 +70,12 @@ namespace BizHawk.Client.Common
|
|||
if (string.IsNullOrWhiteSpace(mnemonic)) return;
|
||||
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++;
|
||||
|
||||
if (key.IsBool)
|
||||
{
|
||||
_myBoolButtons[key.Name] = mnemonic[iterator] != '.';
|
||||
iterator++;
|
||||
}
|
||||
else if (key.IsAxis)
|
||||
if (axisSpec.HasValue)
|
||||
{
|
||||
var commaIndex = mnemonic.IndexOf(',', iterator);
|
||||
#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 val = int.Parse(axisValueString);
|
||||
#endif
|
||||
_myAxisControls[key.Name] = val;
|
||||
_myAxisControls[buttonName] = val;
|
||||
|
||||
iterator = commaIndex + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_myBoolButtons[buttonName] = mnemonic[iterator] != '.';
|
||||
iterator++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,40 +106,23 @@ namespace BizHawk.Client.Common
|
|||
_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
|
||||
{
|
||||
public IReadOnlyList<IReadOnlyList<string>> ControlsFromLog = null;
|
||||
private readonly IReadOnlyList<IReadOnlyList<(string, AxisSpec?)>> _controlsFromLogKey;
|
||||
|
||||
public Bk2ControllerDefinition(ControllerDefinition source)
|
||||
: base(source)
|
||||
public Bk2ControllerDefinition(ControllerDefinition sourceDefinition, string logKey)
|
||||
: 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()
|
||||
=> ControlsFromLog is not null && ControlsFromLog.Count is not 0 ? ControlsFromLog : base.GenOrderedControls();
|
||||
protected override IReadOnlyList<IReadOnlyList<(string Name, AxisSpec? AxisSpec)>> GenOrderedControls() => _controlsFromLogKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
|
@ -6,43 +5,17 @@ using BizHawk.Emulation.Common;
|
|||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
// Designed to be able to last the lifetime of an IMovie
|
||||
public sealed class Bk2LogEntryGenerator
|
||||
public static class Bk2LogEntryGenerator
|
||||
{
|
||||
private readonly string _systemId;
|
||||
private readonly IController _source;
|
||||
|
||||
private readonly Dictionary<string, char> _mnemonics = new();
|
||||
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>
|
||||
/// Gets an input log entry that is considered empty. (booleans will be false, axes will be neutral)
|
||||
/// </summary>
|
||||
public static string EmptyEntry(IController source) => CreateLogEntry(source, createEmpty: true);
|
||||
|
||||
/// <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>
|
||||
public string EmptyEntry => CreateLogEntry(createEmpty: true);
|
||||
|
||||
/// <summary>
|
||||
/// Generates an input log entry for the current state of Source
|
||||
/// </summary>
|
||||
public string GenerateLogEntry() => CreateLogEntry();
|
||||
public static string GenerateLogEntry(IController source) => CreateLogEntry(source);
|
||||
|
||||
/// <summary>
|
||||
/// 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))
|
||||
{
|
||||
sb.Append('#');
|
||||
foreach (var button in group)
|
||||
foreach ((string buttonName, _) in group)
|
||||
{
|
||||
sb.Append(button).Append('|');
|
||||
sb.Append(buttonName).Append('|');
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a dictionary of button names to their corresponding mnemonic values
|
||||
/// </summary>
|
||||
public IDictionary<string, string> Map()
|
||||
private static string CreateLogEntry(IController source, bool createEmpty = false)
|
||||
{
|
||||
var dict = new Dictionary<string, string>();
|
||||
foreach (var button in _source.Definition.OrderedControlsFlat)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
if (!createEmpty && source.Definition.MnemonicsCache is null)
|
||||
throw new InvalidOperationException("Can't generate log entry with empty mnemonics cache");
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
private string CreateLogEntry(bool createEmpty = false)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
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(',');
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(!createEmpty && _source.IsPressed(button)
|
||||
? _mnemonics[button]
|
||||
sb.Append(!createEmpty && source.IsPressed(buttonName)
|
||||
? source.Definition.MnemonicsCache[buttonName]
|
||||
: '.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Libretro;
|
||||
|
||||
// ReSharper disable StyleCop.SA1509
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
internal static class Bk2MnemonicLookup
|
||||
public static class Bk2MnemonicLookup
|
||||
{
|
||||
public static char Lookup(string button, string systemId)
|
||||
{
|
||||
|
@ -65,6 +63,8 @@ namespace BizHawk.Client.Common
|
|||
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>
|
||||
{
|
||||
["Power"] = 'P',
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace BizHawk.Client.Common
|
|||
public partial class Bk2Movie : BasicMovieInfo, IMovie
|
||||
{
|
||||
private Bk2Controller _adapter;
|
||||
//private Bk2LogEntryGenerator _logGenerator;
|
||||
|
||||
public Bk2Movie(IMovieSession session, string filename) : base(filename)
|
||||
{
|
||||
Session = session;
|
||||
|
@ -32,18 +32,6 @@ namespace BizHawk.Client.Common
|
|||
public virtual bool Changes { get; protected set; }
|
||||
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 int InputLogLength => Log.Count;
|
||||
|
||||
|
@ -60,8 +48,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void AppendFrame(IController source)
|
||||
{
|
||||
var lg = LogGeneratorInstance(source);
|
||||
Log.Add(lg.GenerateLogEntry());
|
||||
Log.Add(Bk2LogEntryGenerator.GenerateLogEntry(source));
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
|
@ -75,8 +62,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
var lg = LogGeneratorInstance(source);
|
||||
SetFrameAt(frame, lg.GenerateLogEntry());
|
||||
SetFrameAt(frame, Bk2LogEntryGenerator.GenerateLogEntry(source));
|
||||
|
||||
Changes = true;
|
||||
}
|
||||
|
@ -94,8 +80,8 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
if (frame < FrameCount && frame >= -1)
|
||||
{
|
||||
_adapter ??= new Bk2Controller(LogKey, Session.MovieController.Definition);
|
||||
_adapter.SetFromMnemonic(frame >= 0 ? Log[frame] : Session.Movie.LogGeneratorInstance(Session.MovieController).EmptyEntry);
|
||||
_adapter ??= new Bk2Controller(Session.MovieController.Definition, LogKey);
|
||||
_adapter.SetFromMnemonic(frame >= 0 ? Log[frame] : Bk2LogEntryGenerator.EmptyEntry(_adapter));
|
||||
return _adapter;
|
||||
}
|
||||
|
||||
|
@ -104,8 +90,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public virtual void PokeFrame(int frame, IController source)
|
||||
{
|
||||
var lg = LogGeneratorInstance(source);
|
||||
SetFrameAt(frame, lg.GenerateLogEntry());
|
||||
SetFrameAt(frame, Bk2LogEntryGenerator.GenerateLogEntry(source));
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private void ImportInputFrame(string line)
|
||||
{
|
||||
DeSmuMEControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
SimpleController controller = new(DeSmuMEControllerDef);
|
||||
|
||||
controller["LidOpen"] = false;
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace BizHawk.Client.Common.movie.import
|
|||
NesRightPort = nameof(ControllerNES)
|
||||
};
|
||||
_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
|
||||
uint version = r.ReadUInt32();
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace BizHawk.Client.Common
|
|||
};
|
||||
|
||||
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
|
||||
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
|
||||
Result.Movie.HeaderEntries[HeaderKeys.Platform] = platform;
|
||||
|
||||
|
@ -120,6 +121,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
controllerSettings.NesLeftPort = nameof(ControllerNES);
|
||||
_deck = controllerSettings.Instantiate((x, y) => false).AddSystemToControllerDef();
|
||||
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
}
|
||||
}
|
||||
else if (line.StartsWith("port1", StringComparison.OrdinalIgnoreCase))
|
||||
|
@ -128,6 +130,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
controllerSettings.NesRightPort = nameof(ControllerNES);
|
||||
_deck = controllerSettings.Instantiate((x, y) => false).AddSystemToControllerDef();
|
||||
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
}
|
||||
}
|
||||
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.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -157,6 +161,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
syncSettings.Controls = controllerSettings;
|
||||
Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(syncSettings);
|
||||
Result.Movie.LogKey = Bk2LogEntryGenerator.GenerateLogKey(_deck.ControllerDef);
|
||||
}
|
||||
|
||||
private IControllerDeck _deck;
|
||||
|
|
|
@ -94,6 +94,7 @@ namespace BizHawk.Client.Common.movie.import
|
|||
NesRightPort = controller2 ? nameof(ControllerNES) : nameof(UnpluggedNES)
|
||||
};
|
||||
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
|
||||
_deck.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
syncSettings.Controls.NesLeftPort = controllerSettings.NesLeftPort;
|
||||
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);
|
||||
|
||||
|
||||
controlConverter.ControllerDef.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
SimpleController controller = new(controlConverter.ControllerDef);
|
||||
|
||||
// Unknown.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -21,9 +20,9 @@ namespace BizHawk.Client.Common.movie.import
|
|||
private SimpleController _controller;
|
||||
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(button => $"P{player} {button}").ToArray())
|
||||
.Select(button => ($"P{player} {button}", (AxisSpec?)null)).ToArray())
|
||||
.ToArray();
|
||||
|
||||
protected override void RunImport()
|
||||
|
@ -85,6 +84,7 @@ namespace BizHawk.Client.Common.movie.import
|
|||
}
|
||||
|
||||
ControllerDefinition controllerDefinition = new BsnesControllers(ss, true).Definition;
|
||||
controllerDefinition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.SNES));
|
||||
_emptyController = new SimpleController(controllerDefinition);
|
||||
_controller = new SimpleController(controllerDefinition);
|
||||
_playerCount = controllerDefinition.PlayerCount;
|
||||
|
@ -312,8 +312,8 @@ namespace BizHawk.Client.Common.movie.import
|
|||
{
|
||||
if (player > _playerCount) break;
|
||||
|
||||
IReadOnlyList<string> 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
|
||||
var buttons = _controller.Definition.ControlsOrdered[player];
|
||||
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];
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ namespace BizHawk.Client.Common.movie.import
|
|||
for (int button = 0; button < buttons.Count; button++)
|
||||
{
|
||||
// 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" };
|
||||
|
||||
_deck.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
SimpleController controllers = new(_deck.Definition);
|
||||
|
||||
// Split up the sections of the frame.
|
||||
|
|
|
@ -95,6 +95,7 @@ namespace BizHawk.Client.Common.movie.import
|
|||
|
||||
var ss = new SMS.SmsSyncSettings();
|
||||
var cd = new SMSControllerDeck(ss.Port1, ss.Port2, isGameGear, ss.UseKeyboard);
|
||||
cd.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
SimpleController controllers = new(cd.Definition);
|
||||
|
||||
/*
|
||||
|
|
|
@ -181,6 +181,7 @@ namespace BizHawk.Client.Common
|
|||
OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None
|
||||
};
|
||||
SimpleController controllers = new(Octoshock.CreateControllerDefinition(settings));
|
||||
controllers.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
|
||||
string[] buttons =
|
||||
{
|
||||
|
@ -291,6 +292,7 @@ namespace BizHawk.Client.Common
|
|||
OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None, OctoshockDll.ePeripheralType.None
|
||||
};
|
||||
SimpleController controllers = new(Octoshock.CreateControllerDefinition(settings));
|
||||
controllers.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
|
||||
string[] buttons =
|
||||
{
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace BizHawk.Client.Common.movie.import
|
|||
return;
|
||||
}
|
||||
|
||||
Result.Movie.HeaderEntries[HeaderKeys.Platform] = VSystemID.Raw.SNES;
|
||||
Result.Movie.SystemID = VSystemID.Raw.SNES;
|
||||
|
||||
// 004 4-byte little-endian unsigned int: version number
|
||||
uint versionNumber = r.ReadUInt32();
|
||||
|
@ -189,6 +189,7 @@ namespace BizHawk.Client.Common.movie.import
|
|||
}
|
||||
|
||||
ControllerDefinition definition = new Snes9xControllers(ss).ControllerDefinition;
|
||||
definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
SimpleController controllers = new(definition);
|
||||
|
||||
Result.Movie.LogKey = Bk2LogEntryGenerator.GenerateLogKey(definition);
|
||||
|
|
|
@ -203,6 +203,7 @@ namespace BizHawk.Client.Common.movie.import
|
|||
SimpleController controllers = isGBA
|
||||
? GbaController()
|
||||
: GbController();
|
||||
controllers.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(isGBA ? VSystemID.Raw.GBA : VSystemID.Raw.GB));
|
||||
|
||||
/*
|
||||
* 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"
|
||||
}
|
||||
}.MakeImmutable());
|
||||
controllers.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(Result.Movie.SystemID));
|
||||
|
||||
// Split up the sections of the frame.
|
||||
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++)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public BkmControllerAdapter(ControllerDefinition definition, string systemId)
|
||||
{
|
||||
// We do need to map the definition name to the legacy
|
||||
|
@ -34,6 +32,7 @@ namespace BizHawk.Client.Common
|
|||
_ => "Null Controller",
|
||||
};
|
||||
Definition = new(copyFrom: definition, withName: name);
|
||||
Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(systemId));
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition { get; set; }
|
||||
|
|
|
@ -74,11 +74,6 @@ namespace BizHawk.Client.Common
|
|||
/// </summary>
|
||||
void SaveBackup();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a log generator using the given input source
|
||||
/// </summary>
|
||||
Bk2LogEntryGenerator LogGeneratorInstance(IController source);
|
||||
|
||||
/// <summary>
|
||||
/// Instructs the movie to save the current contents to Filename
|
||||
/// </summary>
|
||||
|
|
|
@ -48,11 +48,10 @@ namespace BizHawk.Client.Common
|
|||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="IMovieController" /> instance based on the
|
||||
/// given button definition if provided else the
|
||||
/// current <see cref="MovieController" /> button definition
|
||||
/// will be used
|
||||
/// given button definition if provided else the current
|
||||
/// <see cref="MovieController"/>s button definition will be used
|
||||
/// </summary>
|
||||
IMovieController GenerateMovieController(ControllerDefinition definition = null);
|
||||
IMovieController GenerateMovieController(ControllerDefinition definition = null, string logKey = null);
|
||||
|
||||
void HandleFrameBefore();
|
||||
void HandleFrameAfter();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
|
|
|
@ -20,8 +20,7 @@ namespace BizHawk.Client.Common
|
|||
ChangeLog.AddGeneralUndo(frame - 1, frame - 1, $"Record Frame: {frame}");
|
||||
}
|
||||
|
||||
var lg = LogGeneratorInstance(source);
|
||||
SetFrameAt(frame, lg.GenerateLogEntry());
|
||||
SetFrameAt(frame, Bk2LogEntryGenerator.GenerateLogEntry(source));
|
||||
|
||||
Changes = true;
|
||||
|
||||
|
@ -86,8 +85,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
ChangeLog.AddGeneralUndo(frame, frame, $"Clear Frame: {frame}");
|
||||
|
||||
var lg = LogGeneratorInstance(Session.MovieController);
|
||||
SetFrameAt(frame, lg.EmptyEntry);
|
||||
SetFrameAt(frame, Bk2LogEntryGenerator.EmptyEntry(Session.MovieController));
|
||||
Changes = true;
|
||||
|
||||
InvalidateAfter(frame);
|
||||
|
@ -210,8 +208,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
foreach (var input in inputStates)
|
||||
{
|
||||
var lg = LogGeneratorInstance(input);
|
||||
inputLog.Add(lg.GenerateLogEntry());
|
||||
inputLog.Add(Bk2LogEntryGenerator.GenerateLogEntry(input));
|
||||
}
|
||||
|
||||
InsertInput(frame, inputLog); // Sets the ChangeLog
|
||||
|
@ -238,8 +235,7 @@ namespace BizHawk.Client.Common
|
|||
break;
|
||||
}
|
||||
|
||||
var lg = LogGeneratorInstance(states[i]);
|
||||
var entry = lg.GenerateLogEntry();
|
||||
var entry = Bk2LogEntryGenerator.GenerateLogEntry(states[i]);
|
||||
if (firstChangedFrame == -1 && Log[frame + i] != entry)
|
||||
{
|
||||
firstChangedFrame = frame + i;
|
||||
|
@ -260,8 +256,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
frame = Math.Min(frame, Log.Count);
|
||||
|
||||
var lg = LogGeneratorInstance(Session.MovieController);
|
||||
Log.InsertRange(frame, Enumerable.Repeat(lg.EmptyEntry, count).ToList());
|
||||
Log.InsertRange(frame, Enumerable.Repeat(Bk2LogEntryGenerator.EmptyEntry(Session.MovieController), count));
|
||||
|
||||
ShiftBindedMarkers(frame, count);
|
||||
|
||||
|
@ -280,11 +275,9 @@ namespace BizHawk.Client.Common
|
|||
Session.MovieController.SetFromSticky(Session.StickySource);
|
||||
|
||||
// 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++)
|
||||
{
|
||||
Log.Add(lg.GenerateLogEntry());
|
||||
Log.Add(Bk2LogEntryGenerator.GenerateLogEntry(Session.MovieController));
|
||||
}
|
||||
|
||||
Changes = true;
|
||||
|
@ -306,8 +299,7 @@ namespace BizHawk.Client.Common
|
|||
var adapter = GetInputState(frame);
|
||||
adapter.SetBool(buttonName, !adapter.IsPressed(buttonName));
|
||||
|
||||
var lg = LogGeneratorInstance(adapter);
|
||||
Log[frame] = lg.GenerateLogEntry();
|
||||
Log[frame] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||
Changes = true;
|
||||
InvalidateAfter(frame);
|
||||
|
||||
|
@ -325,8 +317,7 @@ namespace BizHawk.Client.Common
|
|||
var old = adapter.IsPressed(buttonName);
|
||||
adapter.SetBool(buttonName, val);
|
||||
|
||||
var lg = LogGeneratorInstance(adapter);
|
||||
Log[frame] = lg.GenerateLogEntry();
|
||||
Log[frame] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||
|
||||
if (old != val)
|
||||
{
|
||||
|
@ -352,8 +343,7 @@ namespace BizHawk.Client.Common
|
|||
bool old = adapter.IsPressed(buttonName);
|
||||
adapter.SetBool(buttonName, val);
|
||||
|
||||
var lg = LogGeneratorInstance(adapter);
|
||||
Log[frame + i] = lg.GenerateLogEntry();
|
||||
Log[frame + i] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||
|
||||
if (changed == -1 && old != val)
|
||||
{
|
||||
|
@ -381,8 +371,7 @@ namespace BizHawk.Client.Common
|
|||
var old = adapter.AxisValue(buttonName);
|
||||
adapter.SetAxis(buttonName, val);
|
||||
|
||||
var lg = LogGeneratorInstance(adapter);
|
||||
Log[frame] = lg.GenerateLogEntry();
|
||||
Log[frame] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||
|
||||
if (old != val)
|
||||
{
|
||||
|
@ -408,8 +397,7 @@ namespace BizHawk.Client.Common
|
|||
var old = adapter.AxisValue(buttonName);
|
||||
adapter.SetAxis(buttonName, val);
|
||||
|
||||
var lg = LogGeneratorInstance(adapter);
|
||||
Log[frame + i] = lg.GenerateLogEntry();
|
||||
Log[frame + i] = Bk2LogEntryGenerator.GenerateLogEntry(adapter);
|
||||
|
||||
if (changed == -1 && old != val)
|
||||
{
|
||||
|
|
|
@ -56,15 +56,8 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
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
|
||||
{
|
||||
get => base.StartsFromSavestate;
|
||||
|
@ -146,7 +139,7 @@ namespace BizHawk.Client.Common
|
|||
public void InvalidateEntireGreenzone()
|
||||
=> 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>
|
||||
/// 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);
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
return adapter.IsPressed(buttonName)
|
||||
? _mnemonicCache[buttonName].ToString()
|
||||
? adapter.Definition.MnemonicsCache![buttonName].ToString()
|
||||
: "";
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
private int _dataSize;
|
||||
|
||||
private Dictionary<string, double> _cachedControlProbabilities;
|
||||
private Bk2LogEntryGenerator _logGenerator;
|
||||
|
||||
private bool _previousDisplayMessage;
|
||||
private bool _previousInvisibleEmulation;
|
||||
|
@ -1001,7 +1000,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
InputManager.SyncControls(Emulator, MovieSession, Config);
|
||||
|
||||
if (clear_log) { _currentBotAttempt.Log.Clear(); }
|
||||
_currentBotAttempt.Log.Add(_logGenerator.GenerateLogEntry());
|
||||
_currentBotAttempt.Log.Add(Bk2LogEntryGenerator.GenerateLogEntry(InputManager.ClickyVirtualPadController));
|
||||
}
|
||||
|
||||
private void StartBot()
|
||||
|
@ -1027,7 +1026,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
MovieSession.Movie.IsCountingRerecords = false;
|
||||
}
|
||||
|
||||
_logGenerator = MovieSession.Movie.LogGeneratorInstance(InputManager.ClickyVirtualPadController);
|
||||
_cachedControlProbabilities = ControlProbabilities;
|
||||
|
||||
_doNotUpdateValues = true;
|
||||
|
|
|
@ -34,8 +34,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
// Get a IController that only contains buttons in key.
|
||||
InitController(_inputKey);
|
||||
|
||||
var logGenerator = movieSession.Movie.LogGeneratorInstance(_controller);
|
||||
|
||||
string movieKey = Bk2LogEntryGenerator.GenerateLogKey(_controller.Definition).Replace("#", "");
|
||||
movieKey = movieKey.Substring(startIndex: 0, length: movieKey.Length - 1); // drop last char
|
||||
if (key == movieKey)
|
||||
|
@ -50,7 +48,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
_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 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)
|
||||
var tC = _movieSession.Movie.LogGeneratorInstance(_targetController);
|
||||
_targetController.SetFromMnemonic(tC.EmptyEntry);
|
||||
_targetController.SetFromMnemonic(Bk2LogEntryGenerator.EmptyEntry(_targetController));
|
||||
for (int i = 0; i < Length; i++)
|
||||
{
|
||||
_controller.SetFromMnemonic(_log[i]);
|
||||
LatchFromSourceButtons(_targetController, _controller);
|
||||
newController.SetFrom(_targetController);
|
||||
_log[i] = logGenerator.GenerateLogEntry();
|
||||
_log[i] = Bk2LogEntryGenerator.GenerateLogEntry(newController);
|
||||
}
|
||||
|
||||
_controller = newController;
|
||||
|
|
|
@ -418,7 +418,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
|
||||
_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);
|
||||
}
|
||||
|
||||
|
@ -537,8 +537,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
|
||||
_tasClipboard.Add(new TasClipboardEntry(index, input));
|
||||
var lg = CurrentTasMovie.LogGeneratorInstance(input);
|
||||
sb.AppendLine(lg.GenerateLogEntry());
|
||||
sb.AppendLine(Bk2LogEntryGenerator.GenerateLogEntry(input));
|
||||
}
|
||||
|
||||
Clipboard.SetDataObject(sb.ToString());
|
||||
|
|
|
@ -7,7 +7,6 @@ using System.ComponentModel;
|
|||
using BizHawk.Client.Common;
|
||||
using BizHawk.Client.EmuHawk.ToolExtensions;
|
||||
using BizHawk.Client.EmuHawk.Properties;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
|
@ -351,31 +350,17 @@ namespace BizHawk.Client.EmuHawk
|
|||
Rotatable = true,
|
||||
});
|
||||
|
||||
var columnNames = MovieSession.Movie
|
||||
.LogGeneratorInstance(MovieSession.MovieController)
|
||||
.Map();
|
||||
|
||||
foreach (var (name, mnemonic0) in columnNames)
|
||||
foreach ((string name, string mnemonic0, int maxLength) in MnemonicMap())
|
||||
{
|
||||
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
|
||||
: mnemonic0;
|
||||
ColumnType type;
|
||||
int digits;
|
||||
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;
|
||||
}
|
||||
|
||||
var type = ControllerType.Axes.ContainsKey(name) ? ColumnType.Axis : ColumnType.Boolean;
|
||||
|
||||
TasView.AllColumns.Add(new(
|
||||
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,
|
||||
text: mnemonic));
|
||||
}
|
||||
|
@ -497,8 +482,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
get
|
||||
{
|
||||
var lg = CurrentTasMovie.LogGeneratorInstance(MovieSession.MovieController);
|
||||
var empty = lg.EmptyEntry;
|
||||
var empty = Bk2LogEntryGenerator.EmptyEntry(MovieSession.MovieController);
|
||||
foreach (var row in TasView.SelectedRows)
|
||||
{
|
||||
if (CurrentTasMovie[row].LogEntry != empty)
|
||||
|
@ -1258,5 +1242,27 @@ namespace BizHawk.Client.EmuHawk
|
|||
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.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
@ -21,38 +19,48 @@ namespace BizHawk.Emulation.Common
|
|||
|
||||
private bool _mutable = true;
|
||||
|
||||
private IReadOnlyList<IReadOnlyList<string>> _orderedControls = null;
|
||||
|
||||
private IReadOnlyList<string> _orderedControlsFlat = null;
|
||||
private IReadOnlyList<IReadOnlyList<(string, AxisSpec?)>>? _orderedControls;
|
||||
|
||||
/// <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
|
||||
{
|
||||
if (_orderedControls is not null) return _orderedControls;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
=> Name = name;
|
||||
|
||||
public ControllerDefinition(ControllerDefinition copyFrom, string withName = null)
|
||||
public ControllerDefinition(ControllerDefinition copyFrom, string? withName = null)
|
||||
: this(withName ?? copyFrom.Name)
|
||||
{
|
||||
BoolButtons.AddRange(copyFrom.BoolButtons);
|
||||
foreach (var kvp in copyFrom.Axes) Axes.Add(kvp);
|
||||
HapticsChannels.AddRange(copyFrom.HapticsChannels);
|
||||
CategoryLabels = copyFrom.CategoryLabels;
|
||||
// Do not clone _orderedControls, as GenOrderedControls may be overridden by the derived class
|
||||
// _orderedControls = copyFrom._orderedControls;
|
||||
_mnemonicsCache = copyFrom._mnemonicsCache;
|
||||
MakeImmutable();
|
||||
}
|
||||
|
||||
|
@ -105,11 +113,12 @@ namespace BizHawk.Emulation.Common
|
|||
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();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@ namespace BizHawk.Emulation.Common
|
|||
{
|
||||
public ControllerDefinition Definition { get; } = new ControllerDefinition("Null Controller").MakeImmutable();
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public bool IsPressed(string button) => false;
|
||||
|
||||
public int AxisValue(string name) => 0;
|
||||
|
@ -23,6 +21,7 @@ namespace BizHawk.Emulation.Common
|
|||
|
||||
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;
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public DummyController(
|
||||
IController src,
|
||||
IReadOnlyDictionary<string, string> buttonAxisRemaps)
|
||||
|
|
|
@ -11,9 +11,6 @@ namespace BizHawk.Emulation.Common
|
|||
/// </summary>
|
||||
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"/>
|
||||
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();
|
||||
|
||||
public IInputDisplayGenerator InputDisplayGenerator { get; set; } = null;
|
||||
|
||||
public SaveController()
|
||||
{
|
||||
Definition = null;
|
||||
|
|
|
@ -112,18 +112,18 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
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
|
||||
var players = base.GenOrderedControls().ToList();
|
||||
List<string> retroKeyboard = new();
|
||||
var p0 = (List<string>) players[0];
|
||||
List<(string, AxisSpec?)> retroKeyboard = new();
|
||||
var p0 = (List<(string, AxisSpec?)>) players[0];
|
||||
for (var i = 0; i < p0.Count; /* incremented in body */)
|
||||
{
|
||||
var buttonName = p0[i];
|
||||
if (CategoryLabels.TryGetValue(buttonName, out var v) && v is CAT_KEYBOARD)
|
||||
(string ButtonName, AxisSpec?) button = p0[i];
|
||||
if (CategoryLabels.TryGetValue(button.ButtonName, out var v) && v is CAT_KEYBOARD)
|
||||
{
|
||||
retroKeyboard.Add(buttonName);
|
||||
retroKeyboard.Add(button);
|
||||
p0.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -15,18 +15,19 @@ namespace BizHawk.Tests.Client.Common.Display
|
|||
public void Initializer()
|
||||
{
|
||||
_boolController = new(new ControllerDefinition("Dummy Gamepad") { BoolButtons = { "A" } }.MakeImmutable());
|
||||
_boolController.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.NULL));
|
||||
_axisController = new(
|
||||
new ControllerDefinition("Dummy Gamepad")
|
||||
.AddXYPair("Stick{0}", AxisPairOrientation.RightAndUp, 0.RangeTo(200), MidValue)
|
||||
.MakeImmutable());
|
||||
_axisController.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.NULL));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Generate_BoolPressed_GeneratesMnemonic()
|
||||
{
|
||||
_boolController["A"] = true;
|
||||
var displayGenerator = new Bk2InputDisplayGenerator("NES", _boolController);
|
||||
var actual = displayGenerator.Generate();
|
||||
var actual = Bk2InputDisplayGenerator.Generate(_boolController);
|
||||
Assert.AreEqual("A", actual);
|
||||
}
|
||||
|
||||
|
@ -34,16 +35,14 @@ namespace BizHawk.Tests.Client.Common.Display
|
|||
public void Generate_BoolUnPressed_GeneratesSpace()
|
||||
{
|
||||
_boolController["A"] = false;
|
||||
var displayGenerator = new Bk2InputDisplayGenerator("NES", _boolController);
|
||||
var actual = displayGenerator.Generate();
|
||||
var actual = Bk2InputDisplayGenerator.Generate(_boolController);
|
||||
Assert.AreEqual(" ", actual);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Generate_Floats()
|
||||
{
|
||||
var displayGenerator = new Bk2InputDisplayGenerator("NES", _axisController);
|
||||
var actual = displayGenerator.Generate();
|
||||
var actual = Bk2InputDisplayGenerator.Generate(_axisController);
|
||||
Assert.AreEqual(" 0, 0,", actual);
|
||||
}
|
||||
|
||||
|
@ -51,8 +50,7 @@ namespace BizHawk.Tests.Client.Common.Display
|
|||
public void Generate_MidRangeDisplaysEmpty()
|
||||
{
|
||||
_axisController.AcceptNewAxis("StickX", MidValue);
|
||||
var displayGenerator = new Bk2InputDisplayGenerator("NES", _axisController);
|
||||
var actual = displayGenerator.Generate();
|
||||
var actual = Bk2InputDisplayGenerator.Generate(_axisController);
|
||||
Assert.AreEqual(" 0,", actual);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,19 +14,21 @@ namespace BizHawk.Tests.Client.Common.Movie
|
|||
public void Initializer()
|
||||
{
|
||||
_boolController = new(new ControllerDefinition("Dummy Gamepad") { BoolButtons = { "A" } }.MakeImmutable());
|
||||
_boolController.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.NES));
|
||||
_axisController = new(
|
||||
new ControllerDefinition("Dummy Gamepad")
|
||||
.AddXYPair("Stick{0}", AxisPairOrientation.RightAndUp, 0.RangeTo(200), 100)
|
||||
.MakeImmutable());
|
||||
_axisController.Definition.BuildMnemonicsCache(Bk2MnemonicLookup.MnemonicFunc(VSystemID.Raw.NES));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GenerateLogEntry_ExclamationForUnknownButtons()
|
||||
{
|
||||
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;
|
||||
var actual = lg.GenerateLogEntry();
|
||||
var actual = Bk2LogEntryGenerator.GenerateLogEntry(controller);
|
||||
Assert.AreEqual("|!|", actual);
|
||||
}
|
||||
|
||||
|
@ -34,8 +36,7 @@ namespace BizHawk.Tests.Client.Common.Movie
|
|||
public void GenerateLogEntry_BoolPressed_GeneratesMnemonic()
|
||||
{
|
||||
_boolController["A"] = true;
|
||||
var lg = new Bk2LogEntryGenerator("NES", _boolController);
|
||||
var actual = lg.GenerateLogEntry();
|
||||
var actual = Bk2LogEntryGenerator.GenerateLogEntry(_boolController);
|
||||
Assert.AreEqual("|A|", actual);
|
||||
}
|
||||
|
||||
|
@ -43,17 +44,15 @@ namespace BizHawk.Tests.Client.Common.Movie
|
|||
public void GenerateLogEntry_BoolUnPressed_GeneratesPeriod()
|
||||
{
|
||||
_boolController["A"] = false;
|
||||
var lg = new Bk2LogEntryGenerator("NES", _boolController);
|
||||
var actual = lg.GenerateLogEntry();
|
||||
var actual = Bk2LogEntryGenerator.GenerateLogEntry(_boolController);
|
||||
Assert.AreEqual("|.|", actual);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GenerateLogEntry_Floats()
|
||||
{
|
||||
var lg = new Bk2LogEntryGenerator("NES", _axisController);
|
||||
var actual = lg.GenerateLogEntry();
|
||||
var actual = Bk2LogEntryGenerator.GenerateLogEntry(_axisController);
|
||||
Assert.AreEqual("| 0, 0,|", actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue