public void SetAxis(short collection, HIDPage page, short usage, short value) { if (page == HIDPage.GenericDesktop || page == HIDPage.Simulation) // set axis only when HIDPage is known by HidHelper.TranslateJoystickAxis() to avoid axis0 to be overwritten by unknown HIDPage { //Certain joysticks (Speedlink Black Widow, PS3 pad connected via USB) //return an invalid HID page of 1, so if ((int)usage != 1) { int axis = GetAxis(collection, page, usage); State.SetAxis(axis, value); } } }
public static int TranslateJoystickAxis(HIDPage page, int usage) { switch (page) { case HIDPage.GenericDesktop: switch ((HIDUsageGD)usage) { case HIDUsageGD.X: return(0); case HIDUsageGD.Y: return(1); case HIDUsageGD.Z: return(2); case HIDUsageGD.Rz: return(3); case HIDUsageGD.Rx: return(4); case HIDUsageGD.Ry: return(5); case HIDUsageGD.Slider: return(6); case HIDUsageGD.Dial: return(7); case HIDUsageGD.Wheel: return(8); } break; case HIDPage.Simulation: switch ((HIDUsageSim)usage) { case HIDUsageSim.Rudder: return(9); case HIDUsageSim.Throttle: return(10); } break; } Debug.Print("[Input] Unknown axis with HID page/usage {0}/{1}", page, usage); return(0); }
public static JoystickAxis TranslateJoystickAxis(HIDPage page, int usage) { switch (page) { case HIDPage.GenericDesktop: switch ((HIDUsageGD)usage) { case HIDUsageGD.X: return(JoystickAxis.Axis0); case HIDUsageGD.Y: return(JoystickAxis.Axis1); case HIDUsageGD.Z: return(JoystickAxis.Axis2); case HIDUsageGD.Rz: return(JoystickAxis.Axis3); case HIDUsageGD.Rx: return(JoystickAxis.Axis4); case HIDUsageGD.Ry: return(JoystickAxis.Axis5); case HIDUsageGD.Slider: return(JoystickAxis.Axis6); case HIDUsageGD.Dial: return(JoystickAxis.Axis7); case HIDUsageGD.Wheel: return(JoystickAxis.Axis8); } break; case HIDPage.Simulation: switch ((HIDUsageSim)usage) { case HIDUsageSim.Rudder: return(JoystickAxis.Axis9); case HIDUsageSim.Throttle: return(JoystickAxis.Axis10); } break; } return(JoystickAxis.Last); }
JoystickAxis GetAxis(short collection, HIDPage page, short usage) { int key = MakeKey(collection, page, usage); if (!axes.ContainsKey(key)) { JoystickAxis axis = HidHelper.TranslateJoystickAxis(page, usage); if (axis == JoystickAxis.Last) { return(axis); } axes.Add(key, axis); } return(axes[key]); }
public static JoystickAxis TranslateJoystickAxis(HIDPage page, int usage) { switch (page) { case HIDPage.GenericDesktop: switch ((HIDUsageGD)usage) { case HIDUsageGD.X: return JoystickAxis.Axis0; case HIDUsageGD.Y: return JoystickAxis.Axis1; case HIDUsageGD.Z: return JoystickAxis.Axis2; case HIDUsageGD.Rz: return JoystickAxis.Axis3; case HIDUsageGD.Rx: return JoystickAxis.Axis4; case HIDUsageGD.Ry: return JoystickAxis.Axis5; case HIDUsageGD.Slider: return JoystickAxis.Axis6; case HIDUsageGD.Dial: return JoystickAxis.Axis7; case HIDUsageGD.Wheel: return JoystickAxis.Axis8; } break; case HIDPage.Simulation: switch ((HIDUsageSim)usage) { case HIDUsageSim.Rudder: return JoystickAxis.Axis9; case HIDUsageSim.Throttle: return JoystickAxis.Axis10; } break; } Debug.Print("[Input] Unknown axis with HID page/usage {0}/{1}", page, usage); return 0; }
unsafe void UpdateAxes(RawInput *rin, Device stick) { for (int i = 0; i < stick.AxisCaps.Count; i++) { if (stick.AxisCaps[i].IsRange) { Debug.Print("[{0}] Axis range collections not implemented. Please report your controller type at http://www.opentk.com", GetType().Name); continue; } HIDPage page = stick.AxisCaps[i].UsagePage; short usage = stick.AxisCaps[i].NotRange.Usage; uint value = 0; short collection = stick.AxisCaps[i].LinkCollection; HidProtocolStatus status = HidProtocol.GetUsageValue( HidProtocolReportType.Input, page, 0, usage, ref value, PreparsedData, new IntPtr((void *)&rin->Data.HID.RawData), rin->Data.HID.Size); if (status != HidProtocolStatus.Success) { Debug.Print("[{0}] HidProtocol.GetScaledUsageValue() failed. Error: {1}", GetType().Name, status); continue; } if (page == HIDPage.GenericDesktop && (HIDUsageGD)usage == HIDUsageGD.Hatswitch) { stick.SetHat(collection, page, usage, GetHatPosition(value, stick.AxisCaps[i])); } else { short scaled_value = (short)HidHelper.ScaleValue( (int)((long)value + stick.AxisCaps[i].LogicalMin), stick.AxisCaps[i].LogicalMin, stick.AxisCaps[i].LogicalMax, Int16.MinValue, Int16.MaxValue); stick.SetAxis(collection, page, usage, scaled_value); } } }
static KeyboardState UpdateKeyboard(KeyboardState state, IOHIDValueRef val) { IOHIDElementRef elem = NativeMethods.IOHIDValueGetElement(val); int v_int = NativeMethods.IOHIDValueGetIntegerValue(val).ToInt32(); HIDPage page = NativeMethods.IOHIDElementGetUsagePage(elem); int usage = NativeMethods.IOHIDElementGetUsage(elem); switch (page) { case HIDPage.GenericDesktop: case HIDPage.KeyboardOrKeypad: int raw = (int)usage; if (raw >= RawKeyMap.Length || raw < 0) { Debug.Print("[Warning] Key {0} not mapped.", raw); return(state); } Key key = RawKeyMap[raw]; state[key] = v_int != 0; break; } return(state); }
JoystickAxis GetAxis(short collection, HIDPage page, short usage) { int key = MakeKey(collection, page, usage); if (!axes.ContainsKey(key)) { JoystickAxis axis = HidHelper.TranslateJoystickAxis(page, usage); axes.Add(key, axis); } return axes[key]; }
JoystickButton GetButton(short collection, HIDPage page, short usage) { int key = MakeKey(collection, page, usage); if (!buttons.ContainsKey(key)) { buttons.Add(key, JoystickButton.Button0 + buttons.Count); } return buttons[key]; }
public static extern HidProtocolStatus GetUsageValue(HidProtocolReportType type, HIDPage usage_page, short link_collection, short usage, ref uint usage_value, [In] byte[] preparsed_data, IntPtr report, int report_length);
public void SetAxis(short collection, HIDPage page, short usage, short value) { JoystickAxis axis = GetAxis(collection, page, usage); State.SetAxis(axis, value); }
static int MakeKey(short collection, HIDPage page, short usage) { byte coll_byte = unchecked((byte)collection); byte page_byte = unchecked((byte)(((ushort)page & 0xff00) >> 8 | ((ushort)page & 0xff))); return (coll_byte << 24) | (page_byte << 16) | unchecked((ushort)usage); }
public void SetButton(short collection, HIDPage page, short usage, bool value) { JoystickButton button = GetButton(collection, page, usage); State.SetButton(button, value); }
public RawInputDevice(HIDUsageGD usage, RawInputDeviceFlags flags, HWND target) { UsagePage = HIDPage.GenericDesktop; Usage = (short)usage; Flags = flags; Target = target; }
unsafe public static extern HidProtocolStatus GetUsages(HidProtocolReportType type, HIDPage usage_page, short link_collection, short* usage_list, ref int usage_length, [In] byte[] preparsed_data, IntPtr report, int report_length);
public static extern HidProtocolStatus GetSpecificButtonCaps(HidProtocolReportType ReportType, HIDPage UsagePage, ushort LinkCollection, ushort Usage, [Out] HidProtocolButtonCaps[] ButtonCaps, ref ushort ButtonCapsLength, [In] byte[] PreparsedData);
public void SetHat(short collection, HIDPage page, short usage, HatPosition pos) { JoystickHat hat = GetHat(collection, page, usage); State.SetHat(hat, new JoystickHatState(pos)); }
public RawInputDevice(HIDUsageSim usage, RawInputDeviceFlags flags, HWND target) { UsagePage = HIDPage.Simulation; Usage = (short)usage; Flags = flags; Target = target; }
bool QueryDeviceCaps(Device stick) { Debug.Print("[{0}] Querying joystick {1}", TypeName, stick.GetGuid()); try { Debug.Indent(); HidProtocolCaps caps; if (GetPreparsedData(stick.Handle, ref PreparsedData) && GetDeviceCaps(stick, PreparsedData, out caps)) { if (stick.AxisCaps.Count >= JoystickState.MaxAxes || stick.ButtonCaps.Count >= JoystickState.MaxButtons) { Debug.Print("Device {0} has {1} and {2} buttons. This might be a touch device - skipping.", stick.Handle, stick.AxisCaps.Count, stick.ButtonCaps.Count); return(false); } for (int i = 0; i < stick.AxisCaps.Count; i++) { Debug.Print("Analyzing value collection {0} {1} {2}", i, stick.AxisCaps[i].IsRange ? "range" : "", stick.AxisCaps[i].IsAlias ? "alias" : ""); if (stick.AxisCaps[i].IsRange || stick.AxisCaps[i].IsAlias) { Debug.Print("Skipping value collection {0}", i); continue; } HIDPage page = stick.AxisCaps[i].UsagePage; short collection = stick.AxisCaps[i].LinkCollection; switch (page) { case HIDPage.GenericDesktop: HIDUsageGD gd_usage = (HIDUsageGD)stick.AxisCaps[i].NotRange.Usage; switch (gd_usage) { case HIDUsageGD.X: case HIDUsageGD.Y: case HIDUsageGD.Z: case HIDUsageGD.Rx: case HIDUsageGD.Ry: case HIDUsageGD.Rz: case HIDUsageGD.Slider: case HIDUsageGD.Dial: case HIDUsageGD.Wheel: Debug.Print("Found axis {0} ({1} / {2})", JoystickAxis.Axis0 + stick.GetCapabilities().AxisCount, page, (HIDUsageGD)stick.AxisCaps[i].NotRange.Usage); stick.SetAxis(collection, page, stick.AxisCaps[i].NotRange.Usage, 0); break; case HIDUsageGD.Hatswitch: Debug.Print("Found hat {0} ({1} / {2})", JoystickHat.Hat0 + stick.GetCapabilities().HatCount, page, (HIDUsageGD)stick.AxisCaps[i].NotRange.Usage); stick.SetHat(collection, page, stick.AxisCaps[i].NotRange.Usage, HatPosition.Centered); break; default: Debug.Print("Unknown usage {0} for page {1}", gd_usage, page); break; } break; case HIDPage.Simulation: switch ((HIDUsageSim)stick.AxisCaps[i].NotRange.Usage) { case HIDUsageSim.Rudder: case HIDUsageSim.Throttle: Debug.Print("Found simulation axis {0} ({1} / {2})", JoystickAxis.Axis0 + stick.GetCapabilities().AxisCount, page, (HIDUsageSim)stick.AxisCaps[i].NotRange.Usage); stick.SetAxis(collection, page, stick.AxisCaps[i].NotRange.Usage, 0); break; } break; default: Debug.Print("Unknown page {0}", page); break; } } for (int i = 0; i < stick.ButtonCaps.Count; i++) { Debug.Print("Analyzing button collection {0} {1} {2}", i, stick.ButtonCaps[i].IsRange ? "range" : "", stick.ButtonCaps[i].IsAlias ? "alias" : ""); if (stick.ButtonCaps[i].IsAlias) { Debug.Print("Skipping button collection {0}", i); continue; } bool is_range = stick.ButtonCaps[i].IsRange; HIDPage page = stick.ButtonCaps[i].UsagePage; short collection = stick.ButtonCaps[i].LinkCollection; switch (page) { case HIDPage.Button: if (is_range) { for (short usage = stick.ButtonCaps[i].Range.UsageMin; usage <= stick.ButtonCaps[i].Range.UsageMax; usage++) { Debug.Print("Found button {0} ({1} / {2})", JoystickButton.Button0 + stick.GetCapabilities().ButtonCount, page, usage); stick.SetButton(collection, page, usage, false); } } else { Debug.Print("Found button {0} ({1} / {2})", JoystickButton.Button0 + stick.GetCapabilities().ButtonCount, page, stick.ButtonCaps[i].NotRange.Usage); stick.SetButton(collection, page, stick.ButtonCaps[i].NotRange.Usage, false); } break; default: Debug.Print("Unknown page {0} for button.", page); break; } } } else { return(false); } } finally { Debug.Unindent(); } return(true); }
public static extern bool IOHIDDeviceConformsTo( IOHIDDeviceRef inIOHIDDeviceRef, // IOHIDDeviceRef for the HID device HIDPage inUsagePage, // the usage page to test conformance with int inUsage); // the usage to test conformance with
unsafe public static extern HidProtocolStatus GetUsages(HidProtocolReportType type, HIDPage usage_page, short link_collection, short *usage_list, ref int usage_length, [In] byte[] preparsed_data, IntPtr report, int report_length);
JoystickHat GetHat(short collection, HIDPage page, short usage) { int key = MakeKey(collection, page, usage); if (!hats.ContainsKey(key)) { hats.Add(key, JoystickHat.Hat0 + hats.Count); } return hats[key]; }