From e5cd6a3b9e940207e25921e3e02b475277e66094 Mon Sep 17 00:00:00 2001 From: thefiddler Date: Fri, 25 Jul 2014 23:26:03 +0200 Subject: [PATCH 1/3] [Input] Implemented JoystickHat GamePad mapping --- Source/OpenTK/Input/ConfigurationType.cs | 3 +- Source/OpenTK/Input/GamePadConfiguration.cs | 35 +++++++++++++++++-- .../Input/GamePadConfigurationSource.cs | 26 ++++++++++++-- Source/OpenTK/Platform/MappedGamePadDriver.cs | 22 ++++++++++++ 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/Source/OpenTK/Input/ConfigurationType.cs b/Source/OpenTK/Input/ConfigurationType.cs index 0cbb649a..abfe15e5 100644 --- a/Source/OpenTK/Input/ConfigurationType.cs +++ b/Source/OpenTK/Input/ConfigurationType.cs @@ -35,7 +35,8 @@ namespace OpenTK.Input { Unmapped = 0, Axis, - Button + Button, + Hat } } diff --git a/Source/OpenTK/Input/GamePadConfiguration.cs b/Source/OpenTK/Input/GamePadConfiguration.cs index 54600e79..c7e9877c 100644 --- a/Source/OpenTK/Input/GamePadConfiguration.cs +++ b/Source/OpenTK/Input/GamePadConfiguration.cs @@ -175,8 +175,11 @@ namespace OpenTK.Input return new GamePadConfigurationSource(ParseButton(item)); case 'h': - throw new NotImplementedException(); - //return new MapItem(ParseHat(item)); + { + HatPosition position; + JoystickHat hat = ParseHat(item, out position); + return new GamePadConfigurationSource(hat, position); + } default: throw new InvalidOperationException("[Input] Invalid GamePad configuration value"); @@ -193,12 +196,38 @@ namespace OpenTK.Input static JoystickButton ParseButton(string item) { - // item is in the format "b#" where # a zero-based integer nubmer + // item is in the format "b#" where # a zero-based integer number JoystickButton button = JoystickButton.Button0; int id = Int32.Parse(item.Substring(1)); return button + id; } + static JoystickHat ParseHat(string item, out HatPosition position) + { + // item is in the format "h#.#" where: + // - the 1st # is the zero-based hat id + // - the 2nd # is a bit-flag defining the hat position + JoystickHat hat = JoystickHat.Hat0; + int id = Int32.Parse(item.Substring(1, 1)); + int pos = Int32.Parse(item.Substring(3)); + + position = HatPosition.Centered; + switch (pos) + { + case 1: position = HatPosition.Up; break; + case 2: position = HatPosition.Right; break; + case 3: position = HatPosition.UpRight; break; + case 4: position = HatPosition.Down ; break; + case 6: position = HatPosition.DownRight; break; + case 8: position = HatPosition.Left; break; + case 9: position = HatPosition.UpLeft; break; + case 12: position = HatPosition.DownLeft; break; + default: position = HatPosition.Centered; break; + } + + return hat + id; + } + #endregion } } diff --git a/Source/OpenTK/Input/GamePadConfigurationSource.cs b/Source/OpenTK/Input/GamePadConfigurationSource.cs index c1b25b82..c312f529 100644 --- a/Source/OpenTK/Input/GamePadConfigurationSource.cs +++ b/Source/OpenTK/Input/GamePadConfigurationSource.cs @@ -34,8 +34,10 @@ namespace OpenTK.Input struct GamePadConfigurationSource { ConfigurationType map_type; - Nullable map_button; - Nullable map_axis; + JoystickButton? map_button; + JoystickAxis? map_axis; + JoystickHat? map_hat; + HatPosition? map_hat_position; public GamePadConfigurationSource(JoystickAxis axis) : this() @@ -51,6 +53,14 @@ namespace OpenTK.Input Button = button; } + public GamePadConfigurationSource(JoystickHat hat, HatPosition pos) + : this() + { + Type = ConfigurationType.Hat; + Hat = hat; + map_hat_position = pos; + } + public ConfigurationType Type { get { return map_type; } @@ -68,5 +78,17 @@ namespace OpenTK.Input get { return map_button.Value; } private set { map_button = value; } } + + public JoystickHat Hat + { + get { return map_hat.Value; } + private set { map_hat = value; } + } + + public HatPosition HatPosition + { + get { return map_hat_position.Value; } + private set { map_hat_position = value; } + } } } diff --git a/Source/OpenTK/Platform/MappedGamePadDriver.cs b/Source/OpenTK/Platform/MappedGamePadDriver.cs index 79245405..e6902af2 100644 --- a/Source/OpenTK/Platform/MappedGamePadDriver.cs +++ b/Source/OpenTK/Platform/MappedGamePadDriver.cs @@ -117,6 +117,28 @@ namespace OpenTK.Platform } } break; + + case ConfigurationType.Hat: + { + // JoystickHat -> Buttons/GamePadAxes mapping + JoystickHat source_hat = map.Source.Hat; + bool pressed = joy.GetHat(source_hat).Position == map.Source.HatPosition; + + switch (map.Target.Type) + { + case ConfigurationType.Axis: + // Todo: if SDL2 GameController config is ever updated to + // distinguish between negative/positive axes, then update + // the following line to support both. + pad.SetAxis(map.Target.Axis, pressed ? short.MaxValue : (short)0); + break; + + case ConfigurationType.Button: + pad.SetButton(map.Target.Button, pressed); + break; + } + } + break; } } } From fe1d465b852b18b4d0f4f60fbd50bd35965f3df4 Mon Sep 17 00:00:00 2001 From: Andrew O'Connor Date: Sun, 27 Jul 2014 14:54:36 +0100 Subject: [PATCH 2/3] [Input][SDL] Fix JoystickHat bugs On SDL, DPad inputs were not correctly translated from joystick hat inputs. Updated MappedGamePadDriver so that it will correctly recognize combined joystick hat directions e.g. DPadLeft should be true when DownLeft, Left, or UpLeft are returned from the joystick hat. --- Source/OpenTK/Platform/MappedGamePadDriver.cs | 21 ++++++++++++++++++- Source/OpenTK/Platform/SDL2/Sdl2.cs | 4 ++-- .../Platform/SDL2/Sdl2JoystickDriver.cs | 16 +++++++------- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Source/OpenTK/Platform/MappedGamePadDriver.cs b/Source/OpenTK/Platform/MappedGamePadDriver.cs index e6902af2..2b8b313c 100644 --- a/Source/OpenTK/Platform/MappedGamePadDriver.cs +++ b/Source/OpenTK/Platform/MappedGamePadDriver.cs @@ -122,7 +122,26 @@ namespace OpenTK.Platform { // JoystickHat -> Buttons/GamePadAxes mapping JoystickHat source_hat = map.Source.Hat; - bool pressed = joy.GetHat(source_hat).Position == map.Source.HatPosition; + + bool pressed = false; + switch (map.Source.HatPosition) + { + case HatPosition.Down: + pressed = joy.GetHat(source_hat).IsDown; + break; + + case HatPosition.Up: + pressed = joy.GetHat(source_hat).IsUp; + break; + + case HatPosition.Left: + pressed = joy.GetHat(source_hat).IsLeft; + break; + + case HatPosition.Right: + pressed = joy.GetHat(source_hat).IsRight; + break; + } switch (map.Target.Type) { diff --git a/Source/OpenTK/Platform/SDL2/Sdl2.cs b/Source/OpenTK/Platform/SDL2/Sdl2.cs index 2a9bba15..53418e44 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2.cs @@ -753,8 +753,8 @@ namespace OpenTK.Platform.SDL2 Centered = 0x00, Up = 0x01, Right = 0x02, - Down = 0x03, - Left = 0x04, + Down = 0x04, + Left = 0x08, RightUp = Right | Up, RightDown = Right | Down, LeftUp = Left | Up, diff --git a/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs b/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs index 41726c62..32d8a59f 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs @@ -127,28 +127,28 @@ namespace OpenTK.Platform.SDL2 OpenTK.Input.HatPosition TranslateHat(HatPosition value) { - if ((value & HatPosition.LeftUp) == value) + if ((value & HatPosition.LeftUp) == HatPosition.LeftUp) return OpenTK.Input.HatPosition.UpLeft; - if ((value & HatPosition.RightUp) == value) + if ((value & HatPosition.RightUp) == HatPosition.RightUp) return OpenTK.Input.HatPosition.UpRight; - if ((value & HatPosition.LeftDown) == value) + if ((value & HatPosition.LeftDown) == HatPosition.LeftDown) return OpenTK.Input.HatPosition.DownLeft; - if ((value & HatPosition.RightDown) == value) + if ((value & HatPosition.RightDown) == HatPosition.RightDown) return OpenTK.Input.HatPosition.DownRight; - if ((value & HatPosition.Up) == value) + if ((value & HatPosition.Up) == HatPosition.Up) return OpenTK.Input.HatPosition.Up; - if ((value & HatPosition.Right) == value) + if ((value & HatPosition.Right) == HatPosition.Right) return OpenTK.Input.HatPosition.Right; - if ((value & HatPosition.Down) == value) + if ((value & HatPosition.Down) == HatPosition.Down) return OpenTK.Input.HatPosition.Down; - if ((value & HatPosition.Left) == value) + if ((value & HatPosition.Left) == HatPosition.Left) return OpenTK.Input.HatPosition.Left; return OpenTK.Input.HatPosition.Centered; From e243316e8e6dac62d22e33eaf680fedca2d474d0 Mon Sep 17 00:00:00 2001 From: thefiddler Date: Tue, 29 Jul 2014 23:21:37 +0200 Subject: [PATCH 3/3] [Input] Cleaned up line endings and joystick hat mapping --- Source/OpenTK/Platform/MappedGamePadDriver.cs | 33 ++++++++++--------- .../Platform/SDL2/Sdl2JoystickDriver.cs | 16 ++++----- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/Source/OpenTK/Platform/MappedGamePadDriver.cs b/Source/OpenTK/Platform/MappedGamePadDriver.cs index 2b8b313c..5d55b779 100644 --- a/Source/OpenTK/Platform/MappedGamePadDriver.cs +++ b/Source/OpenTK/Platform/MappedGamePadDriver.cs @@ -122,26 +122,27 @@ namespace OpenTK.Platform { // JoystickHat -> Buttons/GamePadAxes mapping JoystickHat source_hat = map.Source.Hat; + JoystickHatState state = joy.GetHat(source_hat); - bool pressed = false; - switch (map.Source.HatPosition) - { - case HatPosition.Down: - pressed = joy.GetHat(source_hat).IsDown; - break; + bool pressed = false; + switch (map.Source.HatPosition) + { + case HatPosition.Down: + pressed = state.IsDown; + break; - case HatPosition.Up: - pressed = joy.GetHat(source_hat).IsUp; - break; + case HatPosition.Up: + pressed = state.IsUp; + break; - case HatPosition.Left: - pressed = joy.GetHat(source_hat).IsLeft; - break; + case HatPosition.Left: + pressed = state.IsLeft; + break; - case HatPosition.Right: - pressed = joy.GetHat(source_hat).IsRight; - break; - } + case HatPosition.Right: + pressed = state.IsRight; + break; + } switch (map.Target.Type) { diff --git a/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs b/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs index 32d8a59f..7623bf53 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs @@ -127,28 +127,28 @@ namespace OpenTK.Platform.SDL2 OpenTK.Input.HatPosition TranslateHat(HatPosition value) { - if ((value & HatPosition.LeftUp) == HatPosition.LeftUp) + if ((value & HatPosition.LeftUp) == HatPosition.LeftUp) return OpenTK.Input.HatPosition.UpLeft; - if ((value & HatPosition.RightUp) == HatPosition.RightUp) + if ((value & HatPosition.RightUp) == HatPosition.RightUp) return OpenTK.Input.HatPosition.UpRight; - if ((value & HatPosition.LeftDown) == HatPosition.LeftDown) + if ((value & HatPosition.LeftDown) == HatPosition.LeftDown) return OpenTK.Input.HatPosition.DownLeft; - if ((value & HatPosition.RightDown) == HatPosition.RightDown) + if ((value & HatPosition.RightDown) == HatPosition.RightDown) return OpenTK.Input.HatPosition.DownRight; - if ((value & HatPosition.Up) == HatPosition.Up) + if ((value & HatPosition.Up) == HatPosition.Up) return OpenTK.Input.HatPosition.Up; - if ((value & HatPosition.Right) == HatPosition.Right) + if ((value & HatPosition.Right) == HatPosition.Right) return OpenTK.Input.HatPosition.Right; - if ((value & HatPosition.Down) == HatPosition.Down) + if ((value & HatPosition.Down) == HatPosition.Down) return OpenTK.Input.HatPosition.Down; - if ((value & HatPosition.Left) == HatPosition.Left) + if ((value & HatPosition.Left) == HatPosition.Left) return OpenTK.Input.HatPosition.Left; return OpenTK.Input.HatPosition.Centered;