Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/issue64' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
thefiddler committed Mar 16, 2014
2 parents f30ee0f + ccb5408 commit 59c5f6b
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 13 deletions.
54 changes: 53 additions & 1 deletion Source/OpenTK/Input/JoystickHatState.cs
Expand Up @@ -34,7 +34,7 @@ namespace OpenTK.Input
/// <summary>
/// Describes the state of a joystick hat.
/// </summary>
public struct JoystickHatState
public struct JoystickHatState : IEquatable<JoystickHatState>
{
HatPosition position;

Expand Down Expand Up @@ -113,6 +113,58 @@ public bool IsRight
Position == HatPosition.DownRight;
}
}

/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.JoystickHatState"/>.
/// </summary>
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.JoystickHatState"/>.</returns>
public override string ToString()
{
return String.Format(
"{{{0}{1}{2}{3}}}",
IsUp ? "U" : String.Empty,
IsLeft ? "L" : String.Empty,
IsDown ? "D" : String.Empty,
IsRight ? "R" : String.Empty);
}

/// <summary>
/// Serves as a hash function for a <see cref="OpenTK.Input.JoystickHatState"/> object.
/// </summary>
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
/// hash table.</returns>
public override int GetHashCode()
{
return Position.GetHashCode();
}

/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.JoystickHatState"/>.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.JoystickHatState"/>.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
/// <see cref="OpenTK.Input.JoystickHatState"/>; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
return
obj is JoystickHatState &&
Equals((JoystickHatState)obj);
}

#region IEquatable<JoystickHatState> implementation

/// <summary>
/// Determines whether the specified <see cref="OpenTK.Input.JoystickHatState"/> is equal to the current <see cref="OpenTK.Input.JoystickHatState"/>.
/// </summary>
/// <param name="other">The <see cref="OpenTK.Input.JoystickHatState"/> to compare with the current <see cref="OpenTK.Input.JoystickHatState"/>.</param>
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.JoystickHatState"/> is equal to the current
/// <see cref="OpenTK.Input.JoystickHatState"/>; otherwise, <c>false</c>.</returns>
public bool Equals(JoystickHatState other)
{
return Position == other.Position;
}

#endregion
}
}

8 changes: 7 additions & 1 deletion Source/OpenTK/Input/JoystickState.cs
Expand Up @@ -145,9 +145,10 @@ public override string ToString()
sb.Append(String.Format("{0:f4}", GetAxis(JoystickAxis.Axis0 + i)));
}
return String.Format(
"{{Axes:{0}; Buttons: {1}; IsConnected: {2}}}",
"{{Axes:{0}; Buttons: {1}; Hat: {2}; IsConnected: {3}}}",
sb.ToString(),
Convert.ToString((int)buttons, 2).PadLeft(16, '0'),
hat0,
IsConnected);
}

Expand Down Expand Up @@ -303,6 +304,11 @@ public bool Equals(JoystickState other)
{
equals &= GetAxisUnsafe(i) == other.GetAxisUnsafe(i);
}
for (int i = 0; equals && i < MaxHats; i++)
{
JoystickHat hat = JoystickHat.Hat0 + i;
equals &= GetHat(hat).Equals(other.GetHat(hat));
}
return equals;
}

Expand Down
34 changes: 31 additions & 3 deletions Source/OpenTK/Platform/LegacyJoystickDriver.cs
Expand Up @@ -65,7 +65,10 @@ public void Poll()
if (caps.IsConnected && joysticks[i].Description == DisconnectedName)
{
// New joystick connected
joysticks[i] = new LegacyJoystickDevice(i, caps.AxisCount, caps.ButtonCount);
joysticks[i] = new LegacyJoystickDevice(
i,
caps.AxisCount + 2 * caps.HatCount,
caps.ButtonCount);
//device.Description = Joystick.GetName(i);
joysticks[i].Description = ConnectedName;

Expand All @@ -78,16 +81,41 @@ public void Poll()
}

