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..5d55b779 100644 --- a/Source/OpenTK/Platform/MappedGamePadDriver.cs +++ b/Source/OpenTK/Platform/MappedGamePadDriver.cs @@ -117,6 +117,48 @@ namespace OpenTK.Platform } } break; + + case ConfigurationType.Hat: + { + // 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 = state.IsDown; + break; + + case HatPosition.Up: + pressed = state.IsUp; + break; + + case HatPosition.Left: + pressed = state.IsLeft; + break; + + case HatPosition.Right: + pressed = state.IsRight; + break; + } + + 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; } } } 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..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) == 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;