Refactor sticky controller logic to separate it from user input (#4047)

This commit is contained in:
Moritz Bender 2024-09-24 16:05:00 +02:00 committed by GitHub
parent 117b35f037
commit 3af5b7a7f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 121 additions and 147 deletions

View File

@ -22,7 +22,7 @@ namespace BizHawk.Client.Common
public IReadOnlyDictionary<string, object> Get(int? controller = null)
{
return _inputManager.AutofireStickyXorAdapter.ToDictionary(controller);
return _movieSession.MovieIn.ToDictionary(controller);
}
public IReadOnlyDictionary<string, object> GetWithMovie(int? controller = null)
@ -97,7 +97,7 @@ namespace BizHawk.Client.Common
{
try
{
_inputManager.StickyXorAdapter.SetAxisHold(controller == null ? control : $"P{controller} {control}", value);
_inputManager.StickyHoldController.SetAxisHold(controller == null ? control : $"P{controller} {control}", value);
}
catch
{

View File

@ -182,11 +182,11 @@ namespace BizHawk.Client.Common
}
private string InputStrCurrent()
=> MakeStringFor(_inputManager.AutofireStickyXorAdapter);
=> MakeStringFor(_movieSession.MovieIn);
// returns an input string for inputs pressed by the user that are not getting unpressed by the sticky adapters
private string InputStrUser()
=> MakeStringFor(_inputManager.AutofireStickyXorAdapter.And(_inputManager.StickyXorAdapter.Source));
// returns an input string for inputs pressed solely by the sticky controller
private string InputStrSticky()
=> MakeStringFor(_movieSession.MovieIn.And(_inputManager.StickyController));
private static string MakeStringFor(IController controller)
{
@ -198,7 +198,7 @@ namespace BizHawk.Client.Common
if (_movieSession.Movie.IsRecording())
{
var movieInput = _movieSession.Movie.GetInputState(_emulator.Frame - 1);
return MakeStringFor(_inputManager.AutofireStickyXorAdapter.And(movieInput));
return MakeStringFor(_movieSession.MovieIn.And(movieInput));
}
return "";
@ -256,7 +256,7 @@ namespace BizHawk.Client.Common
var previousInput = InputStrMovie();
var currentInput = InputStrCurrent();
var userInput = InputStrUser();
var stickyInput = InputStrSticky();
var currentAndPreviousInput = MakeIntersectImmediatePrevious();
// calculate origin for drawing all strings. Mainly relevant when right-anchoring
@ -264,10 +264,10 @@ namespace BizHawk.Client.Common
// draw previous input first. Currently pressed input will overwrite this
g.DrawString(previousInput, previousColor, point.X, point.Y);
// draw all currently pressed input with the sticky color
g.DrawString(currentInput, stickyColor, point.X, point.Y);
// draw all currently pressed non-sticky input with the current color, overwriting previously drawn non-sticky input in the wrong color
g.DrawString(userInput, currentColor, point.X, point.Y);
// draw all currently pressed input with the current color (including sticky input)
g.DrawString(currentInput, currentColor, point.X, point.Y);
// re-draw all currently pressed sticky input with the sticky color
g.DrawString(stickyInput, stickyColor, point.X, point.Y);
// re-draw all currently pressed inputs that were also pressed on the previous frame in their own color
g.DrawString(currentAndPreviousInput, currentAndPreviousColor, point.X, point.Y);
}
@ -297,12 +297,12 @@ namespace BizHawk.Client.Common
{
var sb = new StringBuilder("Held: ");
foreach (var sticky in _inputManager.StickyXorAdapter.CurrentStickies)
foreach (var sticky in _inputManager.StickyHoldController.CurrentHolds)
{
sb.Append(sticky).Append(' ');
}
foreach (var autoSticky in _inputManager.AutofireStickyXorAdapter.CurrentStickies)
foreach (var autoSticky in _inputManager.StickyAutofireController.CurrentAutofires)
{
sb
.Append("Auto-")

View File

@ -1,42 +1,36 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
{
public interface IStickyAdapter : IInputAdapter
{
bool IsSticky(string buttonOrAxis);
}
public class StickyXorAdapter : IStickyAdapter
public class StickyHoldController : IController
{
private readonly HashSet<string> _buttonHolds = [ ];
// if SetAxis() is called (typically virtual pads), then that axis will entirely override the Source input
// otherwise, the source is passed thru.
private readonly Dictionary<string, int> _axisHolds = [ ];
public IController Source { get; set; }
public ControllerDefinition Definition => Source.Definition;
public ControllerDefinition Definition { get; }
public IReadOnlyCollection<string> CurrentStickies => _buttonHolds; // the callsite doesn't care about sticky axes
public IReadOnlyCollection<string> CurrentHolds => _buttonHolds; // the callsite doesn't care about sticky axes
public StickyHoldController(ControllerDefinition definition)
{
Definition = definition;
}
public bool IsPressed(string button)
{
var source = Source.IsPressed(button);
source ^= _buttonHolds.Contains(button);
return source;
return _buttonHolds.Contains(button);
}
public int AxisValue(string name)
{
return _axisHolds.TryGetValue(name, out int axisValue) ? axisValue : Source.AxisValue(name);
return _axisHolds.TryGetValue(name, out int axisValue) ? axisValue : Definition.Axes[name].Neutral;
}
public IReadOnlyCollection<(string Name, int Strength)> GetHapticsSnapshot() => Source.GetHapticsSnapshot();
public void SetHapticChannelStrength(string name, int strength) => Source.SetHapticChannelStrength(name, strength);
public IReadOnlyCollection<(string Name, int Strength)> GetHapticsSnapshot() => throw new NotSupportedException();
public void SetHapticChannelStrength(string name, int strength) => throw new NotSupportedException();
public void SetButtonHold(string button, bool enabled)
{
@ -90,9 +84,9 @@ namespace BizHawk.Client.Common
}
}
public class AutoFireStickyXorAdapter : IStickyAdapter, IInputAdapter
public class StickyAutofireController : IController
{
// TODO: Change the AutoHold adapter to be one of these, with an 'Off' value of 0?
// TODO: Change the AutoHold controller to be one of these, with an 'Off' value of 0?
// Probably would have slightly lower performance, but it seems weird to have such a similar class that is only used once.
private int _onFrames;
private int _offFrames;
@ -100,41 +94,30 @@ namespace BizHawk.Client.Common
private readonly Dictionary<string, AutoPatternBool> _boolPatterns = [ ];
private readonly Dictionary<string, AutoPatternAxis> _axisPatterns = [ ];
public IController Source { get; set; }
public ControllerDefinition Definition => Source.Definition;
public ControllerDefinition Definition { get; }
public IReadOnlyCollection<string> CurrentStickies => _boolPatterns.Keys; // the callsite doesn't care about sticky axes
public IReadOnlyCollection<string> CurrentAutofires => _boolPatterns.Keys; // the callsite doesn't care about sticky axes
public AutoFireStickyXorAdapter()
public StickyAutofireController(ControllerDefinition definition, int onFrames = 1, int offFrames = 1)
{
_onFrames = 1;
_offFrames = 1;
Definition = definition;
SetDefaultOnOffPattern(onFrames, offFrames);
}
public bool IsPressed(string button)
{
var source = Source.IsPressed(button);
bool patternValue = false;
if (_boolPatterns.TryGetValue(button, out var pattern))
{
patternValue = pattern.PeekNextValue();
}
source ^= patternValue;
return source;
return _boolPatterns.TryGetValue(button, out var pattern) && pattern.PeekNextValue();
}
public int AxisValue(string name)
=> _axisPatterns.TryGetValue(name, out var pattern)
? pattern.PeekNextValue()
: Source.AxisValue(name);
: Definition.Axes[name].Neutral;
public IReadOnlyCollection<(string Name, int Strength)> GetHapticsSnapshot() => Source.GetHapticsSnapshot();
public IReadOnlyCollection<(string Name, int Strength)> GetHapticsSnapshot() => throw new NotSupportedException();
public void SetHapticChannelStrength(string name, int strength) => throw new NotSupportedException();
public void SetHapticChannelStrength(string name, int strength) => Source.SetHapticChannelStrength(name, strength);
public void SetOnOffPatternFromConfig(int onFrames, int offFrames)
public void SetDefaultOnOffPattern(int onFrames, int offFrames)
{
_onFrames = Math.Max(onFrames, 1);
_offFrames = Math.Max(offFrames, 1);

View File

@ -44,9 +44,20 @@ namespace BizHawk.Client.Common
return false;
}
// pass axes solely from the original source
// this works in the code because SourceOr is the autofire controller
public int AxisValue(string name) => Source.AxisValue(name);
// xor logic for axes: xor the logical state of axes (not neutral vs. neutral) and return the result
public int AxisValue(string name)
{
int sourceAxisValue = Source.AxisValue(name);
int sourceXorAxisValue = SourceXor.AxisValue(name);
int neutral = Definition.Axes[name].Neutral;
if (sourceAxisValue == neutral)
{
return sourceXorAxisValue;
}
return sourceXorAxisValue == neutral ? sourceAxisValue : neutral;
}
public IReadOnlyCollection<(string Name, int Strength)> GetHapticsSnapshot() => Source.GetHapticsSnapshot();

View File

@ -25,12 +25,11 @@ namespace BizHawk.Client.Common
private UdlrControllerAdapter UdLRControllerAdapter { get; } = new UdlrControllerAdapter();
public AutoFireStickyXorAdapter AutofireStickyXorAdapter { get; private set; } = new AutoFireStickyXorAdapter();
public StickyHoldController StickyHoldController { get; private set; }
public StickyAutofireController StickyAutofireController { get; private set; }
/// <summary>
/// provides an opportunity to mutate the player's input in an autohold style
/// </summary>
public StickyXorAdapter StickyXorAdapter { get; } = new StickyXorAdapter();
// StickyHold OR StickyAutofire
public IController StickyController { get; private set; }
/// <summary>
/// Used to AND to another controller, used for <see cref="IJoypadApi.Set(IReadOnlyDictionary{string, bool}, int?)">JoypadApi.Set</see>
@ -50,10 +49,13 @@ namespace BizHawk.Client.Common
public Func<(Point Pos, long Scroll, bool LMB, bool MMB, bool RMB, bool X1MB, bool X2MB)> GetMainFormMouseInfo { get; set; }
// TODO does this function make sense? Shouldn't SyncControls be called instead, even for the NullEmulator case?
public void ResetMainControllers(AutofireController nullAutofireController)
{
ActiveController = new Controller(NullController.Instance.Definition);
AutoFireController = nullAutofireController;
StickyHoldController = null;
StickyAutofireController = null;
}
public void SyncControls(IEmulator emulator, IMovieSession session, Config config)
@ -63,6 +65,8 @@ namespace BizHawk.Client.Common
ActiveController = BindToDefinition(def, config.AllTrollers, config.AllTrollersAnalog, config.AllTrollersFeedbacks);
AutoFireController = BindToDefinitionAF(emulator, config.AllTrollersAutoFire, config.AutofireOn, config.AutofireOff);
StickyHoldController = new StickyHoldController(def);
StickyAutofireController = new StickyAutofireController(def, config.AutofireOn, config.AutofireOff);
// allow propagating controls that are in the current controller definition but not in the prebaked one
// these two lines shouldn't be required anymore under the new system? --natt 2013
@ -74,24 +78,22 @@ namespace BizHawk.Client.Common
UdLRControllerAdapter.Source = ActiveController.Or(AutoFireController);
UdLRControllerAdapter.OpposingDirPolicy = config.OpposingDirPolicy;
// these are all reference types which don't change so this SHOULD be a no-op, but I'm not brave enough to move it to the ctor --yoshi
StickyXorAdapter.Source = UdLRControllerAdapter;
AutofireStickyXorAdapter = new() { Source = StickyXorAdapter };
StickyController = StickyHoldController.Or(StickyAutofireController);
session.MovieIn = AutofireStickyXorAdapter;
session.StickySource = AutofireStickyXorAdapter;
session.MovieIn = UdLRControllerAdapter.Xor(StickyController);
session.StickySource = StickyController;
ControllerOutput.Source = session.MovieOut;
}
public void ToggleStickies()
{
StickyXorAdapter.MassToggleStickyState(ActiveController.PressedButtons);
AutofireStickyXorAdapter.MassToggleStickyState(AutoFireController.PressedButtons);
StickyHoldController.MassToggleStickyState(ActiveController.PressedButtons);
StickyAutofireController.MassToggleStickyState(AutoFireController.PressedButtons); // does this even make sense?
}
public void ToggleAutoStickies()
{
AutofireStickyXorAdapter.MassToggleStickyState(ActiveController.PressedButtons);
StickyAutofireController.MassToggleStickyState(ActiveController.PressedButtons);
}
private static Controller BindToDefinition(

View File

@ -48,9 +48,9 @@ namespace BizHawk.Client.Common
public IDictionary<string, object> UserBag { get; set; } = new Dictionary<string, object>();
public IInputAdapter MovieIn { get; set; }
public IController MovieIn { get; set; }
public IInputAdapter MovieOut { get; } = new CopyControllerAdapter();
public IStickyAdapter StickySource { get; set; }
public IController StickySource { get; set; }
public IMovieController MovieController { get; private set; } = new Bk2Controller(NullController.Instance.Definition);
@ -325,7 +325,7 @@ namespace BizHawk.Client.Common
{
var input = Movie.GetInputState(Movie.Emulator.Frame);
MovieController.SetFrom(input ?? GenerateMovieController());
MovieController.SetFrom(input ?? StickySource);
MovieOut.Source = MovieController;
}

View File

@ -54,17 +54,6 @@ namespace BizHawk.Client.Common
}
}
public void SetFromSticky(IStickyAdapter controller)
{
foreach (var button in Definition.BoolButtons)
{
_myBoolButtons[button] = controller.IsSticky(button);
}
// axes don't have sticky logic, so latch default value
foreach (var (k, v) in Definition.Axes) _myAxisControls[k] = v.Neutral;
}
public void SetFromMnemonic(string mnemonic)
{
if (string.IsNullOrWhiteSpace(mnemonic)) return;

View File

@ -9,12 +9,6 @@ namespace BizHawk.Client.Common
/// </summary>
void SetFrom(IController source);
/// <summary>
/// Latches to the given <see cref="IStickyAdapter" />
/// For buttons it latches autohold state, for axes it latches neutral value.
/// </summary>
void SetFromSticky(IStickyAdapter controller);
/// <summary>
/// Sets the controller to the state represented by the given mnemonic string
/// </summary>

View File

@ -28,16 +28,16 @@ namespace BizHawk.Client.Common
IMovieController MovieController { get; }
/// <summary>
/// Provides a source for sticky controls ot use when recording
/// Provides a source for sticky controls to use when recording
/// </summary>
IStickyAdapter StickySource { get; set; }
IController StickySource { get; set; }
/// <summary>
/// Represents the input source that is fed to
/// the movie for the purpose of recording, if active,
/// or to simply pass through if inactive
/// </summary>
IInputAdapter MovieIn { get; set; }
IController MovieIn { get; set; }
/// <summary>
/// Represents the movie input in the input chain

View File

@ -272,7 +272,7 @@ namespace BizHawk.Client.Common
int oldLength = InputLogLength;
ChangeLog.AddGeneralUndo(oldLength, oldLength + numFrames - 1);
Session.MovieController.SetFromSticky(Session.StickySource);
Session.MovieController.SetFrom(Session.StickySource);
// account for autohold. needs autohold pattern to be already recorded in the current frame
for (int i = 0; i < numFrames; i++)

View File

@ -832,7 +832,7 @@ namespace BizHawk.Client.EmuHawk
private void AutofireMenuItem_Click(object sender, EventArgs e)
{
using var form = new AutofireConfig(Config, InputManager.AutoFireController, InputManager.AutofireStickyXorAdapter);
using var form = new AutofireConfig(Config, InputManager.AutoFireController, InputManager.StickyAutofireController);
if (this.ShowDialogWithTempMute(form).IsOk()) AddOnScreenMessage("Autofire settings saved");
}

View File

@ -592,7 +592,6 @@ namespace BizHawk.Client.EmuHawk
}
Sound.StartSound();
InputManager.AutofireStickyXorAdapter.SetOnOffPatternFromConfig(Config.AutofireOn, Config.AutofireOff);
InputManager.SyncControls(Emulator, MovieSession, Config);
CheatList = new CheatCollection(this, Config.Cheats);
CheatList.Changed += Tools.UpdateCheatRelatedTools;
@ -1040,8 +1039,8 @@ namespace BizHawk.Client.EmuHawk
}
else
{
InputManager.StickyXorAdapter.ClearStickies();
InputManager.AutofireStickyXorAdapter.ClearStickies();
InputManager.StickyHoldController.ClearStickies();
InputManager.StickyAutofireController.ClearStickies();
}
}
@ -3062,7 +3061,7 @@ namespace BizHawk.Client.EmuHawk
InputManager.AutoFireController.IncrementStarts();
}
InputManager.AutofireStickyXorAdapter.IncrementLoops(Emulator.CanPollInput() && Emulator.AsInputPollable().IsLagFrame);
InputManager.StickyAutofireController.IncrementLoops(Emulator.CanPollInput() && Emulator.AsInputPollable().IsLagFrame);
PressFrameAdvance = false;
@ -3826,8 +3825,6 @@ namespace BizHawk.Client.EmuHawk
DisplayManager.Blank();
CreateRewinder();
ClearHolds();
RewireSound();
Tools.UpdateCheatRelatedTools(null, null);
if (!MovieSession.NewMovieQueued && Config.AutoLoadLastSaveSlot && HasSlot(Config.SaveSlot))
@ -3984,7 +3981,6 @@ namespace BizHawk.Client.EmuHawk
Game = GameInfo.NullInstance;
Tools.Restart(Config, Emulator, Game);
RewireSound();
ClearHolds();
DisplayManager.UpdateGlobals(Config, Emulator);
InputManager.SyncControls(Emulator, MovieSession, Config);
Tools.UpdateCheatRelatedTools(null, null);

View File

@ -7,16 +7,16 @@ namespace BizHawk.Client.EmuHawk
{
private readonly Config _config;
private readonly AutofireController _autoFireController;
private readonly AutoFireStickyXorAdapter _stickyXorAdapter;
private readonly StickyAutofireController _stickyAutofireController;
public AutofireConfig(
Config config,
AutofireController autoFireController,
AutoFireStickyXorAdapter stickyXorAdapter)
StickyAutofireController stickyAutofireController)
{
_config = config;
_autoFireController = autoFireController;
_stickyXorAdapter = stickyXorAdapter;
_stickyAutofireController = stickyAutofireController;
InitializeComponent();
Icon = Properties.Resources.LightningIcon;
}
@ -57,7 +57,7 @@ namespace BizHawk.Client.EmuHawk
_autoFireController.On = _config.AutofireOn = (int)nudPatternOn.Value;
_autoFireController.Off = _config.AutofireOff = (int)nudPatternOff.Value;
_config.AutofireLagFrames = cbConsiderLag.Checked;
_stickyXorAdapter.SetOnOffPatternFromConfig(_config.AutofireOn, _config.AutofireOff);
_stickyAutofireController.SetDefaultOnOffPattern(_config.AutofireOn, _config.AutofireOff);
DialogResult = DialogResult.OK;
Close();

View File

@ -471,7 +471,7 @@ namespace BizHawk.Client.EmuHawk
if (index < BoolPatterns.Length)
{
AutoPatternBool p = BoolPatterns[index];
InputManager.AutofireStickyXorAdapter.SetButtonAutofire(button, isOn.Value, p);
InputManager.StickyAutofireController.SetButtonAutofire(button, isOn.Value, p);
}
}
else
@ -496,7 +496,7 @@ namespace BizHawk.Client.EmuHawk
if (index < AxisPatterns.Length)
{
AutoPatternAxis p = AxisPatterns[index];
InputManager.AutofireStickyXorAdapter.SetAxisAutofire(button, value, p);
InputManager.StickyAutofireController.SetAxisAutofire(button, value, p);
}
}
}

