public Task <byte[]> getBatteryStatusViaHID() { return(Task.Run(() => { device = getHidDevice(); if (device != null) { device.Connect(); //get handle via reflection, because its a private field (oof) var field = typeof(HidDevice).GetField("m_DevicePtr", BindingFlags.NonPublic | BindingFlags.Instance); devPtr = (IntPtr)field.GetValue(device); var buffer = new byte[5]; HidApi.hid_write(devPtr, data_req, Convert.ToUInt32(data_req.Length)); HidApi.hid_read_timeout(devPtr, buffer, Convert.ToUInt32(buffer.Length), 1000); device.Disconnect(); Thread.Sleep(250); return buffer; } else { return null; } })); }
string GetProduct(IntPtr handle) { var data = new byte[1024]; HidApi.HidD_GetProductString(handle, ref data[0], data.Length); return(Encoding.Unicode.GetString(data).Trim('\0')); }
string GetVendor(IntPtr handle) { var data = new byte[1024]; HidApi.HidD_GetManufacturerString(handle, ref data[0], data.Length); return(Encoding.Unicode.GetString(data).Trim('\0')); }
public void Dispose() { if (Handle == IntPtr.Zero) { return; } HidApi.HidD_FreePreparsedData(Handle); }
HidDeviceValueCapabilities[] GetDeviceValueCapabilities(IntPtr handle) { var capsLength = (short)capabilities.NumberInputValueCaps; var valueCapabilities = new HidApi.HIDP_VALUE_CAPS[capsLength]; using (var dataContext = new PreparsedDataContext(handle)) { HidApi.HidP_GetValueCaps(HidApi.HIDP_REPORT_TYPE.Input, valueCapabilities, ref capsLength, dataContext.Handle); } return(valueCapabilities.Select(caps => new HidDeviceValueCapabilities(caps)).ToArray()); }
public PreparsedDataContext(IntPtr deviceHandle) { var handle = IntPtr.Zero; if (!HidApi.HidD_GetPreparsedData(deviceHandle, ref handle)) { throw new InvalidOperationException("Failed to get PreparsedData pointer"); } Handle = handle; }
public async Task <GamepadState> GetStateAsync(CancellationToken token) { var report = await GetReportAsync(token); var buttonCaps = buttonCapabilities[0]; ushort[] buttonsState; var state = new GamepadState(); using (var deviceContext = new DeviceContext(Path)) { using (var dataContext = new PreparsedDataContext(deviceContext.Handle)) { var buttonsStateLength = buttonCaps.Range.UsageMax - buttonCaps.Range.UsageMin + 1; //var buttonsStateLength = HidApi.HidP_MaxUsageListLength(HidApi.HIDP_REPORT_TYPE.Input, buttonCaps.UsagePage, dataContext.Handle); buttonsState = new ushort[buttonsStateLength]; HidApi.HidP_GetUsages(HidApi.HIDP_REPORT_TYPE.Input, buttonCaps.UsagePage, 0, buttonsState, ref buttonsStateLength, dataContext.Handle, report.Data, report.Data.Length); if (buttonsState.Contains((ushort)2)) { state.A = true; } if (buttonsState.Contains((ushort)3)) { state.B = true; } if (buttonsState.Contains((ushort)1)) { state.X = true; } if (buttonsState.Contains((ushort)4)) { state.Y = true; } if (buttonsState.Contains((ushort)5)) { state.L1 = true; } if (buttonsState.Contains((ushort)7)) { state.L2 = true; } if (buttonsState.Contains((ushort)6)) { state.R1 = true; } if (buttonsState.Contains((ushort)8)) { state.R2 = true; } if (buttonsState.Contains((ushort)9)) { state.Select = true; } if (buttonsState.Contains((ushort)10)) { state.Start = true; } if (buttonsState.Contains((ushort)11)) { state.L3 = true; } if (buttonsState.Contains((ushort)12)) { state.R3 = true; } var hasDpad = valueCapabilities.Any(x => x.Range.UsageMin == 0x39); for (var i = 0; i < capabilities.NumberInputValueCaps; i++) { int value = 0; HidApi.HidP_GetUsageValue(HidApi.HIDP_REPORT_TYPE.Input, valueCapabilities[i].UsagePage, 0, valueCapabilities[i].Range.UsageMin, ref value, dataContext.Handle, report.Data, report.Data.Length); var scaleValue = 256; if (valueCapabilities[i].UsagePage == 1) { switch (valueCapabilities[i].Range.UsageMin) { case 0x30: // X-axis // LX var lAxisX = value - GamepadState.DEFAULT_AXIS_VALUE; // LogMin: 0 / LogMax: 255 // default: 128 if (value == 0) { lAxisX++; } if (hasDpad) { state.LX = lAxisX * scaleValue; } else { if (valueCapabilities[i].LogicalMin + 1 == value) { state.Left = true; } if (valueCapabilities[i].LogicalMax == value) { state.Right = true; } } break; case 0x31: // Y-axis // LY var lAxisY = GamepadState.DEFAULT_AXIS_VALUE - value; //(long)value - 128; // LogMin: 0 / LogMax: 255 // default: 128 if (value == 0) { lAxisY--; } if (hasDpad) { state.LY = lAxisY * scaleValue; } else { if (valueCapabilities[i].LogicalMin + 1 == value) { state.Up = true; } if (valueCapabilities[i].LogicalMax == value) { state.Down = true; } } break; case 0x32: // Z-axis // RX var lAxisZ = value - GamepadState.DEFAULT_AXIS_VALUE; // LogMin: 0 / LogMax: 255 // default: 128 if (value == 0) { lAxisZ++; } state.RX = lAxisZ * scaleValue; break; case 0x35: // Rotate-Z // RY var lAxisRz = value - GamepadState.DEFAULT_AXIS_VALUE; // LogMin: 0 / LogMax: 255 // default: 128 if (value == 0) { lAxisRz++; } state.RY = lAxisRz * scaleValue; break; case 0x39: // Hat Switch // DPAD var lHat = value; // LogMin: 0 / LogMax: 7 // default: 8 // val = 360 / 8 if (lHat == 0) { state.Up = true; } else if (lHat == 1) { state.Up = true; state.Right = true; } else if (lHat == 2) { state.Right = true; } else if (lHat == 3) { state.Right = true; state.Down = true; } else if (lHat == 4) { state.Down = true; } else if (lHat == 5) { state.Down = true; state.Left = true; } else if (lHat == 6) { state.Left = true; } else if (lHat == 7) { state.Left = true; state.Up = true; } break; } } } } } return(state); }