private void ProxyOnNativeFeedReceived(object sender, ScpHidReport report) { if (_vm.CurrentProfile == null) return; 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; } }
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); } }
/// <summary> /// Applies button re-mapping to the supplied report. /// </summary> /// <param name="report">The report to manipulate.</param> public void Remap(ScpHidReport report) { // skip disabled mapping if (!IsEnabled) { return; } switch (MappingTarget.CommandType) { case CommandType.GamepadButton: foreach (var button in SourceButtons) { // turbo is special, apply first if (Turbo.IsEnabled) { Turbo.ApplyOn(report, button); } // get target button IDsButton target = MappingTarget.CommandTarget as Ds3Button; // if target is no valid button or none, skip setting it if (target == null) { continue; } // if it's a DS4, translate button if (report.Model == DsModel.DS4) { target = Ds4Button.Buttons.First(b => b.Name.Equals(target.Name)); } // if original isn't pressed we can ignore if (!report[button].IsPressed) { continue; } // unset original button report.Unset(button); // set new button report.Set(target); } break; } }
/// <summary> /// Applies button re-mapping to the supplied report. /// </summary> /// <param name="report">The report to manipulate.</param> public void Remap(ScpHidReport report) { // determine if profile should be applied switch (Match) { case DsMatch.Global: // always apply break; case DsMatch.Mac: // applies of MAC address matches var reportMac = report.PadMacAddress.ToString(); if (string.CompareOrdinal(MacAddress.Replace(":", string.Empty), reportMac) != 0) { return; } break; case DsMatch.None: // never apply return; case DsMatch.Pad: // applies if pad IDs match if (PadId != report.PadId) { return; } break; } // walk through all buttons foreach (var buttonProfile in Buttons) { buttonProfile.Remap(report); } }
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; } } } }
/// <summary> /// Applies turbo algorithm for a specified <see cref="IDsButton" /> on a given <see cref="ScpHidReport" />. /// </summary> /// <param name="report">The HID report to manipulate.</param> /// <param name="button">The button to trigger turbo on.</param> public void ApplyOn(ScpHidReport report, IDsButton button) { // button type must match model, madness otherwise! if ((report.Model != DsModel.DS3 || !(button is Ds3Button)) && (report.Model != DsModel.DS4 || !(button is Ds4Button))) return; // if button got released... if (_isActive && !report[button].IsPressed) { // ...disable, reset and return _isActive = false; _delayedFrame.Reset(); _engagedFrame.Reset(); _releasedFrame.Reset(); return; } // if turbo is enabled and button is pressed... if (!_isActive && report[button].IsPressed) { // ...start calculating the activation delay... if (!_delayedFrame.IsRunning) _delayedFrame.Restart(); // ...if we are still activating, don't do anything if (_delayedFrame.ElapsedMilliseconds < Delay) return; // time to activate! _isActive = true; _delayedFrame.Reset(); } // if the button was released... if (!report[button].IsPressed) { // ...restore default states and skip processing _isActive = false; return; } // reset engaged ("keep pressed") time frame... if (!_engagedFrame.IsRunning) _engagedFrame.Restart(); // ...do not change state while within frame and button is still pressed, then skip if (_engagedFrame.ElapsedMilliseconds < Interval && report[button].IsPressed) return; // reset released time frame ("forecefully release") for button if (!_releasedFrame.IsRunning) _releasedFrame.Restart(); // while we're still within the released time frame... if (_releasedFrame.ElapsedMilliseconds < Release) { // ...re-set the button state to released report.Unset(button); } else { // all frames passed, reset and start over _isActive = false; _delayedFrame.Stop(); _engagedFrame.Stop(); _releasedFrame.Stop(); } }
/// <summary> /// Applies button re-mapping to the supplied report. /// </summary> /// <param name="report">The report to manipulate.</param> public void Remap(ScpHidReport report) { // skip disabled mapping if (!IsEnabled) return; switch (MappingTarget.CommandType) { case CommandType.GamepadButton: foreach (var button in SourceButtons) { // turbo is special, apply first if (Turbo.IsEnabled) { Turbo.ApplyOn(report, button); } // get target button IDsButton target = MappingTarget.CommandTarget as Ds3Button; // if target is no valid button or none, skip setting it if (target == null) continue; // if it's a DS4, translate button if (report.Model == DsModel.DS4) { target = Ds4Button.Buttons.First(b => b.Name.Equals(target.Name)); } // if original isn't pressed we can ignore if (!report[button].IsPressed) continue; // unset original button report.Unset(button); // set new button report.Set(target); } break; case CommandType.Keystrokes: foreach (var button in SourceButtons) { var target = (VirtualKeyCode) Enum.ToObject(typeof(VirtualKeyCode), MappingTarget.CommandTarget); if (report[button].IsPressed) { VirtualInput.Keyboard.KeyDown(target); } else { VirtualInput.Keyboard.KeyUp(target); } } break; } }
/// <summary> /// Applies button re-mapping to the supplied report. /// </summary> /// <param name="report">The report to manipulate.</param> public void Remap(ScpHidReport report) { // determine if profile should be applied switch (Match) { case DsMatch.Global: // always apply break; case DsMatch.Mac: // applies of MAC address matches var reportMac = report.PadMacAddress.ToString(); if (string.CompareOrdinal(MacAddress.Replace(":", string.Empty), reportMac) != 0) return; break; case DsMatch.None: // never apply return; case DsMatch.Pad: // applies if pad IDs match if (PadId != report.PadId) return; break; } // walk through all buttons foreach (var buttonProfile in Buttons) { buttonProfile.Remap(report); } }
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); } }
private bool CheckDpadDs4(ScpHidReport Data, DSButton parButton) { if (parButton.DS4 != null) { return Data[parButton.DS4].IsPressed; } else { return false; } }
protected void OnHidReportReceived(ScpHidReport report) { _inputReportQueue.Enqueue(() => Task.Run(() => { if (HidReportReceived != null) HidReportReceived.Invoke(this, report); })); }
/// <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; } } }
/// <summary> /// Applies turbo algorithm for a specified <see cref="IDsButton" /> on a given <see cref="ScpHidReport" />. /// </summary> /// <param name="report">The HID report to manipulate.</param> /// <param name="button">The button to trigger turbo on.</param> public void ApplyOn(ScpHidReport report, IDsButton button) { // button type must match model, madness otherwise! if ((report.Model != DsModel.DS3 || !(button is Ds3Button)) && (report.Model != DsModel.DS4 || !(button is Ds4Button))) { return; } // if button got released... if (_isActive && !report[button].IsPressed) { // ...disable, reset and return _isActive = false; _delayedFrame.Reset(); _engagedFrame.Reset(); _releasedFrame.Reset(); return; } // if turbo is enabled and button is pressed... if (!_isActive && report[button].IsPressed) { // ...start calculating the activation delay... if (!_delayedFrame.IsRunning) { _delayedFrame.Restart(); } // ...if we are still activating, don't do anything if (_delayedFrame.ElapsedMilliseconds < Delay) { return; } // time to activate! _isActive = true; _delayedFrame.Reset(); } // if the button was released... if (!report[button].IsPressed) { // ...restore default states and skip processing _isActive = false; return; } // reset engaged ("keep pressed") time frame... if (!_engagedFrame.IsRunning) { _engagedFrame.Restart(); } // ...do not change state while within frame and button is still pressed, then skip if (_engagedFrame.ElapsedMilliseconds < Interval && report[button].IsPressed) { return; } // reset released time frame ("forecefully release") for button if (!_releasedFrame.IsRunning) { _releasedFrame.Restart(); } // while we're still within the released time frame... if (_releasedFrame.ElapsedMilliseconds < Release) { // ...re-set the button state to released report.Unset(button); } else { // all frames passed, reset and start over _isActive = false; _delayedFrame.Stop(); _engagedFrame.Stop(); _releasedFrame.Stop(); } }
/// <summary> /// Applies button re-mapping to the supplied report. /// </summary> /// <param name="report">The report to manipulate.</param> public void Remap(ScpHidReport report) { // skip disabled mapping if (!IsEnabled) { return; } switch (MappingTarget.CommandType) { case CommandType.GamepadButton: foreach (var button in SourceButtons) { // turbo is special, apply first if (Turbo.IsEnabled) { Turbo.ApplyOn(report, button); } // get target button IDsButton target = MappingTarget.CommandTarget as Ds3Button; // if target is no valid button or none, skip setting it if (target == null) { continue; } // if it's a DS4, translate button if (report.Model == DsModel.DS4) { target = Ds4Button.Buttons.First(b => b.Name.Equals(target.Name)); } // if original isn't pressed we can ignore if (!report.HidReport[button].IsPressed) { continue; } // unset original button //TODO: zzz rewrite mapper ((HidReport.Core.HidReport)report.HidReport).Unset(button); // set new button //((HidReport.Core.HidReport)report.HidReport).Set(target); } break; case CommandType.Keystrokes: foreach (var button in SourceButtons) { var target = (VirtualKeyCode)Enum.ToObject(typeof(VirtualKeyCode), MappingTarget.CommandTarget); if (report.HidReport[button].IsPressed) { VirtualInput.Keyboard.KeyDown(target); } else { VirtualInput.Keyboard.KeyUp(target); } } break; } }
private void OnFeedPacketReceived(ScpHidReport data) { _packetCache[data.PadId] = data; if (NativeFeedReceived != null) { NativeFeedReceived(this, data); } }
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; } }
protected void Parse(object sender, ScpHidReport e) { lock (this) { if (runParser & selectedPads[(int)e.PadId]) { gps.Update(e); } } }
/// <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; }