Skip to content

Commit

Permalink
Add sensitivity control to AxisDialButtonAction
Browse files Browse the repository at this point in the history
The AxisDialButtonAction now supports sensitivity control for more granular adjustment of input. Sensitivity UI has been added to the property inspector. This update also includes relevant event handlers and calls for the new feature within AxisDialButtonAction and SimpleVJoyInterface classes. Moreover, a few asynchronous functions have been updated in SimpleButtonAction and ToggleButtonAction classes.
  • Loading branch information
bastianh committed Apr 2, 2024
1 parent 9ed9656 commit c4ce7cd
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 59 deletions.
47 changes: 33 additions & 14 deletions streamdeck-vjoy-w4rl0ck/Actions/AxisDialButtonAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class AxisDialButtonAction : KeyAndEncoderBase
private readonly PluginSettings settings;
private uint _vJoyId;
private ushort _axis;
private ushort _sensitivity;
private bool _propertyInspectorIsOpen;

#endregion
Expand All @@ -27,6 +28,7 @@ public AxisDialButtonAction(SDConnection connection, InitialPayload payload) : b
Connection.OnPropertyInspectorDidAppear += Connection_OnPropertyInspectorDidAppear;
Connection.OnPropertyInspectorDidDisappear += Connection_OnPropertyInspectorDidDisappear;
SimpleVJoyInterface.VJoyStatusSignal += SimpleVJoyInterface_OnVJoyStatusSignal;
SimpleVJoyInterface.AxisSignal += SimpleVJoyInterface_OnAxisSignal;

if (payload.Settings == null || payload.Settings.Count == 0)
{
Expand All @@ -49,24 +51,33 @@ public override void Dispose()
Connection.OnPropertyInspectorDidAppear -= Connection_OnPropertyInspectorDidAppear;
Connection.OnPropertyInspectorDidDisappear -= Connection_OnPropertyInspectorDidDisappear;
SimpleVJoyInterface.VJoyStatusSignal -= SimpleVJoyInterface_OnVJoyStatusSignal;
SimpleVJoyInterface.AxisSignal -= SimpleVJoyInterface_OnAxisSignal;
}

private void Connection_OnPropertyInspectorDidAppear(object sender, SDEventReceivedEventArgs<PropertyInspectorDidAppear> e)
private async void Connection_OnPropertyInspectorDidAppear(object sender, SDEventReceivedEventArgs<PropertyInspectorDidAppear> e)
{
SendPropertyInspectorData();
await SendPropertyInspectorData();
_propertyInspectorIsOpen = true;
}
private void Connection_OnPropertyInspectorDidDisappear(object sender, SDEventReceivedEventArgs<PropertyInspectorDidDisappear> e)
{
_propertyInspectorIsOpen = false;
}

private void SimpleVJoyInterface_OnVJoyStatusSignal(SimpleVJoyInterface.VJoyStatus status)
private async void SimpleVJoyInterface_OnVJoyStatusSignal(SimpleVJoyInterface.VJoyStatus status)
{
if (_propertyInspectorIsOpen)
SendPropertyInspectorData();
await SendPropertyInspectorData();
}
private async void SendPropertyInspectorData()

private async void SimpleVJoyInterface_OnAxisSignal(uint axis, float value)
{
if (axis != _axis) return;
var dict = new Dictionary<string, string> { { "value", value.ToString("P") } };
await Connection.SetFeedbackAsync(dict);
}

