/// <summary> /// Feeds the supplied HID report through all loaded mapping profiles. /// </summary> /// <param name="report">The extended HID report.</param> public void PassThroughAllProfiles(ScpHidReport report) { foreach (var profile in Profiles.Where(p => p.IsActive)) { profile.Remap(report); } }
/// <summary> /// Applies button re-mapping to the supplied report. /// </summary> /// <param name="report">The report to manipulate.</param> public void Remap(ScpHidReport report) { foreach (var buttonProfile in Buttons) { buttonProfile.Remap(report); } }
/// <summary> /// Feeds the supplied HID report through all loaded mapping profiles. /// </summary> /// <param name="report">The extended HID report.</param> public void PassThroughAllProfiles(ScpHidReport report) { foreach (var profile in Profiles) { profile.Remap(report); } }
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; } }
/// <summary> /// Feeds the supplied HID report through all loaded mapping profiles. /// </summary> /// <param name="report">The extended HID report.</param> public void PassThroughAllProfiles(ScpHidReport report) { try { foreach (var profile in Profiles.Where(p => p.IsActive)) { profile.Remap(report); } } catch // TODO: remove! { } }
/// <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; } //scpProxy.Remap(m_SelectedProfile, e); 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; } }
protected virtual void OnHidReportReceived(object sender, ScpHidReport e) { if (Report != null) Report(sender, e); }
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]; }
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; 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. */ } } }
/// <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); } }
/// <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(); } }
public void ApplyOn(ScpHidReport report, IDsButton button) { 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) { if (!_delayedFrame.IsRunning) _delayedFrame.Restart(); if (_delayedFrame.ElapsedMilliseconds < Delay) return; // time to activate! _isActive = true; _delayedFrame.Reset(); } // if the button was released... if (!report[button].IsPressed) { // ...restore default states _isActive = false; return; } if (!_engagedFrame.IsRunning) _engagedFrame.Restart(); if (_engagedFrame.ElapsedMilliseconds < Interval && report[button].IsPressed) return; if (!_releasedFrame.IsRunning) _releasedFrame.Restart(); if (_releasedFrame.ElapsedMilliseconds < Release) { report.Unset(button); } else { _isActive = false; _delayedFrame.Stop(); _engagedFrame.Stop(); _releasedFrame.Stop(); } }
private void OnFeedPacketReceived(ScpHidReport data) { _packetCache[data.PadId] = data.CopyHidReport(); if (NativeFeedReceived != null) { NativeFeedReceived(this, data); } }