diff --git a/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs b/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs index 7a571b14..de174875 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs @@ -92,6 +92,42 @@ namespace OpenTK.Platform.SDL2 case EventType.MOUSEWHEEL: driver.mouse_driver.ProcessWheelEvent(ev.Wheel); break; + + case EventType.JOYDEVICEADDED: + case EventType.JOYDEVICEREMOVED: + driver.joystick_driver.ProcessJoystickEvent(ev.JoyDevice); + break; + + case EventType.JOYAXISMOTION: + driver.joystick_driver.ProcessJoystickEvent(ev.JoyAxis); + break; + + case EventType.JOYBALLMOTION: + driver.joystick_driver.ProcessJoystickEvent(ev.JoyBall); + break; + + case EventType.JOYBUTTONDOWN: + case EventType.JOYBUTTONUP: + driver.joystick_driver.ProcessJoystickEvent(ev.JoyButton); + break; + + case EventType.JOYHATMOTION: + driver.joystick_driver.ProcessJoystickEvent(ev.JoyHat); + break; + + case EventType.CONTROLLERDEVICEADDED: + case EventType.CONTROLLERDEVICEREMOVED: + driver.joystick_driver.ProcessControllerEvent(ev.ControllerDevice); + break; + + case EventType.CONTROLLERAXISMOTION: + driver.joystick_driver.ProcessControllerEvent(ev.ControllerAxis); + break; + + case EventType.CONTROLLERBUTTONDOWN: + case EventType.CONTROLLERBUTTONUP: + driver.joystick_driver.ProcessControllerEvent(ev.ControllerButton); + break; } } } @@ -172,7 +208,7 @@ namespace OpenTK.Platform.SDL2 { get { - throw new NotImplementedException(); + return joystick_driver; } } diff --git a/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs b/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs index 729cee13..380bbd67 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2JoystickDriver.cs @@ -40,6 +40,7 @@ namespace OpenTK.Platform.SDL2 public float RangeMultiplier { get { return 1.0f / 32768.0f; } } public int HatCount { get; set; } public int BallCount { get; set; } + public bool IsConnected { get; set; } } readonly List joysticks = new List(); @@ -49,42 +50,181 @@ namespace OpenTK.Platform.SDL2 public Sdl2JoystickDriver() { joysticks_readonly = joysticks.AsReadOnly(); - - RefreshJoysticks(); - } #region Private Members - void RefreshJoysticks() + JoystickDevice OpenJoystick(int id) { - joysticks.Clear(); + JoystickDevice joystick = null; + int num_axes = 0; + int num_buttons = 0; + int num_hats = 0; + int num_balls = 0; - int count = SDL.NumJoysticks(); - for (int i = 0; i < count; i++) + IntPtr handle = SDL.JoystickOpen(id); + if (handle != IntPtr.Zero) { - JoystickDevice joystick = null; - int num_axes = 0; - int num_buttons = 0; - int num_hats = 0; - int num_balls = 0; + num_axes = SDL.JoystickNumAxes(handle); + num_buttons = SDL.JoystickNumButtons(handle); + num_hats = SDL.JoystickNumHats(handle); + num_balls = SDL.JoystickNumBalls(handle); - IntPtr handle = SDL.JoystickOpen(i); - if (handle != IntPtr.Zero) - { - num_axes = SDL.JoystickNumAxes(handle); - num_buttons = SDL.JoystickNumButtons(handle); - num_hats = SDL.JoystickNumHats(handle); - num_balls = SDL.JoystickNumBalls(handle); + joystick = new JoystickDevice(id, num_axes, num_buttons); + joystick.Description = SDL.JoystickName(handle); + joystick.Details.Handle = handle; + joystick.Details.HatCount = num_hats; + joystick.Details.BallCount = num_balls; - joystick = new JoystickDevice(i, num_axes, num_buttons); - joystick.Description = SDL.JoystickName(handle); - joystick.Details.Handle = handle; - joystick.Details.HatCount = num_hats; - joystick.Details.BallCount = num_balls; - joysticks.Add(joystick); - } + Debug.Print("[SDL2] Joystick device {0} opened successfully. ", id); + Debug.Print("\t\t'{0}' has {1} axes, {2} buttons, {3} hats, {4} balls", + joystick.Description, joystick.Axis.Count, joystick.Button.Count, + joystick.Details.HatCount, joystick.Details.BallCount); } + else + { + Debug.Print("[SDL2] Failed to open joystick device {0}", id); + } + + return joystick; + } + + bool IsJoystickValid(int id) + { + return id >= 0 && id < joysticks.Count; + } + + #endregion + + #region Public Members + + public void ProcessJoystickEvent(JoyDeviceEvent ev) + { + int id = ev.Which; + if (id < 0) + { + Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type); + return; + } + + switch (ev.Type) + { + case EventType.JOYDEVICEADDED: + { + // Make sure we have enough space to store this instance + if (joysticks.Count <= id) + { + joysticks.Capacity = OpenTK.MathHelper.NextPowerOfTwo(id); + } + + IntPtr handle = SDL.JoystickOpen(id); + if (handle != IntPtr.Zero) + { + JoystickDevice joystick = OpenJoystick(id); + if (joysticks != null) + { + joystick.Details.IsConnected = true; + joysticks[id] = joystick; + } + } + } + break; + + case EventType.JOYDEVICEREMOVED: + { + JoystickDevice joystick = (JoystickDevice)joysticks[id]; + joystick.Details.IsConnected = false; + } + break; + } + } + + public void ProcessJoystickEvent(JoyAxisEvent ev) + { + int id = ev.Which; + if (IsJoystickValid(id)) + { + JoystickDevice joystick = (JoystickDevice)joysticks[id]; + float value = ev.Value * joystick.Details.RangeMultiplier; + joystick.SetAxis((JoystickAxis)ev.Axis, value); + } + else + { + Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type); + } + } + + public void ProcessJoystickEvent(JoyBallEvent ev) + { + int id = ev.Which; + if (IsJoystickValid(id)) + { + JoystickDevice joystick = (JoystickDevice)joysticks[id]; + // Todo: does it make sense to support balls? + } + else + { + Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type); + } + } + + public void ProcessJoystickEvent(JoyButtonEvent ev) + { + int id = ev.Which; + if (IsJoystickValid(id)) + { + JoystickDevice joystick = (JoystickDevice)joysticks[id]; + joystick.SetButton((JoystickButton)ev.Button, ev.State == State.Pressed); + } + else + { + Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type); + } + } + + public void ProcessJoystickEvent(JoyHatEvent ev) + { + int id = ev.Which; + if (IsJoystickValid(id)) + { + JoystickDevice joystick = (JoystickDevice)joysticks[id]; + // Todo: map hat to an extra axis + } + else + { + Debug.Print("[SDL2] Invalid joystick id {0} in {1}", id, ev.Type); + } + } + + public void ProcessControllerEvent(ControllerDeviceEvent ev) + { + int id = ev.Which; + + switch (ev.Type) + { + case EventType.CONTROLLERDEVICEADDED: + break; + + case EventType.CONTROLLERDEVICEREMOVED: + break; + + case EventType.CONTROLLERDEVICEREMAPPED: + break; + } + } + + public void ProcessControllerEvent(ControllerAxisEvent ev) + { + int id = ev.Which; + + + } + + public void ProcessControllerEvent(ControllerButtonEvent ev) + { + int id = ev.Which; + + } #endregion @@ -101,24 +241,7 @@ namespace OpenTK.Platform.SDL2 public void Poll() { - SDL.JoystickUpdate(); - foreach (var j in joysticks) - { - var joystick = (JoystickDevice)j; - IntPtr handle = joystick.Details.Handle; - - for (int i = 0; i < joystick.Axis.Count; i++) - { - var axis = JoystickAxis.Axis0 + i; - joystick.SetAxis(axis, SDL.JoystickGetAxis(handle, i) * joystick.Details.RangeMultiplier); - } - - for (int i = 0; i < joystick.Button.Count; i++) - { - var button = JoystickButton.Button0 + i; - joystick.SetButton(button, SDL.JoystickGetButton(handle, i) != 0); - } - } + // Do nothing } #endregion