JoystickState state = Joystick.GetState(i);
for (int axis_index = 0; axis_index < (int)caps.AxisCount; axis_index++)
for (int axis_index = 0; axis_index < caps.AxisCount; axis_index++)
{
JoystickAxis axis = JoystickAxis.Axis0 + axis_index;
joysticks[i].SetAxis(axis, state.GetAxis(axis));
}
for (int button_index = 0; button_index < (int)caps.ButtonCount; button_index++)
for (int button_index = 0; button_index < caps.ButtonCount; button_index++)
{
JoystickButton button = JoystickButton.Button0 + button_index;
joysticks[i].SetButton(button, state.GetButton(button) == ButtonState.Pressed);
}
for (int hat_index = 0; hat_index < caps.HatCount; hat_index++)
{
// LegacyJoystickDriver report hats as pairs of axes
// Make sure we have enough axes left for this mapping
int axis_index = caps.AxisCount + 2 * hat_index;
if (axis_index < JoystickState.MaxAxes)
{
JoystickHat hat = JoystickHat.Hat0 + hat_index;
JoystickHatState hat_state = state.GetHat(hat);
JoystickAxis axis = JoystickAxis.Axis0 + axis_index;
float x = 0;
float y = 0;
if (hat_state.IsDown)
y--;
if (hat_state.IsUp)
y++;
if (hat_state.IsLeft)
x--;
if (hat_state.IsRight)
x++;

joysticks[i].SetAxis(axis, x);
joysticks[i].SetAxis(axis + 1, y);
}
}
}
}

Expand Down
45 changes: 37 additions & 8 deletions Source/OpenTK/Platform/Windows/WinMMJoystick.cs
Expand Up @@ -131,8 +131,16 @@ JoystickDevice<WinMMJoyDetails> OpenJoystick(int number)
// Make sure to reverse the vertical axes, so that +1 points up and -1 points down.
for (int axis = 0; axis < caps.NumAxes; axis++)
{
stick.Details.Min[axis] = caps.GetMin(axis);
stick.Details.Max[axis] = caps.GetMax(axis);
if (axis % 2 == 1)
{
stick.Details.Min[axis] = caps.GetMax(axis);
stick.Details.Max[axis] = caps.GetMin(axis);
}
else
{
stick.Details.Min[axis] = caps.GetMin(axis);
stick.Details.Max[axis] = caps.GetMax(axis);
}
}

if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0)
Expand Down Expand Up @@ -389,21 +397,42 @@ public JoystickState GetState(int player_index)
else
{
// Use joyGetPosEx
JoyInfoEx info = new JoyInfoEx();
info.Size = JoyInfoEx.SizeInBytes;
info.Flags = JoystickFlags.All;
JoyInfoEx info_ex = new JoyInfoEx();
info_ex.Size = JoyInfoEx.SizeInBytes;
info_ex.Flags = JoystickFlags.All;

JoystickError result = UnsafeNativeMethods.joyGetPosEx(device_index, ref info);
JoystickError result = UnsafeNativeMethods.joyGetPosEx(device_index, ref info_ex);
if (result == JoystickError.NoError)
{
for (int i = 0; i < stick.Details.Capabilities.AxisCount; i++)
{
state.SetAxis(JoystickAxis.Axis0 + i, CalculateOffset(info.GetAxis(i), stick.Details.Min[i], stick.Details.Max[i]));
state.SetAxis(JoystickAxis.Axis0 + i, CalculateOffset(info_ex.GetAxis(i), stick.Details.Min[i], stick.Details.Max[i]));
}

for (int i = 0; i < stick.Details.Capabilities.ButtonCount; i++)
{
state.SetButton(JoystickButton.Button0 + i, (info.Buttons & 1 << i) != 0);
state.SetButton(JoystickButton.Button0 + i, (info_ex.Buttons & 1 << i) != 0);
}

for (int i = 0; i < stick.Details.Capabilities.HatCount; i++)
{
// A discrete POV returns specific values for left, right, etc.
// A continuous POV returns an integer indicating an angle in degrees * 100, e.g. 18000 == 180.00 degrees.
// The vast majority of joysticks have discrete POVs, so we'll treat all of them as discrete for simplicity.
if ((JoystickPovPosition)info_ex.Pov != JoystickPovPosition.Centered)
{
HatPosition hatpos = HatPosition.Centered;
if (info_ex.Pov < 4500 || info_ex.Pov >= 31500)
hatpos |= HatPosition.Up;
if (info_ex.Pov >= 4500 && info_ex.Pov < 13500)
hatpos |= HatPosition.Right;
if (info_ex.Pov >= 13500 && info_ex.Pov < 22500)
hatpos |= HatPosition.Down;
if (info_ex.Pov >= 22500 && info_ex.Pov < 31500)
hatpos |= HatPosition.Left;

state.SetHat(JoystickHat.Hat0 + i, new JoystickHatState(hatpos));
}
}

state.SetIsConnected(true);
Expand Down

0 comments on commit 59c5f6b

Please sign in to comment.