private async Task SendPropertyInspectorData()
{
var deviceList = SimpleVJoyInterface.Instance.CheckAvailableDevices();
var devices = JArray.Parse(JsonConvert.SerializeObject(deviceList));
Expand All @@ -91,16 +102,13 @@ public override void KeyReleased(KeyPayload payload)


public override void DialRotate(DialRotatePayload payload)
{
var retval = SimpleVJoyInterface.Instance.MoveAxis(_axis,payload.Ticks * 600);
Logger.Instance.LogMessage(TracingLevel.INFO, $"Dial Rotated: {payload.Ticks} {_axis}: {retval}");

var dict = new Dictionary<string, string> { { "value", retval.ToString("P") } };
Connection.SetFeedbackAsync(dict);
{
SimpleVJoyInterface.Instance.MoveAxis(_axis, payload.Ticks * _sensitivity / 100.0);
}

public override void DialDown(DialPayload payload)
{
SimpleVJoyInterface.Instance.SetAxis(_axis,0);
Logger.Instance.LogMessage(TracingLevel.INFO, "Dial Pressed");
}

Expand All @@ -122,7 +130,7 @@ public override async void ReceivedSettings(ReceivedSettingsPayload payload)
{
Tools.AutoPopulateSettings(settings, payload.Settings);
var oldVJoyId = _vJoyId;
await InitializeSettings();
InitializeSettings();
if (_vJoyId != oldVJoyId)
await Connection.SetGlobalSettingsAsync(new JObject { { "vjoy", _vJoyId } });

Expand All @@ -132,8 +140,9 @@ public override async void ReceivedSettings(ReceivedSettingsPayload payload)
public override async void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload)
{
settings.VJoyId = (string)payload.Settings["vjoy"];
await InitializeSettings();
InitializeSettings();
await SaveSettings();
await SendPropertyInspectorData();
}

#region Private Methods
Expand All @@ -143,7 +152,7 @@ private Task SaveSettings()
return Connection.SetSettingsAsync(JObject.FromObject(settings));
}

private async Task InitializeSettings()
private void InitializeSettings()
{
if (!uint.TryParse(settings.VJoyId, out _vJoyId))
{
Expand All @@ -158,6 +167,12 @@ private async Task InitializeSettings()
// todo: error state
return;
}

if (!ushort.TryParse(settings.sensitivity, out _sensitivity))
{
// todo: error state
return;
}
}

#endregion
Expand All @@ -170,11 +185,15 @@ private class PluginSettings
[JsonProperty(PropertyName = "axis")]
public string axis { get; set; }

[JsonProperty(PropertyName = "sensitivity")]
public string sensitivity { get; set; }

public static PluginSettings CreateDefaultSettings()
{
var instance = new PluginSettings();
instance.VJoyId = string.Empty;
instance.axis = "0";
instance.sensitivity = "100";
return instance;
}
}
Expand Down
18 changes: 9 additions & 9 deletions streamdeck-vjoy-w4rl0ck/Actions/SimpleButtonAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,24 @@ public override void Dispose()
SimpleVJoyInterface.VJoyStatusSignal -= SimpleVJoyInterface_OnVJoyStatusSignal;
}

private void Connection_OnPropertyInspectorDidAppear(object sender,
private async void Connection_OnPropertyInspectorDidAppear(object sender,
SDEventReceivedEventArgs<PropertyInspectorDidAppear> e)
{
SendPropertyInspectorData();
await SendPropertyInspectorData();
_propertyInspectorIsOpen = true;
}
private void Connection_OnPropertyInspectorDidDisappear(object sender, SDEventReceivedEventArgs<PropertyInspectorDidDisappear> e)
{
_propertyInspectorIsOpen = false;
}

private void SimpleVJoyInterface_OnVJoyStatusSignal(SimpleVJoyInterface.VJoyStatus status)
private async void SimpleVJoyInterface_OnVJoyStatusSignal(SimpleVJoyInterface.VJoyStatus status)
{
if (_propertyInspectorIsOpen)
SendPropertyInspectorData();
await SendPropertyInspectorData();
}

private async void SendPropertyInspectorData()
private async Task SendPropertyInspectorData()
{
var deviceList = SimpleVJoyInterface.Instance.CheckAvailableDevices();
var devices = JArray.Parse(JsonConvert.SerializeObject(deviceList));
Expand Down Expand Up @@ -89,17 +89,17 @@ public override async void ReceivedSettings(ReceivedSettingsPayload payload)
{
Tools.AutoPopulateSettings(settings, payload.Settings);
var oldVjoyId = _vJoyId;
await InitializeSettings();
InitializeSettings();
if (_vJoyId != oldVjoyId)
await Connection.SetGlobalSettingsAsync(new JObject { { "vjoy", _vJoyId } });

await SaveSettings();
}

public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload)
public override async void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload)
{
settings.VJoyId = (string)payload.Settings["vjoy"];
SaveSettings();
await SaveSettings();
}

private class PluginSettings
Expand Down Expand Up @@ -135,7 +135,7 @@ private Task SaveSettings()
return Connection.SetSettingsAsync(JObject.FromObject(settings));
}

private async Task InitializeSettings()
private void InitializeSettings()
{
if (!uint.TryParse(settings.VJoyId, out _vJoyId))
{
Expand Down
8 changes: 4 additions & 4 deletions streamdeck-vjoy-w4rl0ck/Actions/ToggleButtonAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,17 @@ public override async void ReceivedSettings(ReceivedSettingsPayload payload)
{
Tools.AutoPopulateSettings(settings, payload.Settings);
var oldVjoyId = _vJoyId;
await InitializeSettings();
InitializeSettings();
if (_vJoyId != oldVjoyId)
await Connection.SetGlobalSettingsAsync(new JObject { { "vjoy", _vJoyId } });

await SaveSettings();
}

public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload)
public override async void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload)
{
settings.VJoyId = (string)payload.Settings["vjoy"];
SaveSettings();
await SaveSettings();
}

private class PluginSettings
Expand Down Expand Up @@ -146,7 +146,7 @@ private Task SaveSettings()
return Connection.SetSettingsAsync(JObject.FromObject(settings));
}

