protected override void ParseHidReport(byte[] report) { PacketCounter++; var inputReport = new HidReport.Core.HidReport(); #region HID Report translation // no battery state since the Gamepad is Usb-powered inputReport.BatteryStatus = DsBattery.None; // packet counter inputReport.PacketCounter = PacketCounter; // circle inputReport.Set(ButtonsEnum.Circle, IsBitSet(report[1], 2)); inputReport.Set(AxesEnum.Circle, report[13]); // cross inputReport.Set(ButtonsEnum.Cross, IsBitSet(report[1], 1)); inputReport.Set(AxesEnum.Cross, report[14]); // triangle inputReport.Set(ButtonsEnum.Triangle, IsBitSet(report[1], 3)); inputReport.Set(AxesEnum.Triangle, report[12]); // square inputReport.Set(ButtonsEnum.Square, IsBitSet(report[1], 0)); inputReport.Set(AxesEnum.Square, report[15]); // select inputReport.Set(ButtonsEnum.Select, IsBitSet(report[2], 0)); // start inputReport.Set(ButtonsEnum.Start, IsBitSet(report[2], 1)); #endregion OnHidReportReceived(inputReport); }
public static void ParseDPad(uint val, HidReport.Core.HidReport inputReport) { switch (val) { case 0: inputReport.Set(ButtonsEnum.Up); break; case 1: inputReport.Set(ButtonsEnum.Up); inputReport.Set(ButtonsEnum.Right); break; case 2: inputReport.Set(ButtonsEnum.Right); break; case 3: inputReport.Set(ButtonsEnum.Right); inputReport.Set(ButtonsEnum.Down); break; case 4: inputReport.Set(ButtonsEnum.Down); break; case 5: inputReport.Set(ButtonsEnum.Down); inputReport.Set(ButtonsEnum.Left); break; case 6: inputReport.Set(ButtonsEnum.Left); break; case 7: inputReport.Set(ButtonsEnum.Left); inputReport.Set(ButtonsEnum.Up); break; } }
protected void OnHidReportReceived(HidReport.Core.HidReport hidReport) { var report = NewHidReport(hidReport); if (GlobalConfiguration.Instance.UseAsyncHidReportProcessing) { _inputReportQueue.Enqueue(() => Task.Run(() => { if (HidReportReceived != null) { HidReportReceived.Invoke(this, report); } })); } else { if (HidReportReceived != null) { HidReportReceived.Invoke(this, report); } } }
/// <summary> /// Interprets a HID report sent by a DualShock 4 device. /// </summary> /// <param name="report">The HID report as byte array.</param> public override void ParseHidReport(byte[] report) { m_Packet++; var inputReport = new HidReport.Core.HidReport(); inputReport.PacketCounter = m_Packet; inputReport.ReportId = report[9]; var tmp = new byte[72]; Buffer.BlockCopy(report, 11, tmp, 8, 64); HidParsers.Ds4Consts.ParseDs4(tmp, inputReport); // Quick Disconnect var trigger = inputReport.IsQuickDisconnect(); if (inputReport.IsPadActive) { m_IsIdle = false; } else if (!m_IsIdle) { m_IsIdle = true; m_Idle = DateTime.Now; } if (trigger && !m_IsDisconnect) { m_IsDisconnect = true; m_Disconnect = DateTime.Now; } else if (!trigger && m_IsDisconnect) { m_IsDisconnect = false; } OnHidReportReceived(inputReport); }
public ScpHidReport(DsConnection connectionType, PhysicalAddress padMacAddress, DsModel model, DsPadId padId, DsState padState, HidReport.Core.HidReport hidReport) { ConnectionType = connectionType; _padMacAddress = padMacAddress.GetAddressBytes(); Model = model; PadId = padId; PadState = padState; _hidReport = hidReport; }
protected override void ParseHidReport(byte[] report) { if (report[2] != 0x00) { return; } var inputReport = new HidReport.Core.HidReport(); #region HID Report translation // no battery state since the Gamepad is Usb-powered inputReport.BatteryStatus = DsBattery.None; // packet counter inputReport.PacketCounter = ++PacketCounter; // control buttons inputReport.Set(ButtonsEnum.Select, IsBitSet(report[6], 4)); inputReport.Set(ButtonsEnum.Start, IsBitSet(report[6], 5)); // Left shoulder inputReport.Set(ButtonsEnum.L1, IsBitSet(report[6], 0)); // Right shoulder inputReport.Set(ButtonsEnum.R1, IsBitSet(report[6], 1)); // Left trigger inputReport.Set(ButtonsEnum.L2, IsBitSet(report[6], 2)); // Right trigger inputReport.Set(ButtonsEnum.R2, IsBitSet(report[6], 3)); // Triangle inputReport.Set(ButtonsEnum.Triangle, IsBitSet(report[5], 4)); // Circle inputReport.Set(ButtonsEnum.Circle, IsBitSet(report[5], 5)); // Cross inputReport.Set(ButtonsEnum.Cross, IsBitSet(report[5], 6)); // Square inputReport.Set(ButtonsEnum.Square, IsBitSet(report[5], 7)); // Left thumb inputReport.Set(ButtonsEnum.L3, IsBitSet(report[6], 6)); // Right thumb inputReport.Set(ButtonsEnum.R3, IsBitSet(report[6], 7)); var dPad = (byte)(report[5] & ~0xF0); // D-Pad HidParsers.ParseDPad(dPad, inputReport); // Left thumb stick inputReport.Set(AxesEnum.Lx, report[0]); inputReport.Set(AxesEnum.Ly, report[1]); // Right thumb stick inputReport.Set(AxesEnum.Rx, report[3]); inputReport.Set(AxesEnum.Ry, report[4]); #endregion OnHidReportReceived(inputReport); }
public static void ParseDs3(byte[] report, HidReport.Core.HidReport inputReport) { inputReport.BatteryStatus = (DsBattery)report[38]; inputReport.Set(ButtonsEnum.Select, IsBitSet(report[10], 0)); inputReport.Set(ButtonsEnum.L3, IsBitSet(report[10], 1)); inputReport.Set(ButtonsEnum.R3, IsBitSet(report[10], 2)); inputReport.Set(ButtonsEnum.Start, IsBitSet(report[10], 3)); inputReport.Set(ButtonsEnum.Up, IsBitSet(report[10], 4)); inputReport.Set(ButtonsEnum.Right, IsBitSet(report[10], 5)); inputReport.Set(ButtonsEnum.Down, IsBitSet(report[10], 6)); inputReport.Set(ButtonsEnum.Left, IsBitSet(report[10], 7)); inputReport.Set(ButtonsEnum.L2, IsBitSet(report[11], 0)); inputReport.Set(ButtonsEnum.R2, IsBitSet(report[11], 1)); inputReport.Set(ButtonsEnum.L1, IsBitSet(report[11], 2)); inputReport.Set(ButtonsEnum.R1, IsBitSet(report[11], 3)); inputReport.Set(ButtonsEnum.Triangle, IsBitSet(report[11], 4)); inputReport.Set(ButtonsEnum.Circle, IsBitSet(report[11], 5)); inputReport.Set(ButtonsEnum.Cross, IsBitSet(report[11], 6)); inputReport.Set(ButtonsEnum.Square, IsBitSet(report[11], 7)); inputReport.Set(ButtonsEnum.Ps, IsBitSet(report[12], 0)); //13 inputReport.Set(AxesEnum.Lx, report[14]); inputReport.Set(AxesEnum.Ly, report[15]); inputReport.Set(AxesEnum.Rx, report[16]); inputReport.Set(AxesEnum.Ry, report[17]); inputReport.Set(AxesEnum.Up, report[22]); inputReport.Set(AxesEnum.Right, report[23]); inputReport.Set(AxesEnum.Down, report[24]); inputReport.Set(AxesEnum.Left, report[25]); inputReport.Set(AxesEnum.L2, report[26]); inputReport.Set(AxesEnum.R2, report[27]); inputReport.Set(AxesEnum.L1, report[28]); inputReport.Set(AxesEnum.R1, report[29]); inputReport.Set(AxesEnum.Triangle, report[30]); inputReport.Set(AxesEnum.Circle, report[31]); inputReport.Set(AxesEnum.Cross, report[32]); inputReport.Set(AxesEnum.Square, report[33]); int accelerometerX = (report[49] << 8) | (report[50] << 0); //0-1023 Debug.Assert(accelerometerX >= 0); Debug.Assert(accelerometerX <= 1023); int accelerometerY = (report[51] << 8) | (report[52] << 0); //0-1023 Debug.Assert(accelerometerY >= 0); Debug.Assert(accelerometerY <= 1023); int accelerometerZ = (report[53] << 8) | (report[54] << 0); //0-1023 Debug.Assert(accelerometerZ >= 0); Debug.Assert(accelerometerZ <= 1023); int gyrometerX = (report[55] << 8) | (report[56] << 0); //0-1023 Debug.Assert(gyrometerX >= 0); Debug.Assert(gyrometerX <= 1023); accelerometerX -= 512; accelerometerY -= 512; accelerometerZ -= 512; gyrometerX -= 498; const int g1Value = 115; int forceVectror = (int) Math.Sqrt(accelerometerX * accelerometerX + accelerometerY * accelerometerY + accelerometerZ * accelerometerZ); // http://www.instructables.com/id/Accelerometer-Gyro-Tutorial/ //TODO: use Kalman filter double yaw = 0; double pitch = (Math.Atan2(accelerometerZ, accelerometerY) + Math.PI / 2) / Math.PI * 180; double roll = (Math.Atan2(accelerometerZ, accelerometerX) + Math.PI / 2) / Math.PI * 180; accelerometerX -= (accelerometerX * g1Value) / forceVectror; accelerometerY -= (accelerometerY * g1Value) / forceVectror; accelerometerZ -= (accelerometerZ * g1Value) / forceVectror; //Debug.Print($"Ax {accelerometerX:+0000;-0000} Ay {accelerometerY:+0000;-0000} Az {accelerometerZ:+0000;-0000} Pitch {pitch} Roll {roll} Gx {gyrometerX:+0000;-0000}"); inputReport.MotionMutable = new DsAccelerometer() { X = (short)(accelerometerX), Y = (short)(accelerometerY), Z = (short)(accelerometerZ), }; inputReport.OrientationMutable = new DsGyroscope() { Yaw = (short)(yaw), Pitch = (short)(pitch), Roll = (short)(roll) }; }
/// <summary> /// Crafts a new <see cref="ScpHidReport"/> with current devices meta data. /// </summary> /// <returns>The new HID <see cref="ScpHidReport"/>.</returns> public ScpHidReport NewHidReport(HidReport.Core.HidReport hidReport) { return(new ScpHidReport(Connection, DeviceAddress, Model, PadId, State, hidReport)); }
protected override void ParseHidReport(byte[] report) { if (report[26] != 0x02) { return; } PacketCounter++; var inputReport = new HidReport.Core.HidReport(); #region HID Report translation // battery inputReport.BatteryStatus = (DsBattery)report[30]; // packet counter inputReport.PacketCounter = PacketCounter; // control buttons inputReport.Set(ButtonsEnum.Ps, IsBitSet(report[1], 4)); inputReport.Set(ButtonsEnum.Select, IsBitSet(report[1], 0)); inputReport.Set(ButtonsEnum.Start, IsBitSet(report[1], 1)); // Left shoulder inputReport.Set(ButtonsEnum.L1, IsBitSet(report[0], 4)); inputReport.Set(AxesEnum.L1, report[15]); // Right shoulder inputReport.Set(ButtonsEnum.R1, IsBitSet(report[0], 5)); inputReport.Set(AxesEnum.R1, report[16]); // Left trigger inputReport.Set(ButtonsEnum.L2, IsBitSet(report[0], 6)); inputReport.Set(AxesEnum.L2, report[17]); // Right trigger inputReport.Set(ButtonsEnum.R2, IsBitSet(report[0], 7)); inputReport.Set(AxesEnum.R2, report[18]); // Triangle inputReport.Set(ButtonsEnum.Triangle, IsBitSet(report[0], 3)); inputReport.Set(AxesEnum.Triangle, report[11]); // Circle inputReport.Set(ButtonsEnum.Circle, IsBitSet(report[0], 2)); inputReport.Set(AxesEnum.Circle, report[12]); // Cross inputReport.Set(ButtonsEnum.Cross, IsBitSet(report[0], 1)); inputReport.Set(AxesEnum.Cross, report[13]); // Square inputReport.Set(ButtonsEnum.Square, IsBitSet(report[0], 0)); inputReport.Set(AxesEnum.Square, report[14]); // Left thumb inputReport.Set(ButtonsEnum.L3, IsBitSet(report[1], 2)); // Right thumb inputReport.Set(ButtonsEnum.R3, IsBitSet(report[1], 3)); // D-Pad if (report[2] != 0x0F) { HidParsers.ParseDPad(report[2], inputReport); } // Left thumb stick inputReport.Set(AxesEnum.Lx, report[3]); inputReport.Set(AxesEnum.Ly, report[4]); // Right thumb stick inputReport.Set(AxesEnum.Rx, report[5]); inputReport.Set(AxesEnum.Ry, report[6]); #endregion OnHidReportReceived(inputReport); }
protected override void ParseHidReport(byte[] report) { if (report[8] != 0xC0 && report[8] != 0x40) { return; } PacketCounter++; var inputReport = new HidReport.Core.HidReport(); #region HID Report translation // no battery state since the Gamepad is Usb-powered inputReport.BatteryStatus = DsBattery.None; // packet counter inputReport.PacketCounter = PacketCounter; // reset buttons // buttons equaly reported in both modes inputReport.Set(ButtonsEnum.Circle, IsBitSet(report[6], 5)); inputReport.Set(ButtonsEnum.Cross, IsBitSet(report[6], 6)); inputReport.Set(ButtonsEnum.Triangle, IsBitSet(report[6], 4)); inputReport.Set(ButtonsEnum.Square, IsBitSet(report[6], 7)); inputReport.Set(ButtonsEnum.Select, IsBitSet(report[7], 4)); inputReport.Set(ButtonsEnum.Start, IsBitSet(report[7], 5)); inputReport.Set(ButtonsEnum.L1, IsBitSet(report[7], 0)); inputReport.Set(ButtonsEnum.R1, IsBitSet(report[7], 1)); inputReport.Set(ButtonsEnum.L2, IsBitSet(report[7], 2)); inputReport.Set(ButtonsEnum.R2, IsBitSet(report[7], 3)); inputReport.Set(ButtonsEnum.L3, IsBitSet(report[7], 6)); inputReport.Set(ButtonsEnum.R3, IsBitSet(report[7], 7)); // detect mode it's running in switch (report[8]) { case 0xC0: // mode 1 { inputReport.Set(ButtonsEnum.Up, (report[2] == 0x00)); inputReport.Set(ButtonsEnum.Right, (report[1] == 0xFF)); inputReport.Set(ButtonsEnum.Down, (report[2] == 0xFF)); inputReport.Set(ButtonsEnum.Left, (report[1] == 0x00)); // mode 1 doesn't report the thumb sticks inputReport.Set(AxesEnum.Lx, 0x80); inputReport.Set(AxesEnum.Ly, 0x80); inputReport.Set(AxesEnum.Rx, 0x80); inputReport.Set(AxesEnum.Ry, 0x80); } break; case 0x40: // mode 2 { var dPad = (byte)(report[6] & ~0xF0); HidParsers.ParseDPad(dPad, inputReport); inputReport.Set(AxesEnum.Lx, report[1]); inputReport.Set(AxesEnum.Ly, report[2]); inputReport.Set(AxesEnum.Rx, report[4]); inputReport.Set(AxesEnum.Ry, report[5]); } break; } #endregion OnHidReportReceived(inputReport); }