View File

@ -399,7 +399,7 @@ namespace BizHawk.Client.EmuHawk
foreach (var column in TasView.VisibleColumns)
{
if (InputManager.StickyXorAdapter.IsSticky(column.Name))
if (InputManager.StickyHoldController.IsSticky(column.Name) || InputManager.StickyAutofireController.IsSticky(column.Name))
{
column.Emphasis = true;
}

View File

@ -119,7 +119,7 @@ namespace BizHawk.Client.EmuHawk
{
ButtonSchema button => GenVirtualPadButton(_inputManager, button),
SingleAxisSchema singleAxis => new VirtualPadAnalogButton(
_inputManager.StickyXorAdapter,
_inputManager.StickyHoldController,
singleAxis.Name,
singleAxis.DisplayName,
singleAxis.MinValue,
@ -131,7 +131,7 @@ namespace BizHawk.Client.EmuHawk
Size = UIHelper.Scale(singleAxis.TargetSize)
},
AnalogSchema analog => new VirtualPadAnalogStick(
_inputManager.StickyXorAdapter,
_inputManager.StickyHoldController,
_setLastFocusedNUD,
analog.Name,
analog.SecondaryName,
@ -143,7 +143,7 @@ namespace BizHawk.Client.EmuHawk
Size = UIHelper.Scale(new Size(180 + 79, 200 + 9))
},
TargetedPairSchema targetedPair => new VirtualPadTargetScreen(
_inputManager.StickyXorAdapter,
_inputManager.StickyHoldController,
_setLastFocusedNUD,
targetedPair.Name,
targetedPair.SecondaryName,

View File

@ -7,7 +7,7 @@ namespace BizHawk.Client.EmuHawk
{
public partial class VirtualPadAnalogButton : UserControl, IVirtualPadControl
{
private readonly StickyXorAdapter _stickyXorAdapter;
private readonly StickyHoldController _stickyHoldController;
private bool _programmaticallyChangingValue;
private bool _readonly;
@ -23,15 +23,14 @@ namespace BizHawk.Client.EmuHawk
}
public VirtualPadAnalogButton(
StickyXorAdapter stickyXorAdapter,
StickyHoldController stickyHoldController,
string name,
string displayName,
int minValue,
int maxValue,
Orientation orientation)
{
_stickyXorAdapter = stickyXorAdapter;
_stickyHoldController = stickyHoldController;
InitializeComponent();
@ -67,7 +66,7 @@ namespace BizHawk.Client.EmuHawk
public void UpdateValues()
{
if (AnalogTrackBar.Value != _stickyXorAdapter.AxisValue(Name))
if (AnalogTrackBar.Value != _stickyHoldController.AxisValue(Name))
{
RefreshWidgets();
}
@ -75,7 +74,7 @@ namespace BizHawk.Client.EmuHawk
public void Clear()
{
_stickyXorAdapter.SetAxisHold(Name, null);
_stickyHoldController.SetAxisHold(Name, null);
IsSet = false;
}
@ -149,7 +148,7 @@ namespace BizHawk.Client.EmuHawk
if (!_programmaticallyChangingValue)
{
CurrentValue = AnalogTrackBar.Value;
_stickyXorAdapter.SetAxisHold(Name, AnalogTrackBar.Value);
_stickyHoldController.SetAxisHold(Name, AnalogTrackBar.Value);
}
}
@ -158,7 +157,7 @@ namespace BizHawk.Client.EmuHawk
if (!_isSet)
{
_programmaticallyChangingValue = true;
AnalogTrackBar.Value = _stickyXorAdapter.AxisValue(Name);
AnalogTrackBar.Value = _stickyHoldController.AxisValue(Name);
ValueLabel.Text = AnalogTrackBar.Value.ToString();
_programmaticallyChangingValue = false;
}

View File

@ -10,7 +10,7 @@ namespace BizHawk.Client.EmuHawk
{
public partial class VirtualPadAnalogStick : UserControl, IVirtualPadControl
{
private readonly StickyXorAdapter _stickyXorAdapter;
private readonly StickyHoldController _stickyHoldController;
private bool _readonly;
private bool _updatingFromAnalog;
@ -24,14 +24,14 @@ namespace BizHawk.Client.EmuHawk
private readonly Func<int, int, (uint R, uint Θ)> RectToPolarHelper;
public VirtualPadAnalogStick(
StickyXorAdapter stickyXorAdapter,
StickyHoldController stickyHoldController,
EventHandler setLastFocusedNUD,
string name,
string secondaryName,
AxisSpec rangeX,
AxisSpec rangeY)
{
_stickyXorAdapter = stickyXorAdapter;
_stickyHoldController = stickyHoldController;
RangeX = rangeX;
RangeY = rangeY;
@ -97,7 +97,7 @@ namespace BizHawk.Client.EmuHawk
MaxYNumeric.LostFocus += UnsetLastFocusedNUD;
AnalogStick.Init(
_stickyXorAdapter,
stickyHoldController,
name,
RangeX,
string.IsNullOrEmpty(secondaryName) ? Name.Replace('X', 'Y') : secondaryName,
@ -138,8 +138,8 @@ namespace BizHawk.Client.EmuHawk
{
AnalogStick.Clear(fromCallback: true);
SetNumericsFromAnalog();
_stickyXorAdapter.SetAxisHold(AnalogStick.XName, null);
_stickyXorAdapter.SetAxisHold(AnalogStick.YName, null);
_stickyHoldController.SetAxisHold(AnalogStick.XName, null);
_stickyHoldController.SetAxisHold(AnalogStick.YName, null);
}
public void Clear() => AnalogStick.Clear();

View File

@ -31,8 +31,8 @@ namespace BizHawk.Client.EmuHawk
RightClicked = false;
Checked = false;
//HOOMOO
InputManager.AutofireStickyXorAdapter.SetButtonAutofire(Name, false);
InputManager.StickyXorAdapter.SetButtonHold(Name, false);
InputManager.StickyAutofireController.SetButtonAutofire(Name, false);
InputManager.StickyHoldController.SetButtonHold(Name, false);
}
}
@ -133,11 +133,11 @@ namespace BizHawk.Client.EmuHawk
{
if (RightClicked)
{
InputManager.AutofireStickyXorAdapter.SetButtonAutofire(Name, Checked);
InputManager.StickyAutofireController.SetButtonAutofire(Name, Checked);
}
else
{
InputManager.StickyXorAdapter.SetButtonHold(Name, Checked);
InputManager.StickyHoldController.SetButtonHold(Name, Checked);
}
if (!Checked)

View File

@ -125,7 +125,7 @@ namespace BizHawk.Client.EmuHawk
private void lvDiscs_SelectedIndexChanged(object sender, EventArgs e)
{
// emergency measure: if no selection, set no disc
_inputManager.StickyXorAdapter.SetAxisHold(_discSelectName, lvDiscs.SelectedIndices.Count == 0 ? 0 : lvDiscs.SelectedIndices[0]);
_inputManager.StickyHoldController.SetAxisHold(_discSelectName, lvDiscs.SelectedIndices.Count == 0 ? 0 : lvDiscs.SelectedIndices[0]);
}
private void btnClose_Click(object sender, EventArgs e)

View File

@ -8,7 +8,7 @@ namespace BizHawk.Client.EmuHawk
{
public partial class VirtualPadTargetScreen : UserControl, IVirtualPadControl
{
private readonly StickyXorAdapter _stickyXorAdapter;
private readonly StickyHoldController _stickyHoldController;
private readonly Pen BlackPen = new Pen(Brushes.Black, 2);
private readonly Pen GrayPen = new Pen(Brushes.Gray, 2);
private readonly Pen RedPen = new Pen(Brushes.Red, 2);
@ -22,14 +22,14 @@ namespace BizHawk.Client.EmuHawk
private int? _overrideY;
public VirtualPadTargetScreen(
StickyXorAdapter stickyXorAdapter,
StickyHoldController stickyHoldController,
EventHandler setLastFocusedNUD,
string nameX,
string nameY,
int maxX,
int maxY)
{
_stickyXorAdapter = stickyXorAdapter;
_stickyHoldController = stickyHoldController;
Name = XName = nameX;
YName = nameY;
MaxX = maxX;
@ -58,8 +58,8 @@ namespace BizHawk.Client.EmuHawk
public void Clear()
{
_stickyXorAdapter.SetAxisHold(XName, null);
_stickyXorAdapter.SetAxisHold(YName, null);
_stickyHoldController.SetAxisHold(XName, null);
_stickyHoldController.SetAxisHold(YName, null);
_overrideX = null;
_overrideY = null;
_isSet = false;
@ -179,7 +179,7 @@ namespace BizHawk.Client.EmuHawk
public int X
{
get => _overrideX ?? (int)(_stickyXorAdapter.AxisValue(XName) / MultiplierX);
get => _overrideX ?? (int)(_stickyHoldController.AxisValue(XName) / MultiplierX);
set
{
if (value < 0)
@ -196,13 +196,13 @@ namespace BizHawk.Client.EmuHawk
XNumeric.Value = XNumeric.Maximum;
}
_stickyXorAdapter.SetAxisHold(XName, (XNumeric.Value.ConvertToF32() * MultiplierX).RoundToInt());
_stickyHoldController.SetAxisHold(XName, (XNumeric.Value.ConvertToF32() * MultiplierX).RoundToInt());
_isSet = true;
}
}
public int Y
{
get => _overrideY ?? (int)(_stickyXorAdapter.AxisValue(YName) / MultiplierY);
get => _overrideY ?? (int)(_stickyHoldController.AxisValue(YName) / MultiplierY);
set
{
if (value < 0)
@ -218,7 +218,7 @@ namespace BizHawk.Client.EmuHawk
YNumeric.Value = YNumeric.Maximum;
}
_stickyXorAdapter.SetAxisHold(YName, (YNumeric.Value.ConvertToF32() * MultiplierY).RoundToInt());
_stickyHoldController.SetAxisHold(YName, (YNumeric.Value.ConvertToF32() * MultiplierY).RoundToInt());
_isSet = true;
}
}

View File

@ -10,7 +10,7 @@ namespace BizHawk.Client.EmuHawk
{
public sealed class AnalogStickPanel : Panel
{
private StickyXorAdapter _stickyXorAdapter;
private StickyHoldController _stickyHoldController;
private int _x;
private int _y;
@ -59,9 +59,9 @@ namespace BizHawk.Client.EmuHawk
Refresh();
}
public void Init(StickyXorAdapter stickyXorAdapter, string nameX, AxisSpec rangeX, string nameY, AxisSpec rangeY)
public void Init(StickyHoldController stickyHoldController, string nameX, AxisSpec rangeX, string nameY, AxisSpec rangeY)
{
_stickyXorAdapter = stickyXorAdapter;
_stickyHoldController = stickyHoldController;
var scaleBase = Math.Min(Size.Width, Size.Height) - 10.0; // be circular when control is stretched
@ -170,8 +170,8 @@ namespace BizHawk.Client.EmuHawk
private void SetAnalog()
{
_stickyXorAdapter.SetAxisHold(XName, HasValue ? X : null);
_stickyXorAdapter.SetAxisHold(YName, HasValue ? Y : null);
_stickyHoldController.SetAxisHold(XName, HasValue ? X : null);
_stickyHoldController.SetAxisHold(YName, HasValue ? Y : null);
Refresh();
}