private async Task InitializeSettings()
private void InitializeSettings()
{
if (!uint.TryParse(settings.VJoyId, out _vJoyId))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@
<option value="7">Dial (sl1)</option>
</select>
</div>

<div type="range" class="sdpi-item" id="range_with_meters">
<div class="sdpi-item-label">Sensivity</div>
<div class="sdpi-item-value">
<span class="clickable" value="50">50%</span>
<input type="range" min="50" max="400" value=100 class="sdProperty" id="sensitivity" oninput="setSettings()">
<span class="clickable" value="400">400%</span>
</div>
</div>


<div class="sdpi-heading">Global Settings</div>
<div class="sdpi-item">
Expand Down
69 changes: 37 additions & 32 deletions streamdeck-vjoy-w4rl0ck/SimpleVJoyInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace dev.w4rl0ck.streamdeck.vjoy.libs
{
public delegate void ButtonSignalHandler(uint button, bool active);

public delegate void AxisSignalHander(uint axis, float value);
public delegate void VJoyStatusSignalHandler(SimpleVJoyInterface.VJoyStatus status);

public sealed class SimpleVJoyInterface
Expand All @@ -20,9 +20,10 @@ public sealed class SimpleVJoyInterface
public uint CurrentVJoyId;
public VJoyStatus Status;

public static event AxisSignalHander AxisSignal;
public static event ButtonSignalHandler UpdateButtonSignal;
public static event VJoyStatusSignalHandler VJoyStatusSignal;
private long _maxval;
private long _maxAxisValue;

public enum ButtonAction
{
Expand Down Expand Up @@ -114,45 +115,49 @@ private void ChangeStatus(VJoyStatus status)
VJoyStatusSignal?.Invoke(status);
}

public float MoveAxis(ushort axis, int value)
private ref int GetAxisReference(ushort axis)
{
if (_maxval == 0) return 0;
ref int axisRef = ref _iReport.AxisX;
switch (axis)
{
case 0:
axisRef = ref _iReport.AxisX;
break;
return ref _iReport.AxisX;
case 1:
axisRef = ref _iReport.AxisY;
break;
return ref _iReport.AxisY;
case 2:
axisRef = ref _iReport.AxisZ;
break;
return ref _iReport.AxisZ;
case 3:
axisRef = ref _iReport.AxisXRot;
break;
return ref _iReport.AxisXRot;
case 4:
axisRef = ref _iReport.AxisYRot;
break;
return ref _iReport.AxisYRot;
case 5:
axisRef = ref _iReport.AxisZRot;
break;
return ref _iReport.AxisZRot;
case 6:
axisRef = ref _iReport.Slider;
break;
return ref _iReport.Slider;
case 7:
axisRef = ref _iReport.Dial;
break;
return ref _iReport.Dial;
}

axisRef += value;

if (axisRef > _maxval) axisRef = (int)_maxval;
else if (axisRef < 0) axisRef = 0;
return ref _iReport.AxisX;
}

public void SetAxis(ushort axis, float percent)
{
if (_maxAxisValue == 0) return;
ref int axisRef = ref GetAxisReference(axis);
var value = (int)(_maxAxisValue / 100.0 * percent);
axisRef = Math.Clamp(value, 0, (int)_maxAxisValue);

if (UpdateVJoy()) AxisSignal?.Invoke(axis, (float)axisRef / _maxAxisValue);
}


public void MoveAxis(ushort axis, double percent)
{
if (_maxAxisValue == 0) return;
ref int axisRef = ref GetAxisReference(axis);
var value = (int)(_maxAxisValue / 100.0 * percent);
axisRef = Math.Clamp(axisRef + value, 0, (int)_maxAxisValue);

if (UpdateVJoy()) return (float)axisRef / _maxval;
return 0;
if (UpdateVJoy()) AxisSignal?.Invoke(axis, (float)axisRef / _maxAxisValue);
}

public void ButtonState(uint button, ButtonAction action)
Expand Down Expand Up @@ -230,12 +235,12 @@ public void ConnectToVJoy(uint id)

CurrentVJoyId = id;
_vJoy.ResetVJD(id);
_vJoy.GetVJDAxisMax(id, HID_USAGES.HID_USAGE_X, ref _maxval);
Logger.Instance.LogMessage(TracingLevel.DEBUG, $"vJoy Device: {id}, axis maxval is now '{_maxval}'");
if (_maxval == 0) // TODO: find out why that happens sometimes
_vJoy.GetVJDAxisMax(id, HID_USAGES.HID_USAGE_X, ref _maxAxisValue);
Logger.Instance.LogMessage(TracingLevel.DEBUG, $"vJoy Device: {id}, axis maxval is now '{_maxAxisValue}'");
if (_maxAxisValue == 0) // TODO: find out why that happens sometimes
{
Logger.Instance.LogMessage(TracingLevel.ERROR, $"overwriting maxval to 32767 :(");
_maxval = 32767;
_maxAxisValue = 32767;
}
UpdateVJoy();
ChangeStatus(VJoyStatus.Connected);
Expand Down

0 comments on commit c4ce7cd

Please sign in to comment.