Use SDL2 event API for joystick devices

This commit is contained in:
thefiddler 2013-12-18 17:16:29 +01:00
parent 022e5c845c
commit d9985fc571
2 changed files with 204 additions and 45 deletions

View file

@ -92,6 +92,42 @@ namespace OpenTK.Platform.SDL2
case EventType.MOUSEWHEEL: case EventType.MOUSEWHEEL:
driver.mouse_driver.ProcessWheelEvent(ev.Wheel); driver.mouse_driver.ProcessWheelEvent(ev.Wheel);
break; 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 get
{ {
throw new NotImplementedException(); return joystick_driver;
} }
} }

View file

@ -40,6 +40,7 @@ namespace OpenTK.Platform.SDL2
public float RangeMultiplier { get { return 1.0f / 32768.0f; } } public float RangeMultiplier { get { return 1.0f / 32768.0f; } }
public int HatCount { get; set; } public int HatCount { get; set; }
public int BallCount { get; set; } public int BallCount { get; set; }
public bool IsConnected { get; set; }
} }
readonly List<JoystickDevice> joysticks = new List<JoystickDevice>(); readonly List<JoystickDevice> joysticks = new List<JoystickDevice>();
@ -49,19 +50,11 @@ namespace OpenTK.Platform.SDL2
public Sdl2JoystickDriver() public Sdl2JoystickDriver()
{ {
joysticks_readonly = joysticks.AsReadOnly(); joysticks_readonly = joysticks.AsReadOnly();
RefreshJoysticks();
} }
#region Private Members #region Private Members
void RefreshJoysticks() JoystickDevice<Sdl2JoystickDetails> OpenJoystick(int id)
{
joysticks.Clear();
int count = SDL.NumJoysticks();
for (int i = 0; i < count; i++)
{ {
JoystickDevice<Sdl2JoystickDetails> joystick = null; JoystickDevice<Sdl2JoystickDetails> joystick = null;
int num_axes = 0; int num_axes = 0;
@ -69,7 +62,7 @@ namespace OpenTK.Platform.SDL2
int num_hats = 0; int num_hats = 0;
int num_balls = 0; int num_balls = 0;
IntPtr handle = SDL.JoystickOpen(i); IntPtr handle = SDL.JoystickOpen(id);
if (handle != IntPtr.Zero) if (handle != IntPtr.Zero)
{ {
num_axes = SDL.JoystickNumAxes(handle); num_axes = SDL.JoystickNumAxes(handle);
@ -77,15 +70,162 @@ namespace OpenTK.Platform.SDL2
num_hats = SDL.JoystickNumHats(handle); num_hats = SDL.JoystickNumHats(handle);
num_balls = SDL.JoystickNumBalls(handle); num_balls = SDL.JoystickNumBalls(handle);
joystick = new JoystickDevice<Sdl2JoystickDetails>(i, num_axes, num_buttons); joystick = new JoystickDevice<Sdl2JoystickDetails>(id, num_axes, num_buttons);
joystick.Description = SDL.JoystickName(handle); joystick.Description = SDL.JoystickName(handle);
joystick.Details.Handle = handle; joystick.Details.Handle = handle;
joystick.Details.HatCount = num_hats; joystick.Details.HatCount = num_hats;
joystick.Details.BallCount = num_balls; 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<Sdl2JoystickDetails> joystick = OpenJoystick(id);
if (joysticks != null)
{
joystick.Details.IsConnected = true;
joysticks[id] = joystick;
} }
} }
} }
break;
case EventType.JOYDEVICEREMOVED:
{
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[id];
joystick.Details.IsConnected = false;
}
break;
}
}
public void ProcessJoystickEvent(JoyAxisEvent ev)
{
int id = ev.Which;
if (IsJoystickValid(id))
{
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)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<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)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<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)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<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)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 #endregion
@ -101,24 +241,7 @@ namespace OpenTK.Platform.SDL2
public void Poll() public void Poll()
{ {
SDL.JoystickUpdate(); // Do nothing
foreach (var j in joysticks)
{
var joystick = (JoystickDevice<Sdl2JoystickDetails>)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);
}
}
} }
#endregion #endregion