Skip to content

Commit ccd813b

Browse files
committed
feat: Add controller passthru option to GVR
Allows user to choose whether they want vibrations passed thru to the controller. Fixes #324
1 parent 94b8391 commit ccd813b

5 files changed

Lines changed: 28 additions & 5 deletions

File tree

Buttplug.Apps.GameVibrationRouter.GUI/MainWindow.xaml.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public MainWindow()
7272
ButtplugTab.SelectedDevicesChanged += OnSelectedDevicesChanged;
7373

7474
_graphTab.MultiplierChanged += MultiplierChanged;
75+
_graphTab.PassthruChanged += PassthruChanged;
7576

7677
var config = new ButtplugConfig("Buttplug");
7778
ButtplugTab.GetAboutControl().CheckUpdate(config, "buttplug-csharp");
@@ -90,6 +91,11 @@ private void MultiplierChanged(object sender, double vibeMultiplier)
9091
_vibrationMultiplier = vibeMultiplier;
9192
}
9293

94+
private void PassthruChanged(object sender, bool shouldPassthru)
95+
{
96+
ButtplugGameVibrationRouterInterface._shouldPassthru = shouldPassthru;
97+
}
98+
9399
public void AddPoint(object o, ElapsedEventArgs e)
94100
{
95101
_graphTab.AddVibrationValue(_lastVibration.LeftMotorSpeed, _lastVibration.RightMotorSpeed);

Buttplug.Apps.GameVibrationRouter.GUI/VibeGraphTab.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<TextBlock Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding ElementName=multiplierSlider, Path=Value, StringFormat='x\{0:0.0\}'}" Height="16" Margin="15.333,0,14,0.333" Width="auto"></TextBlock>
3131
</Grid>
3232
</GroupBox>
33+
<CheckBox Name="PassthruCheckBox" Grid.Row="1" Content="Pass Gamepad Rumble To Gamepad" IsChecked="True" HorizontalAlignment="Left" Margin="0,5,0,5" VerticalAlignment="Stretch" Checked="PassthruCheckBox_Changed" Unchecked="PassthruCheckBox_Changed" />
3334
</Grid>
3435
<wpf:CartesianChart Name="LowPowerChart" Grid.Row="1" Series="{Binding LowPowerSeriesCollection}" Background="Black" DisableAnimations="True" Hoverable="False" DataTooltip="{x:Null}">
3536
<wpf:CartesianChart.AxisY>

Buttplug.Apps.GameVibrationRouter.GUI/VibeGraphTab.xaml.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public partial class VibeGraphTab : UserControl
2424
private readonly ChartValues<double> LowPowerValues;
2525
private readonly ChartValues<double> HighPowerValues;
2626
public event EventHandler<double> MultiplierChanged;
27+
public event EventHandler<bool> PassthruChanged;
2728

2829
public VibeGraphTab()
2930
{
@@ -84,7 +85,11 @@ public void AddVibrationValue(double aLowPower, double aHighPower)
8485
// Usually means we're shutting down. noop.
8586
}
8687
}
87-
88+
89+
private void PassthruCheckBox_Changed(object aSender, RoutedEventArgs aArgs)
90+
{
91+
PassthruChanged?.Invoke(this, PassthruCheckBox.IsChecked.Value);
92+
}
8893

8994
private void multiplierSlider_ValueChanged(object aSender, System.Windows.RoutedPropertyChangedEventArgs<double> aArgs)
9095
{

Buttplug.Apps.GameVibrationRouter.Interface/ButtplugGameVibrationRouterInterface.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ public class ButtplugGameVibrationRouterInterface : MarshalByRefObject
3737
private static bool _shouldStop;
3838

3939
private Timer _exitTimer = new Timer();
40-
private bool _hasPinged = false;
40+
public static bool _shouldPassthru = true;
41+
private bool _hasPinged;
4142
public ButtplugGameVibrationRouterInterface()
4243
{
4344
// Every time we create a new instance, reset the static stopping variable.
4445
_shouldStop = false;
46+
_shouldPassthru = true;
4547
// Check 4 times a second
4648
_exitTimer.Interval = 250;
4749
_exitTimer.Enabled = true;
@@ -59,6 +61,11 @@ private void OnTimerElapsed(object aObj, EventArgs aEventArgs)
5961
_hasPinged = false;
6062
}
6163

64+
public bool ShouldPassthru()
65+
{
66+
return _shouldPassthru;
67+
}
68+
6269
public void Exit()
6370
{
6471
VibrationExitReceived?.Invoke(this, true);

Buttplug.Apps.GameVibrationRouter.Payload/ButtplugGameVibrationRouterPayload.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class ButtplugGameVibrationRouterPayload : IEntryPoint
1212
private readonly ButtplugGameVibrationRouterInterface _interface;
1313
private LocalHook _xinputSetStateHookObj;
1414
private Vibration _lastMessage = new Vibration {LeftMotorSpeed = 65535, RightMotorSpeed = 65535};
15+
private static bool _shouldPassthru = true;
1516
private readonly Queue<Vibration> _messageQueue = new Queue<Vibration>();
1617
private static Exception _ex;
1718
private static ButtplugGameVibrationRouterPayload _instance;
@@ -72,7 +73,7 @@ public void Run(
7273
while (_interface.Ping(RemoteHooking.GetCurrentProcessId(), ""))
7374
{
7475
Thread.Sleep(1);
75-
76+
_shouldPassthru = _interface.ShouldPassthru();
7677
if (_messageQueue.Count > 0)
7778
{
7879
lock (_messageQueue)
@@ -127,8 +128,11 @@ private static uint XInputSetStateHookFunc(int aGamePadIndex, ref Vibration aVib
127128
try
128129
{
129130
// Always send to the controller first, then do what we need to.
130-
XInputSetStateShim(aGamePadIndex, aVibrationRef);
131-
131+
if (_shouldPassthru)
132+
{
133+
XInputSetStateShim(aGamePadIndex, aVibrationRef);
134+
}
135+
132136
ButtplugGameVibrationRouterPayload This = _instance;
133137
// No reason to send duplicate packets.
134138
if (This._lastMessage.LeftMotorSpeed == aVibrationRef.LeftMotorSpeed &&

0 commit comments

Comments
 (0)