private void OnHidReportReceived(object sender, ScpHidReport e) { if (HidReportReceived != null) { HidReportReceived(sender, e); } }
public void Process(ScpHidReport report) { foreach (var mapperProfile in MapperProfiles.Where(p => p.IsActive)) { mapperProfile.Process(report); } }
public void Process(ScpHidReport report) { foreach (var mapperProfile in MapperProfiles) { mapperProfile.Process(report); } }
protected virtual void OnHidReportReceived(object sender, ScpHidReport e) { if (Report != null) { Report(sender, e); } }
private void ProxyOnNativeFeedReceived(object sender, ScpHidReport report) { if (report.PadId != _currentPad) { return; } _vm.CurrentProfile.Model = report.Model; _vm.CurrentProfile.MacAddress = string.Join(":", (from z in report.PadMacAddress.GetAddressBytes() select z.ToString("X2")).ToArray()); _vm.CurrentProfile.PadId = report.PadId; _vm.CurrentProfile.Remap(report); switch (report.Model) { case DsModel.DS3: _vm.CurrentProfile.Ps.CurrentValue = report[Ds3Button.Ps].Value; _vm.CurrentProfile.Circle.CurrentValue = report[Ds3Button.Circle].Value; _vm.CurrentProfile.Cross.CurrentValue = report[Ds3Button.Cross].Value; _vm.CurrentProfile.Square.CurrentValue = report[Ds3Button.Square].Value; _vm.CurrentProfile.Triangle.CurrentValue = report[Ds3Button.Triangle].Value; _vm.CurrentProfile.Select.CurrentValue = report[Ds3Button.Select].Value; _vm.CurrentProfile.Start.CurrentValue = report[Ds3Button.Start].Value; _vm.CurrentProfile.LeftShoulder.CurrentValue = report[Ds3Button.L1].Value; _vm.CurrentProfile.RightShoulder.CurrentValue = report[Ds3Button.R1].Value; _vm.CurrentProfile.LeftTrigger.CurrentValue = report[Ds3Button.L2].Value; _vm.CurrentProfile.RightTrigger.CurrentValue = report[Ds3Button.R2].Value; _vm.CurrentProfile.LeftThumb.CurrentValue = report[Ds3Button.L3].Value; _vm.CurrentProfile.RightThumb.CurrentValue = report[Ds3Button.R3].Value; _vm.CurrentProfile.Up.CurrentValue = report[Ds3Button.Up].Value; _vm.CurrentProfile.Right.CurrentValue = report[Ds3Button.Right].Value; _vm.CurrentProfile.Down.CurrentValue = report[Ds3Button.Down].Value; _vm.CurrentProfile.Left.CurrentValue = report[Ds3Button.Left].Value; break; case DsModel.DS4: _vm.CurrentProfile.Ps.CurrentValue = report[Ds4Button.Ps].Value; _vm.CurrentProfile.Circle.CurrentValue = report[Ds4Button.Circle].Value; _vm.CurrentProfile.Cross.CurrentValue = report[Ds4Button.Cross].Value; _vm.CurrentProfile.Square.CurrentValue = report[Ds4Button.Square].Value; _vm.CurrentProfile.Triangle.CurrentValue = report[Ds4Button.Triangle].Value; _vm.CurrentProfile.Select.CurrentValue = report[Ds4Button.Share].Value; _vm.CurrentProfile.Start.CurrentValue = report[Ds4Button.Options].Value; _vm.CurrentProfile.LeftShoulder.CurrentValue = report[Ds4Button.L1].Value; _vm.CurrentProfile.RightShoulder.CurrentValue = report[Ds4Button.R1].Value; _vm.CurrentProfile.LeftTrigger.CurrentValue = report[Ds4Button.L2].Value; _vm.CurrentProfile.RightTrigger.CurrentValue = report[Ds4Button.R2].Value; _vm.CurrentProfile.LeftThumb.CurrentValue = report[Ds4Button.L3].Value; _vm.CurrentProfile.RightThumb.CurrentValue = report[Ds4Button.R3].Value; _vm.CurrentProfile.Up.CurrentValue = report[Ds4Button.Up].Value; _vm.CurrentProfile.Right.CurrentValue = report[Ds4Button.Right].Value; _vm.CurrentProfile.Down.CurrentValue = report[Ds4Button.Down].Value; _vm.CurrentProfile.Left.CurrentValue = report[Ds4Button.Left].Value; break; } }
private void OnFeedPacketReceived(ScpHidReport data) { _packetCache[data.PadId] = data; if (NativeFeedReceived != null) { NativeFeedReceived(this, data); } }
protected void Parse(object sender, ScpHidReport e) { lock (this) { if (runParser & selectedPads[(int)e.PadId]) { gps.Update(e); } } }
protected void OnHidReportReceived(ScpHidReport report) { _inputReportQueue.Enqueue(() => Task.Run(() => { if (HidReportReceived != null) { HidReportReceived.Invoke(this, report); } })); }
protected override void OnHidReportReceived(object sender, ScpHidReport e) { var serial = (int)e.PadId; var model = e.Model; var report = _mCache[serial].Report; var rumble = _mCache[serial].Rumble; DualShockProfileManager.Instance.PassThroughAllProfiles(e); ScpPlugins.Instance.Process(e); _scpBus.Parse(e, report, model); if (_scpBus.Report(report, rumble) && (DsState)e.RawBytes[1] == DsState.Connected) { var large = rumble[3]; var small = rumble[4]; if (rumble[1] == 0x08 && (large != _mXInput[serial][0] || small != _mXInput[serial][1])) { _mXInput[serial][0] = large; _mXInput[serial][1] = small; Pad[serial].Rumble(large, small); } } if ((DsState)e.RawBytes[1] != DsState.Connected) { _mXInput[serial][0] = _mXInput[serial][1] = 0; _mNative[serial][0] = _mNative[serial][1] = 0; } // skip broadcast if native feed is disabled if (GlobalConfiguration.Instance.DisableNative) { return; } // send native controller inputs to subscribed clients foreach ( var channel in _nativeFeedSubscribers.Select(nativeFeedSubscriber => nativeFeedSubscriber.Value)) { try { channel.SendAsync(e.RawBytes); } catch (AggregateException) { /* This might happen if the client disconnects while sending the * response is still in progress. The exception can be ignored. */ } } }
private bool CheckDpadDs4AxisAsButton(ScpHidReport Data, DSAxis parAxis) { if (parAxis.DS4 != null & parAxis.DS4 != Ds4Axis.None) { return(CheckDpadAxisAsButton(Data[parAxis.DS4].Value, parAxis.triggerHigh)); } else { return(false); } }
private bool CheckDpadDs4(ScpHidReport Data, DSButton parButton) { if (parButton.DS4 != null) { return(Data[parButton.DS4].IsPressed); } else { return(false); } }
public void Process(ScpHidReport report) { if (!report[Ds3Button.Triangle].IsPressed) return; if (_time.ElapsedMilliseconds < 50) return; report.Unset(Ds3Button.Triangle); if (_offCounter++ != 5) return; _time.Restart(); _offCounter = 0; }
public static uint XInputGetCapabilities(uint dwUserIndex, uint dwFlags, ref XINPUT_CAPABILITIES pCapabilities) { #if !EXPERIMENTAL return(OriginalXInputGetCapabilitiesFunction.Value(dwUserIndex, dwFlags, ref pCapabilities)); #else Log.DebugFormat("dwUserIndex = {0}", dwUserIndex); if (OriginalXInputGetCapabilitiesFunction.Value(dwUserIndex, dwFlags, ref pCapabilities) == ResultWin32.ERROR_SUCCESS) { return(ResultWin32.ERROR_SUCCESS); } try { ScpHidReport report = Proxy.GetReport(dwUserIndex); if (report == null || report.PadState != DsState.Connected) { return(ResultWin32.ERROR_DEVICE_NOT_CONNECTED); } pCapabilities.Type = XInputConstants.XINPUT_DEVTYPE_GAMEPAD; pCapabilities.SubType = XInputConstants.XINPUT_DEVSUBTYPE_GAMEPAD; pCapabilities.Flags = (ushort)(XInputConstants.CapabilityFlags.XINPUT_CAPS_FFB_SUPPORTED | XInputConstants.CapabilityFlags.XINPUT_CAPS_WIRELESS); pCapabilities.Gamepad = new XINPUT_GAMEPAD() { wButtons = 0xFFFF, bLeftTrigger = 0xFF, bRightTrigger = 0xFF }; } catch (Exception ex) { Log.ErrorFormat("Unexpected error: {0}", ex); return(ResultWin32.ERROR_DEVICE_NOT_CONNECTED); } return(ResultWin32.ERROR_SUCCESS); #endif }
protected void OnHidReportReceived(ScpHidReport report) { if (GlobalConfiguration.Instance.UseAsyncHidReportProcessing) { _inputReportQueue.Enqueue(() => Task.Run(() => { if (HidReportReceived != null) { HidReportReceived.Invoke(this, report); } })); } else { if (HidReportReceived != null) { HidReportReceived.Invoke(this, report); } } }
public void Process(ScpHidReport report) { if (!report[Ds3Button.Triangle].IsPressed) { return; } if (_time.ElapsedMilliseconds < 50) { return; } report.Unset(Ds3Button.Triangle); if (_offCounter++ != 5) { return; } _time.Restart(); _offCounter = 0; }
protected override void OnHidReportReceived(object sender, ScpHidReport e) { // get current pad ID var serial = (int)e.PadId; // get cached status data var report = _cache[serial].Report; var rumble = _cache[serial].Rumble; // pass current report through user profiles DualShockProfileManager.Instance.PassThroughAllProfiles(e); // translate current report to Xbox format _scpBus.Parse(e, report); if (_scpBus.Report(report, rumble) && e.PadState == DsState.Connected) { var large = rumble[3]; var small = rumble[4]; if (rumble[1] == 0x08 && (large != _mXInput[serial][0] || small != _mXInput[serial][1])) { _mXInput[serial][0] = large; _mXInput[serial][1] = small; Pads[serial].Rumble(large, small); } } if (e.PadState != DsState.Connected) { // reset rumble/vibration to off state _mXInput[serial][0] = _mXInput[serial][1] = 0; _mNative[serial][0] = _mNative[serial][1] = 0; if (GlobalConfiguration.Instance.AlwaysDisconnectVirtualBusDevice) { _scpBus.Unplug(_scpBus.IndexToSerial((byte)e.PadId)); } } // skip broadcast if native feed is disabled if (GlobalConfiguration.Instance.DisableNative) return; // send native controller inputs to subscribed clients foreach ( var channel in _nativeFeedSubscribers.Select(nativeFeedSubscriber => nativeFeedSubscriber.Value)) { try { channel.SendAsync(e.RawBytes); } catch (AggregateException) { /* This might happen if the client disconnects while sending the * response is still in progress. The exception can be ignored. */ } } }
/// <summary> /// Translates an <see cref="ScpHidReport"/> to an Xbox 360 compatible byte array. /// </summary> /// <param name="inputReport">The <see cref="ScpHidReport"/> to translate.</param> /// <returns>The translated data as <see cref="XINPUT_GAMEPAD"/> structure.</returns> public XINPUT_GAMEPAD Parse(ScpHidReport inputReport) { var xButton = X360Button.None; var output = new XINPUT_GAMEPAD(); switch (inputReport.Model) { case DsModel.DS3: { // select & start if (inputReport[Ds3Button.Select].IsPressed) { xButton |= X360Button.Back; } if (inputReport[Ds3Button.Start].IsPressed) { xButton |= X360Button.Start; } // d-pad if (inputReport[Ds3Button.Up].IsPressed) { xButton |= X360Button.Up; } if (inputReport[Ds3Button.Right].IsPressed) { xButton |= X360Button.Right; } if (inputReport[Ds3Button.Down].IsPressed) { xButton |= X360Button.Down; } if (inputReport[Ds3Button.Left].IsPressed) { xButton |= X360Button.Left; } // shoulders if (inputReport[Ds3Button.L1].IsPressed) { xButton |= X360Button.LB; } if (inputReport[Ds3Button.R1].IsPressed) { xButton |= X360Button.RB; } // face buttons if (inputReport[Ds3Button.Triangle].IsPressed) { xButton |= X360Button.Y; } if (inputReport[Ds3Button.Circle].IsPressed) { xButton |= X360Button.B; } if (inputReport[Ds3Button.Cross].IsPressed) { xButton |= X360Button.A; } if (inputReport[Ds3Button.Square].IsPressed) { xButton |= X360Button.X; } // PS/Guide if (inputReport[Ds3Button.Ps].IsPressed) { xButton |= X360Button.Guide; } // thumbs if (inputReport[Ds3Button.L3].IsPressed) { xButton |= X360Button.LS; } if (inputReport[Ds3Button.R3].IsPressed) { xButton |= X360Button.RS; } // face buttons output.wButtons = (ushort)xButton; // trigger output.bLeftTrigger = inputReport[Ds3Axis.L2].Value; output.bRightTrigger = inputReport[Ds3Axis.R2].Value; if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL, inputReport[Ds3Axis.Lx].Value, inputReport[Ds3Axis.Ly].Value)) // Left Stick DeadZone { output.sThumbLX = (short) +DsMath.Scale(inputReport[Ds3Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX); output.sThumbLY = (short) -DsMath.Scale(inputReport[Ds3Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY); } if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR, inputReport[Ds3Axis.Rx].Value, inputReport[Ds3Axis.Ry].Value)) // Right Stick DeadZone { output.sThumbRX = (short) +DsMath.Scale(inputReport[Ds3Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX); output.sThumbRY = (short) -DsMath.Scale(inputReport[Ds3Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY); } } break; case DsModel.DS4: { if (inputReport[Ds4Button.Share].IsPressed) { xButton |= X360Button.Back; } if (inputReport[Ds4Button.Options].IsPressed) { xButton |= X360Button.Start; } if (inputReport[Ds4Button.Up].IsPressed) { xButton |= X360Button.Up; } if (inputReport[Ds4Button.Right].IsPressed) { xButton |= X360Button.Right; } if (inputReport[Ds4Button.Down].IsPressed) { xButton |= X360Button.Down; } if (inputReport[Ds4Button.Left].IsPressed) { xButton |= X360Button.Left; } if (inputReport[Ds4Button.L1].IsPressed) { xButton |= X360Button.LB; } if (inputReport[Ds4Button.R1].IsPressed) { xButton |= X360Button.RB; } if (inputReport[Ds4Button.Triangle].IsPressed) { xButton |= X360Button.Y; } if (inputReport[Ds4Button.Circle].IsPressed) { xButton |= X360Button.B; } if (inputReport[Ds4Button.Cross].IsPressed) { xButton |= X360Button.A; } if (inputReport[Ds4Button.Square].IsPressed) { xButton |= X360Button.X; } if (inputReport[Ds4Button.Ps].IsPressed) { xButton |= X360Button.Guide; } if (inputReport[Ds4Button.L3].IsPressed) { xButton |= X360Button.LS; } if (inputReport[Ds4Button.R3].IsPressed) { xButton |= X360Button.RS; } // face buttons output.wButtons = (ushort)xButton; // trigger output.bLeftTrigger = inputReport[Ds4Axis.L2].Value; output.bRightTrigger = inputReport[Ds4Axis.R2].Value; if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL, inputReport[Ds4Axis.Lx].Value, inputReport[Ds4Axis.Ly].Value)) // Left Stick DeadZone { output.sThumbLX = (short) +DsMath.Scale(inputReport[Ds4Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX); output.sThumbLY = (short) -DsMath.Scale(inputReport[Ds4Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY); } if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR, inputReport[Ds4Axis.Rx].Value, inputReport[Ds4Axis.Ry].Value)) // Right Stick DeadZone { output.sThumbRX = (short) +DsMath.Scale(inputReport[Ds4Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX); output.sThumbRY = (short) -DsMath.Scale(inputReport[Ds4Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY); } } break; } return(output); }
private void Parse(object sender, ScpHidReport e) { lock (this) { if (e.PadId == (DsPadId)m_SelectedPad) { if (e.PadState != DsState.Connected) { ResetControls(); return; } switch (e.Model) { case DsModel.DS3: { axLX.Value = e[Ds3Axis.Lx].Value; axLY.Value = e[Ds3Axis.Ly].Value; axRX.Value = e[Ds3Axis.Rx].Value; axRY.Value = e[Ds3Axis.Ry].Value; axL1.Value = e[Ds3Axis.L1].Value; axR1.Value = e[Ds3Axis.R1].Value; axL2.Value = e[Ds3Axis.L2].Value; axR2.Value = e[Ds3Axis.R2].Value; axL3.Value = (Byte)(e[Ds3Button.L3].IsPressed ? 255 : 0); axR3.Value = (Byte)(e[Ds3Button.R3].IsPressed ? 255 : 0); axSH.Value = (Byte)(e[Ds3Button.Select].IsPressed ? 255 : 0); axOP.Value = (Byte)(e[Ds3Button.Start].IsPressed ? 255 : 0); axT.Value = e[Ds3Axis.Triangle].Value; axC.Value = e[Ds3Axis.Circle].Value; axX.Value = e[Ds3Axis.Cross].Value; axS.Value = e[Ds3Axis.Square].Value; axU.Value = e[Ds3Axis.Up].Value; axR.Value = e[Ds3Axis.Right].Value; axD.Value = e[Ds3Axis.Down].Value; axL.Value = e[Ds3Axis.Left].Value; axPS.Value = (Byte)(e[Ds3Button.Ps].IsPressed ? 255 : 0); } break; case DsModel.DS4: { axLX.Value = e[Ds4Axis.Lx].Value; axLY.Value = e[Ds4Axis.Ly].Value; axRX.Value = e[Ds4Axis.Rx].Value; axRY.Value = e[Ds4Axis.Ry].Value; axL2.Value = e[Ds4Axis.L2].Value; axR2.Value = e[Ds4Axis.R2].Value; axL1.Value = (Byte)(e[Ds4Button.L1].IsPressed ? 255 : 0); axR1.Value = (Byte)(e[Ds4Button.R1].IsPressed ? 255 : 0); axL3.Value = (Byte)(e[Ds4Button.L3].IsPressed ? 255 : 0); axR3.Value = (Byte)(e[Ds4Button.R3].IsPressed ? 255 : 0); axSH.Value = (Byte)(e[Ds4Button.Share].IsPressed ? 255 : 0); axOP.Value = (Byte)(e[Ds4Button.Options].IsPressed ? 255 : 0); axT.Value = (Byte)(e[Ds4Button.Triangle].IsPressed ? 255 : 0); axC.Value = (Byte)(e[Ds4Button.Circle].IsPressed ? 255 : 0); axX.Value = (Byte)(e[Ds4Button.Cross].IsPressed ? 255 : 0); axS.Value = (Byte)(e[Ds4Button.Square].IsPressed ? 255 : 0); axU.Value = (Byte)(e[Ds4Button.Up].IsPressed ? 255 : 0); axR.Value = (Byte)(e[Ds4Button.Right].IsPressed ? 255 : 0); axD.Value = (Byte)(e[Ds4Button.Down].IsPressed ? 255 : 0); axL.Value = (Byte)(e[Ds4Button.Left].IsPressed ? 255 : 0); axPS.Value = (Byte)(e[Ds4Button.Ps].IsPressed ? 255 : 0); axTP.Value = (Byte)(e[Ds4Button.TouchPad].IsPressed ? 255 : 0); } break; } } } }
private void OnFeedPacketReceived(ScpHidReport data) { _packetCache[data.PadId] = data.CopyHidReport(); if (NativeFeedReceived != null) { NativeFeedReceived(this, data); } }
protected override void OnHidReportReceived(object sender, ScpHidReport e) { // get current pad ID var serial = (int)e.PadId; if (GlobalConfiguration.Instance.ProfilesEnabled) { // pass current report through user profiles DualShockProfileManager.Instance.PassThroughAllProfiles(e); } if (e.PadState == DsState.Connected) { // translate current report to Xbox format and send it to bus device XOutputWrapper.Instance.SetState((uint)serial, _scpBus.Parse(e)); // set currently assigned XInput slot Pads[serial].XInputSlot = XOutputWrapper.Instance.GetRealIndex((uint)serial); byte largeMotor = 0; byte smallMotor = 0; // forward rumble request to pad if (XOutputWrapper.Instance.GetState((uint)serial, ref largeMotor, ref smallMotor) && (largeMotor != _vibration[serial][0] || smallMotor != _vibration[serial][1])) { _vibration[serial][0] = largeMotor; _vibration[serial][1] = smallMotor; Pads[serial].Rumble(largeMotor, smallMotor); } } else { // reset rumble/vibration to off state _vibration[serial][0] = _vibration[serial][1] = 0; _mNative[serial][0] = _mNative[serial][1] = 0; if (GlobalConfiguration.Instance.AlwaysDisconnectVirtualBusDevice) { _scpBus.Unplug(_scpBus.IndexToSerial((byte)e.PadId)); } } // skip broadcast if native feed is disabled if (GlobalConfiguration.Instance.DisableNative) { return; } // send native controller inputs to subscribed clients foreach ( var channel in _nativeFeedSubscribers.Select(nativeFeedSubscriber => nativeFeedSubscriber.Value)) { try { channel.SendAsync(e.RawBytes); } catch (AggregateException) { /* This might happen if the client disconnects while sending the * response is still in progress. The exception can be ignored. */ } } }
protected override void OnHidReportReceived(object sender, ScpHidReport e) { // get current pad ID var serial = (int)e.PadId; if (GlobalConfiguration.Instance.ProfilesEnabled) { // pass current report through user profiles DualShockProfileManager.Instance.PassThroughAllProfiles(e); } if (e.PadState == DsState.Connected) { // translate current report to Xbox format and send it to bus device XOutputWrapper.Instance.SetState((uint) serial, _scpBus.Parse(e)); // set currently assigned XInput slot Pads[serial].XInputSlot = XOutputWrapper.Instance.GetRealIndex((uint) serial); byte largeMotor = 0; byte smallMotor = 0; // forward rumble request to pad if (XOutputWrapper.Instance.GetState((uint) serial, ref largeMotor, ref smallMotor) && (largeMotor != _vibration[serial][0] || smallMotor != _vibration[serial][1])) { _vibration[serial][0] = largeMotor; _vibration[serial][1] = smallMotor; Pads[serial].Rumble(largeMotor, smallMotor); } } else { // reset rumble/vibration to off state _vibration[serial][0] = _vibration[serial][1] = 0; _mNative[serial][0] = _mNative[serial][1] = 0; if (GlobalConfiguration.Instance.AlwaysUnPlugVirtualBusDevice) { _scpBus.Unplug(_scpBus.IndexToSerial((byte)e.PadId)); } } // skip broadcast if native feed is disabled if (GlobalConfiguration.Instance.DisableNative) return; // send native controller inputs to subscribed clients foreach ( var channel in _nativeFeedSubscribers.Select(nativeFeedSubscriber => nativeFeedSubscriber.Value)) { try { channel.SendAsync(e.RawBytes); } catch (AggregateException) { /* This might happen if the client disconnects while sending the * response is still in progress. The exception can be ignored. */ } } }
public static uint XInputGetState(uint dwUserIndex, ref XINPUT_STATE pState) { #if !EXPERIMENTAL return(OriginalXInputGetStateFunction.Value(dwUserIndex, ref pState)); #else if (OriginalXInputGetStateFunction.Value(dwUserIndex, ref pState) == ResultWin32.ERROR_SUCCESS) { return(ResultWin32.ERROR_SUCCESS); } try { ScpHidReport report = null; while (dwUserIndex == 0 && (report = Proxy.GetReport(dwUserIndex)) == null) { Thread.Sleep(100); } if (report == null || report.PadState != DsState.Connected) { return(ResultWin32.ERROR_DEVICE_NOT_CONNECTED); } var xPad = new XINPUT_GAMEPAD(); pState.dwPacketNumber = report.PacketCounter; switch (report.Model) { case DsModel.DS3: { // select & start xPad.wButtons |= (ushort)report[Ds3Button.Select].Xbox360Button; xPad.wButtons |= (ushort)report[Ds3Button.Start].Xbox360Button; // d-pad xPad.wButtons |= (ushort)report[Ds3Button.Up].Xbox360Button; xPad.wButtons |= (ushort)report[Ds3Button.Right].Xbox360Button; xPad.wButtons |= (ushort)report[Ds3Button.Down].Xbox360Button; xPad.wButtons |= (ushort)report[Ds3Button.Left].Xbox360Button; // shoulders xPad.wButtons |= (ushort)report[Ds3Button.L1].Xbox360Button; xPad.wButtons |= (ushort)report[Ds3Button.R1].Xbox360Button; // face buttons xPad.wButtons |= (ushort)report[Ds3Button.Triangle].Xbox360Button; xPad.wButtons |= (ushort)report[Ds3Button.Circle].Xbox360Button; xPad.wButtons |= (ushort)report[Ds3Button.Cross].Xbox360Button; xPad.wButtons |= (ushort)report[Ds3Button.Square].Xbox360Button; // PS/Guide xPad.wButtons |= (ushort)report[Ds3Button.Ps].Xbox360Button; // thumbs xPad.wButtons |= (ushort)report[Ds3Button.L3].Xbox360Button; xPad.wButtons |= (ushort)report[Ds3Button.R3].Xbox360Button; // triggers xPad.bLeftTrigger = report[Ds3Axis.L2].Value; xPad.bRightTrigger = report[Ds3Axis.R2].Value; // thumb axes xPad.sThumbLX = (short)+DsMath.Scale(report[Ds3Axis.Lx].Value, false); xPad.sThumbLY = (short)-DsMath.Scale(report[Ds3Axis.Ly].Value, false); xPad.sThumbRX = (short)+DsMath.Scale(report[Ds3Axis.Rx].Value, false); xPad.sThumbRY = (short)-DsMath.Scale(report[Ds3Axis.Ry].Value, false); } break; case DsModel.DS4: { // select & start xPad.wButtons |= (ushort)report[Ds4Button.Share].Xbox360Button; xPad.wButtons |= (ushort)report[Ds4Button.Options].Xbox360Button; // d-pad xPad.wButtons |= (ushort)report[Ds4Button.Up].Xbox360Button; xPad.wButtons |= (ushort)report[Ds4Button.Right].Xbox360Button; xPad.wButtons |= (ushort)report[Ds4Button.Down].Xbox360Button; xPad.wButtons |= (ushort)report[Ds4Button.Left].Xbox360Button; // shoulders xPad.wButtons |= (ushort)report[Ds4Button.L1].Xbox360Button; xPad.wButtons |= (ushort)report[Ds4Button.R1].Xbox360Button; // face buttons xPad.wButtons |= (ushort)report[Ds4Button.Triangle].Xbox360Button; xPad.wButtons |= (ushort)report[Ds4Button.Circle].Xbox360Button; xPad.wButtons |= (ushort)report[Ds4Button.Cross].Xbox360Button; xPad.wButtons |= (ushort)report[Ds4Button.Square].Xbox360Button; // PS/Guide xPad.wButtons |= (ushort)report[Ds4Button.Ps].Xbox360Button; // thumbs xPad.wButtons |= (ushort)report[Ds4Button.L3].Xbox360Button; xPad.wButtons |= (ushort)report[Ds4Button.R3].Xbox360Button; // triggers xPad.bLeftTrigger = report[Ds4Axis.L2].Value; xPad.bRightTrigger = report[Ds4Axis.R2].Value; // thumb axes xPad.sThumbLX = (short)+DsMath.Scale(report[Ds4Axis.Lx].Value, false); xPad.sThumbLY = (short)-DsMath.Scale(report[Ds4Axis.Ly].Value, false); xPad.sThumbRX = (short)+DsMath.Scale(report[Ds4Axis.Rx].Value, false); xPad.sThumbRY = (short)-DsMath.Scale(report[Ds4Axis.Ry].Value, false); } break; } pState.Gamepad = xPad; } catch (Exception ex) { Log.ErrorFormat("Unexpected error: {0}", ex); return(ResultWin32.ERROR_DEVICE_NOT_CONNECTED); } return(ResultWin32.ERROR_SUCCESS); #endif }
public int Parse(ScpHidReport inputReport, byte[] output, DsModel type = DsModel.DS3) { var input = inputReport.RawBytes; var serial = IndexToSerial(input[0]); for (var index = 0; index < ReportSize; index++) { output[index] = 0x00; } output[0] = 0x1C; output[4] = (byte)((serial >> 0) & 0xFF); output[5] = (byte)((serial >> 8) & 0xFF); output[6] = (byte)((serial >> 16) & 0xFF); output[7] = (byte)((serial >> 24) & 0xFF); output[9] = 0x14; var xButton = X360Button.None; if (input[1] == 0x02) // Pad is active { switch (type) { case DsModel.DS3: { // select & start if (inputReport[Ds3Button.Select].IsPressed) { xButton |= X360Button.Back; } if (inputReport[Ds3Button.Start].IsPressed) { xButton |= X360Button.Start; } // d-pad if (inputReport[Ds3Button.Up].IsPressed) { xButton |= X360Button.Up; } if (inputReport[Ds3Button.Right].IsPressed) { xButton |= X360Button.Right; } if (inputReport[Ds3Button.Down].IsPressed) { xButton |= X360Button.Down; } if (inputReport[Ds3Button.Left].IsPressed) { xButton |= X360Button.Left; } // shoulders if (inputReport[Ds3Button.L1].IsPressed) { xButton |= X360Button.LB; } if (inputReport[Ds3Button.R1].IsPressed) { xButton |= X360Button.RB; } // face buttons if (inputReport[Ds3Button.Triangle].IsPressed) { xButton |= X360Button.Y; } if (inputReport[Ds3Button.Circle].IsPressed) { xButton |= X360Button.B; } if (inputReport[Ds3Button.Cross].IsPressed) { xButton |= X360Button.A; } if (inputReport[Ds3Button.Square].IsPressed) { xButton |= X360Button.X; } // PS/Guide if (inputReport[Ds3Button.Ps].IsPressed) { xButton |= X360Button.Guide; } // thumbs if (inputReport[Ds3Button.L3].IsPressed) { xButton |= X360Button.LS; } if (inputReport[Ds3Button.R3].IsPressed) { xButton |= X360Button.RS; } output[(uint)X360Axis.BT_Lo] = (byte)((uint)xButton >> 0 & 0xFF); output[(uint)X360Axis.BT_Hi] = (byte)((uint)xButton >> 8 & 0xFF); // trigger output[(uint)X360Axis.LT] = inputReport[Ds3Axis.L2].Value; output[(uint)X360Axis.RT] = inputReport[Ds3Axis.R2].Value; if ( !DeadZone(GlobalConfiguration.Instance.DeadZoneL, inputReport[Ds3Axis.Lx].Value, inputReport[Ds3Axis.Ly].Value)) // Left Stick DeadZone { var thumbLx = +Scale(inputReport[Ds3Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX); var thumbLy = -Scale(inputReport[Ds3Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY); output[(uint)X360Axis.LX_Lo] = (byte)((thumbLx >> 0) & 0xFF); // LX output[(uint)X360Axis.LX_Hi] = (byte)((thumbLx >> 8) & 0xFF); output[(uint)X360Axis.LY_Lo] = (byte)((thumbLy >> 0) & 0xFF); // LY output[(uint)X360Axis.LY_Hi] = (byte)((thumbLy >> 8) & 0xFF); } if ( !DeadZone(GlobalConfiguration.Instance.DeadZoneR, inputReport[Ds3Axis.Rx].Value, inputReport[Ds3Axis.Ry].Value)) // Right Stick DeadZone { var thumbRx = +Scale(inputReport[Ds3Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX); var thumbRy = -Scale(inputReport[Ds3Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY); output[(uint)X360Axis.RX_Lo] = (byte)((thumbRx >> 0) & 0xFF); // RX output[(uint)X360Axis.RX_Hi] = (byte)((thumbRx >> 8) & 0xFF); output[(uint)X360Axis.RY_Lo] = (byte)((thumbRy >> 0) & 0xFF); // RY output[(uint)X360Axis.RY_Hi] = (byte)((thumbRy >> 8) & 0xFF); } } break; case DsModel.DS4: { var buttons = (Ds4Button)((input[13] << 0) | (input[14] << 8) | (input[15] << 16)); if (buttons.HasFlag(Ds4Button.Share)) { xButton |= X360Button.Back; } if (buttons.HasFlag(Ds4Button.Options)) { xButton |= X360Button.Start; } if (buttons.HasFlag(Ds4Button.Up)) { xButton |= X360Button.Up; } if (buttons.HasFlag(Ds4Button.Right)) { xButton |= X360Button.Right; } if (buttons.HasFlag(Ds4Button.Down)) { xButton |= X360Button.Down; } if (buttons.HasFlag(Ds4Button.Left)) { xButton |= X360Button.Left; } if (buttons.HasFlag(Ds4Button.L1)) { xButton |= X360Button.LB; } if (buttons.HasFlag(Ds4Button.R1)) { xButton |= X360Button.RB; } if (buttons.HasFlag(Ds4Button.Triangle)) { xButton |= X360Button.Y; } if (buttons.HasFlag(Ds4Button.Circle)) { xButton |= X360Button.B; } if (buttons.HasFlag(Ds4Button.Cross)) { xButton |= X360Button.A; } if (buttons.HasFlag(Ds4Button.Square)) { xButton |= X360Button.X; } if (buttons.HasFlag(Ds4Button.PS)) { xButton |= X360Button.Guide; } if (buttons.HasFlag(Ds4Button.L3)) { xButton |= X360Button.LS; } if (buttons.HasFlag(Ds4Button.R3)) { xButton |= X360Button.RS; } output[(uint)X360Axis.BT_Lo] = (byte)((uint)xButton >> 0 & 0xFF); output[(uint)X360Axis.BT_Hi] = (byte)((uint)xButton >> 8 & 0xFF); output[(uint)X360Axis.LT] = input[(uint)Ds4Axis.L2]; output[(uint)X360Axis.RT] = input[(uint)Ds4Axis.R2]; if ( !DeadZone(GlobalConfiguration.Instance.DeadZoneL, input[(uint)Ds4Axis.LX], input[(uint)Ds4Axis.LY])) // Left Stick DeadZone { var thumbLx = +Scale(input[(uint)Ds4Axis.LX], GlobalConfiguration.Instance.FlipLX); var thumbLy = -Scale(input[(uint)Ds4Axis.LY], GlobalConfiguration.Instance.FlipLY); output[(uint)X360Axis.LX_Lo] = (byte)((thumbLx >> 0) & 0xFF); // LX output[(uint)X360Axis.LX_Hi] = (byte)((thumbLx >> 8) & 0xFF); output[(uint)X360Axis.LY_Lo] = (byte)((thumbLy >> 0) & 0xFF); // LY output[(uint)X360Axis.LY_Hi] = (byte)((thumbLy >> 8) & 0xFF); } if ( !DeadZone(GlobalConfiguration.Instance.DeadZoneR, input[(uint)Ds4Axis.RX], input[(uint)Ds4Axis.RY])) // Right Stick DeadZone { var thumbRx = +Scale(input[(uint)Ds4Axis.RX], GlobalConfiguration.Instance.FlipRX); var thumbRy = -Scale(input[(uint)Ds4Axis.RY], GlobalConfiguration.Instance.FlipRY); output[(uint)X360Axis.RX_Lo] = (byte)((thumbRx >> 0) & 0xFF); // RX output[(uint)X360Axis.RX_Hi] = (byte)((thumbRx >> 8) & 0xFF); output[(uint)X360Axis.RY_Lo] = (byte)((thumbRy >> 0) & 0xFF); // RY output[(uint)X360Axis.RY_Hi] = (byte)((thumbRy >> 8) & 0xFF); } } break; } } return(input[0]); }
public void NewReportIncoming(ScpHidReport hidReport) { if (!running) { return; } var clientsList = new List <IPEndPoint>(); var now = DateTime.UtcNow; lock (clients) { var clientsToDelete = new List <IPEndPoint>(); foreach (var cl in clients) { const double TimeoutLimit = 5; if ((now - cl.Value.AllPadsTime).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else if ((hidReport.PadId >= DsPadId.One && hidReport.PadId <= DsPadId.Four) && (now - cl.Value.PadIdsTime[(byte)hidReport.PadId]).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else if (cl.Value.PadMacsTime.ContainsKey(hidReport.PadMacAddress) && (now - cl.Value.PadMacsTime[hidReport.PadMacAddress]).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else //check if this client is totally dead, and remove it if so { bool clientOk = false; for (int i = 0; i < cl.Value.PadIdsTime.Length; i++) { var dur = (now - cl.Value.PadIdsTime[i]).TotalSeconds; if (dur < TimeoutLimit) { clientOk = true; break; } } if (!clientOk) { foreach (var dict in cl.Value.PadMacsTime) { var dur = (now - dict.Value).TotalSeconds; if (dur < TimeoutLimit) { clientOk = true; break; } } if (!clientOk) { clientsToDelete.Add(cl.Key); } } } } foreach (var delCl in clientsToDelete) { clients.Remove(delCl); } clientsToDelete.Clear(); clientsToDelete = null; } if (clientsList.Count <= 0) { return; } byte[] outputData = new byte[100]; int outIdx = BeginPacket(outputData, 1001); Array.Copy(BitConverter.GetBytes((uint)MessageType.DSUS_PadDataRsp), 0, outputData, outIdx, 4); outIdx += 4; outputData[outIdx++] = (byte)hidReport.PadId; outputData[outIdx++] = (byte)hidReport.PadState; outputData[outIdx++] = (byte)hidReport.Model; outputData[outIdx++] = (byte)hidReport.ConnectionType; { byte[] padMac = hidReport.PadMacAddress.GetAddressBytes(); outputData[outIdx++] = padMac[0]; outputData[outIdx++] = padMac[1]; outputData[outIdx++] = padMac[2]; outputData[outIdx++] = padMac[3]; outputData[outIdx++] = padMac[4]; outputData[outIdx++] = padMac[5]; } outputData[outIdx++] = (byte)hidReport.BatteryStatus; outputData[outIdx++] = hidReport.IsPadActive ? (byte)1 : (byte)0; Array.Copy(BitConverter.GetBytes((uint)hidReport.PacketCounter), 0, outputData, outIdx, 4); outIdx += 4; if (!ReportToBuffer(hidReport, outputData, ref outIdx)) { return; } else { FinishPacket(outputData); } foreach (var cl in clientsList) { try { udpSock.SendTo(outputData, cl); } catch (SocketException ex) { } } clientsList.Clear(); clientsList = null; }
protected virtual void OnHidReportReceived(object sender, ScpHidReport e) { if (Report != null) Report(sender, e); }
public void Update(ScpHidReport Data) { lock (this) { uint dsID = (uint)Data.PadId + 1; switch (Data.Model) { #region DS3 case DsModel.DS3: { #region Gryo //Data.Orientation //Data.Motion #endregion #region Axis vJPad.JoyAxis(config.axisL2, Data[Ds3Axis.L2].Value, dsID); vJPad.JoyAxis(config.axisR2, Data[Ds3Axis.R2].Value, dsID); SetAxis(Data[Ds3Axis.Lx].Value, config.axisLX, config.invertLX, dsID); SetAxis(Data[Ds3Axis.Ly].Value, config.axisLY, config.invertLY, dsID); SetAxis(Data[Ds3Axis.Rx].Value, config.axisRX, config.invertRX, dsID); SetAxis(Data[Ds3Axis.Ry].Value, config.axisRY, config.invertRY, dsID); #endregion #region Buttons SetButton(Data[Ds3Button.Cross].IsPressed, config.cross, dsID); SetButton(Data[Ds3Button.Circle].IsPressed, config.circle, dsID); SetButton(Data[Ds3Button.Square].IsPressed, config.square, dsID); SetButton(Data[Ds3Button.Triangle].IsPressed, config.triangle, dsID); SetButton(Data[Ds3Button.L1].IsPressed, config.l1, dsID); SetButton(Data[Ds3Button.R1].IsPressed, config.r1, dsID); SetButton(Data[Ds3Button.L2].IsPressed, config.l2, dsID); SetButton(Data[Ds3Button.R2].IsPressed, config.r2, dsID); SetButton(Data[Ds3Button.Select].IsPressed, config.select_share, dsID); SetButton(Data[Ds3Button.Start].IsPressed, config.start_options, dsID); SetButton(Data[Ds3Button.L3].IsPressed, config.l3, dsID); SetButton(Data[Ds3Button.R3].IsPressed, config.r3, dsID); SetButton(Data[Ds3Button.Ps].IsPressed, config.ps, dsID); //Dpad as button SetButton(Data[Ds3Button.Up].IsPressed, config.up, dsID); SetButton(Data[Ds3Button.Down].IsPressed, config.down, dsID); SetButton(Data[Ds3Button.Left].IsPressed, config.left, dsID); SetButton(Data[Ds3Button.Right].IsPressed, config.right, dsID); //AxisAsButton SetAxisAsButton(Data[Ds3Axis.Lx].Value, config.aLRight, config.aLLeft, dsID); SetAxisAsButton(Data[Ds3Axis.Ly].Value, config.aLDown, config.aLUp, dsID); SetAxisAsButton(Data[Ds3Axis.Rx].Value, config.aRRight, config.aRLeft, dsID); SetAxisAsButton(Data[Ds3Axis.Ry].Value, config.aRDown, config.aRUp, dsID); #endregion #region Dpad //Dpad Direction DSPov = Direction.None; if (CheckDpadDs3(Data, config.pUp)) { DSPov = DSPov | Direction.Up; } if (CheckDpadDs3(Data, config.pDown)) { DSPov = DSPov | Direction.Down; } if (CheckDpadDs3(Data, config.pLeft)) { DSPov = DSPov | Direction.Left; } if (CheckDpadDs3(Data, config.pRight)) { DSPov = DSPov | Direction.Right; } //Axis as Dpad if (CheckDpadDs3AxisAsButton(Data, config.aPUp)) { DSPov = DSPov | Direction.Up; } if (CheckDpadDs3AxisAsButton(Data, config.aPDown)) { DSPov = DSPov | Direction.Down; } if (CheckDpadDs3AxisAsButton(Data, config.aPLeft)) { DSPov = DSPov | Direction.Left; } if (CheckDpadDs3AxisAsButton(Data, config.aPRight)) { DSPov = DSPov | Direction.Right; } vJPad.JoyPov(DSPov, dsID); #endregion } break; #endregion #region DS4 case DsModel.DS4: { #region ThouchPad //These are Int values //What is the range? //Also these have ID values, which mean what? DsTrackPadTouch tp0 = Data.TrackPadTouch0; DsTrackPadTouch tp1 = Data.TrackPadTouch1; #endregion #region Gryo //Data.Orientation //Data.Motion #endregion #region Axis vJPad.JoyAxis(config.axisL2, Data[Ds4Axis.L2].Value, dsID); vJPad.JoyAxis(config.axisR2, Data[Ds4Axis.R2].Value, dsID); SetAxis(Data[Ds4Axis.Lx].Value, config.axisLX, config.invertLX, dsID); SetAxis(Data[Ds4Axis.Ly].Value, config.axisLY, config.invertLY, dsID); SetAxis(Data[Ds4Axis.Rx].Value, config.axisRX, config.invertRX, dsID); SetAxis(Data[Ds4Axis.Ry].Value, config.axisRY, config.invertRY, dsID); #endregion #region Buttons SetButton(Data[Ds4Button.Cross].IsPressed, config.cross, dsID); SetButton(Data[Ds4Button.Circle].IsPressed, config.circle, dsID); SetButton(Data[Ds4Button.Square].IsPressed, config.square, dsID); SetButton(Data[Ds4Button.Triangle].IsPressed, config.triangle, dsID); SetButton(Data[Ds4Button.L1].IsPressed, config.l1, dsID); SetButton(Data[Ds4Button.R1].IsPressed, config.r1, dsID); SetButton(Data[Ds4Button.L2].IsPressed, config.l2, dsID); SetButton(Data[Ds4Button.R2].IsPressed, config.r2, dsID); SetButton(Data[Ds4Button.Share].IsPressed, config.select_share, dsID); SetButton(Data[Ds4Button.Options].IsPressed, config.start_options, dsID); SetButton(Data[Ds4Button.L3].IsPressed, config.l3, dsID); SetButton(Data[Ds4Button.R3].IsPressed, config.r3, dsID); SetButton(Data[Ds4Button.Ps].IsPressed, config.ps, dsID); //Dpad as button SetButton(Data[Ds4Button.Up].IsPressed, config.up, dsID); SetButton(Data[Ds4Button.Down].IsPressed, config.down, dsID); SetButton(Data[Ds4Button.Left].IsPressed, config.left, dsID); SetButton(Data[Ds4Button.Right].IsPressed, config.right, dsID); //AxisAsButton SetAxisAsButton(Data[Ds4Axis.Lx].Value, config.aLRight, config.aLLeft, dsID); SetAxisAsButton(Data[Ds4Axis.Ly].Value, config.aLDown, config.aLUp, dsID); SetAxisAsButton(Data[Ds4Axis.Rx].Value, config.aRRight, config.aRLeft, dsID); SetAxisAsButton(Data[Ds4Axis.Ry].Value, config.aRDown, config.aRUp, dsID); #endregion #region Dpad //Dpad Direction DSPov = Direction.None; if (CheckDpadDs4(Data, config.pUp)) { DSPov = DSPov | Direction.Up; } if (CheckDpadDs4(Data, config.pDown)) { DSPov = DSPov | Direction.Down; } if (CheckDpadDs4(Data, config.pLeft)) { DSPov = DSPov | Direction.Left; } if (CheckDpadDs4(Data, config.pRight)) { DSPov = DSPov | Direction.Right; } //Axis as Dpad if (CheckDpadDs4AxisAsButton(Data, config.aPUp)) { DSPov = DSPov | Direction.Up; } if (CheckDpadDs4AxisAsButton(Data, config.aPDown)) { DSPov = DSPov | Direction.Down; } if (CheckDpadDs4AxisAsButton(Data, config.aPLeft)) { DSPov = DSPov | Direction.Left; } if (CheckDpadDs4AxisAsButton(Data, config.aPRight)) { DSPov = DSPov | Direction.Right; } vJPad.JoyPov(DSPov, dsID); #endregion } break; #endregion } //List<DeadZone> DeadZones = new List<DeadZone>(); //RadialDeadZone adz = new RadialDeadZone(); //adz.AxisX = HID_USAGES.HID_USAGE_X; //adz.AxisTypeX = AxisType.Stick; //adz.AxisY = HID_USAGES.HID_USAGE_Y; //adz.AxisTypeY = AxisType.Stick; //adz.DeadZone = 0.1; //DeadZones.Add(adz); vJPad.ApplyDeadzone(config.deadzones, dsID); vJPad.JoySubmit(dsID); } }
/// <summary> /// Translates an <see cref="ScpHidReport"/> to an Xbox 360 compatible byte array. /// </summary> /// <param name="inputReport">The <see cref="ScpHidReport"/> to translate.</param> /// <param name="output">The target Xbox data array.</param> public void Parse(ScpHidReport inputReport, byte[] output) { var input = inputReport.RawBytes; var serial = IndexToSerial(input[0]); for (var index = 0; index < ReportSize; index++) output[index] = 0x00; output[0] = 0x1C; output[4] = (byte) ((serial >> 0) & 0xFF); output[5] = (byte) ((serial >> 8) & 0xFF); output[6] = (byte) ((serial >> 16) & 0xFF); output[7] = (byte) ((serial >> 24) & 0xFF); output[9] = 0x14; var xButton = X360Button.None; if (inputReport.PadState == DsState.Connected) // Pad is active { switch (inputReport.Model) { case DsModel.DS3: { // select & start if (inputReport[Ds3Button.Select].IsPressed) xButton |= X360Button.Back; if (inputReport[Ds3Button.Start].IsPressed) xButton |= X360Button.Start; // d-pad if (inputReport[Ds3Button.Up].IsPressed) xButton |= X360Button.Up; if (inputReport[Ds3Button.Right].IsPressed) xButton |= X360Button.Right; if (inputReport[Ds3Button.Down].IsPressed) xButton |= X360Button.Down; if (inputReport[Ds3Button.Left].IsPressed) xButton |= X360Button.Left; // shoulders if (inputReport[Ds3Button.L1].IsPressed) xButton |= X360Button.LB; if (inputReport[Ds3Button.R1].IsPressed) xButton |= X360Button.RB; // face buttons if (inputReport[Ds3Button.Triangle].IsPressed) xButton |= X360Button.Y; if (inputReport[Ds3Button.Circle].IsPressed) xButton |= X360Button.B; if (inputReport[Ds3Button.Cross].IsPressed) xButton |= X360Button.A; if (inputReport[Ds3Button.Square].IsPressed) xButton |= X360Button.X; // PS/Guide if (inputReport[Ds3Button.Ps].IsPressed) xButton |= X360Button.Guide; // thumbs if (inputReport[Ds3Button.L3].IsPressed) xButton |= X360Button.LS; if (inputReport[Ds3Button.R3].IsPressed) xButton |= X360Button.RS; output[(uint) X360Axis.BT_Lo] = (byte) ((uint) xButton >> 0 & 0xFF); output[(uint) X360Axis.BT_Hi] = (byte) ((uint) xButton >> 8 & 0xFF); // trigger output[(uint) X360Axis.LT] = inputReport[Ds3Axis.L2].Value; output[(uint) X360Axis.RT] = inputReport[Ds3Axis.R2].Value; if (!DeadZone(GlobalConfiguration.Instance.DeadZoneL, inputReport[Ds3Axis.Lx].Value, inputReport[Ds3Axis.Ly].Value)) // Left Stick DeadZone { var thumbLx = +Scale(inputReport[Ds3Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX); var thumbLy = -Scale(inputReport[Ds3Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY); output[(uint) X360Axis.LX_Lo] = (byte) ((thumbLx >> 0) & 0xFF); // LX output[(uint) X360Axis.LX_Hi] = (byte) ((thumbLx >> 8) & 0xFF); output[(uint) X360Axis.LY_Lo] = (byte) ((thumbLy >> 0) & 0xFF); // LY output[(uint) X360Axis.LY_Hi] = (byte) ((thumbLy >> 8) & 0xFF); } if (!DeadZone(GlobalConfiguration.Instance.DeadZoneR, inputReport[Ds3Axis.Rx].Value, inputReport[Ds3Axis.Ry].Value)) // Right Stick DeadZone { var thumbRx = +Scale(inputReport[Ds3Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX); var thumbRy = -Scale(inputReport[Ds3Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY); output[(uint) X360Axis.RX_Lo] = (byte) ((thumbRx >> 0) & 0xFF); // RX output[(uint) X360Axis.RX_Hi] = (byte) ((thumbRx >> 8) & 0xFF); output[(uint) X360Axis.RY_Lo] = (byte) ((thumbRy >> 0) & 0xFF); // RY output[(uint) X360Axis.RY_Hi] = (byte) ((thumbRy >> 8) & 0xFF); } } break; case DsModel.DS4: { if (inputReport[Ds4Button.Share].IsPressed) xButton |= X360Button.Back; if (inputReport[Ds4Button.Options].IsPressed) xButton |= X360Button.Start; if (inputReport[Ds4Button.Up].IsPressed) xButton |= X360Button.Up; if (inputReport[Ds4Button.Right].IsPressed) xButton |= X360Button.Right; if (inputReport[Ds4Button.Down].IsPressed) xButton |= X360Button.Down; if (inputReport[Ds4Button.Left].IsPressed) xButton |= X360Button.Left; if (inputReport[Ds4Button.L1].IsPressed) xButton |= X360Button.LB; if (inputReport[Ds4Button.R1].IsPressed) xButton |= X360Button.RB; if (inputReport[Ds4Button.Triangle].IsPressed) xButton |= X360Button.Y; if (inputReport[Ds4Button.Circle].IsPressed) xButton |= X360Button.B; if (inputReport[Ds4Button.Cross].IsPressed) xButton |= X360Button.A; if (inputReport[Ds4Button.Square].IsPressed) xButton |= X360Button.X; if (inputReport[Ds4Button.Ps].IsPressed) xButton |= X360Button.Guide; if (inputReport[Ds4Button.L3].IsPressed) xButton |= X360Button.LS; if (inputReport[Ds4Button.R3].IsPressed) xButton |= X360Button.RS; output[(uint) X360Axis.BT_Lo] = (byte) ((uint) xButton >> 0 & 0xFF); output[(uint) X360Axis.BT_Hi] = (byte) ((uint) xButton >> 8 & 0xFF); output[(uint) X360Axis.LT] = inputReport[Ds4Axis.L2].Value; output[(uint) X360Axis.RT] = inputReport[Ds4Axis.R2].Value; if (!DeadZone(GlobalConfiguration.Instance.DeadZoneL, inputReport[Ds4Axis.Lx].Value, inputReport[Ds4Axis.Ly].Value)) // Left Stick DeadZone { var thumbLx = +Scale(inputReport[Ds4Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX); var thumbLy = -Scale(inputReport[Ds4Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY); output[(uint) X360Axis.LX_Lo] = (byte) ((thumbLx >> 0) & 0xFF); // LX output[(uint) X360Axis.LX_Hi] = (byte) ((thumbLx >> 8) & 0xFF); output[(uint) X360Axis.LY_Lo] = (byte) ((thumbLy >> 0) & 0xFF); // LY output[(uint) X360Axis.LY_Hi] = (byte) ((thumbLy >> 8) & 0xFF); } if (!DeadZone(GlobalConfiguration.Instance.DeadZoneR, inputReport[Ds4Axis.Rx].Value, inputReport[Ds4Axis.Ry].Value)) // Right Stick DeadZone { var thumbRx = +Scale(inputReport[Ds4Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX); var thumbRy = -Scale(inputReport[Ds4Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY); output[(uint) X360Axis.RX_Lo] = (byte) ((thumbRx >> 0) & 0xFF); // RX output[(uint) X360Axis.RX_Hi] = (byte) ((thumbRx >> 8) & 0xFF); output[(uint) X360Axis.RY_Lo] = (byte) ((thumbRy >> 0) & 0xFF); // RY output[(uint) X360Axis.RY_Hi] = (byte) ((thumbRy >> 8) & 0xFF); } } break; } } }
/// <summary> /// Translates an <see cref="ScpHidReport"/> to an Xbox 360 compatible byte array. /// </summary> /// <param name="inputReport">The <see cref="ScpHidReport"/> to translate.</param> /// <param name="output">The target Xbox data array.</param> public void Parse(ScpHidReport inputReport, byte[] output) { var input = inputReport.RawBytes; var serial = IndexToSerial(input[0]); for (var index = 0; index < ReportSize; index++) { output[index] = 0x00; } output[0] = 0x1C; output[4] = (byte)((serial >> 0) & 0xFF); output[5] = (byte)((serial >> 8) & 0xFF); output[6] = (byte)((serial >> 16) & 0xFF); output[7] = (byte)((serial >> 24) & 0xFF); output[9] = 0x14; var xButton = X360Button.None; if (inputReport.PadState == DsState.Connected) // Pad is active { switch (inputReport.Model) { case DsModel.DS3: { // select & start if (inputReport[Ds3Button.Select].IsPressed) { xButton |= X360Button.Back; } if (inputReport[Ds3Button.Start].IsPressed) { xButton |= X360Button.Start; } // d-pad if (inputReport[Ds3Button.Up].IsPressed) { xButton |= X360Button.Up; } if (inputReport[Ds3Button.Right].IsPressed) { xButton |= X360Button.Right; } if (inputReport[Ds3Button.Down].IsPressed) { xButton |= X360Button.Down; } if (inputReport[Ds3Button.Left].IsPressed) { xButton |= X360Button.Left; } // shoulders if (inputReport[Ds3Button.L1].IsPressed) { xButton |= X360Button.LB; } if (inputReport[Ds3Button.R1].IsPressed) { xButton |= X360Button.RB; } // face buttons if (inputReport[Ds3Button.Triangle].IsPressed) { xButton |= X360Button.Y; } if (inputReport[Ds3Button.Circle].IsPressed) { xButton |= X360Button.B; } if (inputReport[Ds3Button.Cross].IsPressed) { xButton |= X360Button.A; } if (inputReport[Ds3Button.Square].IsPressed) { xButton |= X360Button.X; } // PS/Guide if (inputReport[Ds3Button.Ps].IsPressed) { xButton |= X360Button.Guide; } // thumbs if (inputReport[Ds3Button.L3].IsPressed) { xButton |= X360Button.LS; } if (inputReport[Ds3Button.R3].IsPressed) { xButton |= X360Button.RS; } output[(uint)X360Axis.BT_Lo] = (byte)((uint)xButton >> 0 & 0xFF); output[(uint)X360Axis.BT_Hi] = (byte)((uint)xButton >> 8 & 0xFF); // trigger output[(uint)X360Axis.LT] = inputReport[Ds3Axis.L2].Value; output[(uint)X360Axis.RT] = inputReport[Ds3Axis.R2].Value; if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL, inputReport[Ds3Axis.Lx].Value, inputReport[Ds3Axis.Ly].Value)) // Left Stick DeadZone { var thumbLx = +DsMath.Scale(inputReport[Ds3Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX); var thumbLy = -DsMath.Scale(inputReport[Ds3Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY); output[(uint)X360Axis.LX_Lo] = (byte)((thumbLx >> 0) & 0xFF); // LX output[(uint)X360Axis.LX_Hi] = (byte)((thumbLx >> 8) & 0xFF); output[(uint)X360Axis.LY_Lo] = (byte)((thumbLy >> 0) & 0xFF); // LY output[(uint)X360Axis.LY_Hi] = (byte)((thumbLy >> 8) & 0xFF); } if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR, inputReport[Ds3Axis.Rx].Value, inputReport[Ds3Axis.Ry].Value)) // Right Stick DeadZone { var thumbRx = +DsMath.Scale(inputReport[Ds3Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX); var thumbRy = -DsMath.Scale(inputReport[Ds3Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY); output[(uint)X360Axis.RX_Lo] = (byte)((thumbRx >> 0) & 0xFF); // RX output[(uint)X360Axis.RX_Hi] = (byte)((thumbRx >> 8) & 0xFF); output[(uint)X360Axis.RY_Lo] = (byte)((thumbRy >> 0) & 0xFF); // RY output[(uint)X360Axis.RY_Hi] = (byte)((thumbRy >> 8) & 0xFF); } } break; case DsModel.DS4: { if (inputReport[Ds4Button.Share].IsPressed) { xButton |= X360Button.Back; } if (inputReport[Ds4Button.Options].IsPressed) { xButton |= X360Button.Start; } if (inputReport[Ds4Button.Up].IsPressed) { xButton |= X360Button.Up; } if (inputReport[Ds4Button.Right].IsPressed) { xButton |= X360Button.Right; } if (inputReport[Ds4Button.Down].IsPressed) { xButton |= X360Button.Down; } if (inputReport[Ds4Button.Left].IsPressed) { xButton |= X360Button.Left; } if (inputReport[Ds4Button.L1].IsPressed) { xButton |= X360Button.LB; } if (inputReport[Ds4Button.R1].IsPressed) { xButton |= X360Button.RB; } if (inputReport[Ds4Button.Triangle].IsPressed) { xButton |= X360Button.Y; } if (inputReport[Ds4Button.Circle].IsPressed) { xButton |= X360Button.B; } if (inputReport[Ds4Button.Cross].IsPressed) { xButton |= X360Button.A; } if (inputReport[Ds4Button.Square].IsPressed) { xButton |= X360Button.X; } if (inputReport[Ds4Button.Ps].IsPressed) { xButton |= X360Button.Guide; } if (inputReport[Ds4Button.L3].IsPressed) { xButton |= X360Button.LS; } if (inputReport[Ds4Button.R3].IsPressed) { xButton |= X360Button.RS; } output[(uint)X360Axis.BT_Lo] = (byte)((uint)xButton >> 0 & 0xFF); output[(uint)X360Axis.BT_Hi] = (byte)((uint)xButton >> 8 & 0xFF); output[(uint)X360Axis.LT] = inputReport[Ds4Axis.L2].Value; output[(uint)X360Axis.RT] = inputReport[Ds4Axis.R2].Value; if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL, inputReport[Ds4Axis.Lx].Value, inputReport[Ds4Axis.Ly].Value)) // Left Stick DeadZone { var thumbLx = +DsMath.Scale(inputReport[Ds4Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX); var thumbLy = -DsMath.Scale(inputReport[Ds4Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY); output[(uint)X360Axis.LX_Lo] = (byte)((thumbLx >> 0) & 0xFF); // LX output[(uint)X360Axis.LX_Hi] = (byte)((thumbLx >> 8) & 0xFF); output[(uint)X360Axis.LY_Lo] = (byte)((thumbLy >> 0) & 0xFF); // LY output[(uint)X360Axis.LY_Hi] = (byte)((thumbLy >> 8) & 0xFF); } if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR, inputReport[Ds4Axis.Rx].Value, inputReport[Ds4Axis.Ry].Value)) // Right Stick DeadZone { var thumbRx = +DsMath.Scale(inputReport[Ds4Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX); var thumbRy = -DsMath.Scale(inputReport[Ds4Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY); output[(uint)X360Axis.RX_Lo] = (byte)((thumbRx >> 0) & 0xFF); // RX output[(uint)X360Axis.RX_Hi] = (byte)((thumbRx >> 8) & 0xFF); output[(uint)X360Axis.RY_Lo] = (byte)((thumbRy >> 0) & 0xFF); // RY output[(uint)X360Axis.RY_Hi] = (byte)((thumbRy >> 8) & 0xFF); } } break; } } }
protected override void OnHidReportReceived(object sender, ScpHidReport e) { // get current pad ID var serial = (int)e.PadId; // get cached status data var report = _cache[serial].Report; var rumble = _cache[serial].Rumble; // pass current report through user profiles DualShockProfileManager.Instance.PassThroughAllProfiles(e); // pass current report through user scripts ScpMapperPlugins.Instance.Process(e); // translate current report to Xbox format _scpBus.Parse(e, report); if (_scpBus.Report(report, rumble) && e.PadState == DsState.Connected) { var large = rumble[3]; var small = rumble[4]; if (rumble[1] == 0x08 && (large != _mXInput[serial][0] || small != _mXInput[serial][1])) { _mXInput[serial][0] = large; _mXInput[serial][1] = small; Pads[serial].Rumble(large, small); } } if (e.PadState != DsState.Connected) { // reset rumble/vibration to off state _mXInput[serial][0] = _mXInput[serial][1] = 0; _mNative[serial][0] = _mNative[serial][1] = 0; if (GlobalConfiguration.Instance.AlwaysDisconnectVirtualBusDevice) { _scpBus.Unplug(_scpBus.IndexToSerial((byte)e.PadId)); } } // skip broadcast if native feed is disabled if (GlobalConfiguration.Instance.DisableNative) { return; } // send native controller inputs to subscribed clients foreach ( var channel in _nativeFeedSubscribers.Select(nativeFeedSubscriber => nativeFeedSubscriber.Value)) { try { channel.SendAsync(e.RawBytes); } catch (AggregateException) { /* This might happen if the client disconnects while sending the * response is still in progress. The exception can be ignored. */ } } }
private bool ReportToBuffer(ScpHidReport hidReport, byte[] outputData, ref int outIdx) { switch (hidReport.Model) { case DsModel.DS3: { outputData[outIdx] = 0; if (hidReport[Ds3Button.Left].IsPressed) { outputData[outIdx] |= 0x80; } if (hidReport[Ds3Button.Down].IsPressed) { outputData[outIdx] |= 0x40; } if (hidReport[Ds3Button.Right].IsPressed) { outputData[outIdx] |= 0x20; } if (hidReport[Ds3Button.Up].IsPressed) { outputData[outIdx] |= 0x10; } if (hidReport[Ds3Button.Start].IsPressed) { outputData[outIdx] |= 0x08; } if (hidReport[Ds3Button.R3].IsPressed) { outputData[outIdx] |= 0x04; } if (hidReport[Ds3Button.L3].IsPressed) { outputData[outIdx] |= 0x02; } if (hidReport[Ds3Button.Select].IsPressed) { outputData[outIdx] |= 0x01; } outputData[++outIdx] = 0; if (hidReport[Ds3Button.Square].IsPressed) { outputData[outIdx] |= 0x80; } if (hidReport[Ds3Button.Cross].IsPressed) { outputData[outIdx] |= 0x40; } if (hidReport[Ds3Button.Circle].IsPressed) { outputData[outIdx] |= 0x20; } if (hidReport[Ds3Button.Triangle].IsPressed) { outputData[outIdx] |= 0x10; } if (hidReport[Ds3Button.R1].IsPressed) { outputData[outIdx] |= 0x08; } if (hidReport[Ds3Button.L1].IsPressed) { outputData[outIdx] |= 0x04; } if (!GlobalConfiguration.Instance.SwapTriggers) { if (hidReport[Ds3Button.R2].IsPressed) { outputData[outIdx] |= 0x02; } if (hidReport[Ds3Button.L2].IsPressed) { outputData[outIdx] |= 0x01; } } else { if (hidReport[Ds3Button.L2].IsPressed) { outputData[outIdx] |= 0x01; } if (hidReport[Ds3Button.R2].IsPressed) { outputData[outIdx] |= 0x02; } } outputData[++outIdx] = (hidReport[Ds3Button.Ps].IsPressed) ? (byte)1 : (byte)0; outputData[++outIdx] = 0; //no Touchpad click on ds3 if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL, hidReport[Ds3Axis.Lx].Value, hidReport[Ds3Axis.Ly].Value)) { outputData[++outIdx] = hidReport[Ds3Axis.Lx].Value; if (GlobalConfiguration.Instance.FlipLX) { outputData[outIdx] = (byte)(255 - outputData[outIdx]); } outputData[++outIdx] = hidReport[Ds3Axis.Ly].Value; if (!GlobalConfiguration.Instance.FlipLY) { outputData[outIdx] = (byte)(255 - outputData[outIdx]); } } else { outputData[++outIdx] = 0x7F; outputData[++outIdx] = 0x7F; } if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR, hidReport[Ds3Axis.Rx].Value, hidReport[Ds3Axis.Ry].Value)) { outputData[++outIdx] = hidReport[Ds3Axis.Rx].Value; if (GlobalConfiguration.Instance.FlipRX) { outputData[outIdx] = (byte)(255 - outputData[outIdx]); } outputData[++outIdx] = hidReport[Ds3Axis.Ry].Value; if (!GlobalConfiguration.Instance.FlipRY) { outputData[outIdx] = (byte)(255 - outputData[outIdx]); } } else { outputData[++outIdx] = 0x7F; outputData[++outIdx] = 0x7F; } //Analog buttons outputData[++outIdx] = hidReport[Ds3Axis.Left].Value; outputData[++outIdx] = hidReport[Ds3Axis.Down].Value; outputData[++outIdx] = hidReport[Ds3Axis.Right].Value; outputData[++outIdx] = hidReport[Ds3Axis.Up].Value; outputData[++outIdx] = hidReport[Ds3Axis.Square].Value; outputData[++outIdx] = hidReport[Ds3Axis.Cross].Value; outputData[++outIdx] = hidReport[Ds3Axis.Circle].Value; outputData[++outIdx] = hidReport[Ds3Axis.Triangle].Value; outputData[++outIdx] = hidReport[Ds3Axis.R1].Value; outputData[++outIdx] = hidReport[Ds3Axis.L1].Value; if (!GlobalConfiguration.Instance.SwapTriggers) { outputData[++outIdx] = hidReport[Ds3Axis.R2].Value; outputData[++outIdx] = hidReport[Ds3Axis.L2].Value; } else { outputData[++outIdx] = hidReport[Ds3Axis.L2].Value; outputData[++outIdx] = hidReport[Ds3Axis.R2].Value; } outIdx++; } break; case DsModel.DS4: { outputData[outIdx] = 0; if (hidReport[Ds4Button.Left].IsPressed) { outputData[outIdx] |= 0x80; } if (hidReport[Ds4Button.Down].IsPressed) { outputData[outIdx] |= 0x40; } if (hidReport[Ds4Button.Right].IsPressed) { outputData[outIdx] |= 0x20; } if (hidReport[Ds4Button.Up].IsPressed) { outputData[outIdx] |= 0x10; } if (hidReport[Ds4Button.Options].IsPressed) { outputData[outIdx] |= 0x08; } if (hidReport[Ds4Button.R3].IsPressed) { outputData[outIdx] |= 0x04; } if (hidReport[Ds4Button.L3].IsPressed) { outputData[outIdx] |= 0x02; } if (hidReport[Ds4Button.Share].IsPressed) { outputData[outIdx] |= 0x01; } outputData[++outIdx] = 0; if (hidReport[Ds4Button.Square].IsPressed) { outputData[outIdx] |= 0x80; } if (hidReport[Ds4Button.Cross].IsPressed) { outputData[outIdx] |= 0x40; } if (hidReport[Ds4Button.Circle].IsPressed) { outputData[outIdx] |= 0x20; } if (hidReport[Ds4Button.Triangle].IsPressed) { outputData[outIdx] |= 0x10; } if (hidReport[Ds4Button.R1].IsPressed) { outputData[outIdx] |= 0x08; } if (hidReport[Ds4Button.L1].IsPressed) { outputData[outIdx] |= 0x04; } if (!GlobalConfiguration.Instance.SwapTriggers) { if (hidReport[Ds4Button.R2].IsPressed) { outputData[outIdx] |= 0x02; } if (hidReport[Ds4Button.L2].IsPressed) { outputData[outIdx] |= 0x01; } } else { if (hidReport[Ds4Button.L2].IsPressed) { outputData[outIdx] |= 0x01; } if (hidReport[Ds4Button.R2].IsPressed) { outputData[outIdx] |= 0x02; } } outputData[++outIdx] = (hidReport[Ds4Button.Ps].IsPressed) ? (byte)1 : (byte)0; outputData[++outIdx] = (hidReport[Ds4Button.TouchPad].IsPressed) ? (byte)1 : (byte)0; if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL, hidReport[Ds4Axis.Lx].Value, hidReport[Ds4Axis.Ly].Value)) { outputData[++outIdx] = hidReport[Ds4Axis.Lx].Value; if (GlobalConfiguration.Instance.FlipLX) { outputData[outIdx] = (byte)(255 - outputData[outIdx]); } outputData[++outIdx] = hidReport[Ds4Axis.Ly].Value; if (!GlobalConfiguration.Instance.FlipLY) { outputData[outIdx] = (byte)(255 - outputData[outIdx]); } } else { outputData[++outIdx] = 0x7F; outputData[++outIdx] = 0x7F; } if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR, hidReport[Ds4Axis.Rx].Value, hidReport[Ds4Axis.Ry].Value)) { outputData[++outIdx] = hidReport[Ds4Axis.Rx].Value; if (GlobalConfiguration.Instance.FlipRX) { outputData[outIdx] = (byte)(255 - outputData[outIdx]); } outputData[++outIdx] = hidReport[Ds4Axis.Ry].Value; if (!GlobalConfiguration.Instance.FlipRY) { outputData[outIdx] = (byte)(255 - outputData[outIdx]); } } else { outputData[++outIdx] = 0x7F; outputData[++outIdx] = 0x7F; } //we don't have analog buttons so just use the Button enums (which give either 0 or 0xFF) outputData[++outIdx] = hidReport[Ds4Button.Left].Value; outputData[++outIdx] = hidReport[Ds4Button.Down].Value; outputData[++outIdx] = hidReport[Ds4Button.Right].Value; outputData[++outIdx] = hidReport[Ds4Button.Up].Value; outputData[++outIdx] = hidReport[Ds4Button.Square].Value; outputData[++outIdx] = hidReport[Ds4Button.Cross].Value; outputData[++outIdx] = hidReport[Ds4Button.Circle].Value; outputData[++outIdx] = hidReport[Ds4Button.Triangle].Value; outputData[++outIdx] = hidReport[Ds4Button.R1].Value; outputData[++outIdx] = hidReport[Ds4Button.L1].Value; if (!GlobalConfiguration.Instance.SwapTriggers) { outputData[++outIdx] = hidReport[Ds4Axis.R2].Value; outputData[++outIdx] = hidReport[Ds4Axis.L2].Value; } else { outputData[++outIdx] = hidReport[Ds4Axis.L2].Value; outputData[++outIdx] = hidReport[Ds4Axis.R2].Value; } outIdx++; } break; default: return(false); //we only support DS3 and DS4 } //DS4 only: touchpad points for (int i = 0; i < 2; i++) { var tpad = hidReport.TrackPadTouch0; if (tpad != null && i > 0) { tpad = hidReport.TrackPadTouch1; } if (tpad != null) { outputData[outIdx++] = tpad.IsActive ? (byte)1 : (byte)0; outputData[outIdx++] = (byte)tpad.Id; Array.Copy(BitConverter.GetBytes((ushort)tpad.X), 0, outputData, outIdx, 2); outIdx += 2; Array.Copy(BitConverter.GetBytes((ushort)tpad.Y), 0, outputData, outIdx, 2); outIdx += 2; } else { outIdx += 6; } } //motion timestamp Array.Copy(BitConverter.GetBytes((ulong)hidReport.Timestamp), 0, outputData, outIdx, 8); outIdx += 8; //accelerometer { var accel = hidReport.Accelerometer; if (accel != null) { Array.Copy(BitConverter.GetBytes((float)accel.X), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes((float)accel.Y), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes((float)accel.Z), 0, outputData, outIdx, 4); outIdx += 4; } else { outIdx += 12; } } //gyroscope { var gyro = hidReport.Gyroscope; if (gyro != null) { Array.Copy(BitConverter.GetBytes((float)gyro.Pitch), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes((float)gyro.Yaw), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes((float)gyro.Roll), 0, outputData, outIdx, 4); outIdx += 4; } else { outIdx += 12; } } return(true); }