{
if (!Elements.ContainsKey(e.Cookie))
{
- Elements.Add(e.Cookie, new JoystickElement(e.Element, e.Cookie, e.Order, e.Page, e.Usage, e.Min, e.Max));
- Debug.Print("[{0}] Discovered joystick element {1:x} ({2}/{3})",
- typeof(HIDInput).Name, e.Cookie, e.Page, e.Usage);
+ Elements.Add(e.Cookie, e);
+ Debug.Print("Discovered joystick element {0:x} ({1}/{2})",
+ e.Cookie, e.Page, e.Usage);
}
else
{
- Debug.Print("[{0}] Attempted to add joystick element {1:x} ({2}/{3}) twice, ignoring.",
- typeof(HIDInput).Name, e.Cookie, e.Page, e.Usage);
+ Debug.Print("Duplicate joystick element {0:x} ({1}/{2}) ignored.",
+ e.Cookie, e.Page, e.Usage);
}
}
}
{
public IntPtr Element;
public IntPtr Cookie;
- // Order in which this element was reported
- public int Order;
public HIDPage Page;
public int Usage;
// Hardware axis range
public int MinReported;
public int MaxReported;
+ // Order in which this element was reported
+ public int Index;
+
public JoystickElement(
- IntPtr element, IntPtr cookie, int order,
+ IntPtr element, IntPtr cookie,
HIDPage page, int usage,
int min, int max)
{
Element = element;
Cookie = cookie;
- Order = order;
Page = page;
Usage = usage;
Min = min;
if (element_array_ref != IntPtr.Zero)
{
joy = new JoystickData();
- int axes = 0;
- int buttons = 0;
- int hats = 0;
- int vendor = 0;
CFStringRef name_ref = NativeMethods.IOHIDDeviceGetProperty(device, NativeMethods.IOHIDProductKey);
string name = CF.CFStringGetCString(name_ref);
button_elements.Clear();
hat_elements.Clear();
vendor_elements.Clear();
- AddElements(joy, element_array_ref, ref axes, ref buttons, ref hats, ref vendor);
+ AddElements(joy, element_array_ref);
// Ensure a stable sorting order that matches SDL2.
// (This is necessary for the gamepad database).
axis_elements.Sort();
- for (int i = 0; i < axis_elements.Count; i++)
+ button_elements.Sort();
+ hat_elements.Sort();
+ vendor_elements.Sort();
+
+ // Store all discovered elements in JoystickData
+ for (int i = 0; i < Math.Min(axis_elements.Count, JoystickState.MaxAxes); i++)
{
JoystickElement e = axis_elements[i];
- e.Order = i;
+ e.Index = i;
joy.AddElement(e);
}
- button_elements.Sort();
- for (int i = 0; i < button_elements.Count; i++)
+ for (int i = 0; i < Math.Min(button_elements.Count, JoystickState.MaxButtons); i++)
{
JoystickElement e = button_elements[i];
- e.Order = i;
+ e.Index = i;
joy.AddElement(e);
}
- hat_elements.Sort();
- for (int i = 0; i < hat_elements.Count; i++)
+ for (int i = 0; i < Math.Min(hat_elements.Count, JoystickState.MaxHats); i++)
{
JoystickElement e = hat_elements[i];
- e.Order = i;
+ e.Index = i;
joy.AddElement(e);
}
- vendor_elements.Sort();
for (int i = 0; i < vendor_elements.Count; i++)
{
JoystickElement e = vendor_elements[i];
- e.Order = i;
+ e.Index = i;
joy.AddElement(e);
}
- if (axes > JoystickState.MaxAxes)
+ if (axis_elements.Count >= 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;
+ axis_elements.Count, JoystickState.MaxAxes);
}
- if (buttons > JoystickState.MaxButtons)
+ if (button_elements.Count > 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;
+ button_elements.Count, JoystickState.MaxButtons);
}
- if (hats > JoystickState.MaxHats)
+ if (hat_elements.Count > 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;
+ hat_elements.Count, JoystickState.MaxHats);
}
joy.Name = name;
joy.Guid = guid;
joy.State.SetIsConnected(true);
- joy.Capabilities = new JoystickCapabilities(axes, buttons, hats, true);
+ joy.Capabilities = new JoystickCapabilities(
+ axis_elements.Count, button_elements.Count, hat_elements.Count, true);
}
CF.CFRelease(element_array_ref);
return joy;
}
- void AddElements(JoystickData joy, CFArrayRef element_array_ref, ref int axes, ref int buttons, ref int hats, ref int vendor)
+ void AddElements(JoystickData joy, CFArrayRef element_array_ref)
{
CFArray element_array = new CFArray(element_array_ref);
for (int i = 0; i < element_array.Count; i++)
IOHIDElementCookie cookie = NativeMethods.IOHIDElementGetCookie(element_ref);
HIDPage page = NativeMethods.IOHIDElementGetUsagePage(element_ref);
int usage = NativeMethods.IOHIDElementGetUsage(element_ref);
+ JoystickElement e = null;
switch (NativeMethods.IOHIDElementGetType(element_ref))
{
case HIDUsageGD.Slider:
case HIDUsageGD.Dial:
case HIDUsageGD.Wheel:
- if (axes < JoystickState.MaxAxes)
- {
- var e = new JoystickElement(element_ref, cookie, axes++, page, usage, 0, 0);
- if (!axis_elements.Contains(e))
- {
- axis_elements.Add(e);
- }
- }
- else
+ e = new JoystickElement(element_ref, cookie, page, usage, 0, 0);
+ if (!axis_elements.Contains(e))
{
- Debug.Print("[{0}] Failed to add axis (limit of {1} has been reached).",
- GetType().Name, JoystickState.MaxAxes);
+ axis_elements.Add(e);
}
break;
case HIDUsageGD.Hatswitch:
- if (hats < JoystickState.MaxHats)
- {
- var e = new JoystickElement(element_ref, cookie, axes++, page, usage, 0, 0);
- if (!hat_elements.Contains(e))
- {
- hat_elements.Add(e);
- }
- }
- else
+ e = new JoystickElement(element_ref, cookie, page, usage, 0, 0);
+ if (!hat_elements.Contains(e))
{
- Debug.Print("[{0}] Failed to add hat (limit of {1} has been reached).",
- GetType().Name, JoystickState.MaxHats);
+ hat_elements.Add(e);
}
break;
}
{
case HIDUsageSim.Rudder:
case HIDUsageSim.Throttle:
- if (axes < JoystickState.MaxAxes)
+ e = new JoystickElement(element_ref, cookie, page, usage, 0, 0);
+ if (!axis_elements.Contains(e))
{
- JoystickElement e = new JoystickElement(element_ref, cookie, axes++, page, usage, 0, 0);
- if (!axis_elements.Contains(e))
- {
- axis_elements.Add(e);
- }
- }
- else
- {
- Debug.Print("[{0}] Failed to add axis (limit of {1} has been reached).",
- GetType().Name, JoystickState.MaxAxes);
+ axis_elements.Add(e);
}
break;
}
break;
case HIDPage.Button:
- if (buttons < JoystickState.MaxButtons)
+ e = new JoystickElement(element_ref, cookie, page, usage, 0, 0);
+ if (!button_elements.Contains(e))
{
- JoystickElement e = new JoystickElement(element_ref, cookie, buttons++, page, usage, 0, 0);
- if (!button_elements.Contains(e))
- {
- button_elements.Add(e);
- }
- }
- else
- {
- Debug.Print("[{0}] Failed to add button (limit of {1} has been reached).",
- GetType().Name, JoystickState.MaxButtons);
+ button_elements.Add(e);
}
break;
case HIDPage.VendorDefinedStart:
+ e = new JoystickElement(element_ref, cookie, page, usage, 0, 0);
+ if (!vendor_elements.Contains(e))
{
- JoystickElement e = new JoystickElement(element_ref, cookie, vendor++, page, usage, 0, 0);
- if (!vendor_elements.Contains(e))
- {
- vendor_elements.Add(e);
- }
+ vendor_elements.Add(e);
}
break;
}
CFArrayRef children_array_ref = NativeMethods.IOHIDElementGetChildren(element_ref);
if (children_array_ref != IntPtr.Zero)
{
- AddElements(joy, children_array_ref, ref axes, ref buttons, ref hats, ref vendor);
+ AddElements(joy, children_array_ref);
}
break;
}
void AddJoystick(CFAllocatorRef sender, CFAllocatorRef device)
{
Debug.Print("Joystick device {0:x} discovered, sender is {1:x}", device, sender);
- JoystickData joy = CreateJoystick(sender, device);
- if (joy != null)
+ Debug.Indent();
+
+ try
{
- // Add a device->joy lookup entry for this device.
- if (!JoystickDevices.ContainsKey(device))
- {
- // First time we've seen this device.
- JoystickDevices.Add(device, joy);
- }
- else
+ JoystickData joy = CreateJoystick(sender, device);
+ if (joy != null)
{
- // This is an old device that is replugged.
- // This branch does not appear to be executed, ever.
- JoystickDevices[device] = joy;
- }
+ // Add a device->joy lookup entry for this device.
+ if (!JoystickDevices.ContainsKey(device))
+ {
+ // First time we've seen this device.
+ JoystickDevices.Add(device, joy);
+ }
+ else
+ {
+ // This is an old device that is replugged.
+ // This branch does not appear to be executed, ever.
+ JoystickDevices[device] = joy;
+ }
- // Add an index->device lookup entry for this device.
- // Use the first free (i.e. disconnected) index.
- // If all indices are connected, append a new one.
- int i;
- for (i = 0; i < JoystickIndexToDevice.Count; i++)
- {
- IntPtr candidate = JoystickIndexToDevice[i];
- if (!JoystickDevices[candidate].State.IsConnected)
+ // Add an index->device lookup entry for this device.
+ // Use the first free (i.e. disconnected) index.
+ // If all indices are connected, append a new one.
+ int i;
+ for (i = 0; i < JoystickIndexToDevice.Count; i++)
{
- break;
+ IntPtr candidate = JoystickIndexToDevice[i];
+ if (!JoystickDevices[candidate].State.IsConnected)
+ {
+ break;
+ }
}
- }
- if (i == JoystickDevices.Count)
- {
- // All indices connected, append a new one.
- JoystickIndexToDevice.Add(JoystickDevices.Count, device);
- }
- else
- {
- // Replace joystick at that index
- JoystickIndexToDevice[i] = device;
+ if (i == JoystickDevices.Count)
+ {
+ // All indices connected, append a new one.
+ JoystickIndexToDevice.Add(JoystickDevices.Count, device);
+ }
+ else
+ {
+ // Replace joystick at that index
+ JoystickIndexToDevice[i] = device;
+ }
}
}
+ finally
+ {
+ Debug.Unindent();
+ }
}
void RemoveJoystick(CFAllocatorRef sender, CFAllocatorRef device)
case HIDUsageGD.Dial:
case HIDUsageGD.Wheel:
short offset = GetJoystickAxis(val, elem);
- JoystickAxis axis = JoystickAxis.Axis0 + joy.Elements[cookie].Order;
+ JoystickAxis axis = JoystickAxis.Axis0 + joy.Elements[cookie].Index;
if (axis >= JoystickAxis.Axis0 && axis <= JoystickAxis.Last)
{
joy.State.SetAxis(axis, offset);
case HIDUsageGD.Hatswitch:
HatPosition position = GetJoystickHat(val, elem);
- JoystickHat hat = JoystickHat.Hat0 + joy.Elements[cookie].Order;
+ JoystickHat hat = JoystickHat.Hat0 + joy.Elements[cookie].Index;
if (hat >= JoystickHat.Hat0 && hat <= JoystickHat.Last)
{
joy.State.SetHat(hat, new JoystickHatState(position));
case HIDUsageSim.Rudder:
case HIDUsageSim.Throttle:
short offset = GetJoystickAxis(val, elem);
- JoystickAxis axis = JoystickAxis.Axis0 + joy.Elements[cookie].Order;
+ JoystickAxis axis = JoystickAxis.Axis0 + joy.Elements[cookie].Index;
if (axis >= JoystickAxis.Axis0 && axis <= JoystickAxis.Last)
{
joy.State.SetAxis(axis, offset);
case HIDPage.Button:
{
bool pressed = GetJoystickButton(val, elem);
- JoystickButton button = JoystickButton.Button0 + joy.Elements[cookie].Order;
+ JoystickButton button = JoystickButton.Button0 + joy.Elements[cookie].Index;
if (button >= JoystickButton.Button0 && button <= JoystickButton.Last)
{
joy.State.SetButton(button, pressed);