private unsafe void UpdateButtons(RawInput *rin, Device stick) { stick.ClearButtons(); for (int i = 0; i < stick.ButtonCaps.Count; i++) { short * usage_list = stackalloc short[64]; int usage_length = 64; HIDPage page = stick.ButtonCaps[i].UsagePage; short collection = stick.ButtonCaps[i].LinkCollection; HidProtocolStatus status = HidProtocol.GetUsages( HidProtocolReportType.Input, page, 0, usage_list, ref usage_length, PreparsedData, new IntPtr((void *)&rin->Data.HID.RawData), rin->Data.HID.Size); if (status != HidProtocolStatus.Success) { Debug.Print("[WinRawJoystick] HidProtocol.GetUsages() failed with {0}", Marshal.GetLastWin32Error()); continue; } for (int j = 0; j < usage_length; j++) { short usage = *(usage_list + j); stick.SetButton(collection, page, usage, true); } } }
private 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 https://github.com/opentk/opentk/issues", 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 { if (stick.AxisCaps[i].LogicalMin > 0) { 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); } else { //If our stick returns a minimum value below zero, we should not add this to our value //before attempting to scale it, as this then inverts the value short scaled_value = (short)HidHelper.ScaleValue( (int)(long)value, stick.AxisCaps[i].LogicalMin, stick.AxisCaps[i].LogicalMax, Int16.MinValue, Int16.MaxValue); stick.SetAxis(collection, page, usage, scaled_value); } } } }
private static bool GetDeviceCaps(Device stick, byte[] preparsed_data, out HidProtocolCaps caps) { // Query joystick capabilities caps = new HidProtocolCaps(); if (HidProtocol.GetCaps(preparsed_data, ref caps) != HidProtocolStatus.Success) { Debug.Print("[WinRawJoystick] HidProtocol.GetCaps() failed with {0}", Marshal.GetLastWin32Error()); return(false); } // Make sure our caps arrays are big enough HidProtocolValueCaps[] axis_caps = new HidProtocolValueCaps[caps.NumberInputValueCaps]; HidProtocolButtonCaps[] button_caps = new HidProtocolButtonCaps[caps.NumberInputButtonCaps]; // Axis capabilities ushort axis_count = (ushort)axis_caps.Length; if (HidProtocol.GetValueCaps(HidProtocolReportType.Input, axis_caps, ref axis_count, preparsed_data) != HidProtocolStatus.Success) { Debug.Print("[WinRawJoystick] HidProtocol.GetValueCaps() failed with {0}", Marshal.GetLastWin32Error()); return(false); } // Button capabilities ushort button_count = (ushort)button_caps.Length; if (HidProtocol.GetButtonCaps(HidProtocolReportType.Input, button_caps, ref button_count, preparsed_data) != HidProtocolStatus.Success) { Debug.Print("[WinRawJoystick] HidProtocol.GetButtonCaps() failed with {0}", Marshal.GetLastWin32Error()); return(false); } stick.AxisCaps.Clear(); stick.AxisCaps.AddRange(axis_caps); stick.ButtonCaps.Clear(); stick.ButtonCaps.AddRange(button_caps); return(true); }
public unsafe bool ProcessEvent(IntPtr raw) { // Query the size of the raw HID data buffer int size = 0; Functions.GetRawInputData(raw, GetRawInputDataEnum.INPUT, IntPtr.Zero, ref size, RawInputHeader.SizeInBytes); if (size > HIDData.Length) { Array.Resize(ref HIDData, size); } // Retrieve the raw HID data buffer if (Functions.GetRawInputData(raw, HIDData) > 0) { fixed(byte *pdata = HIDData) { RawInput *rin = (RawInput *)pdata; IntPtr handle = rin->Header.Device; Device stick = GetDevice(handle); if (stick == null) { Debug.Print("[WinRawJoystick] Unknown device {0}", handle); return(false); } if (stick.IsXInput) { return(true); } if (!GetPreparsedData(handle, ref PreparsedData)) { return(false); } // Query current state // Allocate enough storage to hold the data of the current report int report_count = HidProtocol.MaxDataListLength(HidProtocolReportType.Input, PreparsedData); if (report_count == 0) { Debug.Print("[WinRawJoystick] HidProtocol.MaxDataListLength() failed with {0}", Marshal.GetLastWin32Error()); return(false); } // Fill the data buffer if (DataBuffer.Length < report_count) { Array.Resize(ref DataBuffer, report_count); } UpdateAxes(rin, stick); UpdateButtons(rin, stick); return(true); } } return(false); }