private void _device_DataReceived(object sender, DataReceivedEventArgs e) { bool dpadChanged = false; bool buttonsChanged = false; switch (e.ReportType) { case 0x20: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); var isExtensionConnected = (e.Data[2] & 0x02) > 0; bool changed = isExtensionConnected != _extensionType.HasValue; var th = new Thread(new ThreadStart(() => { try { SetReportingMode(_lastReportingMode); } catch { } })); th.IsBackground = true; th.Start(); if (changed) { if (isExtensionConnected) { try { th = new Thread(new ThreadStart(_HandleExtensionConnected)); th.IsBackground = true; th.Start(); } catch { } } else { _extensionType = null; } } break; } case 0x21: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); int numberOfBytes = (e.Data[2] >> 4) + 1; _readError = e.Data[2] & 0x0F; if (_bytesRemaining >= numberOfBytes) { Array.Copy(e.Data, 5, _bytesRead, _bytesRead.Length - _bytesRemaining, numberOfBytes); } _bytesRemaining -= numberOfBytes; break; } case 0x22: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); lock (_acknowledgements) { var reportType = e.Data[2]; var errorCode = e.Data[3]; if (_acknowledgements.ContainsKey(reportType)) { _acknowledgements.Remove(reportType); } _acknowledgements.Add(reportType, errorCode); } break; } case 0x30: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); break; } case 0x31: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); break; } case 0x32: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); _ParseTabletState(_GetData(e.Data, 2, 6)); break; } case 0x33: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); break; } case 0x34: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); _ParseTabletState(_GetData(e.Data, 2, 6)); break; } case 0x35: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); _ParseTabletState(_GetData(e.Data, 5, 6)); break; } case 0x36: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); _ParseTabletState(_GetData(e.Data, 12, 6)); break; } case 0x37: { var data = _GetData(e.Data, 0, 2); dpadChanged |= _ParseDPadState(data); buttonsChanged |= _ParseButtonState(data); _ParseTabletState(_GetData(e.Data, 15, 6)); break; } default: { break; } } if (buttonsChanged && ButtonStateChanged != null) ButtonStateChanged(this, EventArgs.Empty); if (dpadChanged && DPadStateChanged != null) DPadStateChanged(this, EventArgs.Empty); }
private void _device_DataReceived(object sender, DataReceivedEventArgs e) { const int UNKNOWN_DATA1_OFFSET = 3; const int MULTITOUCH_DISTANCE_OFFSET = 12; const int PEN_PRESSURE_OFFSET = 13; const int PRESSURE_DATA_OFFSET = 15; const int ACCELEROMETER_X_OFFSET = 19; const int ACCELEROMETER_Y_OFFSET = 21; const int ACCELEROMETER_Z_OFFSET = 23; //Save the unknown data Array.Copy(e.Data, UNKNOWN_DATA1_OFFSET, UnknownData1, 0, _UNKNOWN_DATA1_SIZE); //Get the pressure state if (e.Data[11] == (byte)RawPressureType.NotPressed) PressureType = TabletPressureType.NotPressed; else if (e.Data[11] == (byte)RawPressureType.PenPressed) PressureType = TabletPressureType.PenPressed; else if (e.Data[11] == (byte)RawPressureType.FingerPressed) PressureType = TabletPressureType.FingerPressed; else PressureType = TabletPressureType.Multitouch; //Get the pen pressure PenPressure = (ushort)(e.Data[PEN_PRESSURE_OFFSET]); //Get the multitouch distance _multitouchTimer++; if (_multitouchTimer > _MULTITOUCH_SENSITIVITY) { _multitouchTimer = 0; _previousMultitouchDistance = MultitouchDistance; } MultitouchDistance = e.Data[MULTITOUCH_DISTANCE_OFFSET]; //Get the (singular) pressure point PressurePoint = new Point(e.Data[PRESSURE_DATA_OFFSET] * 0x100 + e.Data[PRESSURE_DATA_OFFSET+2], e.Data[PRESSURE_DATA_OFFSET+1] * 0x100 + e.Data[PRESSURE_DATA_OFFSET+3]); //Get the accelerometer data AccelerometerData.XAxis = (ushort)(e.Data[ACCELEROMETER_X_OFFSET] | (e.Data[ACCELEROMETER_X_OFFSET+1] << 8)); AccelerometerData.YAxis = (ushort)(e.Data[ACCELEROMETER_Y_OFFSET] | (e.Data[ACCELEROMETER_Y_OFFSET+1] << 8)); AccelerometerData.ZAxis = (ushort)(e.Data[ACCELEROMETER_Z_OFFSET] | (e.Data[ACCELEROMETER_Z_OFFSET+1] << 8)); //Parse raw data for buttons bool changed = false; bool raw = (e.Data[0] & 0x01) > 0; changed |= ButtonState.SquareHeld != raw; ButtonState.SquareHeld = raw; raw = (e.Data[0] & 0x02) > 0; changed |= ButtonState.CrossHeld != raw; ButtonState.CrossHeld = raw; raw = (e.Data[0] & 0x04) > 0; changed |= ButtonState.CircleHeld != raw; ButtonState.CircleHeld = raw; raw = (e.Data[0] & 0x08) > 0; changed |= ButtonState.TriangleHeld != raw; ButtonState.TriangleHeld = raw; raw = (e.Data[1] & 0x01) > 0; changed |= ButtonState.SelectHeld != raw; ButtonState.SelectHeld = raw; raw = (e.Data[1] & 0x02) > 0; changed |= ButtonState.StartHeld != raw; ButtonState.StartHeld = raw; raw = (e.Data[1] & 0x10) > 0; changed |= ButtonState.PSHeld != raw; ButtonState.PSHeld = raw; if (changed && ButtonStateChanged != null) ButtonStateChanged(this, EventArgs.Empty); //Now parse raw data for D-pad changes changed = false; raw = (e.Data[2] == 0x0) || (e.Data[2] == 0x1) || (e.Data[2] == 0x7); changed |= DPadState.UpHeld != raw; DPadState.UpHeld = raw; raw = (e.Data[2] == 0x3) || (e.Data[2] == 0x4) || (e.Data[2] == 0x5); changed |= DPadState.DownHeld != raw; DPadState.DownHeld = raw; raw = (e.Data[2] == 0x5) || (e.Data[2] == 0x6) || (e.Data[2] == 0x7); changed |= DPadState.LeftHeld != raw; DPadState.LeftHeld = raw; raw = (e.Data[2] == 0x1) || (e.Data[2] == 0x2) || (e.Data[2] == 0x3); changed |= DPadState.RightHeld != raw; DPadState.RightHeld = raw; if (changed && DPadStateChanged != null) DPadStateChanged(this, EventArgs.Empty); }