From 23a7754a2b5951cdd52781441390e215a966ce4c Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Fri, 20 Aug 2021 08:11:21 +1000 Subject: [PATCH] Inline some helpers into OTK_GamePad ctor --- src/BizHawk.Bizware.OpenTK3/OTK_Gamepad.cs | 264 ++++++++---------- .../OpenTKInputAdapter.cs | 2 +- 2 files changed, 119 insertions(+), 147 deletions(-) diff --git a/src/BizHawk.Bizware.OpenTK3/OTK_Gamepad.cs b/src/BizHawk.Bizware.OpenTK3/OTK_Gamepad.cs index e33894282d..851b7bf631 100644 --- a/src/BizHawk.Bizware.OpenTK3/OTK_Gamepad.cs +++ b/src/BizHawk.Bizware.OpenTK3/OTK_Gamepad.cs @@ -88,9 +88,6 @@ namespace BizHawk.Bizware.OpenTK3 return num * 10000.0f; } - /// Signals whether OpenTK returned a GUID for this device - private readonly bool _guidObtained; - /// The OpenTK device index private readonly int _deviceIndex; @@ -130,7 +127,6 @@ namespace BizHawk.Bizware.OpenTK3 guid = Joystick.GetGuid(_deviceIndex); _joystickCapabilities = Joystick.GetCapabilities(_deviceIndex); } - _guidObtained = guid is not null; string name; if (OpenTKGamePad.GetState(_deviceIndex).IsConnected) @@ -149,7 +145,123 @@ namespace BizHawk.Bizware.OpenTK3 InputNamePrefix = $"{InputNamePrefixShort} "; MappingsDatabaseName = $"{guid ?? Guid.Empty} {name}"; Update(); - InitializeMappings(); + + // Setup mappings prior to button initialization. + List<(string ButtonName, Func GetIsPressed)> buttonGetters = new(); + + if (guid is not null) + { + // placeholder for if/when we figure out how to supply OpenTK with custom GamePadConfigurationDatabase entries + } + + // currently OpenTK has an internal database of mappings for the GamePad class: https://github.com/opentk/opentk/blob/master/src/OpenTK/Input/GamePadConfigurationDatabase.cs + if (MappedGamePad) + { + // internal map detected - use OpenTKGamePad + + // OpenTK's ThumbSticks contain float values (as opposed to the shorts of SlimDX) + const float ConversionFactor = 1.0f / short.MaxValue; + const float dzp = 20000 * ConversionFactor; + const float dzn = -20000 * ConversionFactor; + const float dzt = 0.6f; + + // buttons + buttonGetters.Add(("A", () => state.Buttons.A == ButtonState.Pressed)); + buttonGetters.Add(("B", () => state.Buttons.B == ButtonState.Pressed)); + buttonGetters.Add(("X", () => state.Buttons.X == ButtonState.Pressed)); + buttonGetters.Add(("Y", () => state.Buttons.Y == ButtonState.Pressed)); + buttonGetters.Add(("Guide", () => state.Buttons.BigButton == ButtonState.Pressed)); + buttonGetters.Add(("Start", () => state.Buttons.Start == ButtonState.Pressed)); + buttonGetters.Add(("Back", () => state.Buttons.Back == ButtonState.Pressed)); + buttonGetters.Add(("LeftThumb", () => state.Buttons.LeftStick == ButtonState.Pressed)); + buttonGetters.Add(("RightThumb", () => state.Buttons.RightStick == ButtonState.Pressed)); + buttonGetters.Add(("LeftShoulder", () => state.Buttons.LeftShoulder == ButtonState.Pressed)); + buttonGetters.Add(("RightShoulder", () => state.Buttons.RightShoulder == ButtonState.Pressed)); + + // dpad + buttonGetters.Add(("DpadUp", () => state.DPad.Up == ButtonState.Pressed)); + buttonGetters.Add(("DpadDown", () => state.DPad.Down == ButtonState.Pressed)); + buttonGetters.Add(("DpadLeft", () => state.DPad.Left == ButtonState.Pressed)); + buttonGetters.Add(("DpadRight", () => state.DPad.Right == ButtonState.Pressed)); + + // sticks + buttonGetters.Add(("LStickUp", () => state.ThumbSticks.Left.Y >= dzp)); + buttonGetters.Add(("LStickDown", () => state.ThumbSticks.Left.Y <= dzn)); + buttonGetters.Add(("LStickLeft", () => state.ThumbSticks.Left.X <= dzn)); + buttonGetters.Add(("LStickRight", () => state.ThumbSticks.Left.X >= dzp)); + buttonGetters.Add(("RStickUp", () => state.ThumbSticks.Right.Y >= dzp)); + buttonGetters.Add(("RStickDown", () => state.ThumbSticks.Right.Y <= dzn)); + buttonGetters.Add(("RStickLeft", () => state.ThumbSticks.Right.X <= dzn)); + buttonGetters.Add(("RStickRight", () => state.ThumbSticks.Right.X >= dzp)); + + // triggers + buttonGetters.Add(("LeftTrigger", () => state.Triggers.Left > dzt)); + buttonGetters.Add(("RightTrigger", () => state.Triggers.Right > dzt)); + } + else + { + // no internal map detected - use Joystick + + // OpenTK's GetAxis returns float values (as opposed to the shorts of SlimDX) + const float ConversionFactor = 1.0f / short.MaxValue; + const float dzp = 20000 * ConversionFactor; + const float dzn = -20000 * ConversionFactor; +// const float dzt = 0.6f; + + // axis + buttonGetters.Add(("X+", () => jState.GetAxis(0) >= dzp)); + buttonGetters.Add(("X-", () => jState.GetAxis(0) <= dzn)); + buttonGetters.Add(("Y+", () => jState.GetAxis(1) >= dzp)); + buttonGetters.Add(("Y-", () => jState.GetAxis(1) <= dzn)); + buttonGetters.Add(("Z+", () => jState.GetAxis(2) >= dzp)); + buttonGetters.Add(("Z-", () => jState.GetAxis(2) <= dzn)); + buttonGetters.Add(("W+", () => jState.GetAxis(3) >= dzp)); + buttonGetters.Add(("W-", () => jState.GetAxis(3) <= dzn)); + buttonGetters.Add(("V+", () => jState.GetAxis(4) >= dzp)); + buttonGetters.Add(("V-", () => jState.GetAxis(4) <= dzn)); + buttonGetters.Add(("S+", () => jState.GetAxis(5) >= dzp)); + buttonGetters.Add(("S-", () => jState.GetAxis(5) <= dzn)); + buttonGetters.Add(("Q+", () => jState.GetAxis(6) >= dzp)); + buttonGetters.Add(("Q-", () => jState.GetAxis(6) <= dzn)); + buttonGetters.Add(("P+", () => jState.GetAxis(7) >= dzp)); + buttonGetters.Add(("P-", () => jState.GetAxis(7) <= dzn)); + buttonGetters.Add(("N+", () => jState.GetAxis(8) >= dzp)); + buttonGetters.Add(("N-", () => jState.GetAxis(8) <= dzn)); + // should be enough axes, but just in case: + for (var i = 9; i < 64; i++) + { + var j = i; + buttonGetters.Add(($"Axis{j.ToString()}+", () => jState.GetAxis(j) >= dzp)); + buttonGetters.Add(($"Axis{j.ToString()}-", () => jState.GetAxis(j) <= dzn)); + } + + // buttons + for (int i = 0, l = _joystickCapabilities?.ButtonCount ?? 0; i < l; i++) + { + var j = i; + buttonGetters.Add(($"B{i + 1}", () => jState.GetButton(j) == ButtonState.Pressed)); + } + + // hats + buttonGetters.Add(("POV1U", () => jState.GetHat(JoystickHat.Hat0).IsUp)); + buttonGetters.Add(("POV1D", () => jState.GetHat(JoystickHat.Hat0).IsDown)); + buttonGetters.Add(("POV1L", () => jState.GetHat(JoystickHat.Hat0).IsLeft)); + buttonGetters.Add(("POV1R", () => jState.GetHat(JoystickHat.Hat0).IsRight)); + buttonGetters.Add(("POV2U", () => jState.GetHat(JoystickHat.Hat1).IsUp)); + buttonGetters.Add(("POV2D", () => jState.GetHat(JoystickHat.Hat1).IsDown)); + buttonGetters.Add(("POV2L", () => jState.GetHat(JoystickHat.Hat1).IsLeft)); + buttonGetters.Add(("POV2R", () => jState.GetHat(JoystickHat.Hat1).IsRight)); + buttonGetters.Add(("POV3U", () => jState.GetHat(JoystickHat.Hat2).IsUp)); + buttonGetters.Add(("POV3D", () => jState.GetHat(JoystickHat.Hat2).IsDown)); + buttonGetters.Add(("POV3L", () => jState.GetHat(JoystickHat.Hat2).IsLeft)); + buttonGetters.Add(("POV3R", () => jState.GetHat(JoystickHat.Hat2).IsRight)); + buttonGetters.Add(("POV4U", () => jState.GetHat(JoystickHat.Hat3).IsUp)); + buttonGetters.Add(("POV4D", () => jState.GetHat(JoystickHat.Hat3).IsDown)); + buttonGetters.Add(("POV4L", () => jState.GetHat(JoystickHat.Hat3).IsLeft)); + buttonGetters.Add(("POV4R", () => jState.GetHat(JoystickHat.Hat3).IsRight)); + } + + ButtonGetters = buttonGetters; } public void Update() @@ -212,147 +324,7 @@ namespace BizHawk.Bizware.OpenTK3 } /// Contains name and delegate function for all buttons, hats and axis - public readonly List buttonObjects = new List(); - - private void AddItem(string name, Func pressed) => - buttonObjects.Add(new ButtonObject - { - ButtonName = name, - ButtonAction = pressed - }); - - public struct ButtonObject - { - public string ButtonName; - public Func ButtonAction; - } - - /// - /// Setup mappings prior to button initialization.
- /// This is also here in case in the future we want users to be able to supply their own mappings for a device, perhaps via an input form. Possibly wishful thinking/overly complex. - ///
- private void InitializeMappings() - { - if (_guidObtained) - { - // placeholder for if/when we figure out how to supply OpenTK with custom GamePadConfigurationDatabase entries - } - - // currently OpenTK has an internal database of mappings for the GamePad class: https://github.com/opentk/opentk/blob/master/src/OpenTK/Input/GamePadConfigurationDatabase.cs - if (MappedGamePad) - { - // internal map detected - use OpenTKGamePad - InitializeGamePadControls(); - } - else - { - // no internal map detected - use Joystick - InitializeJoystickControls(); - } - } - - private void InitializeJoystickControls() - { - // OpenTK's GetAxis returns float values (as opposed to the shorts of SlimDX) - const float ConversionFactor = 1.0f / short.MaxValue; - const float dzp = 20000 * ConversionFactor; - const float dzn = -20000 * ConversionFactor; - //const float dzt = 0.6f; - - // axis - AddItem("X+", () => jState.GetAxis(0) >= dzp); - AddItem("X-", () => jState.GetAxis(0) <= dzn); - AddItem("Y+", () => jState.GetAxis(1) >= dzp); - AddItem("Y-", () => jState.GetAxis(1) <= dzn); - AddItem("Z+", () => jState.GetAxis(2) >= dzp); - AddItem("Z-", () => jState.GetAxis(2) <= dzn); - AddItem("W+", () => jState.GetAxis(3) >= dzp); - AddItem("W-", () => jState.GetAxis(3) <= dzn); - AddItem("V+", () => jState.GetAxis(4) >= dzp); - AddItem("V-", () => jState.GetAxis(4) <= dzn); - AddItem("S+", () => jState.GetAxis(5) >= dzp); - AddItem("S-", () => jState.GetAxis(5) <= dzn); - AddItem("Q+", () => jState.GetAxis(6) >= dzp); - AddItem("Q-", () => jState.GetAxis(6) <= dzn); - AddItem("P+", () => jState.GetAxis(7) >= dzp); - AddItem("P-", () => jState.GetAxis(7) <= dzn); - AddItem("N+", () => jState.GetAxis(8) >= dzp); - AddItem("N-", () => jState.GetAxis(8) <= dzn); - // should be enough axis, but just in case: - for (var i = 9; i < 64; i++) - { - var j = i; - AddItem($"Axis{j.ToString()}+", () => jState.GetAxis(j) >= dzp); - AddItem($"Axis{j.ToString()}-", () => jState.GetAxis(j) <= dzn); - } - - // buttons - for (var i = 0; i < (_joystickCapabilities?.ButtonCount ?? 0); i++) - { - var j = i; - AddItem($"B{i + 1}", () => jState.GetButton(j) == ButtonState.Pressed); - } - - // hats - AddItem("POV1U", () => jState.GetHat(JoystickHat.Hat0).IsUp); - AddItem("POV1D", () => jState.GetHat(JoystickHat.Hat0).IsDown); - AddItem("POV1L", () => jState.GetHat(JoystickHat.Hat0).IsLeft); - AddItem("POV1R", () => jState.GetHat(JoystickHat.Hat0).IsRight); - AddItem("POV2U", () => jState.GetHat(JoystickHat.Hat1).IsUp); - AddItem("POV2D", () => jState.GetHat(JoystickHat.Hat1).IsDown); - AddItem("POV2L", () => jState.GetHat(JoystickHat.Hat1).IsLeft); - AddItem("POV2R", () => jState.GetHat(JoystickHat.Hat1).IsRight); - AddItem("POV3U", () => jState.GetHat(JoystickHat.Hat2).IsUp); - AddItem("POV3D", () => jState.GetHat(JoystickHat.Hat2).IsDown); - AddItem("POV3L", () => jState.GetHat(JoystickHat.Hat2).IsLeft); - AddItem("POV3R", () => jState.GetHat(JoystickHat.Hat2).IsRight); - AddItem("POV4U", () => jState.GetHat(JoystickHat.Hat3).IsUp); - AddItem("POV4D", () => jState.GetHat(JoystickHat.Hat3).IsDown); - AddItem("POV4L", () => jState.GetHat(JoystickHat.Hat3).IsLeft); - AddItem("POV4R", () => jState.GetHat(JoystickHat.Hat3).IsRight); - } - - private void InitializeGamePadControls() - { - // OpenTK's ThumbSticks contain float values (as opposed to the shorts of SlimDX) - const float ConversionFactor = 1.0f / short.MaxValue; - const float dzp = 20000 * ConversionFactor; - const float dzn = -20000 * ConversionFactor; - const float dzt = 0.6f; - - // buttons - AddItem("A", () => state.Buttons.A == ButtonState.Pressed); - AddItem("B", () => state.Buttons.B == ButtonState.Pressed); - AddItem("X", () => state.Buttons.X == ButtonState.Pressed); - AddItem("Y", () => state.Buttons.Y == ButtonState.Pressed); - AddItem("Guide", () => state.Buttons.BigButton == ButtonState.Pressed); - AddItem("Start", () => state.Buttons.Start == ButtonState.Pressed); - AddItem("Back", () => state.Buttons.Back == ButtonState.Pressed); - AddItem("LeftThumb", () => state.Buttons.LeftStick == ButtonState.Pressed); - AddItem("RightThumb", () => state.Buttons.RightStick == ButtonState.Pressed); - AddItem("LeftShoulder", () => state.Buttons.LeftShoulder == ButtonState.Pressed); - AddItem("RightShoulder", () => state.Buttons.RightShoulder == ButtonState.Pressed); - - // dpad - AddItem("DpadUp", () => state.DPad.Up == ButtonState.Pressed); - AddItem("DpadDown", () => state.DPad.Down == ButtonState.Pressed); - AddItem("DpadLeft", () => state.DPad.Left == ButtonState.Pressed); - AddItem("DpadRight", () => state.DPad.Right == ButtonState.Pressed); - - // sticks - AddItem("LStickUp", () => state.ThumbSticks.Left.Y >= dzp); - AddItem("LStickDown", () => state.ThumbSticks.Left.Y <= dzn); - AddItem("LStickLeft", () => state.ThumbSticks.Left.X <= dzn); - AddItem("LStickRight", () => state.ThumbSticks.Left.X >= dzp); - AddItem("RStickUp", () => state.ThumbSticks.Right.Y >= dzp); - AddItem("RStickDown", () => state.ThumbSticks.Right.Y <= dzn); - AddItem("RStickLeft", () => state.ThumbSticks.Right.X <= dzn); - AddItem("RStickRight", () => state.ThumbSticks.Right.X >= dzp); - - // triggers - AddItem("LeftTrigger", () => state.Triggers.Left > dzt); - AddItem("RightTrigger", () => state.Triggers.Right > dzt); - } + public readonly IReadOnlyCollection<(string ButtonName, Func GetIsPressed)> ButtonGetters; /// and are in 0.. public void SetVibration(int left, int right) diff --git a/src/BizHawk.Bizware.OpenTK3/OpenTKInputAdapter.cs b/src/BizHawk.Bizware.OpenTK3/OpenTKInputAdapter.cs index 61d63e4df7..70b4d1dc71 100644 --- a/src/BizHawk.Bizware.OpenTK3/OpenTKInputAdapter.cs +++ b/src/BizHawk.Bizware.OpenTK3/OpenTKInputAdapter.cs @@ -33,7 +33,7 @@ namespace BizHawk.Bizware.OpenTK3 { foreach (var pad in OTK_GamePad.EnumerateDevices()) { - foreach (var but in pad.buttonObjects) handleButton(pad.InputNamePrefix + but.ButtonName, but.ButtonAction(), ClientInputFocus.Pad); + foreach (var but in pad.ButtonGetters) handleButton(pad.InputNamePrefix + but.ButtonName, but.GetIsPressed(), ClientInputFocus.Pad); foreach (var (axisID, f) in pad.GetAxes()) handleAxis($"{pad.InputNamePrefix}{axisID} Axis", (int) f); #if DEBUG // effectively no-op as OpenTK 3 doesn't seem to actually support haptic feedback foreach (var channel in pad.HapticsChannels)