Skip to content

Commit

Permalink
[Mac] Implemented JoystickHat support
Browse files Browse the repository at this point in the history
  • Loading branch information
thefiddler committed Jan 31, 2014
1 parent a722827 commit 5145ebc
Showing 1 changed file with 78 additions and 0 deletions.
78 changes: 78 additions & 0 deletions Source/OpenTK/Platform/MacOS/HIDInput.cs
Expand Up @@ -73,6 +73,8 @@ class JoystickData
public JoystickCapabilities Capabilities; public JoystickCapabilities Capabilities;
readonly public Dictionary<int, JoystickButton> ElementUsageToButton = readonly public Dictionary<int, JoystickButton> ElementUsageToButton =
new Dictionary<int, JoystickButton>(); new Dictionary<int, JoystickButton>();
readonly public Dictionary<IOHIDElementRef, JoystickHat> ElementToHat =
new Dictionary<IOHIDElementRef, JoystickHat>(new IntPtrEqualityComparer());
} }


readonly IOHIDManagerRef hidmanager; readonly IOHIDManagerRef hidmanager;
Expand Down Expand Up @@ -449,6 +451,7 @@ JoystickData CreateJoystick(IntPtr sender, IntPtr device)
Guid guid = CreateJoystickGuid(device, name); Guid guid = CreateJoystickGuid(device, name);


List<int> button_elements = new List<int>(); List<int> button_elements = new List<int>();
List<IOHIDElementRef> hat_elements = new List<CFAllocatorRef>();
CFArray element_array = new CFArray(element_array_ref); CFArray element_array = new CFArray(element_array_ref);
for (int i = 0; i < element_array.Count; i++) for (int i = 0; i < element_array.Count; i++)
{ {
Expand Down Expand Up @@ -476,6 +479,7 @@ JoystickData CreateJoystick(IntPtr sender, IntPtr device)


case HIDUsageGD.Hatswitch: case HIDUsageGD.Hatswitch:
hats++; hats++;
hat_elements.Add(element_ref);
break; break;
} }
break; break;
Expand All @@ -496,6 +500,25 @@ JoystickData CreateJoystick(IntPtr sender, IntPtr device)
} }
} }


if (axes > JoystickState.MaxAxes)
{
Debug.Print("[Mac] JoystickAxis limit reached ({0} > {1}), please report a bug at http://www.opentk.com",
axes, JoystickState.MaxAxes);
axes = JoystickState.MaxAxes;
}
if (buttons > JoystickState.MaxButtons)
{
Debug.Print("[Mac] JoystickButton limit reached ({0} > {1}), please report a bug at http://www.opentk.com",
buttons, JoystickState.MaxButtons);
buttons = JoystickState.MaxButtons;
}
if (hats > JoystickState.MaxHats)
{
Debug.Print("[Mac] JoystickHat limit reached ({0} > {1}), please report a bug at http://www.opentk.com",
hats, JoystickState.MaxHats);
hats = JoystickState.MaxHats;
}

joy.Name = name; joy.Name = name;
joy.Guid = guid; joy.Guid = guid;
joy.State.SetIsConnected(true); joy.State.SetIsConnected(true);
Expand All @@ -506,6 +529,11 @@ JoystickData CreateJoystick(IntPtr sender, IntPtr device)
{ {
joy.ElementUsageToButton.Add(button_elements[button], JoystickButton.Button0 + button); joy.ElementUsageToButton.Add(button_elements[button], JoystickButton.Button0 + button);
} }

for (int hat = 0; hat < hat_elements.Count; hat++)
{
joy.ElementToHat.Add(hat_elements[hat], JoystickHat.Hat0 + hat);
}
} }
CF.CFRelease(element_array_ref); CF.CFRelease(element_array_ref);


Expand Down Expand Up @@ -608,6 +636,12 @@ static void UpdateJoystick(JoystickData joy, IOHIDValueRef val)
break; break;


case HIDUsageGD.Hatswitch: case HIDUsageGD.Hatswitch:
HatPosition position = GetJoystickHat(val, elem);
JoystickHat hat = TranslateJoystickHat(joy, elem);
if (hat >= JoystickHat.Hat0 && hat <= JoystickHat.Last)
{
joy.State.SetHat(hat, new JoystickHatState(position));
}
break; break;
} }
break; break;
Expand Down Expand Up @@ -709,6 +743,50 @@ static JoystickButton TranslateJoystickButton(JoystickData joy, int usage)
return JoystickButton.Last + 1; return JoystickButton.Last + 1;
} }


static HatPosition GetJoystickHat(IOHIDValueRef val, IOHIDElementRef element)
{
HatPosition position = HatPosition.Centered;
int max = NativeMethods.IOHIDElementGetLogicalMax(element).ToInt32();
int min = NativeMethods.IOHIDElementGetLogicalMin(element).ToInt32();
int value = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32() - min;
int range = Math.Abs(max - min + 1);

if (value >= 0)
{
if (range == 4)
{
// 4-position hat (no diagonals)
// 0 = up; 1 = right; 2 = down; 3 = left
// map to a 8-position hat (processed below)
value *= 2;
}

if (range == 8)
{
// 0 = up; 1 = up-right; 2 = right; 3 = right-down;
// 4 = down; 5 = down-left; 6 = left; 7 = up-left
// Our HatPosition enum
position = (HatPosition)value;
}
else
{
// Todo: implement support for continuous hats
}
}

return position;
}

static JoystickHat TranslateJoystickHat(JoystickData joy, IOHIDElementRef elem)
{
JoystickHat hat;
if (joy.ElementToHat.TryGetValue(elem, out hat))
{
return hat;
}
return JoystickHat.Last + 1;
}

#endregion #endregion


#endregion #endregion
Expand Down

0 comments on commit 5145ebc

Please sign in to comment.