Move types from Input to top-level in Client.Common and cleanup
This commit is contained in:
parent
25da1153b6
commit
726f1f3f11
|
@ -1,15 +0,0 @@
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace BizHawk.Client.Common
|
|
||||||
{
|
|
||||||
[Flags]
|
|
||||||
public enum ClientInputFocus
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Mouse = 1,
|
|
||||||
Keyboard = 2,
|
|
||||||
Pad = 4
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace BizHawk.Client.Common
|
||||||
|
{
|
||||||
|
public class InputCoalescer : SimpleController
|
||||||
|
{
|
||||||
|
protected virtual void ProcessSubsets(string button, bool state) {}
|
||||||
|
|
||||||
|
public void Receive(InputEvent ie)
|
||||||
|
{
|
||||||
|
var state = ie.EventType is InputEventType.Press;
|
||||||
|
var button = ie.LogicalButton.ToString();
|
||||||
|
Buttons[button] = state;
|
||||||
|
ProcessSubsets(button, state);
|
||||||
|
if (state) return;
|
||||||
|
// when a button is released, all modified variants of it are released as well
|
||||||
|
foreach (var k in Buttons.Keys.Where(k => k.EndsWith($"+{ie.LogicalButton.Button}")).ToList()) Buttons[k] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ControllerInputCoalescer : InputCoalescer
|
||||||
|
{
|
||||||
|
protected override void ProcessSubsets(string button, bool state)
|
||||||
|
{
|
||||||
|
// For controller input, we want Shift+X to register as both Shift and X (for Keyboard controllers)
|
||||||
|
foreach (var s in button.Split('+')) Buttons[s] = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BizHawk.Client.Common
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum ClientInputFocus
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Mouse = 1,
|
||||||
|
Keyboard = 2,
|
||||||
|
Pad = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InputEvent
|
||||||
|
{
|
||||||
|
public InputEventType EventType;
|
||||||
|
|
||||||
|
public LogicalButton LogicalButton;
|
||||||
|
|
||||||
|
public ClientInputFocus Source;
|
||||||
|
|
||||||
|
public override string ToString() => $"{EventType}:{LogicalButton}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum InputEventType
|
||||||
|
{
|
||||||
|
Press, Release
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct LogicalButton
|
||||||
|
{
|
||||||
|
public static bool operator ==(LogicalButton lhs, LogicalButton rhs)
|
||||||
|
=> lhs.Button == rhs.Button && lhs.Modifiers == rhs.Modifiers;
|
||||||
|
|
||||||
|
public static bool operator !=(LogicalButton lhs, LogicalButton rhs) => !(lhs == rhs);
|
||||||
|
|
||||||
|
public bool Alt => (Modifiers & ModifierKey.Alt) != 0;
|
||||||
|
|
||||||
|
public readonly string Button;
|
||||||
|
|
||||||
|
public bool Control => (Modifiers & ModifierKey.Control) != 0;
|
||||||
|
|
||||||
|
public readonly ModifierKey Modifiers;
|
||||||
|
|
||||||
|
public bool Shift => (Modifiers & ModifierKey.Shift) != 0;
|
||||||
|
|
||||||
|
public LogicalButton(string button, ModifierKey modifiers)
|
||||||
|
{
|
||||||
|
Button = button;
|
||||||
|
Modifiers = modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override readonly bool Equals(object? obj) => obj is not null && (LogicalButton) obj == this; //TODO safe type check?
|
||||||
|
|
||||||
|
public override readonly int GetHashCode() => Button.GetHashCode() ^ Modifiers.GetHashCode();
|
||||||
|
|
||||||
|
public override readonly string ToString()
|
||||||
|
{
|
||||||
|
var ret = "";
|
||||||
|
if (Control) ret += "Ctrl+";
|
||||||
|
if (Alt) ret += "Alt+";
|
||||||
|
if (Shift) ret += "Shift+";
|
||||||
|
ret += Button;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BizHawk.Client.Common
|
||||||
|
{
|
||||||
|
public enum AllowInput
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
All = 1,
|
||||||
|
OnlyController = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum ModifierKey
|
||||||
|
{
|
||||||
|
/// <summary>The bitmask to extract modifiers from a key value.</summary>
|
||||||
|
Modifiers = -65536,
|
||||||
|
/// <summary>No key pressed.</summary>
|
||||||
|
None = 0,
|
||||||
|
/// <summary>The SHIFT modifier key.</summary>
|
||||||
|
Shift = 65536,
|
||||||
|
/// <summary>The CTRL modifier key.</summary>
|
||||||
|
Control = 131072,
|
||||||
|
/// <summary>The ALT modifier key.</summary>
|
||||||
|
Alt = 262144,
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,7 +43,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
// Input state for game controller inputs are coalesced here
|
// Input state for game controller inputs are coalesced here
|
||||||
// This relies on a client specific implementation!
|
// This relies on a client specific implementation!
|
||||||
public SimpleController ControllerInputCoalescer { get; set; }
|
public ControllerInputCoalescer ControllerInputCoalescer { get; set; }
|
||||||
|
|
||||||
public Controller ClientControls { get; set; }
|
public Controller ClientControls { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
using BizHawk.Client.Common;
|
||||||
using BizHawk.Common;
|
using BizHawk.Common;
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
namespace BizHawk.Client.EmuHawk
|
||||||
|
@ -14,7 +15,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
private readonly Timer _timer = new Timer();
|
private readonly Timer _timer = new Timer();
|
||||||
private readonly List<string> _bindings = new List<string>();
|
private readonly List<string> _bindings = new List<string>();
|
||||||
|
|
||||||
private Input.InputEvent _lastPress;
|
private InputEvent _lastPress;
|
||||||
|
|
||||||
public InputCompositeWidget CompositeWidget { get; set; }
|
public InputCompositeWidget CompositeWidget { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -11,64 +11,8 @@ using BizHawk.Client.Common;
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
// coalesces events back into instantaneous states
|
|
||||||
public class InputCoalescer : SimpleController
|
|
||||||
{
|
|
||||||
public void Receive(Input.InputEvent ie)
|
|
||||||
{
|
|
||||||
bool state = ie.EventType == Input.InputEventType.Press;
|
|
||||||
|
|
||||||
string button = ie.LogicalButton.ToString();
|
|
||||||
Buttons[button] = state;
|
|
||||||
|
|
||||||
//when a button is released, all modified variants of it are released as well
|
|
||||||
if (!state)
|
|
||||||
{
|
|
||||||
var releases = Buttons.Where(kvp => kvp.Key.Contains("+") && kvp.Key.EndsWith(ie.LogicalButton.Button)).ToArray();
|
|
||||||
foreach (var kvp in releases)
|
|
||||||
Buttons[kvp.Key] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ControllerInputCoalescer : SimpleController
|
|
||||||
{
|
|
||||||
public void Receive(Input.InputEvent ie)
|
|
||||||
{
|
|
||||||
bool state = ie.EventType == Input.InputEventType.Press;
|
|
||||||
|
|
||||||
string button = ie.LogicalButton.ToString();
|
|
||||||
Buttons[button] = state;
|
|
||||||
|
|
||||||
//For controller input, we want Shift+X to register as both Shift and X (for Keyboard controllers)
|
|
||||||
string[] subgroups = button.Split('+');
|
|
||||||
if (subgroups.Length > 0)
|
|
||||||
{
|
|
||||||
foreach (string s in subgroups)
|
|
||||||
{
|
|
||||||
Buttons[s] = state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//when a button is released, all modified variants of it are released as well
|
|
||||||
if (!state)
|
|
||||||
{
|
|
||||||
var releases = Buttons.Where((kvp) => kvp.Key.Contains("+") && kvp.Key.EndsWith(ie.LogicalButton.Button)).ToArray();
|
|
||||||
foreach (var kvp in releases)
|
|
||||||
Buttons[kvp.Key] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Input
|
public class Input
|
||||||
{
|
{
|
||||||
public enum AllowInput
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
All = 1,
|
|
||||||
OnlyController = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If your form needs this kind of input focus, be sure to say so.
|
/// If your form needs this kind of input focus, be sure to say so.
|
||||||
/// Really, this only makes sense for mouse, but I've started building it out for other things
|
/// Really, this only makes sense for mouse, but I've started building it out for other things
|
||||||
|
@ -83,30 +27,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private readonly HashSet<Control> _wantingMouseFocus = new HashSet<Control>();
|
private readonly HashSet<Control> _wantingMouseFocus = new HashSet<Control>();
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum ModifierKey
|
|
||||||
{
|
|
||||||
// Summary:
|
|
||||||
// The bitmask to extract modifiers from a key value.
|
|
||||||
Modifiers = -65536,
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// No key pressed.
|
|
||||||
None = 0,
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// The SHIFT modifier key.
|
|
||||||
Shift = 65536,
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// The CTRL modifier key.
|
|
||||||
Control = 131072,
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// The ALT modifier key.
|
|
||||||
Alt = 262144
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Input Instance;
|
public static Input Instance;
|
||||||
|
|
||||||
private readonly Thread _updateThread;
|
private readonly Thread _updateThread;
|
||||||
|
@ -138,67 +58,6 @@ namespace BizHawk.Client.EmuHawk
|
||||||
_updateThread.Start();
|
_updateThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum InputEventType
|
|
||||||
{
|
|
||||||
Press, Release
|
|
||||||
}
|
|
||||||
public struct LogicalButton
|
|
||||||
{
|
|
||||||
public LogicalButton(string button, ModifierKey modifiers)
|
|
||||||
{
|
|
||||||
Button = button;
|
|
||||||
Modifiers = modifiers;
|
|
||||||
}
|
|
||||||
public readonly string Button;
|
|
||||||
public readonly ModifierKey Modifiers;
|
|
||||||
|
|
||||||
public bool Alt => (Modifiers & ModifierKey.Alt) != 0;
|
|
||||||
public bool Control => (Modifiers & ModifierKey.Control) != 0;
|
|
||||||
public bool Shift => (Modifiers & ModifierKey.Shift) != 0;
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string ret = "";
|
|
||||||
if (Control) ret += "Ctrl+";
|
|
||||||
if (Alt) ret += "Alt+";
|
|
||||||
if (Shift) ret += "Shift+";
|
|
||||||
ret += Button;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
if (obj is null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var other = (LogicalButton)obj;
|
|
||||||
return other == this;
|
|
||||||
}
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return Button.GetHashCode() ^ Modifiers.GetHashCode();
|
|
||||||
}
|
|
||||||
public static bool operator ==(LogicalButton lhs, LogicalButton rhs)
|
|
||||||
{
|
|
||||||
return lhs.Button == rhs.Button && lhs.Modifiers == rhs.Modifiers;
|
|
||||||
}
|
|
||||||
public static bool operator !=(LogicalButton lhs, LogicalButton rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class InputEvent
|
|
||||||
{
|
|
||||||
public LogicalButton LogicalButton;
|
|
||||||
public InputEventType EventType;
|
|
||||||
public ClientInputFocus Source;
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"{EventType}:{LogicalButton}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Dictionary<string, LogicalButton> _modifierState = new Dictionary<string, LogicalButton>();
|
private readonly Dictionary<string, LogicalButton> _modifierState = new Dictionary<string, LogicalButton>();
|
||||||
private readonly WorkingDictionary<string, bool> _lastState = new WorkingDictionary<string, bool>();
|
private readonly WorkingDictionary<string, bool> _lastState = new WorkingDictionary<string, bool>();
|
||||||
private readonly WorkingDictionary<string, int> _axisValues = new WorkingDictionary<string, int>();
|
private readonly WorkingDictionary<string, int> _axisValues = new WorkingDictionary<string, int>();
|
||||||
|
|
|
@ -447,14 +447,14 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
null => Config.AcceptBackgroundInput // none of our forms are focused, check the background input config
|
null => Config.AcceptBackgroundInput // none of our forms are focused, check the background input config
|
||||||
? Config.AcceptBackgroundInputControllerOnly
|
? Config.AcceptBackgroundInputControllerOnly
|
||||||
? Input.AllowInput.OnlyController
|
? AllowInput.OnlyController
|
||||||
: Input.AllowInput.All
|
: AllowInput.All
|
||||||
: Input.AllowInput.None,
|
: AllowInput.None,
|
||||||
TAStudio when yieldAlt => Input.AllowInput.None,
|
TAStudio when yieldAlt => AllowInput.None,
|
||||||
FormBase { BlocksInputWhenFocused: false } => Input.AllowInput.All,
|
FormBase { BlocksInputWhenFocused: false } => AllowInput.All,
|
||||||
ControllerConfig => Input.AllowInput.All,
|
ControllerConfig => AllowInput.All,
|
||||||
HotkeyConfig => Input.AllowInput.All,
|
HotkeyConfig => AllowInput.All,
|
||||||
_ => Input.AllowInput.None
|
_ => AllowInput.None
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
InitControls();
|
InitControls();
|
||||||
|
@ -701,7 +701,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
// handle events and dispatch as a hotkey action, or a hotkey button, or an input button
|
// handle events and dispatch as a hotkey action, or a hotkey button, or an input button
|
||||||
// ...but prepare haptics first, those get read in ProcessInput
|
// ...but prepare haptics first, those get read in ProcessInput
|
||||||
var finalHostController = (ControllerInputCoalescer) InputManager.ControllerInputCoalescer;
|
var finalHostController = InputManager.ControllerInputCoalescer;
|
||||||
InputManager.ActiveController.PrepareHapticsForHost(finalHostController);
|
InputManager.ActiveController.PrepareHapticsForHost(finalHostController);
|
||||||
ProcessInput(
|
ProcessInput(
|
||||||
_hotkeyCoalescer,
|
_hotkeyCoalescer,
|
||||||
|
@ -982,7 +982,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
Input.Instance.Adapter.SetHaptics(finalHostController.GetHapticsSnapshot());
|
Input.Instance.Adapter.SetHaptics(finalHostController.GetHapticsSnapshot());
|
||||||
|
|
||||||
// loop through all available events
|
// loop through all available events
|
||||||
Input.InputEvent ie;
|
InputEvent ie;
|
||||||
while ((ie = Input.Instance.DequeueEvent()) != null)
|
while ((ie = Input.Instance.DequeueEvent()) != null)
|
||||||
{
|
{
|
||||||
// useful debugging:
|
// useful debugging:
|
||||||
|
@ -995,7 +995,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
if (triggers.Count == 0)
|
if (triggers.Count == 0)
|
||||||
{
|
{
|
||||||
// Maybe it is a system alt-key which hasn't been overridden
|
// Maybe it is a system alt-key which hasn't been overridden
|
||||||
if (ie.EventType == Input.InputEventType.Press)
|
if (ie.EventType is InputEventType.Press)
|
||||||
{
|
{
|
||||||
if (ie.LogicalButton.Alt && ie.LogicalButton.Button.Length == 1)
|
if (ie.LogicalButton.Alt && ie.LogicalButton.Button.Length == 1)
|
||||||
{
|
{
|
||||||
|
@ -1026,7 +1026,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
finalHostController.Receive(ie);
|
finalHostController.Receive(ie);
|
||||||
|
|
||||||
handled = false;
|
handled = false;
|
||||||
if (ie.EventType == Input.InputEventType.Press)
|
if (ie.EventType is InputEventType.Press)
|
||||||
{
|
{
|
||||||
handled = triggers.Aggregate(handled, (current, trigger) => current | CheckHotkey(trigger));
|
handled = triggers.Aggregate(handled, (current, trigger) => current | CheckHotkey(trigger));
|
||||||
}
|
}
|
||||||
|
@ -1043,7 +1043,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
if (!activeControllerHasBinding(ie.LogicalButton.ToString()))
|
if (!activeControllerHasBinding(ie.LogicalButton.ToString()))
|
||||||
{
|
{
|
||||||
handled = false;
|
handled = false;
|
||||||
if (ie.EventType == Input.InputEventType.Press)
|
if (ie.EventType is InputEventType.Press)
|
||||||
{
|
{
|
||||||
handled = triggers.Aggregate(false, (current, trigger) => current | CheckHotkey(trigger));
|
handled = triggers.Aggregate(false, (current, trigger) => current | CheckHotkey(trigger));
|
||||||
}
|
}
|
||||||
|
@ -1058,7 +1058,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
break;
|
break;
|
||||||
case 2: // Hotkeys override Input
|
case 2: // Hotkeys override Input
|
||||||
handled = false;
|
handled = false;
|
||||||
if (ie.EventType == Input.InputEventType.Press)
|
if (ie.EventType is InputEventType.Press)
|
||||||
{
|
{
|
||||||
handled = triggers.Aggregate(false, (current, trigger) => current | CheckHotkey(trigger));
|
handled = triggers.Aggregate(false, (current, trigger) => current | CheckHotkey(trigger));
|
||||||
}
|
}
|
||||||
|
@ -2110,7 +2110,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
|
|
||||||
InputManager.ClientControls = controls;
|
InputManager.ClientControls = controls;
|
||||||
InputManager.ControllerInputCoalescer = new ControllerInputCoalescer(); // ctor initialises values for host haptics
|
InputManager.ControllerInputCoalescer = new(); // ctor initialises values for host haptics
|
||||||
_autofireNullControls = new AutofireController(
|
_autofireNullControls = new AutofireController(
|
||||||
Emulator,
|
Emulator,
|
||||||
Config.AutofireOn,
|
Config.AutofireOn,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
using BizHawk.Client.Common;
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
public partial class InputCompositeWidget : UserControl
|
public partial class InputCompositeWidget : UserControl
|
||||||
|
@ -80,24 +82,24 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void DropdownMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
|
private void DropdownMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
|
||||||
{
|
{
|
||||||
Input.ModifierKey mods = new Input.ModifierKey();
|
var mods = ModifierKey.None;
|
||||||
|
|
||||||
if ((ModifierKeys & Keys.Shift) != 0)
|
if ((ModifierKeys & Keys.Shift) != 0)
|
||||||
{
|
{
|
||||||
mods |= Input.ModifierKey.Shift;
|
mods |= ModifierKey.Shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ModifierKeys & Keys.Control) != 0)
|
if ((ModifierKeys & Keys.Control) != 0)
|
||||||
{
|
{
|
||||||
mods |= Input.ModifierKey.Control;
|
mods |= ModifierKey.Control;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ModifierKeys & Keys.Alt) != 0)
|
if ((ModifierKeys & Keys.Alt) != 0)
|
||||||
{
|
{
|
||||||
mods |= Input.ModifierKey.Alt;
|
mods |= ModifierKey.Alt;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lb = new Input.LogicalButton(e.ClickedItem.Text, mods);
|
LogicalButton lb = new(e.ClickedItem.Text, mods);
|
||||||
|
|
||||||
widget.SetBinding(lb.ToString());
|
widget.SetBinding(lb.ToString());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue