diff --git a/ControllerCommon/Actions/AxisActions.cs b/ControllerCommon/Actions/AxisActions.cs
deleted file mode 100644
index 10b593a50..000000000
--- a/ControllerCommon/Actions/AxisActions.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System;
-using System.Numerics;
-using System.Windows.Forms;
-using ControllerCommon.Inputs;
-using ControllerCommon.Utils;
-
-namespace ControllerCommon.Actions;
-
-[Serializable]
-public class AxisActions : IActions
-{
- private Vector2 prevVector;
- private Vector2 Vector;
-
- public AxisActions()
- {
- ActionType = ActionType.Joystick;
- Vector = new Vector2();
- prevVector = new Vector2();
- }
-
- public AxisActions(AxisLayoutFlags axis) : this()
- {
- Axis = axis;
- }
-
- public AxisLayoutFlags Axis { get; set; }
-
- // Axis to axis
- public bool AxisInverted { get; set; } = false;
- public bool AxisRotated { get; set; } = false;
- public int AxisDeadZoneInner { get; set; } = 0;
- public int AxisDeadZoneOuter { get; set; } = 0;
- public float AxisAntiDeadZone { get; set; } = 0.0f;
- public bool ImproveCircularity { get; set; } = false;
-
- public override void Execute(AxisFlags axis, short value)
- {
- // Apply inner and outer deadzone adjustments
- value = (short)InputUtils.InnerOuterDeadzone(value, AxisDeadZoneInner, AxisDeadZoneOuter, short.MaxValue);
-
- // Apply anti deadzone adjustments
- value = (short)InputUtils.ApplyAntiDeadzone(value, AxisAntiDeadZone);
-
- Value = (short)(value * (AxisInverted ? -1 : 1));
- }
-
- public void Execute(AxisLayout layout)
- {
- // Apply inner and outer deadzone adjustments
- layout.vector = InputUtils.ThumbScaledRadialInnerOuterDeadzone(layout.vector, AxisDeadZoneInner, AxisDeadZoneOuter);
-
- // Apply anti-deadzone adjustments
- layout.vector = InputUtils.ApplyAntiDeadzone(layout.vector, AxisAntiDeadZone);
-
- // Apply improved circularity
- if (ImproveCircularity)
- layout.vector = InputUtils.ImproveCircularity(layout.vector);
-
- if (AutoRotate)
- Vector = ((Orientation & ScreenOrientation.Angle90) == ScreenOrientation.Angle90
- ? new Vector2(layout.vector.Y, -layout.vector.X)
- : layout.vector)
- * ((Orientation & ScreenOrientation.Angle180) == ScreenOrientation.Angle180 ? -1.0f : 1.0f);
- else
- Vector = (AxisRotated ? new Vector2(layout.vector.Y, -layout.vector.X) : layout.vector)
- * (AxisInverted ? -1.0f : 1.0f);
- }
-
- public Vector2 GetValue()
- {
- return Vector;
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/Actions/ButtonActions.cs b/ControllerCommon/Actions/ButtonActions.cs
deleted file mode 100644
index 08cbaced2..000000000
--- a/ControllerCommon/Actions/ButtonActions.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System;
-using ControllerCommon.Inputs;
-
-namespace ControllerCommon.Actions;
-
-[Serializable]
-public class ButtonActions : IActions
-{
- public ButtonActions()
- {
- ActionType = ActionType.Button;
-
- Value = false;
- prevValue = false;
- }
-
- public ButtonActions(ButtonFlags button) : this()
- {
- Button = button;
- }
-
- public ButtonFlags Button { get; set; }
-
- public bool GetValue()
- {
- return (bool)Value;
- }
-
- public override void Execute(ButtonFlags button, bool value)
- {
- if (Toggle)
- {
- if ((bool)prevValue != value && value)
- IsToggled = !IsToggled;
- }
- else
- {
- IsToggled = false;
- }
-
- if (Turbo)
- {
- if (value || IsToggled)
- {
- if (TurboIdx % TurboDelay == 0)
- IsTurboed = !IsTurboed;
-
- TurboIdx += Period;
- }
- else
- {
- IsTurboed = false;
- TurboIdx = 0;
- }
- }
- else
- {
- IsTurboed = false;
- }
-
- // update previous value
- prevValue = value;
-
- if (Toggle && Turbo)
- Value = IsToggled && IsTurboed;
- else if (Toggle)
- Value = IsToggled;
- else if (Turbo)
- Value = IsTurboed;
- else
- Value = value;
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/Actions/IActions.cs b/ControllerCommon/Actions/IActions.cs
deleted file mode 100644
index 9055975b8..000000000
--- a/ControllerCommon/Actions/IActions.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using System;
-using System.Windows.Forms;
-using ControllerCommon.Inputs;
-using ControllerCommon.Managers;
-
-namespace ControllerCommon.Actions;
-
-[Serializable]
-public enum ActionType
-{
- Disabled = 0,
- Button = 1,
- Joystick = 2,
- Keyboard = 3,
- Mouse = 4,
- Trigger = 5
-}
-
-[Serializable]
-public abstract class IActions : ICloneable
-{
- protected bool IsToggled;
- protected bool IsTurboed;
-
- protected ScreenOrientation Orientation = ScreenOrientation.Angle0;
-
- protected int Period;
- protected object prevValue;
- protected int TurboIdx;
-
- protected object Value;
-
- public IActions()
- {
- Period = TimerManager.GetPeriod();
- }
-
- public ActionType ActionType { get; set; } = ActionType.Disabled;
-
- public bool Turbo { get; set; }
- public byte TurboDelay { get; set; } = 90;
-
- public bool Toggle { get; set; }
- public bool AutoRotate { get; set; } = false;
-
- // Improve me !
- public object Clone()
- {
- return MemberwiseClone();
- }
-
- public virtual void Execute(ButtonFlags button, bool value)
- {
- }
-
- public virtual void Execute(ButtonFlags button, short value)
- {
- }
-
- public virtual void Execute(AxisFlags axis, bool value)
- {
- }
-
- public virtual void Execute(AxisFlags axis, short value)
- {
- }
-
- public virtual void SetOrientation(ScreenOrientation orientation)
- {
- Orientation = orientation;
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/Actions/TriggerActions.cs b/ControllerCommon/Actions/TriggerActions.cs
deleted file mode 100644
index f3a3b7e36..000000000
--- a/ControllerCommon/Actions/TriggerActions.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System;
-using ControllerCommon.Inputs;
-
-namespace ControllerCommon.Actions;
-
-[Serializable]
-public class TriggerActions : IActions
-{
- public TriggerActions()
- {
- ActionType = ActionType.Trigger;
- Value = (short)0;
- }
-
- public TriggerActions(AxisLayoutFlags axis) : this()
- {
- Axis = axis;
- }
-
- public AxisLayoutFlags Axis { get; set; }
-
- public override void Execute(AxisFlags axis, short value)
- {
- // Apply inner and outer deadzone adjustments
- // value = (short)InputUtils.InnerOuterDeadzone(value, AxisDeadZoneInner, AxisDeadZoneOuter, short.MaxValue);
- // value = (short)InputUtils.ApplyAntiDeadzone(value, AxisAntiDeadZone);
-
- Value = value;
- }
-
- public short GetValue()
- {
- return (short)Value;
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/ControllerCommon.csproj b/ControllerCommon/ControllerCommon.csproj
deleted file mode 100644
index 02201938f..000000000
--- a/ControllerCommon/ControllerCommon.csproj
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
- net7.0-windows10.0.19041.0
- true
- x64
- portable
- 0.9.3.0
- $(SolutionDir)bin\$(Configuration)
- AnyCPU;x64
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\Resources\Inkore.UI.WPF.Modern.dll
-
-
- ..\Resources\NamedPipeWrapper.dll
-
-
-
-
-
- Resources.resx
- True
- True
-
-
-
-
-
- Resources.Designer.cs
- PublicResXFileCodeGenerator
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Controllers/ControllerMovements.cs b/ControllerCommon/Controllers/ControllerMovements.cs
deleted file mode 100644
index 915724fde..000000000
--- a/ControllerCommon/Controllers/ControllerMovements.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using MemoryPack;
-using System;
-
-namespace ControllerCommon.Controllers;
-
-[Serializable]
-[MemoryPackable]
-public partial class ControllerMovements
-{
- public float GyroAccelX, GyroAccelY, GyroAccelZ;
- public float GyroRoll, GyroPitch, GyroYaw;
-
- public long TickCount;
-
- public ControllerMovements()
- {
- }
-
- [MemoryPackConstructor]
- public ControllerMovements(float gyroAccelX, float gyroAccelY, float gyroAccelZ, float gyroRoll, float gyroPitch, float gyroYaw)
- {
- this.GyroAccelX = gyroAccelX;
- this.GyroAccelY = gyroAccelY;
- this.GyroAccelZ = gyroAccelZ;
-
- this.GyroRoll = gyroRoll;
- this.GyroPitch = gyroPitch;
- this.GyroYaw = gyroYaw;
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/Controllers/ControllerState.cs b/ControllerCommon/Controllers/ControllerState.cs
deleted file mode 100644
index caed443a1..000000000
--- a/ControllerCommon/Controllers/ControllerState.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-using ControllerCommon.Inputs;
-using MemoryPack;
-
-namespace ControllerCommon.Controllers;
-
-[Serializable]
-[MemoryPackable]
-public partial class ControllerState : ICloneable
-{
- [JsonIgnore] [MemoryPackIgnore] public static readonly SortedDictionary AxisTouchButtons = new()
- {
- { AxisLayoutFlags.RightThumb, ButtonFlags.RightThumbTouch },
- { AxisLayoutFlags.LeftThumb, ButtonFlags.LeftThumbTouch },
- { AxisLayoutFlags.RightPad, ButtonFlags.RightPadTouch },
- { AxisLayoutFlags.LeftPad, ButtonFlags.LeftPadTouch }
- };
-
- public AxisState AxisState = new();
- public ButtonState ButtonState = new();
-
- public ControllerState()
- {
- }
-
- [MemoryPackConstructor]
- public ControllerState(ButtonState buttonState, AxisState axisState, int timestamp)
- {
- ButtonState = buttonState;
- AxisState = axisState;
-
- Timestamp = timestamp;
- }
-
- public int Timestamp { get; set; }
- public bool MotionTriggered { get; set; }
-
- public object Clone()
- {
- return new ControllerState
- {
- ButtonState = ButtonState.Clone() as ButtonState,
- AxisState = AxisState.Clone() as AxisState,
- Timestamp = Timestamp
- };
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/Controllers/IController.cs b/ControllerCommon/Controllers/IController.cs
deleted file mode 100644
index 327e04eae..000000000
--- a/ControllerCommon/Controllers/IController.cs
+++ /dev/null
@@ -1,577 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using ControllerCommon.Inputs;
-using ControllerCommon.Managers;
-using ControllerCommon.Utils;
-using Inkore.UI.WPF.Modern.Controls;
-
-namespace ControllerCommon.Controllers;
-
-[Flags]
-public enum ControllerCapacities : ushort
-{
- None = 0,
- Gyroscope = 1,
- Accelerometer = 2,
- Trackpad = 3
-}
-
-public abstract class IController
-{
- // Buttons and axes we should be able to map to.
- // When we have target controllers with different buttons (e.g. in VigEm) this will have to be moved elsewhere.
- public static readonly List TargetButtons = new()
- {
- ButtonFlags.B1, ButtonFlags.B2, ButtonFlags.B3, ButtonFlags.B4,
- ButtonFlags.DPadUp, ButtonFlags.DPadDown, ButtonFlags.DPadLeft, ButtonFlags.DPadRight,
- ButtonFlags.Start, ButtonFlags.Back, ButtonFlags.Special,
- ButtonFlags.L1, ButtonFlags.R1,
- ButtonFlags.LeftThumb, ButtonFlags.RightThumb
- };
-
- public static readonly List TargetAxis = new()
- {
- AxisLayoutFlags.LeftThumb, AxisLayoutFlags.RightThumb,
- AxisLayoutFlags.L2, AxisLayoutFlags.R2
- };
-
- public static readonly string defaultGlyph = "\u2753";
-
- public ControllerCapacities Capacities = ControllerCapacities.None;
- protected SortedDictionary ColoredAxis = new();
-
- protected SortedDictionary ColoredButtons = new();
- protected FontFamily DefaultFontFamily = new("Segeo WP");
-
- public PnPDetails Details;
- public bool IsPowerCycling;
-
- // UI
- protected FontFamily GlyphFontFamily = new("PromptFont");
-
- public ButtonState InjectedButtons = new();
-
- public ControllerState Inputs = new();
- protected bool isPlugged;
- public ControllerMovements Movements = new();
-
- protected List SourceAxis = new()
- {
- // same as target, we assume all controllers have those axes
- AxisLayoutFlags.LeftThumb, AxisLayoutFlags.RightThumb,
- AxisLayoutFlags.L2, AxisLayoutFlags.R2
- };
-
- // Buttons and axes all controllers have that we can map.
- // Additional ones can be added per controller.
- protected List SourceButtons = new()
- {
- // same as target, we assume all controllers have those buttons
- ButtonFlags.B1, ButtonFlags.B2, ButtonFlags.B3, ButtonFlags.B4,
- ButtonFlags.DPadUp, ButtonFlags.DPadDown, ButtonFlags.DPadLeft, ButtonFlags.DPadRight,
- ButtonFlags.Start, ButtonFlags.Back, ButtonFlags.Special,
- ButtonFlags.L1, ButtonFlags.R1,
- ButtonFlags.LeftThumb, ButtonFlags.RightThumb,
- // additional buttons calculated from the above
- ButtonFlags.L2, ButtonFlags.R2, ButtonFlags.L3, ButtonFlags.R3,
- ButtonFlags.LeftThumbUp, ButtonFlags.LeftThumbDown, ButtonFlags.LeftThumbLeft, ButtonFlags.LeftThumbRight,
- ButtonFlags.RightThumbUp, ButtonFlags.RightThumbDown, ButtonFlags.RightThumbLeft, ButtonFlags.RightThumbRight
- };
-
- // todo: make this a custom control !
- protected Border ui_border = new()
- { CornerRadius = new CornerRadius(4, 4, 4, 4), Padding = new Thickness(15, 12, 12, 12) };
-
- protected Button ui_button_hide = new()
- {
- Width = 100, FontSize = 14, VerticalAlignment = VerticalAlignment.Center,
- Style = Application.Current.FindResource("AccentButtonStyle") as Style
- };
-
- protected Button ui_button_hook = new()
- {
- Width = 100, FontSize = 14, VerticalAlignment = VerticalAlignment.Center,
- Style = Application.Current.FindResource("AccentButtonStyle") as Style
- };
-
- protected SimpleStackPanel ui_dock_buttons = new()
- { Spacing = 6, Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right };
-
- protected DockPanel ui_dock_content = new() { HorizontalAlignment = HorizontalAlignment.Left };
- protected Grid ui_grid = new();
-
- protected FontIcon ui_icon = new()
- { Glyph = "\uE7FC", Height = 40, HorizontalAlignment = HorizontalAlignment.Center };
-
- protected TextBlock ui_name = new()
- { VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(12, 0, 0, 0) };
-
- protected int UserIndex;
- protected double VibrationStrength = 1.0d;
-
- protected IController()
- {
- // attribute controller to tag
- ui_border.Tag = this;
- }
-
- public virtual void UpdateInputs(long ticks)
- {
- // update states
- Inputs.Timestamp = Environment.TickCount;
-
- InputsUpdated?.Invoke(Inputs);
- }
-
- public virtual void UpdateMovements(long ticks)
- {
- // update states
- Movements.TickCount = ticks;
-
- MovementsUpdated?.Invoke(Movements);
- }
-
- public bool HasGyro()
- {
- return Capacities.HasFlag(ControllerCapacities.Gyroscope);
- }
-
- public bool HasAccelerometer()
- {
- return Capacities.HasFlag(ControllerCapacities.Accelerometer);
- }
-
- public bool HasTrackpad()
- {
- return Capacities.HasFlag(ControllerCapacities.Trackpad);
- }
-
- public bool IsVirtual()
- {
- if (Details is not null)
- return Details.isVirtual;
- return true;
- }
-
- public bool IsGaming()
- {
- if (Details is not null)
- return Details.isGaming;
- return false;
- }
-
- public int GetUserIndex()
- {
- return UserIndex;
- }
-
- public string GetInstancePath()
- {
- if (Details is not null)
- return Details.deviceInstanceId;
- return string.Empty;
- }
-
- public string GetContainerInstancePath()
- {
- if (Details is not null)
- return Details.baseContainerDeviceInstanceId;
- return string.Empty;
- }
-
- public override string ToString()
- {
- if (Details is not null)
- return Details.Name;
- return string.Empty;
- }
-
- protected void DrawControls()
- {
- // update name
- ui_name.Text = (IsVirtual() ? "Virtual " : string.Empty) + ToString();
-
- // Define columns
- var colDef0 = new ColumnDefinition { Width = new GridLength(9, GridUnitType.Star), MinWidth = 200 };
- var colDef1 = new ColumnDefinition { MinWidth = 240 };
-
- ui_grid.ColumnDefinitions.Add(colDef0);
- ui_grid.ColumnDefinitions.Add(colDef1);
-
- // SetResourceReference
- /*
- ui_icon.SetResourceReference(Control.ForegroundProperty, "SystemControlForegroundBaseHighBrush");
- ui_name.SetResourceReference(Control.ForegroundProperty, "SystemControlForegroundBaseHighBrush");
- ui_button_hide.SetResourceReference(Control.ForegroundProperty, "SystemControlForegroundBaseHighBrush");
- ui_button_hook.SetResourceReference(Control.ForegroundProperty, "SystemControlForegroundBaseHighBrush");
- */
- ui_border.SetResourceReference(Control.BackgroundProperty, "SystemControlPageBackgroundAltHighBrush");
-
- ui_dock_content.Children.Add(ui_icon);
- ui_dock_content.Children.Add(ui_name);
- ui_grid.Children.Add(ui_dock_content);
- Grid.SetColumn(ui_dock_content, 0);
-
- ui_dock_buttons.Children.Add(ui_button_hook);
- ui_dock_buttons.Children.Add(ui_button_hide);
- ui_grid.Children.Add(ui_dock_buttons);
- Grid.SetColumn(ui_dock_buttons, 1);
-
- ui_border.Child = ui_grid;
-
- // virtual controller shouldn't be visible
- if (IsVirtual())
- ui_border.Visibility = Visibility.Collapsed;
- }
-
- protected void RefreshControls()
- {
- // UI thread (async)
- Application.Current.Dispatcher.BeginInvoke(() =>
- {
- ui_button_hook.IsEnabled = !IsPlugged();
- ui_button_hook.Content = IsPlugged() ? "Connected" : "Connect";
- ui_button_hide.Content = IsHidden() ? "Unhide" : "Hide";
- });
- }
-
- public Border GetControl()
- {
- return ui_border;
- }
-
- public Button GetButtonHook()
- {
- return ui_button_hook;
- }
-
- public Button GetButtonHide()
- {
- return ui_button_hide;
- }
-
- public void InjectState(ButtonState State, bool IsKeyDown, bool IsKeyUp)
- {
- if (State.IsEmpty())
- return;
-
- foreach (var button in State.Buttons)
- InjectedButtons[button] = IsKeyDown;
-
- LogManager.LogDebug("Injecting {0} (IsKeyDown:{1}) (IsKeyUp:{2}) to {3}", string.Join(',', State.Buttons),
- IsKeyDown, IsKeyUp, ToString());
- }
-
- public void InjectButton(ButtonFlags button, bool IsKeyDown, bool IsKeyUp)
- {
- if (button == ButtonFlags.None)
- return;
-
- InjectedButtons[button] = IsKeyDown;
-
- LogManager.LogDebug("Injecting {0} (IsKeyDown:{1}) (IsKeyUp:{2}) to {3}", button, IsKeyDown, IsKeyUp,
- ToString());
- }
-
- public virtual void SetVibrationStrength(double value, bool rumble)
- {
- VibrationStrength = value / 100;
- }
-
- public virtual void SetVibration(byte LargeMotor, byte SmallMotor)
- {
- }
-
- public virtual bool IsConnected()
- {
- return false;
- }
-
- public virtual void Rumble(int Loop = 1, byte LeftValue = byte.MaxValue, byte RightValue = byte.MaxValue,
- byte Duration = 125)
- {
- }
-
- public virtual bool IsPlugged()
- {
- return isPlugged;
- }
-
- public virtual void Plug()
- {
- if (isPlugged)
- return;
-
- isPlugged = true;
-
- InjectedButtons.Clear();
-
- RefreshControls();
- }
-
- public virtual void Unplug()
- {
- if (!isPlugged)
- return;
-
- isPlugged = false;
-
- RefreshControls();
- }
-
- public bool IsHidden()
- {
- var hide_device = HidHide.IsRegistered(Details.deviceInstanceId);
- var hide_base = HidHide.IsRegistered(Details.baseContainerDeviceInstanceId);
- return /* hide_device || */ hide_base;
- }
-
- public void Hide()
- {
- if (IsHidden())
- return;
-
- // set flag
- IsPowerCycling = true;
-
- // get HidHideDevice
- HidHideDevice hideDevice = HidHide.GetHidHideDevice(Details.baseContainerDeviceInstanceId);
- if (hideDevice is not null)
- foreach(HidHideSubDevice subDevice in hideDevice.Devices)
- HidHide.HidePath(subDevice.DeviceInstancePath);
-
- HidHide.HidePath(Details.deviceInstanceId);
- HidHide.HidePath(Details.baseContainerDeviceInstanceId);
-
- Details.CyclePort();
-
- RefreshControls();
- }
-
- public void Unhide()
- {
- if (!IsHidden())
- return;
-
- // set flag
- IsPowerCycling = true;
-
- // get HidHideDevice
- HidHideDevice hideDevice = HidHide.GetHidHideDevice(Details.baseContainerDeviceInstanceId);
- if (hideDevice is not null)
- foreach (HidHideSubDevice subDevice in hideDevice.Devices)
- HidHide.UnhidePath(subDevice.DeviceInstancePath);
-
- HidHide.UnhidePath(Details.deviceInstanceId);
- HidHide.UnhidePath(Details.baseContainerDeviceInstanceId);
-
- Details.CyclePort();
-
- RefreshControls();
- }
-
- public virtual string GetGlyph(ButtonFlags button)
- {
- switch (button)
- {
- case ButtonFlags.DPadUp:
- return "\u219F"; // Button A
- case ButtonFlags.DPadDown:
- return "\u21A1"; // Button B
- case ButtonFlags.DPadLeft:
- return "\u219E"; // Button X
- case ButtonFlags.DPadRight:
- return "\u21A0"; // Button Y
- case ButtonFlags.LeftThumb:
- return "\u21BA";
- case ButtonFlags.RightThumb:
- return "\u21BB";
- case ButtonFlags.LeftThumbUp:
- return "\u21BE";
- case ButtonFlags.LeftThumbDown:
- return "\u21C2";
- case ButtonFlags.LeftThumbLeft:
- return "\u21BC";
- case ButtonFlags.LeftThumbRight:
- return "\u21C0";
- case ButtonFlags.RightThumbUp:
- return "\u21BF";
- case ButtonFlags.RightThumbDown:
- return "\u21C3";
- case ButtonFlags.RightThumbLeft:
- return "\u21BD";
- case ButtonFlags.RightThumbRight:
- return "\u21C1";
- case ButtonFlags.OEM1:
- return "\u2780";
- case ButtonFlags.OEM2:
- return "\u2781";
- case ButtonFlags.OEM3:
- return "\u2782";
- case ButtonFlags.OEM4:
- return "\u2783";
- case ButtonFlags.OEM5:
- return "\u2784";
- case ButtonFlags.OEM6:
- return "\u2785";
- case ButtonFlags.OEM7:
- return "\u2786";
- case ButtonFlags.OEM8:
- return "\u2787";
- case ButtonFlags.OEM9:
- return "\u2788";
- case ButtonFlags.OEM10:
- return "\u2789";
- case ButtonFlags.VolumeUp:
- return "\u21fe";
- case ButtonFlags.VolumeDown:
- return "\u21fd";
- }
-
- return defaultGlyph;
- }
-
- public virtual string GetGlyph(AxisFlags axis)
- {
- switch (axis)
- {
- case AxisFlags.LeftThumbX:
- return "\u21C4";
- case AxisFlags.LeftThumbY:
- return "\u21C5";
- case AxisFlags.RightThumbX:
- return "\u21C6";
- case AxisFlags.RightThumbY:
- return "\u21F5";
- }
-
- return defaultGlyph;
- }
-
- public virtual string GetGlyph(AxisLayoutFlags axis)
- {
- switch (axis)
- {
- case AxisLayoutFlags.LeftThumb:
- return "\u21CB";
- case AxisLayoutFlags.RightThumb:
- return "\u21CC";
- }
-
- return defaultGlyph;
- }
-
- public FontIcon GetFontIcon(ButtonFlags button, int FontIconSize = 14)
- {
- var FontIcon = new FontIcon
- {
- Glyph = GetGlyph(button),
- FontSize = FontIconSize,
- Foreground = GetGlyphColor(button)
- };
-
- if (FontIcon.Glyph is not null)
- {
- FontIcon.FontFamily = GlyphFontFamily;
- FontIcon.FontSize = 28;
- }
-
- return FontIcon;
- }
-
- public FontIcon GetFontIcon(AxisLayoutFlags axis, int FontIconSize = 14)
- {
- var FontIcon = new FontIcon
- {
- Glyph = GetGlyph(axis),
- FontSize = FontIconSize,
- Foreground = GetGlyphColor(axis)
- };
-
- if (FontIcon.Glyph is not null)
- {
- FontIcon.FontFamily = GlyphFontFamily;
- FontIcon.FontSize = 28;
- }
-
- return FontIcon;
- }
-
- public Brush GetGlyphColor(ButtonFlags button)
- {
- if (ColoredButtons.TryGetValue(button, out var brush))
- return brush;
-
- return null;
- }
-
- public Brush GetGlyphColor(AxisLayoutFlags axis)
- {
- /* if (AxisBrush.TryGetValue(axis, out Brush brush))
- return brush; */
-
- return null;
- }
-
- private static bool IsTrigger(AxisLayoutFlags axis)
- {
- return axis is AxisLayoutFlags.L2 || axis is AxisLayoutFlags.R2;
- }
-
- public static IEnumerable GetTargetButtons()
- {
- var buttons = Enum.GetValues(typeof(ButtonFlags)).Cast();
-
- return buttons.Where(a => TargetButtons.Contains(a));
- }
-
- public static IEnumerable GetTargetAxis()
- {
- var axis = Enum.GetValues(typeof(AxisLayoutFlags)).Cast();
-
- return axis.Where(a => TargetAxis.Contains(a) && !IsTrigger(a));
- }
-
- public static IEnumerable GetTargetTriggers()
- {
- var axis = Enum.GetValues(typeof(AxisLayoutFlags)).Cast();
-
- return axis.Where(a => TargetAxis.Contains(a) && IsTrigger(a));
- }
-
- public bool HasSourceButton(ButtonFlags button)
- {
- return SourceButtons.Contains(button);
- }
-
- public bool HasSourceAxis(AxisLayoutFlags axis)
- {
- return SourceAxis.Contains(axis);
- }
-
- public string GetButtonName(ButtonFlags button)
- {
- return EnumUtils.GetDescriptionFromEnumValue(button, GetType().Name);
- }
-
- public string GetAxisName(AxisLayoutFlags axis)
- {
- return EnumUtils.GetDescriptionFromEnumValue(axis, GetType().Name);
- }
-
- #region events
-
- public event InputsUpdatedEventHandler InputsUpdated;
-
- public delegate void InputsUpdatedEventHandler(ControllerState Inputs);
-
- public event MovementsUpdatedEventHandler MovementsUpdated;
-
- public delegate void MovementsUpdatedEventHandler(ControllerMovements Movements);
-
- #endregion
-}
\ No newline at end of file
diff --git a/ControllerCommon/Devices/OneXPlayer/OneXPlayerMiniPro.cs b/ControllerCommon/Devices/OneXPlayer/OneXPlayerMiniPro.cs
deleted file mode 100644
index e31f7908f..000000000
--- a/ControllerCommon/Devices/OneXPlayer/OneXPlayerMiniPro.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using ControllerCommon.Inputs;
-using ControllerCommon.Managers;
-using System.Numerics;
-
-namespace ControllerCommon.Devices;
-
-public class OneXPlayerMiniPro : OneXPlayerMini
-{
- public OneXPlayerMiniPro()
- {
- // https://www.amd.com/en/products/apu/amd-ryzen-7-6800u
- nTDP = new double[] { 15, 15, 20 };
- cTDP = new double[] { 4, 28 };
- GfxClock = new double[] { 100, 2200 };
-
- AccelerationAxis = new Vector3(-1.0f, 1.0f, 1.0f);
- }
-
- public override bool Open()
- {
- var success = base.Open();
- if (!success)
- return false;
-
- // allow OneX button to pass key inputs
- LogManager.LogInformation("Unlocked {0} OEM button", ButtonFlags.OEM1);
- return ECRamDirectWrite(0xF1, ECDetails, 0x40);
- }
-
- public override void Close()
- {
- LogManager.LogInformation("Locked {0} OEM button", ButtonFlags.OEM1);
- ECRamDirectWrite(0x1E, ECDetails, 0x00);
- base.Close();
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/FlickStick.cs b/ControllerCommon/FlickStick.cs
deleted file mode 100644
index 4ac3bce84..000000000
--- a/ControllerCommon/FlickStick.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-using System;
-using System.Numerics;
-using static ControllerCommon.Utils.CommonUtils;
-
-namespace ControllerCommon;
-
-public class FlickStick
-{
- private int CurrentInputIndex;
- // Flickstick
- // Based on: http://gyrowiki.jibbsmart.com/blog:good-gyro-controls-part-2:the-flick-stick
-
- private float FlickProgress;
- private float FlickSize;
-
- private float FlickTimePartial = 0.01f;
-
- private readonly float[] InputBuffer = new float[16];
- private readonly OneEuroFilterPair JoystickFilter = new();
- private Vector2 LastStick;
- private Vector2 LastStickFiltered;
- private Vector2 StickFiltered;
- private double UpdateTimePreviousMilliSeconds;
-
- // Flick stick, flick to initial angle, allow for stick rotation in horizontal plane after
- public float Handle(Vector2 Stick, float FlickDuration, float StickSensitivity, double TotalMilliseconds)
- {
- // Provide -1 to 1 joystickposition range for function.
- // @Benjamin not sure about converting here again from float to short.
- Stick = new Vector2(MapShortToMinusOnePlusOneRange((short)Stick.X),
- MapShortToMinusOnePlusOneRange((short)Stick.Y));
-
- // Variables
- var Result = 0.0f;
- var LastLength = LastStick.Length();
- var Length = Stick.Length();
-
- // Settings
- var FlickThreshold = 0.9f;
- var TurnSmoothThreshold = 0.1f;
-
- var DeltaTimeSeconds = (TotalMilliseconds - UpdateTimePreviousMilliSeconds) / 1000L;
- var rate = 1.0 / (TotalMilliseconds - UpdateTimePreviousMilliSeconds);
- UpdateTimePreviousMilliSeconds = TotalMilliseconds;
-
- StickFiltered = new Vector2((float)JoystickFilter.axis1Filter.Filter(Stick.X, rate),
- (float)JoystickFilter.axis2Filter.Filter(Stick.Y, rate));
-
- // Compare last frame to this, determine if flick occured
- if (Length >= FlickThreshold)
- {
- if (LastLength < FlickThreshold)
- {
- // Start flick
- FlickProgress = 0.0f; // Reset flick timer
- FlickSize = (float)Math.Atan2(-Stick.X, Stick.Y); // Stick angle from up/forward
-
- // Determine flick pulse duration
- // Partial flick time based on flick size
- // Flick duration is 180 degrees, flick partial duration is time needed for partial turn
- // Note, games that use acceleration and deceleration won't be 100% accurate
- FlickTimePartial = FlickDuration * Math.Abs(FlickSize) / (float)Math.PI;
- }
- else
- {
- // Possible improvement: already combine stick rotation and flick
- // for last flick output to allow for smoother transition.
-
- // Stick turn along horizontal plane
- var StickAngle = (float)Math.Atan2(-StickFiltered.X, StickFiltered.Y); // Stick angle from up/forward
- var LastStickAngle = (float)Math.Atan2(-LastStickFiltered.X, LastStickFiltered.Y);
-
- var AngleChange = (float)WrapMinMax(StickAngle - LastStickAngle, -Math.PI, Math.PI);
-
- Result += GetTieredSmoothedStickRotation(AngleChange, TurnSmoothThreshold / 2.0f, TurnSmoothThreshold)
- * StickSensitivity * 2;
- }
- }
- else
- {
- // Turn cleanup
- if (LastLength >= FlickThreshold)
- // Transitioned from flick/turn to no flick, clean up
- ZeroTurnSmoothing();
- }
-
- // Continue flick
- if (FlickProgress < FlickTimePartial)
- {
- // Determine flick strength
- // Strength remains 1 up to last cycle,
- // then it's proportional to remaining time,
- // assuming same duration as last cycle
- if (FlickTimePartial - FlickProgress > DeltaTimeSeconds)
- Result = 1.0f;
- else
- // Determine proportional strength
- // Assumption is made here that
- // next cycle will take as long as last cycle
- // Could use HID rate as alternative
- Result = (float)(1.0f * (FlickTimePartial - FlickProgress) / DeltaTimeSeconds);
-
- // Apply flick direction
- Result *= Math.Sign(FlickSize);
-
- // Increment progress
- // Possible improvement, determine flickprogress at the start to compensate for timing inaccuracy
- FlickProgress += (float)DeltaTimeSeconds;
- }
-
- LastStick = Stick;
- LastStickFiltered = StickFiltered;
-
- return Result * short.MaxValue;
- }
-
- private static float MapShortToMinusOnePlusOneRange(short Input)
- {
- return (Input - (float)short.MinValue) * (1 - (float)-1) / (short.MaxValue - (float)short.MinValue) + -1;
- }
-
- // Zero i.e. reset input buffer
- private void ZeroTurnSmoothing()
- {
- for (var i = 0; i < InputBuffer.Length; i++) InputBuffer[i] = 0.0f;
- }
-
- private float GetSmoothedStickRotation(float input)
- {
- CurrentInputIndex = (CurrentInputIndex + 1) % InputBuffer.Length;
- InputBuffer[CurrentInputIndex] = input;
- var Average = 0.0f;
-
- foreach (var Sample in InputBuffer) Average += Sample;
-
- Average /= InputBuffer.Length;
-
- return Average;
- }
-
- private float GetTieredSmoothedStickRotation(float Input, float Threshold1, float Threshold2)
- {
- var InputMagnitude = Math.Abs(Input);
-
- var DirectWeight = (InputMagnitude - Threshold1) /
- (Threshold2 - Threshold1);
- DirectWeight = Math.Clamp(DirectWeight, 0.0f, 1.0f);
-
- return Input * DirectWeight + GetSmoothedStickRotation(Input * (1.0f - DirectWeight));
- }
-
- // Wrap around max
- private static double WrapMax(double X, double Max)
- {
- return (Max + X % Max) % Max;
- }
-
- // Wrap around min max
- private static double WrapMinMax(double X, double Min, double Max)
- {
- return Min + WrapMax(X - Min, Max - Min);
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/LegacyDevcon.cs b/ControllerCommon/LegacyDevcon.cs
deleted file mode 100644
index 2d930c6ac..000000000
--- a/ControllerCommon/LegacyDevcon.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using ControllerCommon.Managers;
-using ControllerCommon.Processor;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ControllerCommon
-{
- public static class LegacyDevcon
- {
- private static readonly string path;
- private static bool _IsInstalled;
-
- static LegacyDevcon()
- {
- path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "devcon.exe");
-
- if (!File.Exists(path))
- {
- LogManager.LogError("devcon.exe is missing.");
- return;
- }
-
- _IsInstalled = true;
- }
-
- public static bool Restart(string InstanceId)
- {
- if (!_IsInstalled)
- return false;
-
- string output = string.Empty;
- using (Process process = new Process())
- {
- process.StartInfo.FileName = path;
- process.StartInfo.UseShellExecute = false;
- process.StartInfo.RedirectStandardOutput = true;
- process.StartInfo.RedirectStandardError = true;
- process.StartInfo.CreateNoWindow = true;
-
- // register command
- process.StartInfo.Arguments = $"restart \"{InstanceId}\"";
-
- process.Start();
-
- StreamReader reader = process.StandardOutput;
- output = reader.ReadToEnd();
-
- process.WaitForExit();
- }
-
- if (output.Contains("No matching devices found."))
- return false;
- else if (output.Contains("Restarted"))
- return true;
-
- return false;
- }
- }
-}
diff --git a/ControllerCommon/Managers/ServiceManager.cs b/ControllerCommon/Managers/ServiceManager.cs
deleted file mode 100644
index 7e165baa0..000000000
--- a/ControllerCommon/Managers/ServiceManager.cs
+++ /dev/null
@@ -1,308 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.ServiceProcess;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Timers;
-using ControllerCommon.Utils;
-using Timer = System.Timers.Timer;
-
-namespace ControllerCommon.Managers;
-
-public enum ServiceControllerStatus
-{
- Failed = -1,
- None = 0,
- Stopped = 1,
- StartPending = 2,
- StopPending = 3,
- Running = 4,
- ContinuePending = 5,
- PausePending = 6,
- Paused = 7,
- Uninstalled = 8
-}
-
-public class ServiceManager : Manager
-{
- public delegate void StartFailedEventHandler(ServiceControllerStatus status, string message);
-
- public delegate void StopFailedEventHandler(ServiceControllerStatus status);
-
- public delegate void UpdatedEventHandler(ServiceControllerStatus status, int mode);
-
- private readonly Timer MonitorTimer = new(2000) { Enabled = true, AutoReset = true };
- private readonly object updateLock = new();
-
- private readonly ServiceController controller;
- private readonly string Description;
- private readonly string DisplayName;
- private ServiceControllerStatus nextStatus;
- private int prevStatus, prevType = -1;
-
- private readonly Process process;
- private readonly string ServiceName;
-
- private int StartTentative;
- public ServiceControllerStatus status = ServiceControllerStatus.None;
-
- private int StopTentative;
- public ServiceStartMode type = ServiceStartMode.Disabled;
-
- public ServiceManager(string name, string display, string description)
- {
- ServiceName = name;
- DisplayName = display;
- Description = description;
-
- controller = new ServiceController(name);
-
- process = new Process
- {
- StartInfo =
- {
- UseShellExecute = false,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- CreateNoWindow = true,
- FileName = @"C:\Windows\system32\sc.exe",
- Verb = "runas"
- }
- };
- }
-
- public event UpdatedEventHandler Updated;
-
- public event StartFailedEventHandler StartFailed;
-
- public event StopFailedEventHandler StopFailed;
-
- public override void Start()
- {
- MonitorTimer.Elapsed += MonitorHelper;
- }
-
- public override void Stop()
- {
- if (!IsInitialized)
- return;
-
- MonitorTimer.Elapsed -= MonitorHelper;
- MonitorTimer.Dispose();
-
- base.Stop();
- }
-
- public bool Exists()
- {
- try
- {
- process.StartInfo.Arguments = $"interrogate {ServiceName}";
- process.Start();
- process.WaitForExit();
- var output = process.StandardOutput.ReadToEnd();
- var error = CommonUtils.Between(output, "FAILED ", ":");
-
- switch (error)
- {
- case "1060":
- return false;
- default:
- return true;
- }
- }
- catch (Exception ex)
- {
- LogManager.LogError("Service manager returned error: {0}", ex.Message);
- }
-
- return false;
- }
-
- private void MonitorHelper(object sender, ElapsedEventArgs e)
- {
- if (Monitor.TryEnter(updateLock))
- {
- try
- {
- // refresh service status
- controller.Refresh();
-
- // check if service is installed
- if (CheckServiceInstalled(ServiceName))
- {
- if (!string.IsNullOrEmpty(controller.ServiceName))
- {
- status = (ServiceControllerStatus)controller.Status;
- type = controller.StartType;
- }
- }
- else
- {
- status = ServiceControllerStatus.Uninstalled;
- type = ServiceStartMode.Disabled;
- }
- }
- catch
- {
- status = ServiceControllerStatus.None;
- type = ServiceStartMode.Disabled;
- }
-
- // exit lock before calling base function ?
- Monitor.Exit(updateLock);
-
- // initialize only once we've pulled service status
- if (!IsInitialized)
- {
- base.Start();
- }
- else
- {
- if (prevStatus != (int)status || prevType != (int)type || nextStatus != 0)
- {
- Updated?.Invoke(status, (int)type);
- nextStatus = ServiceControllerStatus.None;
- LogManager.LogInformation("Controller Service status has changed to: {0}", status.ToString());
- }
-
- prevStatus = (int)status;
- prevType = (int)type;
- }
- }
- }
-
- public bool CheckServiceInstalled(string serviceToFind)
- {
- var servicelist = ServiceController.GetServices();
- foreach (var service in servicelist)
- if (service.ServiceName == serviceToFind)
- return true;
- return false;
- }
-
- public void CreateService(string path)
- {
- Updated?.Invoke(ServiceControllerStatus.StartPending, -1);
- nextStatus = ServiceControllerStatus.StartPending;
-
- try
- {
- process.StartInfo.Arguments =
- $"create {ServiceName} binpath= \"{path}\" start= \"demand\" DisplayName= \"{DisplayName}\"";
- process.Start();
- process.WaitForExit();
-
- process.StartInfo.Arguments = $"description {ServiceName} \"{Description}\"";
- process.Start();
- process.WaitForExit();
- }
- catch (Exception ex)
- {
- LogManager.LogError("Service manager returned error: {0}", ex.Message);
- }
- }
-
- public void DeleteService()
- {
- Updated?.Invoke(ServiceControllerStatus.StopPending, -1);
- nextStatus = ServiceControllerStatus.StopPending;
-
- process.StartInfo.Arguments = $"delete {ServiceName}";
- process.Start();
- process.WaitForExit();
- }
-
- public async Task StartServiceAsync()
- {
- if (type == ServiceStartMode.Disabled)
- return;
-
- if (status == ServiceControllerStatus.Running)
- return;
-
- if (!IsInitialized)
- return;
-
- while (status != ServiceControllerStatus.Running && status != ServiceControllerStatus.StartPending)
- {
- Updated?.Invoke(ServiceControllerStatus.StartPending, -1);
-
- try
- {
- controller.Refresh();
- switch (controller.Status)
- {
- case System.ServiceProcess.ServiceControllerStatus.Running:
- case System.ServiceProcess.ServiceControllerStatus.StartPending:
- break;
- default:
- controller.Start();
- break;
- }
- }
- catch (Exception ex)
- {
- await Task.Delay(2000);
- LogManager.LogError("Service manager returned error: {0}", ex.Message);
- StartTentative++;
-
- // exit loop
- if (StartTentative == 3)
- {
- nextStatus = ServiceControllerStatus.Failed;
- StartFailed?.Invoke(status, ex.Message);
- break;
- }
- }
- }
-
- StartTentative = 0;
- }
-
- public async Task StopServiceAsync()
- {
- if (status != ServiceControllerStatus.Running)
- return;
-
- while (status != ServiceControllerStatus.Stopped && status != ServiceControllerStatus.StopPending)
- {
- Updated?.Invoke(ServiceControllerStatus.StopPending, -1);
-
- try
- {
- controller.Refresh();
- switch (controller.Status)
- {
- case System.ServiceProcess.ServiceControllerStatus.Stopped:
- case System.ServiceProcess.ServiceControllerStatus.StopPending:
- break;
- default:
- controller.Stop();
- break;
- }
- }
- catch (Exception ex)
- {
- await Task.Delay(2000);
- LogManager.LogError("Service manager returned error: {0}", ex.Message);
- StopTentative++;
-
- // exit loop
- if (StopTentative == 3)
- {
- nextStatus = ServiceControllerStatus.Failed;
- StopFailed?.Invoke(status);
- break;
- }
- }
- }
-
- StopTentative = 0;
- }
-
- public void SetStartType(ServiceStartMode mode)
- {
- ServiceHelper.ChangeStartMode(controller, mode);
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/Pipes/PipeClient.cs b/ControllerCommon/Pipes/PipeClient.cs
deleted file mode 100644
index 10f1b91e2..000000000
--- a/ControllerCommon/Pipes/PipeClient.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Timers;
-using ControllerCommon.Managers;
-using NamedPipeWrapper;
-
-namespace ControllerCommon.Pipes;
-
-public static class PipeClient
-{
- public delegate void ConnectedEventHandler();
-
- public delegate void DisconnectedEventHandler();
-
- public delegate void ServerMessageEventHandler(PipeMessage e);
-
- private const string PipeName = "HandheldCompanion";
- public static NamedPipeClient client;
-
- private static readonly ConcurrentQueue m_queue = new();
- private static readonly Timer m_timer;
-
- public static bool IsConnected;
-
- static PipeClient()
- {
- // monitors processes and settings
- m_timer = new Timer(1000) { Enabled = false, AutoReset = true };
- m_timer.Elapsed += SendMessageQueue;
-
- client = new NamedPipeClient(PipeName);
- client.AutoReconnect = true;
- }
-
- public static event ConnectedEventHandler Connected;
-
- public static event DisconnectedEventHandler Disconnected;
-
- public static event ServerMessageEventHandler ServerMessage;
-
- private static void OnClientDisconnected(NamedPipeConnection connection)
- {
- LogManager.LogInformation("Client {0} disconnected", connection.Id);
- Disconnected?.Invoke();
-
- IsConnected = false;
- }
-
- public static void Open()
- {
- client.Disconnected += OnClientDisconnected;
- client.ServerMessage += OnServerMessage;
- client.Error += OnError;
-
- client?.Start();
- LogManager.LogInformation("{0} has started", "PipeClient");
- }
-
- public static void Close()
- {
- client.Disconnected -= OnClientDisconnected;
- client.ServerMessage -= OnServerMessage;
- client.Error -= OnError;
-
- client?.Stop();
- LogManager.LogInformation("{0} has stopped", "PipeClient");
- client = null;
- }
-
- private static void OnServerMessage(NamedPipeConnection connection, PipeMessage message)
- {
- ServerMessage?.Invoke(message);
-
- switch (message.code)
- {
- case PipeCode.SERVER_PING:
- IsConnected = true;
- Connected?.Invoke();
- LogManager.LogInformation("Client {0} is now connected!", connection.Id);
- break;
- }
- }
-
- private static void OnError(Exception exception)
- {
- LogManager.LogError("{0} failed. {1}", "PipeClient", exception.Message);
- }
-
- public static void SendMessage(PipeMessage message)
- {
- if (!IsConnected)
- {
- var nodeType = message.GetType();
- if (nodeType == typeof(PipeClientCursor))
- return;
- if (nodeType == typeof(PipeClientInputs))
- return;
- if (nodeType == typeof(PipeClientMovements))
- return;
-
- m_queue.Enqueue(message);
- m_timer.Start();
- return;
- }
-
- client?.PushMessage(message);
- }
-
- private static void SendMessageQueue(object sender, ElapsedEventArgs e)
- {
- if (!IsConnected)
- return;
-
- foreach (var m in m_queue)
- client?.PushMessage(m);
-
- m_queue.Clear();
- m_timer.Stop();
- }
-
- public static void ClearQueue()
- {
- m_queue.Clear();
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/Pipes/PipeCode.cs b/ControllerCommon/Pipes/PipeCode.cs
deleted file mode 100644
index c60aefe4e..000000000
--- a/ControllerCommon/Pipes/PipeCode.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-namespace ControllerCommon.Pipes;
-
-public enum PipeCode
-{
- SERVER_PING = 0, // Sent to client during initialization
- // args: ...
-
- CLIENT_PROFILE = 1, // Sent to server to switch profiles
- // args: process id, process path
-
- SERVER_TOAST = 2, // Sent to client to display toast notification.
- // args: title, message
-
- CLIENT_CURSOR = 3, // Sent to server when mouse click is up
- // args: cursor x, cursor Y
-
- SERVER_SETTINGS = 6, // Sent to client during initialization
- // args: ...
-
- CLIENT_INPUT = 7, // Sent to server to request a specific gamepad input
- // args: ...
-
- CLIENT_SETTINGS = 8, // Sent to server to update settings
- // args: ...
-
- CLIENT_CONTROLLER_CONNECT = 9, // Sent to server to share current controller details
-
- CLIENT_CONTROLLER_DISCONNECT = 11, // Sent to server to warn current controller was disconnected
-
- CLIENT_CONSOLE = 12, // Sent from client to client to pass parameters
- // args: string[] parameters
-
- CLIENT_PROCESS = 13, // Sent to server each time a new process is in the foreground.
-
- SERVER_SENSOR = 14, // Sent to client to share sensor values
- // args: ...
-
- CLIENT_NAVIGATED = 15, // Sent to server to share current navigated page
- // args: ...
-
- CLIENT_OVERLAY = 16, // Sent to server to share current overlay status
- // args: ...
-
- SERVER_VIBRATION = 17, // Sent to client to notify a vibration feedback arrived
- // args: ...
-
- CLIENT_MOVEMENTS = 18, // Sent to server to inform on controller/device movements
-
- CLIENT_CLEARINDEX = 19 // Sent to server to clear all hidden controllers
- // args: ...
-}
\ No newline at end of file
diff --git a/ControllerCommon/Pipes/PipeMessage.cs b/ControllerCommon/Pipes/PipeMessage.cs
deleted file mode 100644
index d0e0b7424..000000000
--- a/ControllerCommon/Pipes/PipeMessage.cs
+++ /dev/null
@@ -1,287 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Formats.Asn1;
-using System.Numerics;
-using ControllerCommon.Controllers;
-using ControllerCommon.Platforms;
-using MemoryPack;
-using Newtonsoft.Json;
-
-namespace ControllerCommon.Pipes;
-
-[Serializable]
-[MemoryPackable]
-[MemoryPackUnion(0, typeof(PipeServerToast))]
-[MemoryPackUnion(1, typeof(PipeServerPing))]
-[MemoryPackUnion(2, typeof(PipeServerSettings))]
-[MemoryPackUnion(3, typeof(PipeClientProfile))]
-[MemoryPackUnion(4, typeof(PipeClientProcess))]
-[MemoryPackUnion(5, typeof(PipeClientSettings))]
-[MemoryPackUnion(6, typeof(PipeClientCursor))]
-[MemoryPackUnion(7, typeof(PipeClientInputs))]
-[MemoryPackUnion(8, typeof(PipeClientMovements))]
-[MemoryPackUnion(9, typeof(PipeClientVibration))]
-[MemoryPackUnion(10, typeof(PipeClientControllerConnect))]
-[MemoryPackUnion(11, typeof(PipeClientControllerDisconnect))]
-[MemoryPackUnion(12, typeof(PipeSensor))]
-[MemoryPackUnion(13, typeof(PipeNavigation))]
-[MemoryPackUnion(14, typeof(PipeOverlay))]
-public abstract partial class PipeMessage
-{
- public PipeCode code;
-}
-
-#region serverpipe
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeServerToast : PipeMessage
-{
- public string content;
- public string image = "Toast";
- public string title;
-
- public PipeServerToast()
- {
- code = PipeCode.SERVER_TOAST;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeServerPing : PipeMessage
-{
- public PipeServerPing()
- {
- code = PipeCode.SERVER_PING;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeServerSettings : PipeMessage
-{
- public Dictionary Settings { get; set; } = new();
-
- public PipeServerSettings()
- {
- code = PipeCode.SERVER_SETTINGS;
- }
-}
-
-#endregion
-
-#region clientpipe
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeClientProfile : PipeMessage
-{
- public Profile profile;
-
- public PipeClientProfile()
- {
- code = PipeCode.CLIENT_PROFILE;
- }
-
- [MemoryPackConstructor]
- public PipeClientProfile(Profile profile) : this()
- {
- this.profile = profile;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeClientProcess : PipeMessage
-{
- public string executable;
- public PlatformType platform;
-
- public PipeClientProcess()
- {
- code = PipeCode.CLIENT_PROCESS;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeClientSettings : PipeMessage
-{
- public Dictionary Settings { get; set; } = new();
-
- public PipeClientSettings()
- {
- code = PipeCode.CLIENT_SETTINGS;
- }
-}
-
-[Serializable]
-public enum CursorAction
-{
- CursorUp = 0,
- CursorDown = 1,
- CursorMove = 2
-}
-
-[Serializable]
-public enum CursorButton
-{
- None = 0,
- TouchLeft = 1,
- TouchRight = 2
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeClientCursor : PipeMessage
-{
- public CursorAction action;
- public CursorButton button;
- public int flags;
- public double x;
- public double y;
-
- public PipeClientCursor()
- {
- code = PipeCode.CLIENT_CURSOR;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeClientInputs : PipeMessage
-{
- public ControllerState controllerState;
-
- public PipeClientInputs()
- {
- code = PipeCode.CLIENT_INPUT;
- }
-
- [MemoryPackConstructor]
- public PipeClientInputs(ControllerState controllerState) : this()
- {
- this.controllerState = controllerState;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeClientMovements : PipeMessage
-{
- public ControllerMovements Movements;
-
- public PipeClientMovements()
- {
- code = PipeCode.CLIENT_MOVEMENTS;
- }
-
- [MemoryPackConstructor]
- public PipeClientMovements(ControllerMovements movements) : this()
- {
- Movements = movements;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeClientVibration : PipeMessage
-{
- public byte LargeMotor;
- public byte SmallMotor;
-
- public PipeClientVibration()
- {
- code = PipeCode.SERVER_VIBRATION;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeClientControllerConnect : PipeMessage
-{
- public ControllerCapacities Capacities;
- public string ControllerName;
-
- public PipeClientControllerConnect()
- {
- code = PipeCode.CLIENT_CONTROLLER_CONNECT;
- }
-
- [MemoryPackConstructor]
- public PipeClientControllerConnect(string controllerName, ControllerCapacities capacities) : this()
- {
- ControllerName = controllerName;
- Capacities = capacities;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeClientControllerDisconnect : PipeMessage
-{
- public PipeClientControllerDisconnect()
- {
- code = PipeCode.CLIENT_CONTROLLER_DISCONNECT;
- }
-}
-
-[Serializable]
-public enum SensorType
-{
- Girometer = 0,
- Accelerometer = 1,
- Inclinometer = 2,
- Quaternion = 3
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeSensor : PipeMessage
-{
- public Vector3 reading;
- public Quaternion quaternion;
- public SensorType sensorType;
-
- public PipeSensor()
- {
- code = PipeCode.SERVER_SENSOR;
- }
-
- [MemoryPackConstructor]
- public PipeSensor(Vector3 reading, Quaternion quaternion, SensorType sensorType) : this()
- {
- this.reading = reading;
- this.quaternion = quaternion;
- this.sensorType = sensorType;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeNavigation : PipeMessage
-{
- public string Tag;
-
- public PipeNavigation(string Tag)
- {
- code = PipeCode.CLIENT_NAVIGATED;
- this.Tag = Tag;
- }
-}
-
-[Serializable]
-[MemoryPackable]
-public partial class PipeOverlay : PipeMessage
-{
- public int Visibility;
-
- public PipeOverlay(int Visibility)
- {
- code = PipeCode.CLIENT_OVERLAY;
- this.Visibility = Visibility;
- }
-}
-
-#endregion
\ No newline at end of file
diff --git a/ControllerCommon/Pipes/PipeServer.cs b/ControllerCommon/Pipes/PipeServer.cs
deleted file mode 100644
index 2d3e31c28..000000000
--- a/ControllerCommon/Pipes/PipeServer.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.IO.Pipes;
-using System.Security.AccessControl;
-using System.Security.Principal;
-using System.Timers;
-using ControllerCommon.Managers;
-using NamedPipeWrapper;
-
-namespace ControllerCommon.Pipes;
-
-public static class PipeServer
-{
- public delegate void ClientMessageEventHandler(PipeMessage e);
-
- public delegate void ConnectedEventHandler();
-
- public delegate void DisconnectedEventHandler();
-
- private const string PipeName = "HandheldCompanion";
- private static NamedPipeServer server;
-
- private static readonly ConcurrentQueue m_queue = new();
- private static readonly Timer m_timer;
-
- public static bool IsConnected;
-
- static PipeServer()
- {
- // monitors processes and settings
- m_timer = new Timer(1000) { Enabled = false, AutoReset = true };
- m_timer.Elapsed += SendMessageQueue;
-
- PipeSecurity ps = new();
- SecurityIdentifier sid = new(WellKnownSidType.BuiltinUsersSid, null);
- PipeAccessRule par = new(sid, PipeAccessRights.ReadWrite, AccessControlType.Allow);
- ps.AddAccessRule(par);
-
- server = new NamedPipeServer(PipeName, ps);
- }
-
- public static event ConnectedEventHandler Connected;
-
- public static event DisconnectedEventHandler Disconnected;
-
- public static event ClientMessageEventHandler ClientMessage;
-
- public static void Open()
- {
- server.ClientConnected += OnClientConnected;
- server.ClientDisconnected += OnClientDisconnected;
- server.ClientMessage += OnClientMessage;
- server.Error += OnError;
- server?.Start();
-
- LogManager.LogInformation("{0} has started", "PipeServer");
- }
-
- public static void Close()
- {
- server.ClientConnected -= OnClientConnected;
- server.ClientDisconnected -= OnClientDisconnected;
- server.ClientMessage -= OnClientMessage;
- server.Error -= OnError;
- server?.Stop();
-
- LogManager.LogInformation("{0} has stopped", "PipeServer");
- server = null;
- }
-
- private static void OnClientConnected(NamedPipeConnection connection)
- {
- LogManager.LogInformation("Client {0} is now connected!", connection.Id);
- Connected?.Invoke();
-
- IsConnected = true;
-
- // send ping
- SendMessage(new PipeServerPing());
- }
-
- private static void OnClientDisconnected(NamedPipeConnection connection)
- {
- LogManager.LogInformation("Client {0} disconnected", connection.Id);
- Disconnected?.Invoke();
-
- IsConnected = false;
- }
-
- private static void OnClientMessage(NamedPipeConnection connection, PipeMessage message)
- {
- ClientMessage?.Invoke(message);
- }
-
- private static void OnError(Exception exception)
- {
- LogManager.LogError("{0} failed. {1}", "PipeServer", exception.Message);
- }
-
- public static void SendMessage(PipeMessage message)
- {
- if (!IsConnected)
- {
- var nodeType = message.GetType();
- if (nodeType == typeof(PipeSensor))
- return;
-
- m_queue.Enqueue(message);
- m_timer.Start();
- return;
- }
-
- server?.PushMessage(message);
- }
-
- private static void SendMessageQueue(object sender, ElapsedEventArgs e)
- {
- if (!IsConnected)
- return;
-
- foreach (var m in m_queue)
- server?.PushMessage(m);
-
- m_queue.Clear();
- m_timer.Stop();
- }
-
- public static void ClearQueue()
- {
- m_queue.Clear();
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/Properties/Resources.Designer.cs b/ControllerCommon/Properties/Resources.Designer.cs
deleted file mode 100644
index dacb358b9..000000000
--- a/ControllerCommon/Properties/Resources.Designer.cs
+++ /dev/null
@@ -1,1296 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace ControllerCommon.Properties {
- using System;
-
-
- ///
- /// A strongly-typed resource class, for looking up localized strings, etc.
- ///
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- public class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// Returns the cached ResourceManager instance used by this class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- public static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ControllerCommon.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- public static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// Looks up a localized string similar to This input will operate as a simple joystick. Ideal for laptop and clamshell type handhelds, automatic yaw roll swap based on how device is being held (90 or 180 degree open)..
- ///
- public static string AutoRollYawSwapDesc {
- get {
- return ResourceManager.GetString("AutoRollYawSwapDesc", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to AYA.
- ///
- public static string Enum_AYANEO2_ButtonFlags_OEM1 {
- get {
- return ResourceManager.GetString("Enum.AYANEO2.ButtonFlags.OEM1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to ≈.
- ///
- public static string Enum_AYANEO2_ButtonFlags_OEM2 {
- get {
- return ResourceManager.GetString("Enum.AYANEO2.ButtonFlags.OEM2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to RC.
- ///
- public static string Enum_AYANEO2_ButtonFlags_OEM3 {
- get {
- return ResourceManager.GetString("Enum.AYANEO2.ButtonFlags.OEM3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to LC.
- ///
- public static string Enum_AYANEO2_ButtonFlags_OEM4 {
- get {
- return ResourceManager.GetString("Enum.AYANEO2.ButtonFlags.OEM4", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Win.
- ///
- public static string Enum_AYANEO2021Pro_ButtonFlags_OEM1 {
- get {
- return ResourceManager.GetString("Enum.AYANEO2021Pro.ButtonFlags.OEM1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Esc.
- ///
- public static string Enum_AYANEO2021Pro_ButtonFlags_OEM2 {
- get {
- return ResourceManager.GetString("Enum.AYANEO2021Pro.ButtonFlags.OEM2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to KB.
- ///
- public static string Enum_AYANEO2021Pro_ButtonFlags_OEM3 {
- get {
- return ResourceManager.GetString("Enum.AYANEO2021Pro.ButtonFlags.OEM3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to AYA.
- ///
- public static string Enum_AYANEOAIR_ButtonFlags_OEM1 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIR.ButtonFlags.OEM1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to ≈.
- ///
- public static string Enum_AYANEOAIR_ButtonFlags_OEM2 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIR.ButtonFlags.OEM2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to RC.
- ///
- public static string Enum_AYANEOAIR_ButtonFlags_OEM3 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIR.ButtonFlags.OEM3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to LC.
- ///
- public static string Enum_AYANEOAIR_ButtonFlags_OEM4 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIR.ButtonFlags.OEM4", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to AYA.
- ///
- public static string Enum_AYANEOAIRLite_ButtonFlags_OEM1 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIRLite.ButtonFlags.OEM1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to ≈.
- ///
- public static string Enum_AYANEOAIRLite_ButtonFlags_OEM2 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIRLite.ButtonFlags.OEM2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to RC.
- ///
- public static string Enum_AYANEOAIRLite_ButtonFlags_OEM3 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIRLite.ButtonFlags.OEM3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to LC.
- ///
- public static string Enum_AYANEOAIRLite_ButtonFlags_OEM4 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIRLite.ButtonFlags.OEM4", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to AYA.
- ///
- public static string Enum_AYANEOAIRPro_ButtonFlags_OEM1 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIRPro.ButtonFlags.OEM1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to ≈.
- ///
- public static string Enum_AYANEOAIRPro_ButtonFlags_OEM2 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIRPro.ButtonFlags.OEM2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to RC.
- ///
- public static string Enum_AYANEOAIRPro_ButtonFlags_OEM3 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIRPro.ButtonFlags.OEM3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to LC.
- ///
- public static string Enum_AYANEOAIRPro_ButtonFlags_OEM4 {
- get {
- return ResourceManager.GetString("Enum.AYANEOAIRPro.ButtonFlags.OEM4", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cross.
- ///
- public static string Enum_DS4Controller_ButtonFlags_B1 {
- get {
- return ResourceManager.GetString("Enum.DS4Controller.ButtonFlags.B1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Circle.
- ///
- public static string Enum_DS4Controller_ButtonFlags_B2 {
- get {
- return ResourceManager.GetString("Enum.DS4Controller.ButtonFlags.B2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Square.
- ///
- public static string Enum_DS4Controller_ButtonFlags_B3 {
- get {
- return ResourceManager.GetString("Enum.DS4Controller.ButtonFlags.B3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Triangle.
- ///
- public static string Enum_DS4Controller_ButtonFlags_B4 {
- get {
- return ResourceManager.GetString("Enum.DS4Controller.ButtonFlags.B4", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Share.
- ///
- public static string Enum_DS4Controller_ButtonFlags_Back {
- get {
- return ResourceManager.GetString("Enum.DS4Controller.ButtonFlags.Back", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Sony.
- ///
- public static string Enum_DS4Controller_ButtonFlags_Special {
- get {
- return ResourceManager.GetString("Enum.DS4Controller.ButtonFlags.Special", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Options.
- ///
- public static string Enum_DS4Controller_ButtonFlags_Start {
- get {
- return ResourceManager.GetString("Enum.DS4Controller.ButtonFlags.Start", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to A.
- ///
- public static string Enum_GamepadButtonFlagsExt_A {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.A", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Always On.
- ///
- public static string Enum_GamepadButtonFlagsExt_AlwaysOn {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.AlwaysOn", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to B.
- ///
- public static string Enum_GamepadButtonFlagsExt_B {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.B", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Back.
- ///
- public static string Enum_GamepadButtonFlagsExt_Back {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.Back", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to DPad Down.
- ///
- public static string Enum_GamepadButtonFlagsExt_DPadDown {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.DPadDown", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to DPad Left.
- ///
- public static string Enum_GamepadButtonFlagsExt_DPadLeft {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.DPadLeft", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to DPad Right.
- ///
- public static string Enum_GamepadButtonFlagsExt_DPadRight {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.DPadRight", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to DPad Up.
- ///
- public static string Enum_GamepadButtonFlagsExt_DPadUp {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.DPadUp", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Shoulder.
- ///
- public static string Enum_GamepadButtonFlagsExt_LeftShoulder {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.LeftShoulder", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Thumb.
- ///
- public static string Enum_GamepadButtonFlagsExt_LeftThumb {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.LeftThumb", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Trigger.
- ///
- public static string Enum_GamepadButtonFlagsExt_LeftTrigger {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.LeftTrigger", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Shoulder.
- ///
- public static string Enum_GamepadButtonFlagsExt_RightShoulder {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.RightShoulder", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Thumb.
- ///
- public static string Enum_GamepadButtonFlagsExt_RightThumb {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.RightThumb", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Trigger.
- ///
- public static string Enum_GamepadButtonFlagsExt_RightTrigger {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.RightTrigger", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Start.
- ///
- public static string Enum_GamepadButtonFlagsExt_Start {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.Start", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to X.
- ///
- public static string Enum_GamepadButtonFlagsExt_X {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.X", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Y.
- ///
- public static string Enum_GamepadButtonFlagsExt_Y {
- get {
- return ResourceManager.GetString("Enum.GamepadButtonFlagsExt.Y", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Emulated DualShock 4 controller.
- ///
- public static string Enum_HIDmode_DualShock4Controller {
- get {
- return ResourceManager.GetString("Enum.HIDmode.DualShock4Controller", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No emulated controller.
- ///
- public static string Enum_HIDmode_NoController {
- get {
- return ResourceManager.GetString("Enum.HIDmode.NoController", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Emulated XBOX 360 controller.
- ///
- public static string Enum_HIDmode_Xbox360Controller {
- get {
- return ResourceManager.GetString("Enum.HIDmode.Xbox360Controller", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Connected.
- ///
- public static string Enum_HIDstatus_Connected {
- get {
- return ResourceManager.GetString("Enum.HIDstatus.Connected", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Disconnected.
- ///
- public static string Enum_HIDstatus_Disconnected {
- get {
- return ResourceManager.GetString("Enum.HIDstatus.Disconnected", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Auto Roll Yaw Swap.
- ///
- public static string Enum_Input_AutoRollYawSwap {
- get {
- return ResourceManager.GetString("Enum.Input.AutoRollYawSwap", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Joystick camera.
- ///
- public static string Enum_Input_JoystickCamera {
- get {
- return ResourceManager.GetString("Enum.Input.JoystickCamera", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Joystick steering.
- ///
- public static string Enum_Input_JoystickSteering {
- get {
- return ResourceManager.GetString("Enum.Input.JoystickSteering", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Player space.
- ///
- public static string Enum_Input_PlayerSpace {
- get {
- return ResourceManager.GetString("Enum.Input.PlayerSpace", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Custom.
- ///
- public static string Enum_InputsHotkeyType_Custom {
- get {
- return ResourceManager.GetString("Enum.InputsHotkeyType.Custom", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Device.
- ///
- public static string Enum_InputsHotkeyType_Device {
- get {
- return ResourceManager.GetString("Enum.InputsHotkeyType.Device", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Handheld Companion.
- ///
- public static string Enum_InputsHotkeyType_Handheld {
- get {
- return ResourceManager.GetString("Enum.InputsHotkeyType.Handheld", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Handheld Companion.
- ///
- public static string Enum_InputsHotkeyType_HC {
- get {
- return ResourceManager.GetString("Enum.InputsHotkeyType.HC", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Overlay.
- ///
- public static string Enum_InputsHotkeyType_Overlay {
- get {
- return ResourceManager.GetString("Enum.InputsHotkeyType.Overlay", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Quick tools.
- ///
- public static string Enum_InputsHotkeyType_Quicktools {
- get {
- return ResourceManager.GetString("Enum.InputsHotkeyType.Quicktools", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Windows.
- ///
- public static string Enum_InputsHotkeyType_Windows {
- get {
- return ResourceManager.GetString("Enum.InputsHotkeyType.Windows", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Auto Roll Yaw Swap.
- ///
- public static string Enum_MotionInput_AutoRollYawSwap {
- get {
- return ResourceManager.GetString("Enum.MotionInput.AutoRollYawSwap", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Joystick Camera.
- ///
- public static string Enum_MotionInput_JoystickCamera {
- get {
- return ResourceManager.GetString("Enum.MotionInput.JoystickCamera", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Joystick Steering.
- ///
- public static string Enum_MotionInput_JoystickSteering {
- get {
- return ResourceManager.GetString("Enum.MotionInput.JoystickSteering", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Player Space.
- ///
- public static string Enum_MotionInput_PlayerSpace {
- get {
- return ResourceManager.GetString("Enum.MotionInput.PlayerSpace", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Stick.
- ///
- public static string Enum_MotionOutput_LeftStick {
- get {
- return ResourceManager.GetString("Enum.MotionOutput.LeftStick", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Stick.
- ///
- public static string Enum_MotionOutput_RightStick {
- get {
- return ResourceManager.GetString("Enum.MotionOutput.RightStick", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to A.
- ///
- public static string Enum_NeptuneController_ButtonFlags_B1 {
- get {
- return ResourceManager.GetString("Enum.NeptuneController.ButtonFlags.B1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to B.
- ///
- public static string Enum_NeptuneController_ButtonFlags_B2 {
- get {
- return ResourceManager.GetString("Enum.NeptuneController.ButtonFlags.B2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to X.
- ///
- public static string Enum_NeptuneController_ButtonFlags_B3 {
- get {
- return ResourceManager.GetString("Enum.NeptuneController.ButtonFlags.B3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Y.
- ///
- public static string Enum_NeptuneController_ButtonFlags_B4 {
- get {
- return ResourceManager.GetString("Enum.NeptuneController.ButtonFlags.B4", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to View.
- ///
- public static string Enum_NeptuneController_ButtonFlags_Back {
- get {
- return ResourceManager.GetString("Enum.NeptuneController.ButtonFlags.Back", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to STEAM.
- ///
- public static string Enum_NeptuneController_ButtonFlags_Special {
- get {
- return ResourceManager.GetString("Enum.NeptuneController.ButtonFlags.Special", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Menu.
- ///
- public static string Enum_NeptuneController_ButtonFlags_Start {
- get {
- return ResourceManager.GetString("Enum.NeptuneController.ButtonFlags.Start", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left joystick.
- ///
- public static string Enum_Output_LeftStick {
- get {
- return ResourceManager.GetString("Enum.Output.LeftStick", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right joystick.
- ///
- public static string Enum_Output_RightStick {
- get {
- return ResourceManager.GetString("Enum.Output.RightStick", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to This is your default controller profile. This profile will be applied for all your applications that do not have a specific profile. Some options requiring an executable might be disabled..
- ///
- public static string Enum_ProfileErrorCode_Default {
- get {
- return ResourceManager.GetString("Enum.ProfileErrorCode.Default", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Oops. This profile seems to be running. Some options requiring an executable may be disabled..
- ///
- public static string Enum_ProfileErrorCode_IsRunning {
- get {
- return ResourceManager.GetString("Enum.ProfileErrorCode.IsRunning", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Oops. It seems this profile does not have an executable. How is this even possible?.
- ///
- public static string Enum_ProfileErrorCode_MissingExecutable {
- get {
- return ResourceManager.GetString("Enum.ProfileErrorCode.MissingExecutable", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Oops. It seems this profile does not have a path to the application. Some options requiring an executable might be disabled..
- ///
- public static string Enum_ProfileErrorCode_MissingPath {
- get {
- return ResourceManager.GetString("Enum.ProfileErrorCode.MissingPath", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Oops. It seems you do not have the necessary permission level to modify the content of this application. Make sure you have started this program in administrator mode..
- ///
- public static string Enum_ProfileErrorCode_MissingPermission {
- get {
- return ResourceManager.GetString("Enum.ProfileErrorCode.MissingPermission", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Nothing to see here..
- ///
- public static string Enum_ProfileErrorCode_None {
- get {
- return ResourceManager.GetString("Enum.ProfileErrorCode.None", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Oops. It seems this profile excutable is running. Some options requiring an executable might be disabled..
- ///
- public static string Enum_ProfileErrorCode_Running {
- get {
- return ResourceManager.GetString("Enum.ProfileErrorCode.Running", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Default.
- ///
- public static string Enum_QualityOfServiceLevel_Default {
- get {
- return ResourceManager.GetString("Enum.QualityOfServiceLevel.Default", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Eco.
- ///
- public static string Enum_QualityOfServiceLevel_Eco {
- get {
- return ResourceManager.GetString("Enum.QualityOfServiceLevel.Eco", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to High.
- ///
- public static string Enum_QualityOfServiceLevel_High {
- get {
- return ResourceManager.GetString("Enum.QualityOfServiceLevel.High", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Command center.
- ///
- public static string Enum_ROGAlly_ButtonFlags_OEM1 {
- get {
- return ResourceManager.GetString("Enum.ROGAlly.ButtonFlags.OEM1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Armory crate.
- ///
- public static string Enum_ROGAlly_ButtonFlags_OEM2 {
- get {
- return ResourceManager.GetString("Enum.ROGAlly.ButtonFlags.OEM2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to M1 / M2.
- ///
- public static string Enum_ROGAlly_ButtonFlags_OEM3 {
- get {
- return ResourceManager.GetString("Enum.ROGAlly.ButtonFlags.OEM3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Automatic.
- ///
- public static string Enum_ServiceStartMode_Automatic {
- get {
- return ResourceManager.GetString("Enum.ServiceStartMode.Automatic", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Disabled.
- ///
- public static string Enum_ServiceStartMode_Disabled {
- get {
- return ResourceManager.GetString("Enum.ServiceStartMode.Disabled", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Manual.
- ///
- public static string Enum_ServiceStartMode_Manual {
- get {
- return ResourceManager.GetString("Enum.ServiceStartMode.Manual", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Options.
- ///
- public static string Enum_SteamDeck_ButtonFlags_OEM1 {
- get {
- return ResourceManager.GetString("Enum.SteamDeck.ButtonFlags.OEM1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to L2.
- ///
- public static string Enum_XInputController_AxisLayoutFlags_L2 {
- get {
- return ResourceManager.GetString("Enum.XInputController.AxisLayoutFlags.L2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Thumb.
- ///
- public static string Enum_XInputController_AxisLayoutFlags_LeftThumb {
- get {
- return ResourceManager.GetString("Enum.XInputController.AxisLayoutFlags.LeftThumb", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to R2.
- ///
- public static string Enum_XInputController_AxisLayoutFlags_R2 {
- get {
- return ResourceManager.GetString("Enum.XInputController.AxisLayoutFlags.R2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Thumb.
- ///
- public static string Enum_XInputController_AxisLayoutFlags_RightThumb {
- get {
- return ResourceManager.GetString("Enum.XInputController.AxisLayoutFlags.RightThumb", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to A.
- ///
- public static string Enum_XInputController_ButtonFlags_B1 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.B1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to B.
- ///
- public static string Enum_XInputController_ButtonFlags_B2 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.B2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to X.
- ///
- public static string Enum_XInputController_ButtonFlags_B3 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.B3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Y.
- ///
- public static string Enum_XInputController_ButtonFlags_B4 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.B4", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to B5.
- ///
- public static string Enum_XInputController_ButtonFlags_B5 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.B5", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to B6.
- ///
- public static string Enum_XInputController_ButtonFlags_B6 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.B6", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to B7.
- ///
- public static string Enum_XInputController_ButtonFlags_B7 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.B7", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to B8.
- ///
- public static string Enum_XInputController_ButtonFlags_B8 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.B8", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to View.
- ///
- public static string Enum_XInputController_ButtonFlags_Back {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.Back", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to DPad Down.
- ///
- public static string Enum_XInputController_ButtonFlags_DPadDown {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.DPadDown", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to DPad Left.
- ///
- public static string Enum_XInputController_ButtonFlags_DPadLeft {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.DPadLeft", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to PPad Right.
- ///
- public static string Enum_XInputController_ButtonFlags_DPadRight {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.DPadRight", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to DPad Up.
- ///
- public static string Enum_XInputController_ButtonFlags_DPadUp {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.DPadUp", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to LB.
- ///
- public static string Enum_XInputController_ButtonFlags_L1 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.L1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to L2.
- ///
- public static string Enum_XInputController_ButtonFlags_L2 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.L2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to L3.
- ///
- public static string Enum_XInputController_ButtonFlags_L3 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.L3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to L4.
- ///
- public static string Enum_XInputController_ButtonFlags_L4 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.L4", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to L5.
- ///
- public static string Enum_XInputController_ButtonFlags_L5 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.L5", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Thumb.
- ///
- public static string Enum_XInputController_ButtonFlags_LeftThumb {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.LeftThumb", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Thumb Down.
- ///
- public static string Enum_XInputController_ButtonFlags_LeftThumbDown {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.LeftThumbDown", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Thumb Left.
- ///
- public static string Enum_XInputController_ButtonFlags_LeftThumbLeft {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.LeftThumbLeft", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Thumb Right.
- ///
- public static string Enum_XInputController_ButtonFlags_LeftThumbRight {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.LeftThumbRight", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Left Thumb Up.
- ///
- public static string Enum_XInputController_ButtonFlags_LeftThumbUp {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.LeftThumbUp", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to OEM1.
- ///
- public static string Enum_XInputController_ButtonFlags_OEM1 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.OEM1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to OEM2.
- ///
- public static string Enum_XInputController_ButtonFlags_OEM2 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.OEM2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to OEM3.
- ///
- public static string Enum_XInputController_ButtonFlags_OEM3 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.OEM3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to RB.
- ///
- public static string Enum_XInputController_ButtonFlags_R1 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.R1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to R2.
- ///
- public static string Enum_XInputController_ButtonFlags_R2 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.R2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to R3.
- ///
- public static string Enum_XInputController_ButtonFlags_R3 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.R3", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to R4.
- ///
- public static string Enum_XInputController_ButtonFlags_R4 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.R4", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to R5.
- ///
- public static string Enum_XInputController_ButtonFlags_R5 {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.R5", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Thumb.
- ///
- public static string Enum_XInputController_ButtonFlags_RightThumb {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.RightThumb", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Thumb Down.
- ///
- public static string Enum_XInputController_ButtonFlags_RightThumbDown {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.RightThumbDown", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Thumb Left.
- ///
- public static string Enum_XInputController_ButtonFlags_RightThumbLeft {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.RightThumbLeft", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Thumb Right.
- ///
- public static string Enum_XInputController_ButtonFlags_RightThumbRight {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.RightThumbRight", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Right Thumb Up.
- ///
- public static string Enum_XInputController_ButtonFlags_RightThumbUp {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.RightThumbUp", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Guide.
- ///
- public static string Enum_XInputController_ButtonFlags_Special {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.Special", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Menu.
- ///
- public static string Enum_XInputController_ButtonFlags_Start {
- get {
- return ResourceManager.GetString("Enum.XInputController.ButtonFlags.Start", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to This input will operate as a simple joystick. This is intended for traditional joystick applications.
- ///
- public static string JoystickCameraDesc {
- get {
- return ResourceManager.GetString("JoystickCameraDesc", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to This input will operate as a joystick optimized for controlling a steering wheel or a racing game.
- ///
- public static string JoystickSteeringDesc {
- get {
- return ResourceManager.GetString("JoystickSteeringDesc", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to This input will operate as a joystick optimized for controlling a first or third person camera.
- ///
- public static string PlayerSpaceDesc {
- get {
- return ResourceManager.GetString("PlayerSpaceDesc", resourceCulture);
- }
- }
- }
-}
diff --git a/ControllerCommon/Properties/Resources.de-DE.resx b/ControllerCommon/Properties/Resources.de-DE.resx
deleted file mode 100644
index 006c7ec79..000000000
--- a/ControllerCommon/Properties/Resources.de-DE.resx
+++ /dev/null
@@ -1,531 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Dieser Eingang funktioniert wie ein einfacher Joystick. Ideal für Laptops und Clamshell-Handhelds, automatischer Yaw-Roll-Wechsel je nachdem, wie das Gerät gehalten wird (90 oder 180 Grad geöffnet).
-
-
- Taste A
-
-
- Immer an
-
-
- Button B
-
-
- Zurück
-
-
- Unten
-
-
- Links
-
-
- Rechts
-
-
- Hoch
-
-
- Linke Schultertaste
-
-
- Linker Stick
-
-
- Linke Analogtaste
-
-
- Rechte Schultertaste
-
-
- Rechter Stick
-
-
- Rechte Triggertaste
-
-
- Start
-
-
- X-Taste
-
-
- Y-Taste
-
-
- Emulierter DualShock 4 Controller
-
-
- Kein emulierter Controller
-
-
- Emulierter XBOX 360 Controller
-
-
- Verbunden
-
-
- Getrennt
-
-
- Auto-Roll-Gier-Swap
-
-
- Joystick-Kamera
-
-
- Joystick-Lenkung
-
-
- Player space
-
-
- Handheld Companion
-
-
- Overlay
-
-
- QuickTools
-
-
- Windows
-
-
- Linker Joystick
-
-
- Rechter Joystick
-
-
- Hoppla. Es scheint, dass dieses Profil ausgeführt wird. Einige Optionen, die eine ausführbare Datei erfordern, sind möglicherweise deaktiviert.
-
-
- Hoppla. Es scheint, dass dieses Profil keine ausführbare Datei hat. Wie ist das überhaupt möglich?
-
-
- Hoppla, Es scheint, dass dieses Profil keinen Pfad zu der Anwendung enthält. Einige Optionen, die eine ausführbare Datei erfordern, sind möglicherweise deaktiviert.
-
-
- Hoppla. Es scheint, dass Sie nicht über die erforderliche Berechtigungsstufe verfügen, um den Inhalt dieser Anwendung zu ändern. Vergewissern Sie sich, dass Sie das Programm im Administratormodus gestartet haben.
-
-
- Hier gibt es nichts zu sehen.
-
-
- Standard
-
-
- Eco
-
-
- Hoch
-
-
- Automatisch
-
-
- Deaktiviert
-
-
- Manuell
-
-
- Dieser Eingang funktioniert wie ein einfacher Joystick. Er ist für traditionelle Joystick-Anwendungen gedacht
-
-
- Dieser Eingang funktioniert wie ein Joystick, der für die Steuerung eines Lenkrads oder eines Rennspiels optimiert ist.
-
-
- Diese Eingabe funktioniert wie ein Joystick, der für die Steuerung einer First- oder Third-Person-Kamera optimiert ist
-
-
- Handheld Companion
-
-
- ≈
-
-
- ≈
-
-
- ≈
-
-
- ≈
-
-
- AYA
-
-
- AYA
-
-
- AYA
-
-
- AYA
-
-
- KB
-
-
- RC
-
-
- LC
-
-
- RC
-
-
- LC
-
-
- RC
-
-
- LC
-
-
- Win
-
-
- Esc
-
-
- RC
-
-
- LC
-
-
- Dies ist Ihr Standard-Controller-Profil. Dieses Profil wird für alle Ihre Anwendungen verwendet, die kein spezifisches Profil haben. Einige Optionen, die eine ausführbare Datei erfordern, sind möglicherweise deaktiviert.
-
-
- M1 / M2
-
-
- Kreuz
-
-
- Kreis
-
-
- Viereck
-
-
- Dreieck
-
-
- Teilen
-
-
- Sony
-
-
- Optionen
-
-
- Benutzerdefiniert
-
-
- Gerät
-
-
- Auto-Roll-Gier-Swap
-
-
- Joystick Camera
-
-
- Joystick Steering
-
-
- Player Space
-
-
- Linker Stick
-
-
- Rechter Stick
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- Anzeigen
-
-
- STEAM
-
-
- Menü
-
-
- Hoppla, It seems this profile excutable is running. Some options requiring an executable might be disabled.
-
-
- Command Center
-
-
- Armory Crate
-
-
- Optionen
-
-
- L2
-
-
- Linker Stick
-
-
- R2
-
-
- Rechter Stick
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- B5
-
-
- B6
-
-
- B7
-
-
- B8
-
-
- Anzeigen
-
-
- Unten
-
-
- Links
-
-
- PPad Rechts
-
-
- Hoch
-
-
- LB
-
-
- L2
-
-
- L3
-
-
- L4
-
-
- L5
-
-
- Linker Stick
-
-
- Linker Stick unten
-
-
- Linker Stick links
-
-
- Linker Stick rechts
-
-
- Linker Stick oben
-
-
- OEM1
-
-
- OEM2
-
-
- OEM3
-
-
- RB
-
-
- R2
-
-
- R3
-
-
- R4
-
-
- R5
-
-
- Rechter Stick
-
-
- Rechter Stick unten
-
-
- Rechter Stick links
-
-
- Rechter Stick rechts
-
-
- Rechter Stick oben
-
-
- XBOX-Taste
-
-
- Menü
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Properties/Resources.es-ES.resx b/ControllerCommon/Properties/Resources.es-ES.resx
deleted file mode 100644
index 7f659a38d..000000000
--- a/ControllerCommon/Properties/Resources.es-ES.resx
+++ /dev/null
@@ -1,531 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Esta entrada funcionará como un simple joystick. Ideal para portátiles y dispositivos de mano tipo clamshell, cambio automático de balanceo de guiñada en función de cómo se sostenga el dispositivo (90 o 180 grados abiertos).
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- Equis
-
-
- Circulo
-
-
- Cuadrado
-
-
- Triangulo
-
-
- Share
-
-
- Sony
-
-
- Opciones
-
-
- Controlador DualShock 4 emulado
-
-
- Sin controlador emulado
-
-
- Controladora XBOX 360 emulada
-
-
- Conectado
-
-
- Desconectado
-
-
- Auto Roll Yaw Swap
-
-
- Cámara con joystick
-
-
- Dirección con joystick
-
-
- Espacio del jugador
-
-
- Handheld Companion
-
-
- Sobreposicion
-
-
- Herramientas rápidas
-
-
- Windows
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- Menu
-
-
- Joystick izquierdo
-
-
- Joystick derecho
-
-
- Este es su perfil de controlador predeterminado. Este perfil se aplicará a todas tus aplicaciones que no tengan un perfil específico. Algunas opciones que requieren un ejecutable pueden estar deshabilitadas.
-
-
- Ups. Parece que este perfil no tiene un ejecutable. Como es esto posible?
-
-
- Ups. Parece que este perfil no tiene una ruta a la aplicación. Algunas opciones que requieren un ejecutable pueden estar deshabilitadas.
-
-
- Ups. Parece que no tienes el nivel de permiso necesario para modificar el contenido de esta aplicación. Asegúrese de haber iniciado este programa en modo administrador.
-
-
- Nada que ver aqui.
-
-
- Ups. Parece que este perfil ejecutable se está ejecutando. Algunas opciones que requieren un ejecutable pueden estar deshabilitadas.
-
-
- Por defecto
-
-
- Eco
-
-
- Alta
-
-
- Automatico
-
-
- Desactivado
-
-
- Manual
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- LB
-
-
- RB
-
-
- Guide
-
-
- Menu
-
-
- Esta entrada funcionará como un simple joystick. Esto está diseñado para aplicaciones de joystick tradicionales.
-
-
- Esta entrada funcionará como un joystick optimizado para controlar un volante o un juego de carreras.
-
-
- Esta entrada funcionará como un joystick optimizado para controlar una cámara en primera o tercera persona
-
-
- Handheld Companion
-
-
- Opciones
-
-
- STEAM
-
-
- Command center
-
-
- Armory crate
-
-
- M1 / M2
-
-
- Right Thumb Down
-
-
- Right Thumb Left
-
-
- Right Thumb Right
-
-
- Right Thumb Up
-
-
- A
-
-
- Always On
-
-
- B
-
-
- Back
-
-
- Right Thumb
-
-
- DPad Down
-
-
- DPad Right
-
-
- DPad Up
-
-
- Left Shoulder
-
-
- Left Thumb
-
-
- Left Trigger
-
-
- Right Shoulder
-
-
- Right Thumb
-
-
- Right Trigger
-
-
- DPad Left
-
-
- R5
-
-
- R4
-
-
- R3
-
-
- B7
-
-
- B8
-
-
- DPad Down
-
-
- DPad Left
-
-
- PPad Right
-
-
- DPad Up
-
-
- L2
-
-
- L3
-
-
- L4
-
-
- L5
-
-
- Left Thumb
-
-
- Left Thumb Down
-
-
- Left Thumb Left
-
-
- Left Thumb Right
-
-
- Left Thumb Up
-
-
- OEM1
-
-
- OEM2
-
-
- OEM3
-
-
- R2
-
-
- Start
-
-
- X
-
-
- Y
-
-
- Oops. This profile seems to be running. Some options requiring an executable may be disabled.
-
-
- B6
-
-
- B5
-
-
- R2
-
-
- Right Thumb
-
-
- Esc
-
-
- KB
-
-
- Custom
-
-
- Device
-
-
- Joystick Camera
-
-
- Joystick Steering
-
-
- Player Space
-
-
- Left Stick
-
-
- Right Stick
-
-
- L2
-
-
- Left Thumb
-
-
- Auto Roll Yaw Swap
-
-
- Win
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Properties/Resources.fr-FR.resx b/ControllerCommon/Properties/Resources.fr-FR.resx
deleted file mode 100644
index 426c5cedc..000000000
--- a/ControllerCommon/Properties/Resources.fr-FR.resx
+++ /dev/null
@@ -1,532 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- This input will operate as a simple joystick. Ideal for laptop and clamshell type handhelds, automatic yaw roll swap based on how device is being held (90 or 180 degree open).
-
-
- Bouton A
-
-
- Toujours activé
-
-
- Bouton B
-
-
- Retour
-
-
- DPAD - Bas
-
-
- DPAD - Gauche
-
-
- DPAD - Droit
-
-
- DPAD - Bas
-
-
- Gâchette haute gauche
-
-
- Clic stick gauche
-
-
- Gâchette gauche
-
-
- Gâchette haute droite
-
-
- Clic stick droit
-
-
- Gâchette droite
-
-
- Menu
-
-
- Bouton X
-
-
- Bouton Y
-
-
- Contrôleur DualShock 4 émulé
-
-
- Aucun contrôleur émulé
-
-
- Contrôleur XBOX 360 émulé
-
-
- Connecté
-
-
- Déconnecté
-
-
- Auto Roll Yaw Swap
-
-
- Caméra joystick
-
-
- Conduite par joystick
-
-
- Player space
- A traduire...
-
-
- Joystick gauche
-
-
- Joystick droit
-
-
- Il s'agit de votre profil de contrôleur par défaut. Ce profil sera appliqué pour toutes vos applications qui n'ont pas de profil spécifique. Certaines options nécessitant un exécutable peuvent être désactivées.
-
-
- Oups. Il semble que ce profil soit en cours d'exécution. Certaines options nécessitant un exécutable pourraient être désactivées.
-
-
- Oups. Il semble que ce profil n'ait pas d'exécutable. Comment cela est-il possible ?
-
-
- Oups. Il semble que ce profil ne dispose pas d'un chemin vers l'application. Certaines options nécessitant un exécutable pourraient être désactivées.
-
-
- Oups. Il semble que vous n'ayez pas le niveau de permission nécessaire pour modifier le contenu de cette application. Assurez-vous que vous avez lancé ce programme en mode administrateur.
-
-
- Rien à voir ici.
-
-
- Automatique
-
-
- Désactivé
-
-
- Manuel
-
-
- Cette entrée fonctionnera comme un simple joystick. Elle est destinée aux applications traditionnelles de joystick
-
-
- Cette entrée fonctionnera comme un joystick optimisé pour le contrôle d'un volant ou d'un jeu de course
-
-
- Cette entrée fonctionnera comme un joystick optimisé pour le contrôle d'une caméra à la première ou à la troisième personne
-
-
- Handheld Companion
-
-
- Overlay
-
-
- Quick tools
-
-
- Windows
-
-
- Default
-
-
- Eco
-
-
- High
-
-
- Handheld Companion
-
-
- ≈
-
-
- ≈
-
-
- ≈
-
-
- ≈
-
-
- AYA
-
-
- AYA
-
-
- AYA
-
-
- AYA
-
-
- KB
-
-
- RC
-
-
- LC
-
-
- RC
-
-
- LC
-
-
- RC
-
-
- LC
-
-
- Win
-
-
- Esc
-
-
- RC
-
-
- LC
-
-
- M1 / M2
-
-
- Cross
-
-
- Circle
-
-
- Square
-
-
- Triangle
-
-
- Share
-
-
- Sony
-
-
- Options
-
-
- Custom
-
-
- Device
-
-
- Auto Roll Yaw Swap
-
-
- Joystick Camera
-
-
- Joystick Steering
-
-
- Player Space
-
-
- Left Stick
-
-
- Right Stick
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- STEAM
-
-
- Menu
-
-
- Oops. It seems this profile excutable is running. Some options requiring an executable might be disabled.
-
-
- Command center
-
-
- Armory crate
-
-
- Options
-
-
- L2
-
-
- R2
-
-
- Right Thumb
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- B5
-
-
- B6
-
-
- B7
-
-
- B8
-
-
- View
-
-
- DPad Down
-
-
- DPad Left
-
-
- PPad Right
-
-
- DPad Up
-
-
- LB
-
-
- L2
-
-
- L3
-
-
- L4
-
-
- L5
-
-
- Left Thumb
-
-
- Left Thumb Down
-
-
- Left Thumb Left
-
-
- Left Thumb Right
-
-
- Left Thumb Up
-
-
- OEM1
-
-
- OEM2
-
-
- OEM3
-
-
- RB
-
-
- R2
-
-
- R3
-
-
- R4
-
-
- R5
-
-
- Right Thumb
-
-
- Right Thumb Down
-
-
- Right Thumb Left
-
-
- Right Thumb Right
-
-
- Right Thumb Up
-
-
- Guide
-
-
- Menu
-
-
- Left Thumb
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Properties/Resources.it-IT.resx b/ControllerCommon/Properties/Resources.it-IT.resx
deleted file mode 100644
index 69466e46d..000000000
--- a/ControllerCommon/Properties/Resources.it-IT.resx
+++ /dev/null
@@ -1,531 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Questo input funzionerà come un semplice joystick. Ideale per laptop e dispositivi portatili di tipo clamshell, lo scambio automatico di rollio di beccheggio in base al modo in cui il dispositivo viene tenuto (aperto a 90 o 180 gradi).
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- Croce
-
-
- Cerchio
-
-
- Quadrato
-
-
- Triangolo
-
-
- Condividi
-
-
- Sony
-
-
- Opzioni
-
-
- Controller DualShock 4 emulato
-
-
- Nessun controller emulato
-
-
- Controller XBOX 360 emulato
-
-
- Connesso
-
-
- Disconnesso
-
-
- Scambio automatico beccheggio-rollio
-
-
- Joystick telecamera
-
-
- Joystick sterzo
-
-
- Spazio del giocatore
-
-
- Handheld Companion
-
-
- Overlay
-
-
- Strumenti rapidi
-
-
- Windows
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- Vista
-
-
- Menu
-
-
- Joystick sinistro
-
-
- Joystick destro
-
-
- Questo è il tuo profilo controller predefinito. Questo profilo verrà applicato a tutte le tue applicazioni che non hanno un profilo specifico. Alcune opzioni che richiedono un'eseguibile potrebbero essere disabilitate.
-
-
- Oops. Sembra che questo profilo non abbia un'eseguibile. Come è possibile?
-
-
- Oops. Sembra che questo profilo non abbia un percorso per l'applicazione. Alcune opzioni che richiedono un'eseguibile potrebbero essere disabilitate.
-
-
- Oops. Sembra che tu non abbia il livello di autorizzazione necessario per modificare il contenuto di questa applicazione. Assicurati di aver avviato questo programma in modalità amministratore.
-
-
- Niente da vedere qui.
-
-
- Oops. Sembra che l'eseguibile di questo profilo sia in esecuzione. Alcune opzioni che richiedono un'eseguibile potrebbero essere disabilitate.
-
-
- Predefinito
-
-
- Eco
-
-
- Alta
-
-
- Automatico
-
-
- Disabilitato
-
-
- Manuale
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- Vista
-
-
- LB
-
-
- RB
-
-
- Guida
-
-
- Menu
-
-
- Questo input funzionerà come un semplice joystick. È destinato alle applicazioni joystick tradizionali
-
-
- Questo input funzionerà come un joystick ottimizzato per il controllo di un volante o un gioco di guida
-
-
- Questo input funzionerà come un joystick ottimizzato per il controllo di una telecamera in prima o terza persona
-
-
- Handheld Companion
-
-
- Opzioni
-
-
- STEAM
-
-
- Centro comandi
-
-
- Cassetta dell'armatura
-
-
- M1 / M2
-
-
- Win
-
-
- Esc
-
-
- Tastiera
-
-
- Personalizzato
-
-
- Dispositivo
-
-
- Scambio automatico beccheggio-rollio
-
-
- Joystick telecamera
-
-
- Joystick sterzo
-
-
- Spazio del giocatore
-
-
- Joystick sinistro
-
-
- Joystick destro
-
-
- L2
-
-
- Levetta sinistra
-
-
- R2
-
-
- Levetta destra
-
-
- B5
-
-
- B6
-
-
- B7
-
-
- B8
-
-
- Pulsante D-Pad giù
-
-
- Pulsante D-Pad sinistra
-
-
- Pulsante D-Pad destra
-
-
- Pulsante D-Pad su
-
-
- L2
-
-
- L3
-
-
- L4
-
-
- L5
-
-
- Levetta sinistra
-
-
- Levetta sinistra giù
-
-
- Levetta sinistra sinistra
-
-
- Levetta sinistra destra
-
-
- Levetta sinistra su
-
-
- OEM1
-
-
- OEM2
-
-
- OEM3
-
-
- R2
-
-
- R3
-
-
- R4
-
-
- R5
-
-
- Levetta destra
-
-
- Levetta destra giù
-
-
- Levetta destra sinistra
-
-
- Levetta destra destra
-
-
- Levetta destra su
-
-
- A
-
-
- Always On
-
-
- B
-
-
- Indietro
-
-
- Pulsante D-Pad giù
-
-
- Pulsante D-Pad sinistra
-
-
- Pulsante D-Pad destra
-
-
- Pulsante D-Pad su
-
-
- Spalla sinistra
-
-
- Levetta sinistra
-
-
- Grilletto sinistro
-
-
- Spalla destra
-
-
- Levetta destra
-
-
- Grilletto destro
-
-
- Avvio
-
-
- X
-
-
- Y
-
-
- Oops. Sembra che questo profilo sia già in esecuzione. Alcune opzioni che richiedono un'eseguibile potrebbero essere disabilitate.
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Properties/Resources.ja-JP.resx b/ControllerCommon/Properties/Resources.ja-JP.resx
deleted file mode 100644
index 3d6c910f9..000000000
--- a/ControllerCommon/Properties/Resources.ja-JP.resx
+++ /dev/null
@@ -1,530 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- This input will operate as a simple joystick. Ideal for laptop and clamshell type handhelds, automatic yaw roll swap based on how device is being held (90 or 180 degree open).
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- Cross
-
-
- Circle
-
-
- Square
-
-
- Triangle
-
-
- Share
-
-
- Sony
-
-
- Options
-
-
- DualShock 4 コントローラー
-
-
- コントローラー無効
-
-
- XBOX 360 コントローラー
-
-
- 接続済み
-
-
- 切断
-
-
- Auto Roll Yaw Swap
-
-
- ジョイスティックカメラ
-
-
- ジョイスティックステアリング
-
-
- プレーヤースペース
-
-
- Handheld Companion
-
-
- オーバーレイ
-
-
- クイック ツール
-
-
- Windows
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- Menu
-
-
- 左ジョイスティック
-
-
- 右ジョイスティック
-
-
- デフォルトのコントローラー プロファイル
-
-
- 実行可能ファイルがありません
-
-
- アプリケーションへのパスがありません
-
-
- コンテンツを変更の権限がありません
-
-
- ここには何も表示されません
-
-
- このプロファイルは実行されています
-
-
- Default
-
-
- Eco
-
-
- High
-
-
- 自動
-
-
- 無効
-
-
- マニュアル
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- LB
-
-
- RB
-
-
- Guide
-
-
- Menu
-
-
- 単純なジョイスティックとして動作します。これは従来のジョイスティック アプリケーションを対象としています
-
-
- ステアリング ホイールやレーシング ゲームの制御に最適化されたジョイスティックとして動作します
-
-
- 一人称または三人称カメラの制御に最適化されたジョイスティックとして動作します
-
-
- Handheld Companion
-
-
- オプション
-
-
- STEAM
-
-
- KB
-
-
- Win
-
-
- Esc
-
-
- M1 / M2
-
-
- A
-
-
- Always On
-
-
- B
-
-
- Back
-
-
- DPad Down
-
-
- DPad Left
-
-
- DPad Right
-
-
- DPad Up
-
-
- Left Shoulder
-
-
- Left Thumb
-
-
- Left Trigger
-
-
- Right Shoulder
-
-
- Right Thumb
-
-
- Right Trigger
-
-
- Start
-
-
- X
-
-
- Y
-
-
- Custom
-
-
- Device
-
-
- Auto Roll Yaw Swap
-
-
- Joystick Camera
-
-
- Joystick Steering
-
-
- Player Space
-
-
- Left Stick
-
-
- Right Stick
-
-
- Oops. This profile seems to be running. Some options requiring an executable may be disabled.
-
-
- Command center
-
-
- Armory crate
-
-
- L2
-
-
- Left Thumb
-
-
- R2
-
-
- Right Thumb
-
-
- B5
-
-
- B6
-
-
- B7
-
-
- B8
-
-
- DPad Down
-
-
- DPad Left
-
-
- PPad Right
-
-
- DPad Up
-
-
- L2
-
-
- L3
-
-
- L4
-
-
- L5
-
-
- Left Thumb
-
-
- Left Thumb Down
-
-
- Left Thumb Left
-
-
- Left Thumb Right
-
-
- Left Thumb Up
-
-
- OEM1
-
-
- OEM2
-
-
- OEM3
-
-
- R2
-
-
- R3
-
-
- R4
-
-
- R5
-
-
- Right Thumb
-
-
- Right Thumb Down
-
-
- Right Thumb Left
-
-
- Right Thumb Right
-
-
- Right Thumb Up
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Properties/Resources.pt-BR.resx b/ControllerCommon/Properties/Resources.pt-BR.resx
deleted file mode 100644
index 7200217e3..000000000
--- a/ControllerCommon/Properties/Resources.pt-BR.resx
+++ /dev/null
@@ -1,531 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Esta entrada irá operar como um joystick simples. Ideal para notebook ou portáteis no estilo concha, alternada automática de rolagem de guinada baseado em como o dispositivo está sendo segurado (aberto em 90 ou 180 graus).
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- Cruz
-
-
- Círculo
-
-
- Quadrado
-
-
- Triângulo
-
-
- Share
-
-
- Sony
-
-
- Options
-
-
- Controle DualShock 4 emulado
-
-
- Sem controle emulado
-
-
- Controle XBOX 360 emulado
-
-
- Conectado
-
-
- Desconectado
-
-
- Alternar Rolagem de Guinada Auto
-
-
- Câmera de Joystick
-
-
- Joystick de direção (tipo volante)
-
-
- Espaço do jogador
-
-
- Handheld Companion
-
-
- Sobreposição
-
-
- Ferramentas rápidas
-
-
- Windows
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- Menu
-
-
- Analógico esquerdo
-
-
- Analógico direito
-
-
- Este é seu perfil padrão de controle. Este perfil será aplicado a todas as suas aplicações que não possuem um perfil específico. Algumas opções que requerem a definição de um arquivo executável estarão desabilitadas.
-
-
- Opa. Parece que esse perfil não possui um arquivo executável definido. Como isto será possível?
-
-
- Opa. Parece que esse perfil não possui um caminho de diretório até a aplicação. Algumas opções que requerem a definição de um arquivo executável estarão desabilitadas.
-
-
- Opa. Parece que você não possui o nível de permissão necessário para modificar o conteúdo desta aplicação. Certifique-se de iniciar este programa com privilégios administrativos.
-
-
- Nada para ver aqui.
-
-
- Opa. Parece que o arquivo executável deste perfil está em execução. Algumas opções estarão indisponíveis até que a execução seja encerrada.
-
-
- Padrão
-
-
- Eco
-
-
- Alta
-
-
- Automático
-
-
- Desabilitado
-
-
- Manual
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- LB
-
-
- RB
-
-
- Guia
-
-
- Menu
-
-
- Esta entrada irá operar como um joystick simples. Isto é voltado para aplicações que utilizam joystick tradicional
-
-
- Esta entrada irá operar como um joystick otimizado para controlar um volante ou um jogo de corrida
-
-
- Esta entrada irá operar como um joystick otimizado para controlar uma câmera em primeira ou terceira pessoa
-
-
- Handheld Companion
-
-
- Opções
-
-
- STEAM
-
-
- Centro de comando
-
-
- Armory crate
-
-
- M1 / M2
-
-
- Win
-
-
- Esc
-
-
- KB
-
-
- Personalizado
-
-
- Dispositivo
-
-
- Troca automática Rolamento e Leme
-
-
- Câmera de Joystick
-
-
- Direção de Joystick
-
-
- Espaço do Jogador
-
-
- Analógico Esquerdo
-
-
- Analógico Direito
-
-
- L2
-
-
- Analógico Esquerdo
-
-
- R2
-
-
- Analógico Direito
-
-
- B5
-
-
- B6
-
-
- B7
-
-
- B8
-
-
- DPad Baixo
-
-
- DPad Esquerda
-
-
- PPad Direita
-
-
- DPad Cima
-
-
- L2
-
-
- L3
-
-
- L4
-
-
- L5
-
-
- Analógico Esquerdo
-
-
- Analógico Esquerdo Baixo
-
-
- Analógico Esquerdo Esquerda
-
-
- Analógico Esquerdo Direita
-
-
- Analógico Esquerdo Cima
-
-
- OEM1
-
-
- OEM2
-
-
- OEM3
-
-
- R2
-
-
- R3
-
-
- R4
-
-
- R5
-
-
- Analógico Direito
-
-
- Analógico Direito Baixo
-
-
- Analógico Direito Esquerda
-
-
- Analógico Direito Direita
-
-
- Analógico Direito Cima
-
-
- A
-
-
- Sempre Ligado
-
-
- B
-
-
- Back
-
-
- DPad Baixo
-
-
- DPad Esquerda
-
-
- DPad Direita
-
-
- DPad Cima
-
-
- Ombro Esquerda
-
-
- Polegar Esquerda
-
-
- Gatilho Esquerda
-
-
- Ombro Direita
-
-
- Polegar Direita
-
-
- Gatilho Direita
-
-
- Start
-
-
- X
-
-
- Y
-
-
- Opa. Este perfil parece estar em execução algumas opções necessitam que o executável esteja encerrado.
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Properties/Resources.resx b/ControllerCommon/Properties/Resources.resx
deleted file mode 100644
index edb94fe40..000000000
--- a/ControllerCommon/Properties/Resources.resx
+++ /dev/null
@@ -1,531 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- This input will operate as a simple joystick. Ideal for laptop and clamshell type handhelds, automatic yaw roll swap based on how device is being held (90 or 180 degree open).
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- AYA
-
-
- ≈
-
-
- RC
-
-
- LC
-
-
- Cross
-
-
- Circle
-
-
- Square
-
-
- Triangle
-
-
- Share
-
-
- Sony
-
-
- Options
-
-
- Emulated DualShock 4 controller
-
-
- No emulated controller
-
-
- Emulated XBOX 360 controller
-
-
- Connected
-
-
- Disconnected
-
-
- Auto Roll Yaw Swap
-
-
- Joystick camera
-
-
- Joystick steering
-
-
- Player space
-
-
- Handheld Companion
-
-
- Overlay
-
-
- Quick tools
-
-
- Windows
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- Menu
-
-
- Left joystick
-
-
- Right joystick
-
-
- This is your default controller profile. This profile will be applied for all your applications that do not have a specific profile. Some options requiring an executable might be disabled.
-
-
- Oops. It seems this profile does not have an executable. How is this even possible?
-
-
- Oops. It seems this profile does not have a path to the application. Some options requiring an executable might be disabled.
-
-
- Oops. It seems you do not have the necessary permission level to modify the content of this application. Make sure you have started this program in administrator mode.
-
-
- Nothing to see here.
-
-
- Oops. It seems this profile excutable is running. Some options requiring an executable might be disabled.
-
-
- Default
-
-
- Eco
-
-
- High
-
-
- Automatic
-
-
- Disabled
-
-
- Manual
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- LB
-
-
- RB
-
-
- Guide
-
-
- Menu
-
-
- This input will operate as a simple joystick. This is intended for traditional joystick applications
-
-
- This input will operate as a joystick optimized for controlling a steering wheel or a racing game
-
-
- This input will operate as a joystick optimized for controlling a first or third person camera
-
-
- Handheld Companion
-
-
- Options
-
-
- STEAM
-
-
- Command center
-
-
- Armory crate
-
-
- M1 / M2
-
-
- Win
-
-
- Esc
-
-
- KB
-
-
- Custom
-
-
- Device
-
-
- Auto Roll Yaw Swap
-
-
- Joystick Camera
-
-
- Joystick Steering
-
-
- Player Space
-
-
- Left Stick
-
-
- Right Stick
-
-
- L2
-
-
- Left Thumb
-
-
- R2
-
-
- Right Thumb
-
-
- B5
-
-
- B6
-
-
- B7
-
-
- B8
-
-
- DPad Down
-
-
- DPad Left
-
-
- PPad Right
-
-
- DPad Up
-
-
- L2
-
-
- L3
-
-
- L4
-
-
- L5
-
-
- Left Thumb
-
-
- Left Thumb Down
-
-
- Left Thumb Left
-
-
- Left Thumb Right
-
-
- Left Thumb Up
-
-
- OEM1
-
-
- OEM2
-
-
- OEM3
-
-
- R2
-
-
- R3
-
-
- R4
-
-
- R5
-
-
- Right Thumb
-
-
- Right Thumb Down
-
-
- Right Thumb Left
-
-
- Right Thumb Right
-
-
- Right Thumb Up
-
-
- A
-
-
- Always On
-
-
- B
-
-
- Back
-
-
- DPad Down
-
-
- DPad Left
-
-
- DPad Right
-
-
- DPad Up
-
-
- Left Shoulder
-
-
- Left Thumb
-
-
- Left Trigger
-
-
- Right Shoulder
-
-
- Right Thumb
-
-
- Right Trigger
-
-
- Start
-
-
- X
-
-
- Y
-
-
- Oops. This profile seems to be running. Some options requiring an executable may be disabled.
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Properties/Resources.zh-CN.resx b/ControllerCommon/Properties/Resources.zh-CN.resx
deleted file mode 100644
index 8ef855ee0..000000000
--- a/ControllerCommon/Properties/Resources.zh-CN.resx
+++ /dev/null
@@ -1,531 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- 该模式适合笔记本或翻盖式掌机,可以根据该设备如何被握持(屏幕以90度角或者180度角打开)判断重力方向,来自动切换陀螺仪方向。
-
-
- A
-
-
- 始终开启
-
-
- B
-
-
- Back
-
-
- 下
-
-
- 左
-
-
- 右
-
-
- 上
-
-
- 左肩键
-
-
- 左摇杆按压
-
-
- 左板机
-
-
- 右肩键
-
-
- 右摇杆按压
-
-
- 右板机
-
-
- Start
-
-
- X
-
-
- Y
-
-
- 模拟 DualShock4 手柄
-
-
- 无模拟手柄
-
-
- 模拟 XBOX 360 手柄
-
-
- 已连接
-
-
- 未连接
-
-
- 重力轴向切换
-
-
- 体感视角
-
-
- 体感驾驶
-
-
- 玩家空间
-
-
- 掌机
-
-
- 浮窗
-
-
- 快捷工具
-
-
- 窗口
-
-
- 左摇杆
-
-
- 右摇杆
-
-
- 这是默认的全局配置。此配置将应用于没有特定配置的应用程序。一些需要指定程序才可生效的选项可能被禁用。
-
-
- 这个配置正在运行。一些选项可能被禁用。
-
-
- 这个配置似乎没有找到应用程序的可执行文件。
-
-
- 这个配置似乎没有找到指定的路径。
-
-
- 似乎你的权限不够更改这里的选项。请确保在管理员模式下启动此程序。
-
-
- 这里没什么东西。
-
-
- 默认
-
-
- 节能
-
-
- 高性能
-
-
- 自动
-
-
- 关闭
-
-
- 手动
-
-
- 这个模式将反转X轴,适用于将陀螺仪模拟鼠标。
-
-
- 这个模式适用于一些赛车游戏,陀螺仪输入将模拟方向盘。
-
-
- 这个模式适用于第一人称或第三人称视角的游戏,体感输入将模拟玩家视角,
-
-
- 掌机伴侣
-
-
- ≈
-
-
- ≈
-
-
- ≈
-
-
- ≈
-
-
- AYA
-
-
- AYA
-
-
- AYA
-
-
- AYA
-
-
- KB
-
-
- RC
-
-
- LC
-
-
- RC
-
-
- LC
-
-
- RC
-
-
- LC
-
-
- Win
-
-
- Esc
-
-
- RC
-
-
- LC
-
-
- M1 / M2
-
-
- 叉
-
-
- 圈
-
-
- 方
-
-
- 三角
-
-
- Share
-
-
- Sony
-
-
- Options
-
-
- 自定义
-
-
- 设备
-
-
- 重力切换模式
-
-
- X轴反转模式
-
-
- 方向盘模式
-
-
- 普通模式
-
-
- 左摇杆
-
-
- 右摇杆
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- STEAM
-
-
- Menu
-
-
- 这个配置正在运行。一些选项可能被禁用。
-
-
- Command center
-
-
- Armory crate
-
-
- Options
-
-
- L2
-
-
- 左摇杆
-
-
- R2
-
-
- 右摇杆
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- B5
-
-
- B6
-
-
- B7
-
-
- B8
-
-
- View
-
-
- 下方向键
-
-
- 左方向键
-
-
- 右方向键
-
-
- 上方向键
-
-
- LB
-
-
- LT
-
-
- L3
-
-
- L4
-
-
- L5
-
-
- 左摇杆
-
-
- 左摇杆下推
-
-
- 左摇杆左推
-
-
- 左摇杆右推
-
-
- 左摇杆上推
-
-
- OEM1
-
-
- OEM2
-
-
- OEM3
-
-
- RB
-
-
- RT
-
-
- R3
-
-
- R4
-
-
- R5
-
-
- 左摇杆
-
-
- 左摇杆下推
-
-
- 左摇杆左推
-
-
- 左摇杆右推
-
-
- 左摇杆上推
-
-
- 导航键
-
-
- Menu
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Properties/Resources.zh-Hant.resx b/ControllerCommon/Properties/Resources.zh-Hant.resx
deleted file mode 100644
index b165bc18c..000000000
--- a/ControllerCommon/Properties/Resources.zh-Hant.resx
+++ /dev/null
@@ -1,531 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- 該模式適合筆記本或翻蓋式掌機,可以根據該設備如何被握持(屏幕以90度角或者180度角打開)判斷重力方向,來自動切換陀螺儀方向。
-
-
- A
-
-
- 始終開啟
-
-
- B
-
-
- Back
-
-
- 下
-
-
- 左
-
-
- 右
-
-
- 上
-
-
- 左肩鍵
-
-
- 左搖杆按壓
-
-
- 左板機
-
-
- 右肩鍵
-
-
- 右搖杆按壓
-
-
- 右板機
-
-
- Start
-
-
- X
-
-
- Y
-
-
- 模擬 DualShock4 手柄
-
-
- 無模擬手柄
-
-
- 模擬 XBOX 360 手柄
-
-
- 已連接
-
-
- 未連接
-
-
- 重力軸向切換
-
-
- 體感視角
-
-
- 體感駕駛
-
-
- 玩家空間
-
-
- 掌機
-
-
- 浮窗
-
-
- 快捷工具
-
-
- 窗口
-
-
- 左搖杆
-
-
- 右搖杆
-
-
- 這是默認的全局配置。此配置將應用於沒有特定配置的應用程式。一些需要指定程序才可生效的選項可能被禁用。
-
-
- 這個配置正在運行。一些選項可能被禁用。
-
-
- 這個配置似乎沒有找到應用程式的可執行文件。
-
-
- 這個配置似乎沒有找到指定的路徑。
-
-
- 似乎你的權限不夠更改這裡的選項。請確保在管理員模式下啟動此程序。
-
-
- 這裡沒什麼東西。
-
-
- 默認
-
-
- 節能
-
-
- 高性能
-
-
- 自動
-
-
- 關閉
-
-
- 手動
-
-
- 這個模式將反轉X軸,適用於將陀螺儀模擬滑鼠。
-
-
- 這個模式適用於一些賽車遊戲,陀螺儀輸入將模擬方向盤。
-
-
- 這個模式適用於第一人稱或第三人稱視角的遊戲,體感輸入將模擬玩家視角,
-
-
- 掌機伴侶
-
-
- ≈
-
-
- ≈
-
-
- ≈
-
-
- ≈
-
-
- AYA
-
-
- AYA
-
-
- AYA
-
-
- AYA
-
-
- KB
-
-
- RC
-
-
- LC
-
-
- RC
-
-
- LC
-
-
- RC
-
-
- LC
-
-
- Win
-
-
- Esc
-
-
- RC
-
-
- LC
-
-
- M1 / M2
-
-
- 叉
-
-
- 圈
-
-
- 方
-
-
- 三角
-
-
- Share
-
-
- Sony
-
-
- Options
-
-
- 自定義
-
-
- 設備
-
-
- 重力切換模式
-
-
- X軸反轉模式
-
-
- 方向盤模式
-
-
- 普通模式
-
-
- 左搖杆
-
-
- 右搖杆
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- View
-
-
- STEAM
-
-
- Menu
-
-
- 這個配置正在運行。一些選項可能被禁用。
-
-
- Command center
-
-
- Armory crate
-
-
- Options
-
-
- L2
-
-
- 左搖杆
-
-
- R2
-
-
- 右搖杆
-
-
- A
-
-
- B
-
-
- X
-
-
- Y
-
-
- B5
-
-
- B6
-
-
- B7
-
-
- B8
-
-
- View
-
-
- 下方向鍵
-
-
- 左方向鍵
-
-
- 右方向鍵
-
-
- 上方向鍵
-
-
- LB
-
-
- LT
-
-
- L3
-
-
- L4
-
-
- L5
-
-
- 左搖杆
-
-
- 左搖杆下推
-
-
- 左搖杆左推
-
-
- 左搖杆右推
-
-
- 左搖杆上推
-
-
- OEM1
-
-
- OEM2
-
-
- OEM3
-
-
- RB
-
-
- RT
-
-
- R3
-
-
- R4
-
-
- R5
-
-
- 左搖杆
-
-
- 左搖杆下推
-
-
- 左搖杆左推
-
-
- 左搖杆右推
-
-
- 左搖杆上推
-
-
- 導航鍵
-
-
- Menu
-
-
\ No newline at end of file
diff --git a/ControllerCommon/Resources/devcon.exe b/ControllerCommon/Resources/devcon.exe
deleted file mode 100644
index f64189991..000000000
Binary files a/ControllerCommon/Resources/devcon.exe and /dev/null differ
diff --git a/ControllerCommon/SensorFusion.cs b/ControllerCommon/SensorFusion.cs
deleted file mode 100644
index a6e92ddd7..000000000
--- a/ControllerCommon/SensorFusion.cs
+++ /dev/null
@@ -1,225 +0,0 @@
-using System;
-using System.Numerics;
-using ControllerCommon.Utils;
-
-namespace ControllerCommon;
-
-public class SensorFusion
-{
- private readonly double AdditionalFactor = 60.0; // Bring more on par with gyro only
- public double CameraPitchDelta;
-
- // Player Space
- public double CameraYawDelta;
-
- // Device Angle
- public Vector2 DeviceAngle;
-
- private Vector3 GravityVectorFancy;
-
- // Gravity Simple
- public Vector3 GravityVectorSimple;
-
- // Gravity Fancy
- private float Shakiness;
- private Vector3 SmoothAccel;
-
- public void UpdateReport(double TotalMilliseconds, double DeltaSeconds, Vector3 AngularVelocity,
- Vector3 Acceleration)
- {
- // Check for empty inputs, prevent NaN computes
- Vector3 EmptyVector = new(0f, 0f, 0f);
-
- if (AngularVelocity.Equals(EmptyVector) || Acceleration.Equals(EmptyVector))
- return;
-
- // Perform calculations
- // Todo, kickstart gravity vector with = acceleration when calculation is either
- // run for the first time or is selcted to be run based on user profile?
-
- CalculateGravitySimple(TotalMilliseconds, DeltaSeconds, AngularVelocity, Acceleration);
- //CalculateGravityFancy(TotalMilliseconds, DeltaSeconds, AngularVelocity, Acceleration);
-
- DeviceAngles(TotalMilliseconds, GravityVectorSimple);
- PlayerSpace(TotalMilliseconds, DeltaSeconds, AngularVelocity, GravityVectorSimple);
- }
-
- public void CalculateGravitySimple(double TotalMilliseconds, double DeltaMilliseconds, Vector3 AngularVelocity,
- Vector3 Acceleration)
- {
- // Gravity determination using sensor fusion, "Something Simple" example from:
- // http://gyrowiki.jibbsmart.com/blog:finding-gravity-with-sensor-fusion
-
- // Convert to radian as per library spec
- var AngularVelocityRad = new Vector3(InputUtils.Deg2Rad(AngularVelocity.X),
- InputUtils.Deg2Rad(AngularVelocity.Y), InputUtils.Deg2Rad(AngularVelocity.Z));
-
- // Normalize before creating quat from axis angle as per library spec
- AngularVelocityRad = Vector3.Normalize(AngularVelocityRad);
-
- // Convert gyro input to reverse rotation
- var reverseRotation = Quaternion.CreateFromAxisAngle(-AngularVelocityRad,
- AngularVelocityRad.Length() * (float)DeltaMilliseconds);
-
- // Rotate gravity vector
- GravityVectorSimple = Vector3.Transform(GravityVectorSimple, reverseRotation);
-
- // Nudge towards gravity according to current acceleration
- var newGravity = -Acceleration;
- var gravityDelta = Vector3.Subtract(newGravity, GravityVectorSimple);
-
- GravityVectorSimple += Vector3.Multiply(0.02f, Vector3.Normalize(gravityDelta));
- }
-
- public void CalculateGravityFancy(double TotalMilliseconds, double DeltaTimeSec, Vector3 AngularVelocity,
- Vector3 Acceleration)
- {
- // TODO Does not work yet!!!
-
- // Gravity determination using sensor fusion, "Something Fancy" example from:
- // http://gyrowiki.jibbsmart.com/blog:finding-gravity-with-sensor-fusion
-
- // SETTINGS
- // the time it takes in our acceleration smoothing for 'A' to get halfway to 'B'
- var SmoothingHalfTime = 0.25f;
-
- // thresholds of trust for accel shakiness. less shakiness = more trust
- var ShakinessMaxThreshold = 0.4f;
- var ShakinessMinThreshold = 0.27f; //0.01f;
-
- // when we trust the accel a lot (the controller is "still"), how quickly do we correct our gravity vector?
- var CorrectionStillRate = 1f;
- // when we don't trust the accel (the controller is "shaky"), how quickly do we correct our gravity vector?
- var CorrectionShakyRate = 0.1f;
-
- // if our old gravity vector is close enough to our new one, limit further corrections to this proportion of the rotation speed
- var CorrectionGyroFactor = 0.1f;
- // thresholds for what's considered "close enough"
- var CorrectionGyroMinThreshold = 0.05f;
- var CorrectionGyroMaxThreshold = 0.25f;
-
- // no matter what, always apply a minimum of this much correction to our gravity vector
- var CorrectionMinimumSpeed = 0.01f;
-
- // Question
- // Isn't this always true with the default settings? if (ShakinessMaxThreshold > ShakinessMinThreshold)
-
- // Convert to radian as per library spec
- var AngularVelocityRad = new Vector3(InputUtils.Deg2Rad(AngularVelocity.X),
- InputUtils.Deg2Rad(AngularVelocity.Y), InputUtils.Deg2Rad(AngularVelocity.Z));
- // Normalize before creating quat from axis angle as per library spec
- AngularVelocityRad = Vector3.Normalize(AngularVelocityRad);
-
- // convert gyro input to reverse rotation
- var reverseRotation =
- Quaternion.CreateFromAxisAngle(-AngularVelocityRad, AngularVelocityRad.Length() * (float)DeltaTimeSec);
-
- // rotate gravity vector
- GravityVectorFancy = Vector3.Transform(GravityVectorFancy, reverseRotation);
-
- // Correction factor variables
- SmoothAccel = Vector3.Transform(SmoothAccel, reverseRotation);
-
- // Note to self, SmoothAccel seems OK.
- var smoothInterpolator = (float)Math.Pow(2, -(float)DeltaTimeSec / SmoothingHalfTime);
- // Note to self, SmoothInterpolator seems OK, still no sure about the Pow from C++ to C#, also, is it suppose to be a negative value?
-
- Shakiness *= smoothInterpolator;
- Shakiness = Math.Max(Shakiness,
- Vector3.Subtract(Acceleration, SmoothAccel)
- .Length()); // Does this apply vector subtract and length correctly?
- SmoothAccel =
- Vector3.Lerp(Acceleration, SmoothAccel,
- smoothInterpolator); // smoothInterpolator is a negative value, correct?
-
- var gravityDelta = Vector3.Subtract(-Acceleration, GravityVectorFancy);
- var gravityDirection = Vector3.Normalize(gravityDelta);
- float correctionRate;
-
- // Shakiness correction rate impact
- if (ShakinessMaxThreshold > ShakinessMinThreshold)
- {
- var stillOrShaky =
- Math.Clamp((Shakiness - ShakinessMinThreshold) / (ShakinessMaxThreshold - ShakinessMaxThreshold), 0, 1);
- correctionRate = CorrectionStillRate + (CorrectionShakyRate - CorrectionStillRate) * stillOrShaky;
- // 1 + (0.1 - 1) * 1 = 0.1
- // Note, found still or shaky to be a constant 1, correction rate to be a constant 0.1
- }
- else if (Shakiness > ShakinessMaxThreshold)
- {
- correctionRate = CorrectionShakyRate;
- }
- else
- {
- correctionRate = CorrectionStillRate;
- }
-
- // limit in proportion to rotation rate
- // my input library has the gyro report degrees per second, so convert to radians per second here
- var angleRate = AngularVelocity.Length() * (float)Math.PI / 180;
- var correctionLimit = angleRate * GravityVectorFancy.Length() * CorrectionGyroFactor;
-
- if (correctionRate > correctionLimit)
- {
- float closeEnoughFactor;
-
- if (CorrectionGyroMaxThreshold > CorrectionGyroMinThreshold)
- closeEnoughFactor =
- Math.Clamp(
- (gravityDelta.Length() - CorrectionGyroMinThreshold) /
- (CorrectionGyroMaxThreshold - CorrectionGyroMinThreshold), 0, 1);
- else if (gravityDelta.Length() > CorrectionGyroMaxThreshold)
- closeEnoughFactor = 1;
- else
- closeEnoughFactor = 0;
- correctionRate += (correctionLimit - correctionRate) * closeEnoughFactor;
- }
-
- // finally, let's always allow a little bit of correction
- correctionRate = Math.Max(correctionRate, CorrectionMinimumSpeed);
-
- // apply correction
- var correction = gravityDirection * (float)(correctionRate * DeltaTimeSec);
-
- if (correction.LengthSquared() < gravityDelta.LengthSquared())
- GravityVectorFancy += correction;
- else
- GravityVectorFancy += gravityDelta;
- }
-
- private void PlayerSpace(double TotalMilliseconds, double DeltaSeconds, Vector3 AngularVelocity,
- Vector3 GravityVector)
- {
- // PlayerSpace
- var GravityNorm = Vector3.Normalize(GravityVector);
-
- // Yaw (Use world yaw for yaw direction, local combined yaw for magnitude)
- // Dot product but just yaw and roll
- double worldYaw = AngularVelocity.Y * GravityNorm.Y + AngularVelocity.Z * GravityNorm.Z;
-
- // Handle NaN
- if (worldYaw == 0f) return;
-
- double yawRelaxFactor = 1.41f;
- Vector2 AngularVelocityYZ = new(AngularVelocity.Y, AngularVelocity.Z);
-
- CameraYawDelta = Math.Sign(worldYaw)
- * Math.Min(Math.Abs(worldYaw) * yawRelaxFactor, AngularVelocityYZ.Length())
- * AdditionalFactor * DeltaSeconds;
-
- // Pitch (local space)
- CameraPitchDelta = AngularVelocity.X * AdditionalFactor * DeltaSeconds;
- }
-
- private void DeviceAngles(double TotalMilliseconds, Vector3 GravityVector)
- {
- // Calculate angles around Y and X axis (Theta and Psi) using all 3 directions of accelerometer
- // Based on: https://www.digikey.com/en/articles/using-an-accelerometer-for-inclination-sensing
- DeviceAngle.X =
- (float)(Math.Atan(GravityVector.Y /
- Math.Sqrt(Math.Pow(GravityVector.X, 2) + Math.Pow(GravityVector.Z, 2))) * 180 / Math.PI);
- DeviceAngle.Y =
- (float)(Math.Atan(GravityVector.X /
- Math.Sqrt(Math.Pow(GravityVector.Y, 2) + Math.Pow(GravityVector.Z, 2))) * 180 / Math.PI);
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/ServiceHelper.cs b/ControllerCommon/ServiceHelper.cs
deleted file mode 100644
index 5e80e4a4d..000000000
--- a/ControllerCommon/ServiceHelper.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using System.ServiceProcess;
-
-namespace ControllerCommon;
-
-public static class ServiceHelper
-{
- private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
- private const uint SERVICE_QUERY_CONFIG = 0x00000001;
- private const uint SERVICE_CHANGE_CONFIG = 0x00000002;
- private const uint SC_MANAGER_ALL_ACCESS = 0x000F003F;
-
- [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
- public static extern bool ChangeServiceConfig(
- IntPtr hService,
- uint nServiceType,
- uint nStartType,
- uint nErrorControl,
- string lpBinaryPathName,
- string lpLoadOrderGroup,
- IntPtr lpdwTagId,
- [In] char[] lpDependencies,
- string lpServiceStartName,
- string lpPassword,
- string lpDisplayName);
-
- [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
- private static extern IntPtr OpenService(
- IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
-
- [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode,
- SetLastError = true)]
- public static extern IntPtr OpenSCManager(
- string machineName, string databaseName, uint dwAccess);
-
- [DllImport("advapi32.dll", EntryPoint = "CloseServiceHandle")]
- public static extern int CloseServiceHandle(IntPtr hSCObject);
-
- public static void ChangeStartMode(ServiceController svc, ServiceStartMode mode)
- {
- var scManagerHandle = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
- if (scManagerHandle == IntPtr.Zero)
- return;
-
- IntPtr serviceHandle;
- try
- {
- serviceHandle = OpenService(
- scManagerHandle,
- svc.ServiceName,
- SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
- }
- catch
- {
- // service was not found
- return;
- }
-
- if (serviceHandle == IntPtr.Zero)
- return;
-
- var result = ChangeServiceConfig(
- serviceHandle,
- SERVICE_NO_CHANGE,
- (uint)mode,
- SERVICE_NO_CHANGE,
- null,
- null,
- IntPtr.Zero,
- null,
- null,
- null,
- null);
-
- if (result == false)
- return;
-
- CloseServiceHandle(serviceHandle);
- CloseServiceHandle(scManagerHandle);
- }
-}
\ No newline at end of file
diff --git a/ControllerCommon/Utils/InputUtils.cs b/ControllerCommon/Utils/InputUtils.cs
deleted file mode 100644
index efb754dd6..000000000
--- a/ControllerCommon/Utils/InputUtils.cs
+++ /dev/null
@@ -1,308 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-
-namespace ControllerCommon.Utils;
-
-public struct SensorSpec
-{
- public float minIn;
- public float maxIn;
- public float minOut;
- public float maxOut;
-}
-
-public enum MotionInput
-{
- PlayerSpace = 0,
- JoystickCamera = 1,
- AutoRollYawSwap = 2,
- JoystickSteering = 3
-}
-
-public enum MotionMode
-{
- Off = 0,
- On = 1
-}
-
-public enum MotionOutput
-{
- LeftStick = 0,
-
- RightStick = 1
- /* [Description("Mouse")]
- Mouse = 2 */
-}
-
-public enum OverlayModelMode
-{
- OEM = 0,
- Virtual = 1,
- XboxOne = 2,
- ZDOPlus = 3,
- EightBitDoLite2 = 4,
- MachenikeHG510 = 5,
- Toy = 6,
- N64 = 7,
- DualSense = 8
-}
-
-public static class InputUtils
-{
- // Custom sensitivity
- // Interpolation function (linear), takes list of nodes coordinates and gamepad joystick position returns game input
- private static readonly int SensivityIdx = 2;
-
- public static float rangeMap(float value, SensorSpec spec)
- {
- var inRange = spec.maxIn - spec.minIn;
- var outRange = spec.maxOut - spec.minOut;
-
- return spec.minOut + outRange * ((value - spec.minIn) / inRange);
- }
-
- public static float Deg2Rad(float degrees)
- {
- return (float)(Math.PI / 180 * degrees);
- }
-
- public static float Rad2Deg(float rad)
- {
- return (float)(rad * (180 / Math.PI));
- }
-
- public static float MapRange(float value, float oldMin, float oldMax, float newMin, float newMax)
- {
- if (oldMin == oldMax)
- // Prevent division by zero
- return newMin;
-
- return newMin + (newMax - newMin) * (value - oldMin) / (oldMax - oldMin);
- }
-
- public static byte NormalizeXboxInput(float input)
- {
- input = Math.Clamp(input, short.MinValue, short.MaxValue);
- var output = input / ushort.MaxValue * byte.MaxValue + byte.MaxValue / 2.0f;
- return (byte)Math.Round(output);
- }
-
- public static float Steering(float deviceAngle, float deviceAngleMax, float toThePowerOf, float deadzoneAngle)
- {
- // Range angle y value (0 to user defined angle) into -1.0 to 1.0 position value taking into account deadzone angle
- var result = AngleToJoystickPos(deviceAngle, deviceAngleMax, deadzoneAngle);
-
- // Apply user-defined to the power of to joystick position
- result = DirectionRespectingPowerOf(result, toThePowerOf);
-
- // Scale joystick x position -1 to 1 to joystick range
- return -result * short.MaxValue;
- }
-
- // Determine -1 to 1 joystick position given user defined max input angle and dead zone
- // Angles in degrees
- public static float AngleToJoystickPos(float angle, float deviceAngleMax, float deadzoneAngle)
- {
- // Deadzone remapped angle, note this angle is no longer correct with device angle
- var result = (Math.Abs(angle) - deadzoneAngle) / (deviceAngleMax - deadzoneAngle) * deviceAngleMax;
-
- // Clamp deadzone remapped angle, prevents negative values when
- // actual device angle is below dead zone angle
- // Divide by max angle, angle to joystick position with user max
- result = Math.Clamp(result, 0, deviceAngleMax) / deviceAngleMax;
-
- // Apply the direction based on the original angle
- return angle < 0f ? -result : result;
- }
-
- // Apply power of to -1 to 1 joystick position while respecting direction
- public static float DirectionRespectingPowerOf(float joystickPos, float power)
- {
- var result = (float)Math.Pow(Math.Abs(joystickPos), power);
-
- // Apply direction based on the the original joystick position
- return joystickPos < 0.0 ? -result : result;
- }
-
- // Compensation for in-game deadzone
- // Inputs: raw ThumbValue and deadzone 0-100%
- // Should not be used under normal circumstances, in-game deadzone should be set to 0% if possible. Results in loss of resolution.
- // Use cases foreseen:
- // - Game has a deadzone but no way to configure or change it
- // - User does not want to change general emulator deadzone setting but wants it removed for a specific game and use UMC Steering
- public static Vector2 ApplyAntiDeadzone(Vector2 thumbValue, float deadzonePercentage)
- {
- // Return thumbValue if deadzone percentage is 0 or thumbValue is already zero
- if (deadzonePercentage.Equals(0.0f) || thumbValue == Vector2.Zero)
- return thumbValue;
-
- // Convert short value input to -1 to 1 range
- var stickInput = thumbValue / short.MaxValue;
-
- // Convert 0-100% deadzone to 0-1 range
- var deadzone = deadzonePercentage / 100f;
-
- // Map vector to new range by determining the multiplier
- var multiplier = ((1f - deadzone) * stickInput.Length() + deadzone) / stickInput.Length();
-
- // Convert -1 to 1 back to short value and return
- return stickInput * multiplier * short.MaxValue;
- }
-
- public static float ApplyAntiDeadzone(float ThumbValue, float DeadzonePercentage)
- {
- var StickInput = ThumbValue / short.MaxValue;
-
- if (DeadzonePercentage.Equals(0.0f) || StickInput <= DeadzonePercentage)
- return ThumbValue;
-
- var Deadzone = DeadzonePercentage / 100 * Math.Sign(ThumbValue);
- return (StickInput + Deadzone) * short.MaxValue;
- }
-
- public static Vector2 ImproveCircularity(Vector2 thumbValue)
- {
- // Convert short value input to -1 to 1 range
- var stickInput = thumbValue / short.MaxValue;
-
- // Return thumbValue if length is not longer than 1
- if (stickInput.LengthSquared() <= 1.0f)
- return thumbValue;
-
- // Cap vector length to 1 by normalizing it
- var normalizedInput = Vector2.Normalize(stickInput);
-
- // Convert -1 to 1 back to short value and return
- return normalizedInput * short.MaxValue;
- }
-
- // Triggers, inner and outer deadzone
- public static float InnerOuterDeadzone(float triggerInput, int innerDeadzonePercentage, int outerDeadzonePercentage,
- int maxValue)
- {
- // Return triggerInput if both inner and outer deadzones are 0 or if triggerInput is NaN or 0
- if ((innerDeadzonePercentage == 0 && outerDeadzonePercentage == 0) || float.IsNaN(triggerInput) ||
- triggerInput == 0.0f)
- return triggerInput;
-
- // Convert deadzone percentages to the 0-1 range
- var innerDeadzone = innerDeadzonePercentage / 100.0f;
- var outerDeadzone = outerDeadzonePercentage / 100.0f;
-
- // Convert 0-MaxValue range input to -1 to 1
- var trigger = Math.Abs(triggerInput / maxValue);
-
- // Trigger is either:
- // - Within inner deadzone, return 0
- // - Within outer deadzone, return max
- // - In between deadzone values, map accordingly
- if (trigger <= innerDeadzone)
- return 0.0f;
- if (trigger >= 1.0f - outerDeadzone)
- return triggerInput > 0 ? maxValue : -maxValue;
- // Map trigger to the new range and convert back to 0-MaxValue range
- return MapRange(trigger, innerDeadzone, 1.0f - outerDeadzone, 0, 1) * maxValue * Math.Sign(triggerInput);
- }
-
- // Inner and outer scaled radial deadzone
- public static Vector2 ThumbScaledRadialInnerOuterDeadzone(Vector2 ThumbValue, int InnerDeadzonePercentage,
- int OuterDeadzonePercentage)
- {
- // Return if thumbstick or deadzone is not used
- if ((InnerDeadzonePercentage.Equals(0) && OuterDeadzonePercentage.Equals(0)) || ThumbValue == Vector2.Zero)
- return ThumbValue;
-
- // Convert short value input to -1 to 1
- var StickInput = new Vector2(ThumbValue.X, ThumbValue.Y) / short.MaxValue;
-
- // Convert deadzone percentage to 0 - 1 range
- var InnerDeadZone = InnerDeadzonePercentage / 100.0f;
- var OuterDeadZone = OuterDeadzonePercentage / 100.0f;
-
- // Joystick is either:
- // - Within inner deadzone, return 0
- // - Within outer deadzone, return max
- // - In between deadzone values, map accordingly
- if (StickInput.Length() <= InnerDeadZone) return Vector2.Zero;
-
- if (StickInput.Length() >= 1 - OuterDeadZone)
- {
- // Cap vector length to 1 by determining the multiplier
- var Multiplier = 1 / StickInput.Length();
-
- // Convert -1 to 1 back to short value and return
- return StickInput * Multiplier * short.MaxValue;
- }
-
- // Normalize values, used for direction signs
- var StickValueNormalized = StickInput / StickInput.Length();
-
- // Map to new range
- var StickInputMapped =
- StickValueNormalized * MapRange(StickInput.Length(), InnerDeadZone, 1 - OuterDeadZone, 0, 1);
-
- // Return and convert from 0 1 range back to short
- return StickInputMapped * short.MaxValue;
- }
-
- public static float ApplyCustomSensitivity(float AngularValue, float MaxValue,
- SortedDictionary Nodes)
- {
- // Use absolute joystick position, range -1 to 1, re-apply direction later
- var JoystickPosAbs = Math.Abs(AngularValue / MaxValue);
- var JoystickPosAdjusted = 0.0f;
-
- // Check what we will be sending
- if (JoystickPosAbs <= 0)
- {
- // Send 0 output to game
- JoystickPosAdjusted = 0.0f;
- }
- else if (JoystickPosAbs >= 1)
- {
- // Send 1 output to game
- JoystickPosAdjusted = 1.0f;
- }
- // Calculate custom sensitivty
- else
- {
- var closests = Nodes.Select(n => new { n, distance = Math.Abs(n.Key - JoystickPosAbs) })
- .OrderBy(p => p.distance).Take(SensivityIdx);
- foreach (var item in closests)
- JoystickPosAdjusted += (float)(item.n.Value / (1.0f + item.distance));
-
- JoystickPosAdjusted /= SensivityIdx;
- JoystickPosAdjusted *= 2.0f; // a 1.0f vector means a 100% increase
- }
-
- // Apply direction
- return JoystickPosAdjusted;
- }
-
- public static Vector2 AutoRollYawSwap(Vector3 Gravity, Vector3 AngularVelocityDeg)
- {
- // Auto roll yaw swap function allows for clampshell, laptop and controller type devices to
- // automatically change the roll and yaw axis depending on how the device is being held. No need for changing settings.
-
- // Depending on how a device is being held, one of the gravity vector values will be near 1 and the others near 0
- // multiplying this with the respective desired rotational angle speed vector (roll or yaw) will result in a motion input
- // for the horizontal plane.
-
- // Normalize gravity to:
- // - Prevent multiplying with values > 1 ie additional user shaking
- // - When rolling device and maintaining the roll angle, accelY and accelZare less than horizon angle.
- var GravityNormalized = Vector3.Normalize(new Vector3(Gravity.X, Gravity.Y, Gravity.Z));
-
- // Handle NaN, check for empty inputs, prevent NaN computes
- Vector3 EmptyVector = new(0f, 0f, 0f);
-
- if (Gravity.Equals(EmptyVector))
- return new Vector2(EmptyVector.X, EmptyVector.Y);
-
- // -acc[1] * gyro[1] + -acc[2] * gyro[2]
- return new Vector2(-GravityNormalized.Z * -AngularVelocityDeg.Z + -GravityNormalized.Y * -AngularVelocityDeg.Y,
- AngularVelocityDeg.X);
- }
-}
\ No newline at end of file
diff --git a/ControllerService.sln b/ControllerService.sln
deleted file mode 100644
index df3f8b4f4..000000000
--- a/ControllerService.sln
+++ /dev/null
@@ -1,83 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.0.31919.166
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerService", "ControllerService\ControllerService.csproj", "{6B7B570E-8C8B-4189-9C98-B3BBFE630615}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerCommon", "ControllerCommon\ControllerCommon.csproj", "{D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4A4F8C55-09C7-4B4C-9752-E2E05AF25E30}"
- ProjectSection(SolutionItems) = preProject
- .editorconfig = .editorconfig
- EndProjectSection
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HandheldCompanion", "HandheldCompanion\HandheldCompanion.csproj", "{AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}"
- ProjectSection(ProjectDependencies) = postProject
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2} = {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}
- {F7283783-81EF-4CD2-BD86-598FE193C11F} = {F7283783-81EF-4CD2-BD86-598FE193C11F}
- EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hidapi.net", "hidapi.net\hidapi.net.csproj", "{9B860078-9AD1-45DD-8F85-E6D806E5DC9B}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "neptune-hidapi.net", "neptune-hidapi.net\neptune-hidapi.net.csproj", "{F7283783-81EF-4CD2-BD86-598FE193C11F}"
- ProjectSection(ProjectDependencies) = postProject
- {9B860078-9AD1-45DD-8F85-E6D806E5DC9B} = {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Debug|x64 = Debug|x64
- Release|Any CPU = Release|Any CPU
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Debug|x64.ActiveCfg = Debug|x64
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Debug|x64.Build.0 = Debug|x64
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Release|Any CPU.Build.0 = Release|Any CPU
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Release|x64.ActiveCfg = Release|x64
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Release|x64.Build.0 = Release|x64
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Debug|x64.ActiveCfg = Debug|x64
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Debug|x64.Build.0 = Debug|x64
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Release|Any CPU.Build.0 = Release|Any CPU
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Release|x64.ActiveCfg = Release|x64
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Release|x64.Build.0 = Release|x64
- {AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Debug|x64.ActiveCfg = Debug|x64
- {AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Debug|x64.Build.0 = Debug|x64
- {AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Release|Any CPU.Build.0 = Release|Any CPU
- {AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Release|x64.ActiveCfg = Release|x64
- {AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Release|x64.Build.0 = Release|x64
- {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}.Debug|x64.ActiveCfg = Debug|x64
- {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}.Debug|x64.Build.0 = Debug|x64
- {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}.Release|Any CPU.Build.0 = Release|Any CPU
- {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}.Release|x64.ActiveCfg = Release|x64
- {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}.Release|x64.Build.0 = Release|x64
- {F7283783-81EF-4CD2-BD86-598FE193C11F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F7283783-81EF-4CD2-BD86-598FE193C11F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F7283783-81EF-4CD2-BD86-598FE193C11F}.Debug|x64.ActiveCfg = Debug|x64
- {F7283783-81EF-4CD2-BD86-598FE193C11F}.Debug|x64.Build.0 = Debug|x64
- {F7283783-81EF-4CD2-BD86-598FE193C11F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F7283783-81EF-4CD2-BD86-598FE193C11F}.Release|Any CPU.Build.0 = Release|Any CPU
- {F7283783-81EF-4CD2-BD86-598FE193C11F}.Release|x64.ActiveCfg = Release|x64
- {F7283783-81EF-4CD2-BD86-598FE193C11F}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {AD9A944E-70E1-4512-9F51-8786F866BACA}
- EndGlobalSection
-EndGlobal
diff --git a/ControllerService/AssemblyInfo1.cs b/ControllerService/AssemblyInfo1.cs
deleted file mode 100644
index b533cb63f..000000000
--- a/ControllerService/AssemblyInfo1.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.Reflection;
-
-// Les informations générales relatives à un assembly dépendent de
-// l'ensemble d'attributs suivant. Pour modifier les informations
-// associées à un assembly.
-[assembly: AssemblyTitle("ControllerService")]
-[assembly:
- AssemblyDescription(
- "A combination of a Windows service and a touch interface optimized GUI to increase your handheld gaming computer experience. Features include: motion control a.k.a. gyro control, virtual controller simulation, quick tools overlay, virtual touchpads and 3D controller model, per application based profile settings system.")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ControllerService")]
-[assembly: AssemblyCopyright("Copyright © BenjaminLSR 2021")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
-//
-// Version principale
-// Version secondaire
-// Numéro de build
-// Révision
-//
-[assembly: AssemblyVersion("0.16.2.5")]
-[assembly: AssemblyFileVersion("0.16.2.5")]
\ No newline at end of file
diff --git a/ControllerService/ControllerService.cs b/ControllerService/ControllerService.cs
deleted file mode 100644
index f1b66943a..000000000
--- a/ControllerService/ControllerService.cs
+++ /dev/null
@@ -1,674 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using ControllerCommon;
-using ControllerCommon.Devices;
-using ControllerCommon.Managers;
-using ControllerCommon.Pipes;
-using ControllerCommon.Platforms;
-using ControllerCommon.Sensors;
-using ControllerCommon.Utils;
-using ControllerService.Properties;
-using ControllerService.Targets;
-using Microsoft.Extensions.Hosting;
-using Nefarius.Utilities.DeviceManagement.PnP;
-using Nefarius.ViGEm.Client;
-using static ControllerCommon.Managers.PowerManager;
-using static ControllerCommon.Utils.DeviceUtils;
-
-namespace ControllerService;
-
-public class ControllerService : IHostedService
-{
- public delegate void UpdatedEventHandler();
-
- // controllers vars
- public static ViGEmClient vClient;
- public static ViGEmTarget vTarget;
-
- // devices vars
- public static IDevice CurrentDevice;
-
- public static string CurrentPath, CurrentPathDep;
- public static string CurrentTag;
- public static int CurrentOverlayStatus = 2;
-
- // sensor vars
- private static SensorFamily SensorSelection;
- private static int SensorPlacement;
- private static bool SensorPlacementUpsideDown;
-
- // profile vars
- public static Profile currentProfile = new();
- public static PlatformType currentPlatform;
-
- // settings vars
- public Configuration configuration;
- private readonly bool DSUEnabled;
- private readonly string DSUip;
- private readonly int DSUport;
-
- private readonly DSUServer DSUServer;
- private HIDmode HIDmode = HIDmode.NoController;
- private HIDstatus HIDstatus = HIDstatus.Disconnected;
- private SerialUSBIMU sensor;
-
- public ControllerService(IHostApplicationLifetime lifetime)
- {
- CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
- CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
-
- // paths
- CurrentPath = AppDomain.CurrentDomain.BaseDirectory;
- CurrentPathDep = Path.Combine(CurrentPath, "dependencies");
-
- // settings
- // todo: move me to a specific class
- configuration = ConfigurationManager.OpenExeConfiguration("ControllerService.exe");
-
- HIDmode = Enum.Parse(configuration.AppSettings.Settings["HIDmode"].Value);
- HIDstatus = Enum.Parse(configuration.AppSettings.Settings["HIDstatus"].Value);
-
- DSUEnabled = bool.Parse(configuration.AppSettings.Settings["DSUEnabled"].Value);
- DSUip = configuration.AppSettings.Settings["DSUip"].Value;
- DSUport = int.Parse(configuration.AppSettings.Settings["DSUport"].Value);
-
- SensorSelection = Enum.Parse(configuration.AppSettings.Settings["SensorSelection"].Value);
- SensorPlacement = int.Parse(configuration.AppSettings.Settings["SensorPlacement"].Value);
- SensorPlacementUpsideDown = bool.Parse(configuration.AppSettings.Settings["SensorPlacementUpsideDown"].Value);
-
- // verifying ViGEm is installed
- try
- {
- vClient = new ViGEmClient();
- }
- catch (Exception)
- {
- LogManager.LogCritical("ViGEm is missing. Please get it from: {0}",
- "https://github.com/ViGEm/ViGEmBus/releases");
- throw new InvalidOperationException();
- }
-
- // initialize PipeServer
- PipeServer.Connected += OnClientConnected;
- PipeServer.Disconnected += OnClientDisconnected;
- PipeServer.ClientMessage += OnClientMessage;
-
- // initialize manager(s)
- DeviceManager.UsbDeviceRemoved += GenericDeviceRemoved;
- DeviceManager.Start();
-
- // initialize device
- CurrentDevice = IDevice.GetDefault();
- CurrentDevice.PullSensors();
-
- // as of 06/20/2023, Bosch BMI320/BMI323 is crippled
- string currentDeviceType = CurrentDevice.GetType().Name;
- switch (currentDeviceType)
- {
- case "AYANEOAIRPlus":
- case "ROGAlly":
- {
- LogManager.LogInformation("Restarting: {0}", CurrentDevice.InternalSensorName);
-
- if (CurrentDevice.RestartSensor())
- {
- // give the device some breathing space once restarted
- Thread.Sleep(500);
-
- LogManager.LogInformation("Successfully restarted: {0}", CurrentDevice.InternalSensorName);
- }
- else
- LogManager.LogError("Failed to restart: {0}", CurrentDevice.InternalSensorName);
- }
- break;
- }
-
- // initialize DSUClient
- DSUServer = new DSUServer(DSUip, DSUport);
- DSUServer.Started += OnDSUStarted;
- DSUServer.Stopped += OnDSUStopped;
- }
-
- public Task StartAsync(CancellationToken cancellationToken)
- {
- // start master timer
- TimerManager.Start();
-
- // start DSUClient
- if (DSUEnabled)
- DSUServer.Start();
-
- // start Pipe Server
- PipeServer.Open();
-
- // start Power Manager
- SystemStatusChanged += OnSystemStatusChanged;
- Start(true);
-
- return Task.CompletedTask;
- }
-
- public Task StopAsync(CancellationToken cancellationToken)
- {
- // stop master timer
- TimerManager.Stop();
-
- // stop listening from controller
- IMU.Stop();
-
- // update virtual controller
- SetControllerMode(HIDmode.NoController);
-
- // stop Power Manager
- Stop();
-
- // stop DSUClient
- DSUServer?.Stop();
-
- // stop Pipe Server
- PipeServer.Close();
-
- // stop System Manager
- DeviceManager.Stop();
-
- return Task.CompletedTask;
- }
-
- public static event UpdatedEventHandler ForegroundUpdated;
-
- private void GenericDeviceRemoved(PnPDevice device, DeviceEventArgs obj)
- {
- // If the USB Gyro is unplugged, close serial connection
- if (sensor is null)
- return;
-
- sensor.Close();
-
- // Stop IMU is USB Gyro was our motion source
- switch (SensorSelection)
- {
- case SensorFamily.SerialUSBIMU:
- IMU.Stop();
- break;
- }
- }
-
- private void SetControllerMode(HIDmode mode)
- {
- // do not disconnect if similar to previous mode
- if (HIDmode == mode && vTarget is not null)
- return;
-
- // disconnect current virtual controller
- if (vTarget is not null)
- vTarget.Disconnect();
-
- switch (mode)
- {
- case HIDmode.Xbox360Controller:
- vTarget = new Xbox360Target();
- break;
- case HIDmode.DualShock4Controller:
- vTarget = new DualShock4Target();
- break;
- default:
- case HIDmode.NoController:
- if (vTarget is not null)
- {
- vTarget.Dispose();
- vTarget = null;
- }
-
- break;
- }
-
- // failed to initialize controller
- if (vTarget is null)
- {
- if (mode != HIDmode.NoController)
- LogManager.LogError("Failed to initialise virtual controller with HIDmode: {0}", mode);
- return;
- }
-
- vTarget.Connected += OnTargetConnected;
- vTarget.Disconnected += OnTargetDisconnected;
-
- // update status
- SetControllerStatus(HIDstatus);
-
- // update current HIDmode
- HIDmode = mode;
- }
-
- private void SetControllerStatus(HIDstatus status)
- {
- if (vTarget is null)
- return;
-
- switch (status)
- {
- default:
- case HIDstatus.Connected:
- vTarget.Connect();
- break;
- case HIDstatus.Disconnected:
- vTarget.Disconnect();
- break;
- }
-
- // update current HIDstatus
- HIDstatus = status;
- }
-
- private void OnTargetDisconnected(ViGEmTarget target)
- {
- // send notification
- PipeServer.SendMessage(new PipeServerToast
- {
- title = $"{target}",
- content = Resources.ToastOnTargetDisconnected,
- image = $"HIDmode{(uint)target.HID}"
- });
- }
-
- private void OnTargetConnected(ViGEmTarget target)
- {
- // send notification
- PipeServer.SendMessage(new PipeServerToast
- {
- title = $"{target}",
- content = Resources.ToastOnTargetConnected,
- image = $"HIDmode{(uint)target.HID}"
- });
- }
-
- // deprecated
- private void OnDSUStopped(DSUServer server)
- {
- /* DSUEnabled = false;
- configuration.GetSection("Settings:DSUEnabled").Value = false.ToString();
-
- PipeServerSettings settings = new PipeServerSettings("DSUEnabled", DSUEnabled.ToString());
- pipeServer.SendMessage(settings); */
- }
-
- // deprecated
- private void OnDSUStarted(DSUServer server)
- {
- /* DSUEnabled = true;
- configuration.GetSection("Settings:DSUEnabled").Value = true.ToString();
-
- PipeServerSettings settings = new PipeServerSettings("DSUEnabled", DSUEnabled.ToString());
- pipeServer.SendMessage(settings); */
- }
-
- private void OnClientMessage(PipeMessage message)
- {
- switch (message.code)
- {
- case PipeCode.CLIENT_PROFILE:
- {
- var profileMsg = (PipeClientProfile)message;
- UpdateProfile(profileMsg.profile);
-
- // unset flag
- SystemPending = false;
- }
- break;
-
- case PipeCode.CLIENT_PROCESS:
- {
- var process = (PipeClientProcess)message;
- UpdateProcess(process.executable, process.platform);
- }
- break;
-
- case PipeCode.CLIENT_CURSOR:
- {
- var cursor = (PipeClientCursor)message;
-
- switch (cursor.action)
- {
- case CursorAction.CursorUp:
- DS4Touch.OnMouseUp(cursor.x, cursor.y, cursor.button, cursor.flags);
- break;
- case CursorAction.CursorDown:
- DS4Touch.OnMouseDown(cursor.x, cursor.y, cursor.button, cursor.flags);
- break;
- case CursorAction.CursorMove:
- DS4Touch.OnMouseMove(cursor.x, cursor.y, cursor.button, cursor.flags);
- break;
- }
- }
- break;
-
- case PipeCode.CLIENT_SETTINGS:
- {
- var settings = (PipeClientSettings)message;
- UpdateSettings(settings.Settings);
- }
- break;
-
- case PipeCode.CLIENT_NAVIGATED:
- {
- var navigation = (PipeNavigation)message;
- CurrentTag = navigation.Tag;
-
- switch (navigation.Tag)
- {
- case "SettingsMode0":
- // do something
- break;
- case "SettingsMode1":
- // do something
- break;
- }
- }
- break;
-
- case PipeCode.CLIENT_OVERLAY:
- {
- var overlay = (PipeOverlay)message;
- CurrentOverlayStatus = overlay.Visibility;
- }
- break;
-
- case PipeCode.CLIENT_INPUT:
- {
- var inputMsg = (PipeClientInputs)message;
-
- vTarget?.UpdateInputs(inputMsg.controllerState);
- DSUServer.UpdateInputs(inputMsg.controllerState);
- DS4Touch.UpdateInputs(inputMsg.controllerState);
- }
- break;
-
- case PipeCode.CLIENT_MOVEMENTS:
- {
- var movements = (PipeClientMovements)message;
-
- IMU.UpdateMovements(movements.Movements);
- }
- break;
-
- case PipeCode.CLIENT_CONTROLLER_CONNECT:
- {
- var connect = (PipeClientControllerConnect)message;
- // do something?
- }
- break;
-
- case PipeCode.CLIENT_CONTROLLER_DISCONNECT:
- {
- var disconnect = (PipeClientControllerDisconnect)message;
- // do something ?
- }
- break;
- }
- }
-
- private void OnClientDisconnected()
- {
- DS4Touch.OnMouseUp(0, 0, CursorButton.TouchLeft);
- DS4Touch.OnMouseUp(0, 0, CursorButton.TouchRight);
- }
-
- private void OnClientConnected()
- {
- // send server settings to client
- PipeServer.SendMessage(new PipeServerSettings { Settings = GetSettings() });
- }
-
- internal void UpdateProfile(Profile profile)
- {
- // skip if current profile
- if (profile == currentProfile)
- return;
-
- // update current profile
- currentProfile = profile;
- ForegroundUpdated?.Invoke();
-
- LogManager.LogInformation("Profile {0} applied", profile.Name);
- }
-
- internal void UpdateProcess(string executable, PlatformType platform)
- {
- // skip if current platform
- if (platform == currentPlatform)
- return;
-
- // update current platform
- currentPlatform = platform;
- ForegroundUpdated?.Invoke();
-
- LogManager.LogInformation("Platform {0} detected", platform);
- }
-
- public void UpdateSettings(Dictionary args)
- {
- foreach (var pair in args)
- {
- var name = pair.Key;
- var property = pair.Value;
-
- if (configuration.AppSettings.Settings.AllKeys.ToList().Contains(name))
- {
- configuration.AppSettings.Settings[name].Value = property;
- configuration.Save(ConfigurationSaveMode.Modified);
- }
-
- ApplySetting(name, property);
- LogManager.LogDebug("{0} set to {1}", name, property);
- }
- }
-
- private void ApplySetting(string name, string property)
- {
- switch (name)
- {
- case "HIDmode":
- {
- var value = Enum.Parse(property);
-
- if (HIDmode == value)
- return;
-
- SetControllerMode(value);
- }
- break;
- case "HIDstatus":
- {
- var value = Enum.Parse(property);
-
- if (HIDstatus == value)
- return;
-
- SetControllerStatus(value);
- }
- break;
- case "DSUEnabled":
- {
- var value = Convert.ToBoolean(property);
- switch (value)
- {
- case true:
- DSUServer.Start();
- break;
- case false:
- DSUServer.Stop();
- break;
- }
- }
- break;
- case "DSUip":
- {
- var value = Convert.ToString(property);
- // DSUServer.ip = value;
- }
- break;
- case "DSUport":
- {
- var value = Convert.ToInt32(property);
- DSUServer.port = value;
- }
- break;
- case "SensorPlacement":
- {
- var value = Convert.ToInt32(property);
- SensorPlacement = value;
- sensor?.SetSensorPlacement((SerialPlacement)SensorPlacement, SensorPlacementUpsideDown);
- }
- break;
- case "SensorPlacementUpsideDown":
- {
- var value = Convert.ToBoolean(property);
- SensorPlacementUpsideDown = value;
- sensor?.SetSensorPlacement((SerialPlacement)SensorPlacement, SensorPlacementUpsideDown);
- }
- break;
- case "SensorSelection":
- {
- var value = Enum.Parse(property);
-
- if (SensorSelection == value)
- return;
-
- // In case current selection is USG Gyro, close serial connection
- if (SensorSelection == SensorFamily.SerialUSBIMU)
- if (sensor is not null)
- sensor.Close();
-
- SensorSelection = value;
-
- // Establish serial port connection on selection change to USG Gyro
- if (SensorSelection == SensorFamily.SerialUSBIMU)
- {
- sensor = SerialUSBIMU.GetDefault();
-
- if (sensor is null)
- break;
-
- sensor.Open();
- sensor.SetSensorPlacement((SerialPlacement)SensorPlacement, SensorPlacementUpsideDown);
- }
-
- IMU.Stop();
- IMU.SetSensorFamily(SensorSelection);
- IMU.Start();
- }
- break;
- }
- }
-
- private bool SystemPending;
- private int SystemPendingIdx;
-
- private async void OnSystemStatusChanged(SystemStatus status, SystemStatus prevStatus)
- {
- if (status == prevStatus)
- return;
-
- switch (status)
- {
- case SystemStatus.SystemReady:
- {
- switch (prevStatus)
- {
- case SystemStatus.SystemBooting:
- // cold boot
- IMU.SetSensorFamily(SensorSelection);
- IMU.Start();
- break;
- case SystemStatus.SystemPending:
- // resume from sleep
- // restart IMU
- IMU.Restart(true);
- break;
- }
-
- // check if service/system was suspended previously
- if (vTarget is not null)
- return;
-
- // extra delay for device functions
- while (SystemPending && SystemPendingIdx < CurrentDevice.ResumeDelay / 1000)
- {
- Thread.Sleep(1000);
- SystemPendingIdx++;
- }
-
- while (vTarget is null || !vTarget.IsConnected)
- {
- // reset vigem
- ResetViGEm();
-
- // create new ViGEm client
- vClient = new ViGEmClient();
-
- // set controller mode
- SetControllerMode(HIDmode);
-
- Thread.Sleep(1000);
- }
-
- // start timer manager
- TimerManager.Start();
- }
- break;
-
- case SystemStatus.SystemPending:
- {
- // set flag
- SystemPending = true;
- SystemPendingIdx = 0;
-
- // stop timer manager
- TimerManager.Stop();
-
- // clear pipes
- PipeServer.ClearQueue();
-
- // stop sensors
- IMU.Stop();
-
- // reset vigem
- ResetViGEm();
- }
- break;
- }
- }
-
- private void ResetViGEm()
- {
- // dispose virtual controller
- if (vTarget is not null)
- {
- vTarget.Dispose();
- vTarget = null;
- }
-
- // dispose ViGEm drivers
- if (vClient is not null)
- {
- vClient.Dispose();
- vClient = null;
- }
- }
-
- public Dictionary GetSettings()
- {
- Dictionary settings = new();
-
- foreach (var key in configuration.AppSettings.Settings.AllKeys)
- settings.Add(key, configuration.AppSettings.Settings[key].Value);
-
- return settings;
- }
-}
\ No newline at end of file
diff --git a/ControllerService/ControllerService.csproj b/ControllerService/ControllerService.csproj
deleted file mode 100644
index cdd562913..000000000
--- a/ControllerService/ControllerService.csproj
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
- Exe
- true
- net7.0-windows10.0.19041.0
- true
- false
- true
- true
- ControllerService
- ControllerService
- Copyright © 2021
- x64
- true
- $(SolutionDir)bin\$(Configuration)
- portable
- 0.10.0.0
- AnyCPU;x64
-
-
- full
- false
-
-
- full
- false
-
-
- pdbonly
- true
-
-
- pdbonly
- true
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
-
-
-
- all
-
-
- all
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
\ No newline at end of file
diff --git a/ControllerService/ControllerService.exe.config b/ControllerService/ControllerService.exe.config
deleted file mode 100644
index d8b48f169..000000000
--- a/ControllerService/ControllerService.exe.config
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ControllerService/ControllerService.json b/ControllerService/ControllerService.json
deleted file mode 100644
index 0c82922c7..000000000
--- a/ControllerService/ControllerService.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
- }
- },
- "Serilog": {
- "Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console" ],
- "MinimumLevel": "Debug",
- "WriteTo": [
- {
- "Name": "File",
- "Args": {
- "path": ".\\logs\\ControllerService.log",
- "rollingInterval": "Day"
- }
- },
- {
- "Name": "Console",
- "Args": {
- "restrictedToMinimumLevel": "Information"
- }
- }
- ]
- },
- "HostOptions": {
- "ShutdownTimeout": "00:00:15"
- }
-}
\ No newline at end of file
diff --git a/ControllerService/IMU.cs b/ControllerService/IMU.cs
deleted file mode 100644
index 585987c04..000000000
--- a/ControllerService/IMU.cs
+++ /dev/null
@@ -1,198 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Numerics;
-using System.Threading;
-using ControllerCommon;
-using ControllerCommon.Controllers;
-using ControllerCommon.Managers;
-using ControllerCommon.Pipes;
-using ControllerCommon.Utils;
-using ControllerService.Sensors;
-using static ControllerCommon.Utils.DeviceUtils;
-
-namespace ControllerService;
-
-public static class IMU
-{
- public delegate void InitializedEventHandler();
-
- public delegate void UpdatedEventHandler();
-
- public static SortedDictionary Acceleration = new();
- public static SortedDictionary AngularVelocity = new();
-
- public static IMUGyrometer Gyrometer;
- public static IMUAccelerometer Accelerometer;
-
- public static SensorFusion sensorFusion;
- public static MadgwickAHRS madgwickAHRS;
-
- public static Stopwatch stopwatch;
- public static long CurrentMicroseconds;
-
- public static double TotalMilliseconds;
- public static double UpdateTimePreviousMilliseconds;
- public static double DeltaSeconds = 100.0d;
-
- private static readonly object updateLock = new();
-
- public static bool IsInitialized;
-
- static IMU()
- {
- // initialize sensorfusion and madgwick
- sensorFusion = new SensorFusion();
- madgwickAHRS = new MadgwickAHRS(0.01f, 0.1f);
-
- // initialize stopwatch
- stopwatch = new Stopwatch();
- }
-
- public static event UpdatedEventHandler Updated;
-
- public static event InitializedEventHandler Initialized;
-
- public static void SetSensorFamily(SensorFamily sensorFamily)
- {
- // initialize sensors
- var UpdateInterval = TimerManager.GetPeriod();
-
- Gyrometer = new IMUGyrometer(sensorFamily, UpdateInterval);
- Accelerometer = new IMUAccelerometer(sensorFamily, UpdateInterval);
- }
-
- public static void Start()
- {
- stopwatch.Start();
-
- TimerManager.Tick += Tick;
-
- IsInitialized = true;
- Initialized?.Invoke();
- }
-
- public static void Stop()
- {
- TimerManager.Tick -= Tick;
-
- // halt sensors
- Gyrometer?.StopListening();
- Accelerometer?.StopListening();
-
- stopwatch.Stop();
-
- IsInitialized = false;
- }
-
- public static void Restart(bool update)
- {
- Stop();
-
- // force update sensors
- if (update)
- Update();
-
- Start();
- }
-
- public static void Update()
- {
- Gyrometer.UpdateSensor();
- Accelerometer.UpdateSensor();
- }
-
- public static void UpdateMovements(ControllerMovements movements)
- {
- Gyrometer.ReadingChanged(movements.GyroRoll, movements.GyroPitch, movements.GyroYaw);
- Accelerometer.ReadingChanged(movements.GyroAccelX, movements.GyroAccelY, movements.GyroAccelZ);
- }
-
- private static void Tick(long ticks)
- {
- if (Monitor.TryEnter(updateLock))
- {
- // update timestamp
- CurrentMicroseconds = stopwatch.ElapsedMilliseconds * 1000L;
- TotalMilliseconds = stopwatch.Elapsed.TotalMilliseconds;
- DeltaSeconds = (TotalMilliseconds - UpdateTimePreviousMilliseconds) / 1000L;
- UpdateTimePreviousMilliseconds = TotalMilliseconds;
-
- // update reading(s)
- foreach (var flags in (XInputSensorFlags[])Enum.GetValues(typeof(XInputSensorFlags)))
- switch (flags)
- {
- case XInputSensorFlags.Default:
- AngularVelocity[flags] = Gyrometer.GetCurrentReading();
- Acceleration[flags] = Accelerometer.GetCurrentReading();
- break;
-
- case XInputSensorFlags.RawValue:
- AngularVelocity[flags] = Gyrometer.GetCurrentReadingRaw();
- Acceleration[flags] = Accelerometer.GetCurrentReadingRaw();
- break;
-
- case XInputSensorFlags.Centered:
- AngularVelocity[flags] = Gyrometer.GetCurrentReading(true);
- Acceleration[flags] = Accelerometer.GetCurrentReading(true);
- break;
-
- case XInputSensorFlags.WithRatio:
- AngularVelocity[flags] = Gyrometer.GetCurrentReading(false, true);
- Acceleration[flags] = Accelerometer.GetCurrentReading();
- break;
-
- case XInputSensorFlags.CenteredRatio:
- AngularVelocity[flags] = Gyrometer.GetCurrentReading(true, true);
- Acceleration[flags] = Accelerometer.GetCurrentReading(true);
- break;
-
- case XInputSensorFlags.CenteredRaw:
- AngularVelocity[flags] = Gyrometer.GetCurrentReadingRaw(true);
- Acceleration[flags] = Accelerometer.GetCurrentReadingRaw(true);
- break;
- }
-
- // update sensorFusion
- switch (ControllerService.currentProfile.MotionInput)
- {
- case MotionInput.PlayerSpace:
- case MotionInput.AutoRollYawSwap:
- case MotionInput.JoystickSteering:
- sensorFusion.UpdateReport(TotalMilliseconds, DeltaSeconds, AngularVelocity[XInputSensorFlags.Centered], Acceleration[XInputSensorFlags.Default]);
- break;
- }
-
- switch (ControllerService.CurrentTag)
- {
- case "SettingsMode0":
- PipeServer.SendMessage(new PipeSensor(AngularVelocity[XInputSensorFlags.Centered], Quaternion.Zero, SensorType.Girometer));
- break;
-
- case "SettingsMode1":
- PipeServer.SendMessage(new PipeSensor(new Vector3() { X = sensorFusion.DeviceAngle.X, Y = sensorFusion.DeviceAngle.Y }, Quaternion.Zero, SensorType.Inclinometer));
- break;
- }
-
- switch (ControllerService.CurrentOverlayStatus)
- {
- case 0: // Visible
- var AngularVelocityRad = new Vector3();
- AngularVelocityRad.X = -InputUtils.Deg2Rad(AngularVelocity[XInputSensorFlags.CenteredRaw].X);
- AngularVelocityRad.Y = -InputUtils.Deg2Rad(AngularVelocity[XInputSensorFlags.CenteredRaw].Y);
- AngularVelocityRad.Z = -InputUtils.Deg2Rad(AngularVelocity[XInputSensorFlags.CenteredRaw].Z);
- madgwickAHRS.UpdateReport(AngularVelocityRad.X, AngularVelocityRad.Y, AngularVelocityRad.Z,
- -Acceleration[XInputSensorFlags.RawValue].X, Acceleration[XInputSensorFlags.RawValue].Y,
- Acceleration[XInputSensorFlags.RawValue].Z, DeltaSeconds);
-
- PipeServer.SendMessage(new PipeSensor(madgwickAHRS.GetEuler(), madgwickAHRS.GetQuaternion(),
- SensorType.Quaternion));
- break;
- }
-
- Updated?.Invoke();
-
- Monitor.Exit(updateLock);
- }
- }
-}
\ No newline at end of file
diff --git a/ControllerService/Program.cs b/ControllerService/Program.cs
deleted file mode 100644
index ed6be21ce..000000000
--- a/ControllerService/Program.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Reflection;
-using ControllerCommon.Managers;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using static ControllerCommon.WinAPI;
-
-namespace ControllerService;
-
-internal static class Program
-{
- public static void Main(string[] args)
- {
- // force high priority
- using (var process = Process.GetCurrentProcess())
- {
- SetPriorityClass(process.Handle, (int)PriorityClass.HIGH_PRIORITY_CLASS);
- }
-
- Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
-
- var CurrentAssembly = Assembly.GetExecutingAssembly();
- var fileVersionInfo = FileVersionInfo.GetVersionInfo(CurrentAssembly.Location);
-
- // initialize log manager
- LogManager.Initialize("ControllerService");
- LogManager.LogInformation("{0} ({1})", CurrentAssembly.GetName(), fileVersionInfo.ProductVersion);
-
- var proc = Process.GetCurrentProcess().ProcessName;
- var processes = Process.GetProcessesByName(proc);
-
- if (processes.Length > 1)
- {
- LogManager.LogCritical("{0} is already running. Exiting...", proc);
- return;
- }
-
- CreateHostBuilder(args).Build().Run();
- }
-
- public static IHostBuilder CreateHostBuilder(string[] args)
- {
- return Host.CreateDefaultBuilder(args)
- .UseWindowsService()
- .ConfigureServices((hostContext, services) =>
- {
- services.AddLogging(builder => { builder.SetMinimumLevel(LogLevel.Information); });
-
- services.AddHostedService();
- });
- }
-}
\ No newline at end of file
diff --git a/ControllerService/Properties/AssemblyInfo.cs b/ControllerService/Properties/AssemblyInfo.cs
deleted file mode 100644
index 849de40ea..000000000
--- a/ControllerService/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Runtime.InteropServices;
-
-// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly
-// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de
-// COM, affectez la valeur True à l'attribut ComVisible sur ce type.
-[assembly: ComVisible(false)]
-
-// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM
-[assembly: Guid("6b7b570e-8c8b-4189-9c98-b3bbfe630615")]
\ No newline at end of file
diff --git a/ControllerService/Properties/Resources.Designer.cs b/ControllerService/Properties/Resources.Designer.cs
deleted file mode 100644
index 5c3ee4e0f..000000000
--- a/ControllerService/Properties/Resources.Designer.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace ControllerService.Properties {
- using System;
-
-
- ///
- /// A strongly-typed resource class, for looking up localized strings, etc.
- ///
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// Returns the cached ResourceManager instance used by this class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ControllerService.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// Looks up a localized string similar to is now connected.
- ///
- internal static string ToastOnTargetConnected {
- get {
- return ResourceManager.GetString("ToastOnTargetConnected", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to is now disconnected.
- ///
- internal static string ToastOnTargetDisconnected {
- get {
- return ResourceManager.GetString("ToastOnTargetDisconnected", resourceCulture);
- }
- }
- }
-}
diff --git a/ControllerService/Properties/Resources.de-DE.resx b/ControllerService/Properties/Resources.de-DE.resx
deleted file mode 100644
index f20c86ae7..000000000
--- a/ControllerService/Properties/Resources.de-DE.resx
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Virtueller Controller ist verbunden
-
-
- Virtueller Controller ist getrennt
-
-
\ No newline at end of file
diff --git a/ControllerService/Properties/Resources.es-ES.resx b/ControllerService/Properties/Resources.es-ES.resx
deleted file mode 100644
index cabd8897f..000000000
--- a/ControllerService/Properties/Resources.es-ES.resx
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Esta ahora conectado
-
-
- Esta ahora desconectado
-
-
\ No newline at end of file
diff --git a/ControllerService/Properties/Resources.fr-FR.resx b/ControllerService/Properties/Resources.fr-FR.resx
deleted file mode 100644
index cce443dba..000000000
--- a/ControllerService/Properties/Resources.fr-FR.resx
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Le contrôleur virtuel est maintenant connecté
-
-
- Le contrôleur virtuel est maintenant déconnecté
-
-
\ No newline at end of file
diff --git a/ControllerService/Properties/Resources.it-IT.resx b/ControllerService/Properties/Resources.it-IT.resx
deleted file mode 100644
index 2853e9732..000000000
--- a/ControllerService/Properties/Resources.it-IT.resx
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ora è connesso
-
-
- ora è disconnesso
-
-
\ No newline at end of file
diff --git a/ControllerService/Properties/Resources.ja-JP.resx b/ControllerService/Properties/Resources.ja-JP.resx
deleted file mode 100644
index ba541b9eb..000000000
--- a/ControllerService/Properties/Resources.ja-JP.resx
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- 接続されました
-
-
- 切断されました
-
-
\ No newline at end of file
diff --git a/ControllerService/Properties/Resources.pt-BR.resx b/ControllerService/Properties/Resources.pt-BR.resx
deleted file mode 100644
index 2a6ad56ab..000000000
--- a/ControllerService/Properties/Resources.pt-BR.resx
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- está agora conectado
-
-
- está agora desconectado
-
-
\ No newline at end of file
diff --git a/ControllerService/Properties/Resources.resx b/ControllerService/Properties/Resources.resx
deleted file mode 100644
index afd1a2190..000000000
--- a/ControllerService/Properties/Resources.resx
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- is now connected
-
-
- is now disconnected
-
-
\ No newline at end of file
diff --git a/ControllerService/Properties/Resources.zh-CN.resx b/ControllerService/Properties/Resources.zh-CN.resx
deleted file mode 100644
index 725296c00..000000000
--- a/ControllerService/Properties/Resources.zh-CN.resx
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- 虚拟手柄已连接
-
-
- 虚拟手柄已断开
-
-
\ No newline at end of file
diff --git a/ControllerService/Properties/Resources.zh-Hant.resx b/ControllerService/Properties/Resources.zh-Hant.resx
deleted file mode 100644
index 06445c0e2..000000000
--- a/ControllerService/Properties/Resources.zh-Hant.resx
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- 虛擬手柄已連接
-
-
- 虛擬手柄已斷開
-
-
\ No newline at end of file
diff --git a/ControllerService/References/Windows.winmd b/ControllerService/References/Windows.winmd
deleted file mode 100644
index 2705d0bc5..000000000
Binary files a/ControllerService/References/Windows.winmd and /dev/null differ
diff --git a/ControllerService/Targets/DualShock4Target.cs b/ControllerService/Targets/DualShock4Target.cs
deleted file mode 100644
index dbb6663bf..000000000
--- a/ControllerService/Targets/DualShock4Target.cs
+++ /dev/null
@@ -1,244 +0,0 @@
-using System;
-using ControllerCommon.Inputs;
-using ControllerCommon.Managers;
-using ControllerCommon.Pipes;
-using ControllerCommon.Utils;
-using ControllerService.Sensors;
-using Nefarius.ViGEm.Client.Exceptions;
-using Nefarius.ViGEm.Client.Targets;
-using Nefarius.ViGEm.Client.Targets.DualShock4;
-
-namespace ControllerService.Targets;
-
-internal class DualShock4Target : ViGEmTarget
-{
- // DS4 Accelerometer g-force measurement range G SI unit to short
- // Various sources state either +/- 2 or 4 ranges are in use
- private static readonly SensorSpec DS4AccelerometerSensorSpec = new()
- {
- minIn = -4.0f,
- maxIn = 4.0f,
- minOut = short.MinValue,
- maxOut = short.MaxValue
- };
-
- // DS4 Gyroscope angular rate measurement range deg/sec SI unit to short
- // Note, at +/- 2000 the value is still off by a factor 5
- private static readonly SensorSpec DS4GyroscopeSensorSpec = new()
- {
- minIn = -2000.0f,
- maxIn = 2000.0f,
- minOut = short.MinValue,
- maxOut = short.MaxValue
- };
-
- private DS4_REPORT_EX outDS4Report;
-
- private new readonly IDualShock4Controller virtualController;
-
- public DualShock4Target()
- {
- // initialize controller
- HID = HIDmode.DualShock4Controller;
-
- virtualController = ControllerService.vClient.CreateDualShock4Controller(0x054C, 0x09CC);
- virtualController.AutoSubmitReport = false;
- virtualController.FeedbackReceived += FeedbackReceived;
-
- LogManager.LogInformation("{0} initialized, {1}", ToString(), virtualController);
- }
-
- public override void Connect()
- {
- if (IsConnected)
- return;
-
- try
- {
- virtualController.Connect();
- TimerManager.Tick += UpdateReport;
-
- base.Connect();
- }
- catch (Exception ex)
- {
- virtualController.Disconnect();
- LogManager.LogWarning("Failed to connect {0}. {1}", ToString(), ex.Message);
- }
- }
-
- public override void Disconnect()
- {
- if (!IsConnected)
- return;
-
- try
- {
- virtualController.Disconnect();
- TimerManager.Tick -= UpdateReport;
-
- base.Disconnect();
- }
- catch
- {
- }
- }
-
- public void FeedbackReceived(object sender, DualShock4FeedbackReceivedEventArgs e)
- {
- // pass raw vibration to client
- PipeServer.SendMessage(new PipeClientVibration { LargeMotor = e.LargeMotor, SmallMotor = e.SmallMotor });
- }
-
- public override unsafe void UpdateReport(long ticks)
- {
- if (!IsConnected)
- return;
-
- base.UpdateReport(ticks);
-
- // reset vars
- var rawOutReportEx = new byte[63];
- ushort tempButtons = 0;
- ushort tempSpecial = 0;
- var tempDPad = DualShock4DPadDirection.None;
-
- outDS4Report.bThumbLX = 127;
- outDS4Report.bThumbLY = 127;
- outDS4Report.bThumbRX = 127;
- outDS4Report.bThumbRY = 127;
-
- unchecked
- {
- if (Inputs.ButtonState[ButtonFlags.B1])
- tempButtons |= DualShock4Button.Cross.Value;
- if (Inputs.ButtonState[ButtonFlags.B2])
- tempButtons |= DualShock4Button.Circle.Value;
- if (Inputs.ButtonState[ButtonFlags.B3])
- tempButtons |= DualShock4Button.Square.Value;
- if (Inputs.ButtonState[ButtonFlags.B4])
- tempButtons |= DualShock4Button.Triangle.Value;
-
- if (Inputs.ButtonState[ButtonFlags.Start])
- tempButtons |= DualShock4Button.Options.Value;
- if (Inputs.ButtonState[ButtonFlags.Back])
- tempButtons |= DualShock4Button.Share.Value;
-
- if (Inputs.ButtonState[ButtonFlags.RightThumb])
- tempButtons |= DualShock4Button.ThumbRight.Value;
- if (Inputs.ButtonState[ButtonFlags.LeftThumb])
- tempButtons |= DualShock4Button.ThumbLeft.Value;
-
- if (Inputs.ButtonState[ButtonFlags.L1])
- tempButtons |= DualShock4Button.ShoulderLeft.Value;
- if (Inputs.ButtonState[ButtonFlags.R1])
- tempButtons |= DualShock4Button.ShoulderRight.Value;
-
- if (Inputs.AxisState[AxisFlags.L2] > 0)
- tempButtons |= DualShock4Button.TriggerLeft.Value;
- if (Inputs.AxisState[AxisFlags.R2] > 0)
- tempButtons |= DualShock4Button.TriggerRight.Value;
-
- if (Inputs.ButtonState[ButtonFlags.DPadUp] && Inputs.ButtonState[ButtonFlags.DPadLeft])
- tempDPad = DualShock4DPadDirection.Northwest;
- else if (Inputs.ButtonState[ButtonFlags.DPadUp] && Inputs.ButtonState[ButtonFlags.DPadRight])
- tempDPad = DualShock4DPadDirection.Northeast;
- else if (Inputs.ButtonState[ButtonFlags.DPadDown] && Inputs.ButtonState[ButtonFlags.DPadLeft])
- tempDPad = DualShock4DPadDirection.Southwest;
- else if (Inputs.ButtonState[ButtonFlags.DPadDown] && Inputs.ButtonState[ButtonFlags.DPadRight])
- tempDPad = DualShock4DPadDirection.Southeast;
- else if (Inputs.ButtonState[ButtonFlags.DPadUp])
- tempDPad = DualShock4DPadDirection.North;
- else if (Inputs.ButtonState[ButtonFlags.DPadDown])
- tempDPad = DualShock4DPadDirection.South;
- else if (Inputs.ButtonState[ButtonFlags.DPadLeft])
- tempDPad = DualShock4DPadDirection.West;
- else if (Inputs.ButtonState[ButtonFlags.DPadRight])
- tempDPad = DualShock4DPadDirection.East;
-
- if (Inputs.ButtonState[ButtonFlags.Special])
- tempSpecial |= DualShock4SpecialButton.Ps.Value;
- if (Inputs.ButtonState[ButtonFlags.LeftPadClick] || Inputs.ButtonState[ButtonFlags.RightPadClick] || DS4Touch.OutputClickButton)
- tempSpecial |= DualShock4SpecialButton.Touchpad.Value;
-
- outDS4Report.bSpecial = (byte)(tempSpecial | (0 << 2));
- }
-
- if (!IsSilenced)
- {
- outDS4Report.wButtons = tempButtons;
- outDS4Report.wButtons |= tempDPad.Value;
-
- outDS4Report.bTriggerL = (byte)Inputs.AxisState[AxisFlags.L2];
- outDS4Report.bTriggerR = (byte)Inputs.AxisState[AxisFlags.R2];
-
- outDS4Report.bThumbLX = InputUtils.NormalizeXboxInput(LeftThumb.X);
- outDS4Report.bThumbLY = (byte)(byte.MaxValue - InputUtils.NormalizeXboxInput(LeftThumb.Y));
- outDS4Report.bThumbRX = InputUtils.NormalizeXboxInput(RightThumb.X);
- outDS4Report.bThumbRY = (byte)(byte.MaxValue - InputUtils.NormalizeXboxInput(RightThumb.Y));
- }
-
- unchecked
- {
- outDS4Report.bTouchPacketsN = 0x01;
- outDS4Report.sCurrentTouch.bPacketCounter = DS4Touch.TouchPacketCounter;
- outDS4Report.sCurrentTouch.bIsUpTrackingNum1 = (byte)DS4Touch.LeftPadTouch.RawTrackingNum;
- outDS4Report.sCurrentTouch.bTouchData1[0] = (byte)(DS4Touch.LeftPadTouch.X & 0xFF);
- outDS4Report.sCurrentTouch.bTouchData1[1] =
- (byte)(((DS4Touch.LeftPadTouch.X >> 8) & 0x0F) | ((DS4Touch.LeftPadTouch.Y << 4) & 0xF0));
- outDS4Report.sCurrentTouch.bTouchData1[2] = (byte)(DS4Touch.LeftPadTouch.Y >> 4);
-
- outDS4Report.sCurrentTouch.bIsUpTrackingNum2 = (byte)DS4Touch.RightPadTouch.RawTrackingNum;
- outDS4Report.sCurrentTouch.bTouchData2[0] = (byte)(DS4Touch.RightPadTouch.X & 0xFF);
- outDS4Report.sCurrentTouch.bTouchData2[1] =
- (byte)(((DS4Touch.RightPadTouch.X >> 8) & 0x0F) | ((DS4Touch.RightPadTouch.Y << 4) & 0xF0));
- outDS4Report.sCurrentTouch.bTouchData2[2] = (byte)(DS4Touch.RightPadTouch.Y >> 4);
- }
-
- // Use IMU sensor data, map to proper range, invert where needed
- if (IMU.AngularVelocity.TryGetValue(XInputSensorFlags.Default, out var velocity))
- {
- outDS4Report.wGyroX = (short)InputUtils.rangeMap(velocity.X, DS4GyroscopeSensorSpec); // gyroPitchFull
- outDS4Report.wGyroY = (short)InputUtils.rangeMap(-velocity.Y, DS4GyroscopeSensorSpec); // gyroYawFull
- outDS4Report.wGyroZ = (short)InputUtils.rangeMap(velocity.Z, DS4GyroscopeSensorSpec); // gyroRollFull
- }
-
- if (IMU.Acceleration.TryGetValue(XInputSensorFlags.Default, out var acceleration))
- {
- outDS4Report.wAccelX =
- (short)InputUtils.rangeMap(-acceleration.X, DS4AccelerometerSensorSpec); // accelXFull
- outDS4Report.wAccelY =
- (short)InputUtils.rangeMap(-acceleration.Y, DS4AccelerometerSensorSpec); // accelYFull
- outDS4Report.wAccelZ = (short)InputUtils.rangeMap(acceleration.Z, DS4AccelerometerSensorSpec); // accelZFull
- }
-
- outDS4Report.bBatteryLvlSpecial = 11;
-
- outDS4Report.wTimestamp = (ushort)TimerManager.GetElapsedSeconds();
-
- DS4OutDeviceExtras.CopyBytes(ref outDS4Report, rawOutReportEx);
-
- try
- {
- virtualController.SubmitRawReport(rawOutReportEx);
- }
- catch (VigemBusNotFoundException ex)
- {
- LogManager.LogCritical(ex.Message);
- }
- catch (VigemInvalidTargetException ex)
- {
- LogManager.LogCritical(ex.Message);
- }
-
- SubmitReport();
- }
-
- public override void Dispose()
- {
- if (virtualController is not null)
- virtualController.Disconnect();
-
- base.Dispose();
- }
-}
\ No newline at end of file
diff --git a/ControllerService/Targets/ViGEmTarget.cs b/ControllerService/Targets/ViGEmTarget.cs
deleted file mode 100644
index 2de9cfd3b..000000000
--- a/ControllerService/Targets/ViGEmTarget.cs
+++ /dev/null
@@ -1,213 +0,0 @@
-using System;
-using System.Numerics;
-using ControllerCommon;
-using ControllerCommon.Controllers;
-using ControllerCommon.Inputs;
-using ControllerCommon.Managers;
-using ControllerCommon.Utils;
-using ControllerService.Sensors;
-using Nefarius.ViGEm.Client;
-
-namespace ControllerService.Targets;
-
-public abstract class ViGEmTarget : IDisposable
-{
- public delegate void ConnectedEventHandler(ViGEmTarget target);
-
- public delegate void DisconnectedEventHandler(ViGEmTarget target);
-
- public FlickStick flickStick;
-
- public HIDmode HID = HIDmode.NoController;
- protected ControllerState Inputs = new();
-
- public bool IsConnected;
- protected bool IsSilenced;
-
- protected Vector2 LeftThumb;
- protected Vector2 RightThumb;
-
- protected IVirtualGamepad virtualController;
-
- protected ViGEmTarget()
- {
- // initialize flick stick
- flickStick = new FlickStick();
-
- ControllerService.ForegroundUpdated += ForegroundUpdated;
- }
-
- public virtual void Dispose()
- {
- Disconnect();
- GC.SuppressFinalize(this);
- }
-
- public event ConnectedEventHandler Connected;
-
- public event DisconnectedEventHandler Disconnected;
-
- private void ForegroundUpdated()
- {
- if (ControllerService.currentProfile.Whitelisted)
- IsSilenced = true;
- else
- IsSilenced = false;
- }
-
- protected void FeedbackReceived(object sender, EventArgs e)
- {
- }
-
- public override string ToString()
- {
- return EnumUtils.GetDescriptionFromEnumValue(HID);
- }
-
- public virtual void Connect()
- {
- IsConnected = true;
- Connected?.Invoke(this);
- LogManager.LogInformation("{0} connected", ToString());
- }
-
- public virtual void Disconnect()
- {
- IsConnected = false;
- Disconnected?.Invoke(this);
- LogManager.LogInformation("{0} disconnected", ToString());
- }
-
- public void UpdateInputs(ControllerState inputs)
- {
- Inputs = inputs;
- }
-
- public virtual void UpdateReport(long ticks)
- {
- // get sticks values
- LeftThumb = new Vector2(Inputs.AxisState[AxisFlags.LeftThumbX], Inputs.AxisState[AxisFlags.LeftThumbY]);
- RightThumb = new Vector2(Inputs.AxisState[AxisFlags.RightThumbX], Inputs.AxisState[AxisFlags.RightThumbY]);
-
- if (ControllerService.currentProfile.MotionEnabled && Inputs.MotionTriggered)
- switch (ControllerService.currentProfile.MotionInput)
- {
- case MotionInput.PlayerSpace:
- case MotionInput.JoystickCamera:
- case MotionInput.AutoRollYawSwap:
- {
- Vector2 Angular;
-
- switch (ControllerService.currentProfile.MotionInput)
- {
- case MotionInput.PlayerSpace:
- Angular = new Vector2((float)IMU.sensorFusion.CameraYawDelta,
- (float)IMU.sensorFusion.CameraPitchDelta);
- break;
- case MotionInput.AutoRollYawSwap:
- Angular = InputUtils.AutoRollYawSwap(IMU.sensorFusion.GravityVectorSimple,
- IMU.AngularVelocity[XInputSensorFlags.Centered]);
- break;
- default:
- case MotionInput.JoystickCamera:
- Angular = new Vector2(-IMU.AngularVelocity[XInputSensorFlags.Centered].Z,
- IMU.AngularVelocity[XInputSensorFlags.Centered].X);
- break;
- }
-
- // apply sensivity curve
- Angular.X *= InputUtils.ApplyCustomSensitivity(Angular.X, IMUGyrometer.sensorSpec.maxIn,
- ControllerService.currentProfile.MotionSensivityArray);
- Angular.Y *= InputUtils.ApplyCustomSensitivity(Angular.Y, IMUGyrometer.sensorSpec.maxIn,
- ControllerService.currentProfile.MotionSensivityArray);
-
- // apply aiming down scopes multiplier if activated
- if (Inputs.ButtonState.Contains(ControllerService.currentProfile.AimingSightsTrigger))
- Angular *= ControllerService.currentProfile.AimingSightsMultiplier;
-
- // apply sensivity
- var GamepadThumb = new Vector2(
- Angular.X * ControllerService.currentProfile.GetSensitivityX(),
- Angular.Y * ControllerService.currentProfile.GetSensitivityY());
-
- // apply anti deadzone to motion based thumb input to overcome deadzone and experience small movements properly
- GamepadThumb = InputUtils.ApplyAntiDeadzone(GamepadThumb,
- ControllerService.currentProfile.MotionAntiDeadzone);
-
- // Improve circularity to prevent 1,1 joystick values based on motion
- GamepadThumb = InputUtils.ImproveCircularity(GamepadThumb);
-
- switch (ControllerService.currentProfile.MotionOutput)
- {
- default:
- case MotionOutput.RightStick:
-
- if (ControllerService.currentProfile.FlickstickEnabled)
- {
- // Flick Stick:
- // - Detect flicking
- // - Filter stick input
- // - Determine and compute either flick or stick output
- var FlickStickX = flickStick.Handle(RightThumb,
- ControllerService.currentProfile.FlickstickDuration,
- ControllerService.currentProfile.FlickstickSensivity,
- IMU.TotalMilliseconds);
-
- // X input combines motion controls plus flick stick result
- // Y input only from motion controls
- RightThumb.X = (short)Math.Clamp(GamepadThumb.X - FlickStickX, short.MinValue,
- short.MaxValue);
- RightThumb.Y = (short)Math.Clamp(GamepadThumb.Y, short.MinValue, short.MaxValue);
- }
- else
- {
- RightThumb.X = (short)Math.Clamp(RightThumb.X + GamepadThumb.X, short.MinValue,
- short.MaxValue);
- RightThumb.Y = (short)Math.Clamp(RightThumb.Y + GamepadThumb.Y, short.MinValue,
- short.MaxValue);
- }
-
- break;
-
- case MotionOutput.LeftStick:
- LeftThumb.X = (short)Math.Clamp(LeftThumb.X + GamepadThumb.X, short.MinValue,
- short.MaxValue);
- LeftThumb.Y = (short)Math.Clamp(LeftThumb.Y + GamepadThumb.Y, short.MinValue,
- short.MaxValue);
-
- break;
- }
- }
- break;
-
- case MotionInput.JoystickSteering:
- {
- var GamepadThumbX = InputUtils.Steering(
- IMU.sensorFusion.DeviceAngle.Y,
- ControllerService.currentProfile.SteeringMaxAngle,
- ControllerService.currentProfile.SteeringPower,
- ControllerService.currentProfile.SteeringDeadzone);
-
- switch (ControllerService.currentProfile.MotionOutput)
- {
- default:
- case MotionOutput.RightStick:
- RightThumb.X = (short)GamepadThumbX;
- break;
- case MotionOutput.LeftStick:
- LeftThumb.X = (short)GamepadThumbX;
- break;
- }
- }
- break;
- }
- }
-
- internal void SubmitReport()
- {
- /*
- * ButtonsInjector = 0;
- * sStateInjector.wButtons = 0;
- */
- }
-}
\ No newline at end of file
diff --git a/ControllerService/Targets/Xbox360Target.cs b/ControllerService/Targets/Xbox360Target.cs
deleted file mode 100644
index 82183e660..000000000
--- a/ControllerService/Targets/Xbox360Target.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using System;
-using ControllerCommon.Inputs;
-using ControllerCommon.Managers;
-using ControllerCommon.Pipes;
-using ControllerCommon.Utils;
-using Nefarius.ViGEm.Client.Exceptions;
-using Nefarius.ViGEm.Client.Targets;
-using Nefarius.ViGEm.Client.Targets.Xbox360;
-
-namespace ControllerService.Targets;
-
-internal class Xbox360Target : ViGEmTarget
-{
- private new readonly IXbox360Controller virtualController;
-
- public Xbox360Target()
- {
- // initialize controller
- HID = HIDmode.Xbox360Controller;
-
- virtualController = ControllerService.vClient.CreateXbox360Controller();
- virtualController.AutoSubmitReport = false;
- virtualController.FeedbackReceived += FeedbackReceived;
-
- LogManager.LogInformation("{0} initialized, {1}", ToString(), virtualController);
- }
-
- public override void Connect()
- {
- if (IsConnected)
- return;
-
- try
- {
- virtualController.Connect();
- TimerManager.Tick += UpdateReport;
-
- base.Connect();
- }
- catch (Exception ex)
- {
- virtualController.Disconnect();
- LogManager.LogWarning("Failed to connect {0}. {1}", ToString(), ex.Message);
- }
- }
-
- public override void Disconnect()
- {
- if (!IsConnected)
- return;
-
- try
- {
- virtualController.Disconnect();
- TimerManager.Tick -= UpdateReport;
-
- base.Disconnect();
- }
- catch
- {
- }
- }
-
- public void FeedbackReceived(object sender, Xbox360FeedbackReceivedEventArgs e)
- {
- // pass raw vibration to client
- PipeServer.SendMessage(new PipeClientVibration { LargeMotor = e.LargeMotor, SmallMotor = e.SmallMotor });
- }
-
- public override void UpdateReport(long ticks)
- {
- if (!IsConnected)
- return;
-
- if (IsSilenced)
- return;
-
- base.UpdateReport(ticks);
-
- virtualController.SetAxisValue(Xbox360Axis.LeftThumbX, (short)LeftThumb.X);
- virtualController.SetAxisValue(Xbox360Axis.LeftThumbY, (short)LeftThumb.Y);
- virtualController.SetAxisValue(Xbox360Axis.RightThumbX, (short)RightThumb.X);
- virtualController.SetAxisValue(Xbox360Axis.RightThumbY, (short)RightThumb.Y);
-
- virtualController.SetSliderValue(Xbox360Slider.LeftTrigger, (byte)Inputs.AxisState[AxisFlags.L2]);
- virtualController.SetSliderValue(Xbox360Slider.RightTrigger, (byte)Inputs.AxisState[AxisFlags.R2]);
-
- virtualController.SetButtonState(Xbox360Button.A, Inputs.ButtonState[ButtonFlags.B1]);
- virtualController.SetButtonState(Xbox360Button.B, Inputs.ButtonState[ButtonFlags.B2]);
- virtualController.SetButtonState(Xbox360Button.X, Inputs.ButtonState[ButtonFlags.B3]);
- virtualController.SetButtonState(Xbox360Button.Y, Inputs.ButtonState[ButtonFlags.B4]);
-
- virtualController.SetButtonState(Xbox360Button.Up, Inputs.ButtonState[ButtonFlags.DPadUp]);
- virtualController.SetButtonState(Xbox360Button.Down, Inputs.ButtonState[ButtonFlags.DPadDown]);
- virtualController.SetButtonState(Xbox360Button.Left, Inputs.ButtonState[ButtonFlags.DPadLeft]);
- virtualController.SetButtonState(Xbox360Button.Right, Inputs.ButtonState[ButtonFlags.DPadRight]);
-
- virtualController.SetButtonState(Xbox360Button.Back, Inputs.ButtonState[ButtonFlags.Back]);
- virtualController.SetButtonState(Xbox360Button.Start, Inputs.ButtonState[ButtonFlags.Start]);
-
- virtualController.SetButtonState(Xbox360Button.LeftShoulder, Inputs.ButtonState[ButtonFlags.L1]);
- virtualController.SetButtonState(Xbox360Button.RightShoulder, Inputs.ButtonState[ButtonFlags.R1]);
-
- virtualController.SetButtonState(Xbox360Button.LeftThumb, Inputs.ButtonState[ButtonFlags.LeftThumb]);
- virtualController.SetButtonState(Xbox360Button.RightThumb, Inputs.ButtonState[ButtonFlags.RightThumb]);
-
- virtualController.SetButtonState(Xbox360Button.Guide, Inputs.ButtonState[ButtonFlags.Special]);
-
- try
- {
- virtualController.SubmitReport();
- }
- catch (VigemBusNotFoundException ex)
- {
- LogManager.LogCritical(ex.Message);
- }
- catch (VigemInvalidTargetException ex)
- {
- LogManager.LogCritical(ex.Message);
- }
-
- SubmitReport();
- }
-
- public override void Dispose()
- {
- if (virtualController is not null)
- virtualController.Disconnect();
-
- base.Dispose();
- }
-}
\ No newline at end of file
diff --git a/HandheldCompanion-Offline.iss b/HandheldCompanion-Offline.iss
deleted file mode 100644
index 8def1f8a9..000000000
--- a/HandheldCompanion-Offline.iss
+++ /dev/null
@@ -1,519 +0,0 @@
-; -- CodeDependencies.iss --
-;
-; This script shows how to download and install any dependency such as .NET,
-; Visual C++ or SQL Server during your application's installation process.
-;
-; contribute: https://github.com/DomGries/InnoDependencyInstaller
-
-
-; -----------
-; SHARED CODE
-; -----------
-[Code]
-// types and variables
-type
- TDependency_Entry = record
- Filename: String;
- Parameters: String;
- Title: String;
- URL: String;
- Checksum: String;
- ForceSuccess: Boolean;
- RestartAfter: Boolean;
- end;
-
-var
- Dependency_Memo: String;
- Dependency_List: array of TDependency_Entry;
- Dependency_NeedRestart, Dependency_ForceX86: Boolean;
- Dependency_DownloadPage: TDownloadWizardPage;
-
-procedure Dependency_Add(const Filename, Parameters, Title, URL, Checksum: String; const ForceSuccess, RestartAfter: Boolean);
-var
- Dependency: TDependency_Entry;
- DependencyCount: Integer;
-begin
- Dependency_Memo := Dependency_Memo + #13#10 + '%1' + Title;
-
- Dependency.Filename := Filename;
- Dependency.Parameters := Parameters;
- Dependency.Title := Title;
-
- if FileExists(ExpandConstant('{tmp}{\}') + Filename) then begin
- Dependency.URL := '';
- end else begin
- Dependency.URL := URL;
- end;
-
- Dependency.Checksum := Checksum;
- Dependency.ForceSuccess := ForceSuccess;
- Dependency.RestartAfter := RestartAfter;
-
- DependencyCount := GetArrayLength(Dependency_List);
- SetArrayLength(Dependency_List, DependencyCount + 1);
- Dependency_List[DependencyCount] := Dependency;
-end;
-
-procedure Dependency_InitializeWizard;
-begin
- Dependency_DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil);
-end;
-
-function Dependency_PrepareToInstall(var NeedsRestart: Boolean): String;
-var
- DependencyCount, DependencyIndex, ResultCode: Integer;
- Retry: Boolean;
- TempValue: String;
-begin
- DependencyCount := GetArrayLength(Dependency_List);
-
- if DependencyCount > 0 then begin
- Dependency_DownloadPage.Show;
-
- for DependencyIndex := 0 to DependencyCount - 1 do begin
- if Dependency_List[DependencyIndex].URL <> '' then begin
- Dependency_DownloadPage.Clear;
- Dependency_DownloadPage.Add(Dependency_List[DependencyIndex].URL, Dependency_List[DependencyIndex].Filename, Dependency_List[DependencyIndex].Checksum);
-
- Retry := True;
- while Retry do begin
- Retry := False;
-
- try
- Dependency_DownloadPage.Download;
- except
- if Dependency_DownloadPage.AbortedByUser then begin
- Result := Dependency_List[DependencyIndex].Title;
- DependencyIndex := DependencyCount;
- end else begin
- case SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
- IDABORT: begin
- Result := Dependency_List[DependencyIndex].Title;
- DependencyIndex := DependencyCount;
- end;
- IDRETRY: begin
- Retry := True;
- end;
- end;
- end;
- end;
- end;
- end;
- end;
-
- if Result = '' then begin
- for DependencyIndex := 0 to DependencyCount - 1 do begin
- Dependency_DownloadPage.SetText(Dependency_List[DependencyIndex].Title, '');
- Dependency_DownloadPage.SetProgress(DependencyIndex + 1, DependencyCount + 1);
-
- while True do begin
- ResultCode := 0;
- if ShellExec('', ExpandConstant('{tmp}{\}') + Dependency_List[DependencyIndex].Filename, Dependency_List[DependencyIndex].Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then begin
- if Dependency_List[DependencyIndex].RestartAfter then begin
- if DependencyIndex = DependencyCount - 1 then begin
- Dependency_NeedRestart := True;
- end else begin
- NeedsRestart := True;
- Result := Dependency_List[DependencyIndex].Title;
- end;
- break;
- end else if (ResultCode = 0) or Dependency_List[DependencyIndex].ForceSuccess then begin // ERROR_SUCCESS (0)
- break;
- end else if ResultCode = 1641 then begin // ERROR_SUCCESS_REBOOT_INITIATED (1641)
- NeedsRestart := True;
- Result := Dependency_List[DependencyIndex].Title;
- break;
- end else if ResultCode = 3010 then begin // ERROR_SUCCESS_REBOOT_REQUIRED (3010)
- Dependency_NeedRestart := True;
- break;
- end;
- end;
-
- case SuppressibleMsgBox(FmtMessage(SetupMessage(msgErrorFunctionFailed), [Dependency_List[DependencyIndex].Title, IntToStr(ResultCode)]), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
- IDABORT: begin
- Result := Dependency_List[DependencyIndex].Title;
- break;
- end;
- IDIGNORE: begin
- break;
- end;
- end;
- end;
-
- if Result <> '' then begin
- break;
- end;
- end;
-
- if NeedsRestart then begin
- TempValue := '"' + ExpandConstant('{srcexe}') + '" /restart=1 /LANG="' + ExpandConstant('{language}') + '" /DIR="' + WizardDirValue + '" /GROUP="' + WizardGroupValue + '" /TYPE="' + WizardSetupType(False) + '" /COMPONENTS="' + WizardSelectedComponents(False) + '" /TASKS="' + WizardSelectedTasks(False) + '"';
- if WizardNoIcons then begin
- TempValue := TempValue + ' /NOICONS';
- end;
- RegWriteStringValue(HKA, 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce', '{#SetupSetting("AppName")}', TempValue);
- end;
- end;
-
- Dependency_DownloadPage.Hide;
- end;
-end;
-
-function Dependency_UpdateReadyMemo(const Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
-begin
- Result := '';
- if MemoUserInfoInfo <> '' then begin
- Result := Result + MemoUserInfoInfo + Newline + NewLine;
- end;
- if MemoDirInfo <> '' then begin
- Result := Result + MemoDirInfo + Newline + NewLine;
- end;
- if MemoTypeInfo <> '' then begin
- Result := Result + MemoTypeInfo + Newline + NewLine;
- end;
- if MemoComponentsInfo <> '' then begin
- Result := Result + MemoComponentsInfo + Newline + NewLine;
- end;
- if MemoGroupInfo <> '' then begin
- Result := Result + MemoGroupInfo + Newline + NewLine;
- end;
- if MemoTasksInfo <> '' then begin
- Result := Result + MemoTasksInfo;
- end;
-
- if Dependency_Memo <> '' then begin
- if MemoTasksInfo = '' then begin
- Result := Result + SetupMessage(msgReadyMemoTasks);
- end;
- Result := Result + FmtMessage(Dependency_Memo, [Space]);
- end;
-end;
-
-function Dependency_IsX64: Boolean;
-begin
- Result := not Dependency_ForceX86 and Is64BitInstallMode;
-end;
-
-function Dependency_String(const x86, x64: String): String;
-begin
- if Dependency_IsX64 then begin
- Result := x64;
- end else begin
- Result := x86;
- end;
-end;
-
-function Dependency_ArchSuffix: String;
-begin
- Result := Dependency_String('', '_x64');
-end;
-
-function Dependency_ArchTitle: String;
-begin
- Result := Dependency_String(' (x86)', ' (x64)');
-end;
-
-[Setup]
-; -------------
-; EXAMPLE SETUP
-; -------------
-#ifndef Dependency_NoExampleSetup
-
-#define UseOfflineInstaller
-
-; requires netcorecheck.exe and netcorecheck_x64.exe (see download link below)
-; #define UseNetCoreCheck
-#ifdef UseNetCoreCheck
-#endif
-
-#define UseDotNet70
-
-#define UseVC2005
-#define UseVC2008
-#define UseVC2010
-#define UseVC2012
-#define UseVC2013
-#define UseVC2015To2019
-
-#define UseDirectX
-#define UseHideHide
-#define UseViGem
-#define UseRTSS
-#define UseHWiNFO
-
-#define MyAppSetupName 'Handheld Companion'
-#define MyBuildId 'HandheldCompanion'
-#define MyAppVersion '0.16.2.5'
-#define MyAppPublisher 'BenjaminLSR'
-#define MyAppCopyright 'Copyright © BenjaminLSR'
-#define MyAppURL 'https://github.com/Valkirie/HandheldCompanion'
-#define MyAppExeName "HandheldCompanion.exe"
-#define MySerExeName "ControllerService.exe"
-#define MyConfiguration "Release"
-
-#ifdef UseDotNet70
- #define MyConfigurationExt "net7.0"
-#endif
-
-; #define ClearProfiles
-; #define ClearHotkeys
-
-AppName={#MyAppSetupName}
-AppVersion={#MyAppVersion}
-AppVerName={#MyAppSetupName}
-AppCopyright={#MyAppCopyright}
-VersionInfoVersion={#MyAppVersion}
-VersionInfoCompany={#MyAppPublisher}
-AppPublisher={#MyAppPublisher}
-AppPublisherURL={#MyAppURL}
-AppSupportURL={#MyAppURL}
-AppUpdatesURL={#MyAppURL}
-OutputBaseFilename={#MyBuildId}-{#MyAppVersion}-offline
-DefaultGroupName={#MyAppSetupName}
-DefaultDirName={autopf}\{#MyAppSetupName}
-UninstallDisplayIcon={app}\{#MyAppExeName}
-SetupIconFile="{#SourcePath}\HandheldCompanion\Resources\icon.ico"
-SourceDir=redist
-OutputDir={#SourcePath}\install
-AllowNoIcons=yes
-
-MinVersion=6.0
-PrivilegesRequired=admin
-
-// remove next line if you only deploy 32-bit binaries and dependencies
-ArchitecturesInstallIn64BitMode=x64
-
-[Languages]
-Name: en; MessagesFile: "compiler:Default.isl"
-
-[Setup]
-AlwaysRestart = yes
-CloseApplications = yes
-
-[Files]
-#ifdef UseNetCoreCheck
-// download netcorecheck.exe: https://go.microsoft.com/fwlink/?linkid=2135256
-// download netcorecheck_x64.exe: https://go.microsoft.com/fwlink/?linkid=2135504
-Source: "netcorecheck.exe"; Flags: dontcopy noencryption
-Source: "netcorecheck_x64.exe"; Flags: dontcopy noencryption
-#endif
-
-#ifdef UseOfflineInstaller
-Source: "dxwebsetup.exe"; Flags: dontcopy noencryption
-Source: "vcredist2005_x64.exe"; Flags: dontcopy noencryption
-Source: "vcredist2008_x64.exe"; Flags: dontcopy noencryption
-Source: "vcredist2010_x64.exe"; Flags: dontcopy noencryption
-Source: "vcredist2012_x64.exe"; Flags: dontcopy noencryption
-Source: "vcredist2013_x64.exe"; Flags: dontcopy noencryption
-Source: "vcredist2019_x64.exe"; Flags: dontcopy noencryption
-
- #ifdef UseDotNet70
- Source: "dotnet-runtime-7.0.0-win-x64.exe"; Flags: dontcopy noencryption
- Source: "windowsdesktop-runtime-7.0.0-win-x64.exe"; Flags: dontcopy noencryption
- #endif
-#endif
-
-Source: "{#SourcePath}\bin\{#MyConfiguration}\{#MyConfigurationExt}-windows10.0.19041.0\WinRing0x64.dll"; DestDir: "{app}"; Flags: onlyifdoesntexist
-Source: "{#SourcePath}\bin\{#MyConfiguration}\{#MyConfigurationExt}-windows10.0.19041.0\WinRing0x64.sys"; DestDir: "{app}"; Flags: onlyifdoesntexist
-Source: "{#SourcePath}\bin\{#MyConfiguration}\{#MyConfigurationExt}-windows10.0.19041.0\*"; Excludes: "*WinRing0x64.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
-
-Source: "{#SourcePath}\redist\SegoeIcons.ttf"; DestDir: "{autofonts}"; FontInstall: "Segoe Fluent Icons (TrueType)"; Flags: onlyifdoesntexist uninsneveruninstall
-Source: "{#SourcePath}\redist\PromptFont.otf"; DestDir: "{autofonts}"; FontInstall: "PromptFont"; Flags: uninsneveruninstall
-
-Source: "{#SourcePath}\redist\ViGEmBus_1.21.442_x64_x86_arm64.exe"; DestDir: "{app}\redist\"; Flags: ignoreversion recursesubdirs createallsubdirs
-Source: "{#SourcePath}\redist\HidHide_1.2.98_x64.exe"; DestDir: "{app}\redist\"; Flags: ignoreversion recursesubdirs createallsubdirs
-Source: "{#SourcePath}\redist\RTSSSetup734.exe"; DestDir: "{app}\redist\"; Flags: ignoreversion recursesubdirs createallsubdirs
-Source: "{#SourcePath}\redist\hwi_746.exe"; DestDir: "{app}\redist\"; Flags: ignoreversion recursesubdirs createallsubdirs
-
-[Icons]
-Name: "{group}\{#MyAppSetupName}"; Filename: "{app}\{#MyAppExeName}"
-Name: "{group}\{cm:UninstallProgram,{#MyAppSetupName}}"; Filename: "{uninstallexe}"
-Name: "{commondesktop}\{#MyAppSetupName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
-
-[Tasks]
-Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"
-
-[Run]
-Filename: "{tmp}\dxwebsetup.exe"; StatusMsg: "Installing DirectX Runtime"; Parameters: "/q"; Flags: waituntilterminated
-Filename: "{tmp}\vcredist2019_x64.exe"; StatusMsg: "Installing Visual C++ 2015-2019 Redistributable"; Parameters: "/passive /norestart"; Flags: waituntilterminated
-Filename: "{tmp}\vcredist2013_x64.exe"; StatusMsg: "Installing Visual C++ 2013 Redistributable"; Parameters: "/passive /norestart"; Flags: waituntilterminated
-Filename: "{tmp}\vcredist2012_x64.exe"; StatusMsg: "Installing Visual C++ 2012 Redistributable"; Parameters: "/passive /norestart"; Flags: waituntilterminated
-Filename: "{tmp}\vcredist2010_x64.exe"; StatusMsg: "Installing Visual C++ 2010 Redistributable"; Parameters: "/passive /norestart"; Flags: waituntilterminated
-Filename: "{tmp}\vcredist2008_x64.exe"; StatusMsg: "Installing Visual C++ 2008 Redistributable"; Parameters: "/passive /norestart"; Flags: waituntilterminated
-Filename: "{tmp}\vcredist2005_x64.exe"; StatusMsg: "Installing Visual C++ 2005 Redistributable"; Parameters: "/Q"; Flags: waituntilterminated
-
-#ifdef UseDotNet70
-Filename: "{tmp}\windowsdesktop-runtime-7.0.0-win-x64"; StatusMsg: ".NET Desktop Runtime 7.0.0"; Parameters: "/passive /norestart"; Flags: waituntilterminated
-Filename: "{tmp}\dotnet-runtime-7.0.0-win-x64"; StatusMsg: "Installing .NET Runtime 7.0.0"; Parameters: "/passive /norestart"; Flags: waituntilterminated
-#endif
-
-Filename: "{app}\redist\ViGEmBus_1.21.442_x64_x86_arm64.exe"; StatusMsg: "Installing ViGEmBus"; Parameters: "/quiet /norestart"; Flags: runascurrentuser
-Filename: "{app}\redist\HidHide_1.2.98_x64.exe"; StatusMsg: "Installing HidHide"; Parameters: "/quiet /norestart"; Flags: runascurrentuser
-Filename: "{app}\redist\RTSSSetup734.exe"; StatusMsg: "Installing RTSS"; Parameters: "/S"; Flags: runascurrentuser
-Filename: "{app}\redist\hwi_746.exe"; StatusMsg: "Installing HWiNFO"; Parameters: "/silent"; Flags: runascurrentuser
-
-[UninstallRun]
-Filename: "{sys}\sc.exe"; Parameters: "stop ControllerService" ; RunOnceId: "StopService"; Flags: runascurrentuser runhidden
-Filename: "{sys}\sc.exe"; Parameters: "delete ControllerService" ; RunOnceId: "DeleteService"; Flags: runascurrentuser runhidden
-Filename: "C:\Program Files\Nefarius Software Solutions e.U\HidHideCLI\HidHideCLI.exe"; Parameters: "--cloak-off" ; RunOnceId: "CloakOff"; Flags: runascurrentuser runhidden
-
-[UninstallDelete]
-Type: filesandordirs; Name: "{app}"
-
-[InstallDelete]
-#ifdef ClearHotkeys
-Type: filesandordirs; Name: "{userdocs}\{#MyBuildId}\hotkeys"
-#endif
-
-#ifdef ClearProfiles
-Type: filesandordirs; Name: "{userdocs}\{#MyBuildId}\profiles"
-#endif
-
-[Registry]
-Root: HKLM; Subkey: "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps"; Flags: uninsdeletekeyifempty
-Root: HKLM; Subkey: "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\ControllerService.exe"; ValueType: string; ValueName: "DumpFolder"; ValueData: "{userdocs}\HandheldCompanion\dumps"; Flags: uninsdeletekey
-Root: HKLM; Subkey: "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\HandheldCompanion.exe"; ValueType: string; ValueName: "DumpFolder"; ValueData: "{userdocs}\HandheldCompanion\dumps"; Flags: uninsdeletekey
-
-[Code]
-#include "./UpdateUninstallWizard.iss"
-
-procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
-var
- resultCode:integer;
-begin
- if CurUninstallStep = usUninstall then
- begin
- if not(checkListBox.checked[keepAllCheck]) then
- begin
- if DirExists(ExpandConstant('{userdocs}\{#MyBuildId}\profiles')) then
- DelTree(ExpandConstant('{userdocs}\{#MyBuildId}\profiles'), True, True, True);
- if DirExists(ExpandConstant('{userdocs}\{#MyBuildId}\hotkeys')) then
- DelTree(ExpandConstant('{userdocs}\{#MyBuildId}\hotkeys'), True, True, True);
- DelTree(ExpandConstant('{localappdata}\HandheldCompanion'), True, True, True);
- DelTree(ExpandConstant('{localappdata}\ControllerService'), True, True, True);
- exit;
- end
- else
- begin
- if not(checkListBox.checked[profilesCheck]) then
- begin
- if DirExists(ExpandConstant('{userdocs}\{#MyBuildId}\profiles')) then
- DelTree(ExpandConstant('{userdocs}\{#MyBuildId}\profiles'), True, True, True);
- end;
-
- if not(checkListBox.checked[hotkeysCheck]) then
- begin
- if DirExists(ExpandConstant('{userdocs}\{#MyBuildId}\hotkeys')) then
- DelTree(ExpandConstant('{userdocs}\{#MyBuildId}\hotkeys'), True, True, True);
- end;
-
- if not(checkListBox.checked[applicationSettingsCheck]) then
- begin
- DelTree(ExpandConstant('{localappdata}\HandheldCompanion'), True, True, True);
- DelTree(ExpandConstant('{localappdata}\ControllerService'), True, True, True);
- end;
- end;
-
- if not(keepHidhideCheckbox.Checked) then
- begin
- if(ShellExec('', 'msiexec.exe', '/X{27AF679E-48DB-4B49-A689-1D6A3A52C472} /qn /norestart', '', SW_SHOW, ewWaitUntilTerminated, resultCode)) then
- begin
- log('Successfully executed Hidhide uninstaller');
- if(resultCode = 0) then
- log('Hidhide uninstaller finished successfully')
- else
- log('Hidhide uninstaller failed with exit code ' +intToStr(resultCode));
- end
- else
- begin
- log('Failed to execute Hidhide uninstaller');
- end;
- end;
-
- if not(keepVigemCheckbox.Checked) then
- begin
- if(ShellExec('', 'msiexec.exe', '/X{9C581C76-2D68-40F8-AA6F-94D3C5215C05} /qn /norestart', '', SW_SHOW, ewWaitUntilTerminated, resultCode)) then
- begin
- log('Successfully executed Vigem uninstaller');
- if(resultCode = 0) then
- log('Vigem uninstaller finished successfully')
- else
- log('Vigem uninstaller failed with exit code ' +intToStr(resultCode));
- end
- else
- begin
- log('Failed to execute Vigem uninstaller');
- end;
- end;
- end;
-end;
-
-procedure InitializeWizard;
-begin
- Dependency_InitializeWizard;
-end;
-
-function PrepareToInstall(var NeedsRestart: Boolean): String;
-begin
- Result := Dependency_PrepareToInstall(NeedsRestart);
-end;
-
-function NeedRestart: Boolean;
-begin
- Result := Dependency_NeedRestart;
-end;
-
-function UpdateReadyMemo(const Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
-begin
- Result := Dependency_UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo);
-end;
-
-function InitializeSetup: Boolean;
-begin
-#ifdef UseDotNet70
- ExtractTemporaryFile('dotnet-runtime-7.0.0-win-x64.exe');
- ExtractTemporaryFile('windowsdesktop-runtime-7.0.0-win-x64.exe');
-#endif
-
-#ifdef UseVC2005
- ExtractTemporaryFile('vcredist2005_x64.exe');
-#endif
-#ifdef UseVC2008
- ExtractTemporaryFile('vcredist2008_x64.exe');
-#endif
-#ifdef UseVC2010
- ExtractTemporaryFile('vcredist2010_x64.exe');
-#endif
-#ifdef UseVC2012
- ExtractTemporaryFile('vcredist2012_x64.exe');
-#endif
-#ifdef UseVC2013
- ExtractTemporaryFile('vcredist2013_x64.exe');
-#endif
-#ifdef UseVC2015To2019
- ExtractTemporaryFile('vcredist2019_x64.exe');
-#endif
-
-#ifdef UseDirectX
- ExtractTemporaryFile('dxwebsetup.exe');
-#endif
-
-#ifdef UseHideHide
- ExtractTemporaryFile('HidHide_1.2.98_x64.exe');
-#endif
-
-#ifdef UseViGem
- ExtractTemporaryFile('ViGEmBus_1.21.442_x64_x86_arm64.exe');
-#endif
-
-#ifdef UseRTSS
- ExtractTemporaryFile('RTSSSetup734.exe');
-#endif
-
-#ifdef UseHWiNFO
- ExtractTemporaryFile('hwi_746.exe');
-#endif
-
- Result := True;
-end;
-
-#endif
\ No newline at end of file
diff --git a/HandheldCompanion.iss b/HandheldCompanion.iss
index dd36d0c65..8c9c52ae3 100644
--- a/HandheldCompanion.iss
+++ b/HandheldCompanion.iss
@@ -231,12 +231,12 @@ end;
procedure Dependency_AddDotNet70Desktop;
begin
// https://dotnet.microsoft.com/download/dotnet/7.0
- if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 7.0.0') then begin
+ if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App 7.0.10') then begin
Dependency_Add('dotnet70desktop' + Dependency_ArchSuffix + '.exe',
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
'.NET Desktop Runtime 7.0.0' + Dependency_ArchTitle,
- Dependency_String('https://download.visualstudio.microsoft.com/download/pr/d05a833c-2cf9-4d06-89ae-a0f3e10c5c91/c668ff42e23c2f67aa3d80227860585f/windowsdesktop-runtime-7.0.0-win-x86.exe',
- 'https://download.visualstudio.microsoft.com/download/pr/5b2fbe00-507e-450e-8b52-43ab052aadf2/79d54c3a19ce3fce314f2367cf4e3b21/windowsdesktop-runtime-7.0.0-win-x64.exe'),
+ Dependency_String('https://download.visualstudio.microsoft.com/download/pr/9812249d-fc42-41ab-bd2e-6e858d5dd5a7/95fa5a1a77eace4482bcb98ede190003/windowsdesktop-runtime-7.0.10-win-x86.exe',
+ 'https://download.visualstudio.microsoft.com/download/pr/747f4a98-2586-4bc6-b828-34f35e384a7d/44225cfd9d365855ec77d00c4812133c/windowsdesktop-runtime-7.0.10-win-x64.exe'),
'', False, False);
end;
end;
@@ -373,12 +373,12 @@ end;
#define UseDotNet70
#endif
-#define UseVC2005
-#define UseVC2008
-#define UseVC2010
-#define UseVC2012
-#define UseVC2013
-#define UseVC2015To2019
+;#define UseVC2005
+;#define UseVC2008
+;#define UseVC2010
+;#define UseVC2012
+;#define UseVC2013
+;#define UseVC2015To2019
#define UseDirectX
; install ViGem first
@@ -389,12 +389,11 @@ end;
#define MyAppSetupName 'Handheld Companion'
#define MyBuildId 'HandheldCompanion'
-#define MyAppVersion '0.16.2.5'
+#define MyAppVersion '0.18.0.1'
#define MyAppPublisher 'BenjaminLSR'
#define MyAppCopyright 'Copyright @ BenjaminLSR'
#define MyAppURL 'https://github.com/Valkirie/HandheldCompanion'
#define MyAppExeName "HandheldCompanion.exe"
-#define MySerExeName "ControllerService.exe"
#define MyConfiguration "Release"
#ifdef UseDotNet70
@@ -456,10 +455,10 @@ Name: "{commondesktop}\{#MyAppSetupName}"; Filename: "{app}\{#MyAppExeName}"; Ta
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"
[Run]
+Filename: "{sys}\sc.exe"; Parameters: "stop ControllerService" ; Flags: runascurrentuser runhidden
+Filename: "{sys}\sc.exe"; Parameters: "delete ControllerService" ; Flags: runascurrentuser runhidden
[UninstallRun]
-Filename: "{sys}\sc.exe"; Parameters: "stop ControllerService" ; RunOnceId: "StopService"; Flags: runascurrentuser runhidden
-Filename: "{sys}\sc.exe"; Parameters: "delete ControllerService" ; RunOnceId: "DeleteService"; Flags: runascurrentuser runhidden
Filename: "C:\Program Files\Nefarius Software Solutions e.U\HidHideCLI\HidHideCLI.exe"; Parameters: "--cloak-off" ; RunOnceId: "CloakOff"; Flags: runascurrentuser runhidden
[UninstallDelete]
@@ -467,12 +466,10 @@ Type: filesandordirs; Name: "{app}"
[Registry]
Root: HKLM; Subkey: "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps"; Flags: uninsdeletekeyifempty
-Root: HKLM; Subkey: "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\ControllerService.exe"; ValueType: string; ValueName: "DumpFolder"; ValueData: "{userdocs}\HandheldCompanion\dumps"; Flags: uninsdeletekey
Root: HKLM; Subkey: "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\HandheldCompanion.exe"; ValueType: string; ValueName: "DumpFolder"; ValueData: "{userdocs}\HandheldCompanion\dumps"; Flags: uninsdeletekey
[Code]
-#include "./UpdateUninstallWizard.iss"
-
+#include "./UpdateUninstallWizard.iss"
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
@@ -487,7 +484,6 @@ begin
if DirExists(ExpandConstant('{userdocs}\{#MyBuildId}\hotkeys')) then
DelTree(ExpandConstant('{userdocs}\{#MyBuildId}\hotkeys'), True, True, True);
DelTree(ExpandConstant('{localappdata}\HandheldCompanion'), True, True, True);
- DelTree(ExpandConstant('{localappdata}\ControllerService'), True, True, True);
exit;
end
else
@@ -507,7 +503,6 @@ begin
if not(checkListBox.checked[applicationSettingsCheck]) then
begin
DelTree(ExpandConstant('{localappdata}\HandheldCompanion'), True, True, True);
- DelTree(ExpandConstant('{localappdata}\ControllerService'), True, True, True);
end;
end;
@@ -570,7 +565,6 @@ function InitializeSetup: Boolean;
begin
#ifdef UseDotNet70
- Dependency_AddDotNet70;
Dependency_AddDotNet70Desktop;
#endif
diff --git a/HandheldCompanion.sln b/HandheldCompanion.sln
index edd9c538a..037936fb8 100644
--- a/HandheldCompanion.sln
+++ b/HandheldCompanion.sln
@@ -3,10 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31919.166
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerService", "ControllerService\ControllerService.csproj", "{6B7B570E-8C8B-4189-9C98-B3BBFE630615}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerCommon", "ControllerCommon\ControllerCommon.csproj", "{D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4A4F8C55-09C7-4B4C-9752-E2E05AF25E30}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
@@ -14,13 +10,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HandheldCompanion", "HandheldCompanion\HandheldCompanion.csproj", "{AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}"
ProjectSection(ProjectDependencies) = postProject
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2} = {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}
{F7283783-81EF-4CD2-BD86-598FE193C11F} = {F7283783-81EF-4CD2-BD86-598FE193C11F}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hidapi.net", "hidapi.net\hidapi.net.csproj", "{9B860078-9AD1-45DD-8F85-E6D806E5DC9B}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "neptune-hidapi.net", "neptune-hidapi.net\neptune-hidapi.net.csproj", "{F7283783-81EF-4CD2-BD86-598FE193C11F}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "steam-hidapi.net", "steam-hidapi.net\steam-hidapi.net.csproj", "{F7283783-81EF-4CD2-BD86-598FE193C11F}"
ProjectSection(ProjectDependencies) = postProject
{9B860078-9AD1-45DD-8F85-E6D806E5DC9B} = {9B860078-9AD1-45DD-8F85-E6D806E5DC9B}
EndProjectSection
@@ -33,22 +28,6 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Debug|x64.ActiveCfg = Debug|x64
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Debug|x64.Build.0 = Debug|x64
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Release|Any CPU.Build.0 = Release|Any CPU
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Release|x64.ActiveCfg = Release|x64
- {6B7B570E-8C8B-4189-9C98-B3BBFE630615}.Release|x64.Build.0 = Release|x64
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Debug|x64.ActiveCfg = Debug|x64
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Debug|x64.Build.0 = Debug|x64
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Release|Any CPU.Build.0 = Release|Any CPU
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Release|x64.ActiveCfg = Release|x64
- {D1B95ACA-77CF-4332-A1DC-AF4A6DA54FC2}.Release|x64.Build.0 = Release|x64
{AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD4B9060-93FE-4FD2-B64D-4D31EABC7C4D}.Debug|x64.ActiveCfg = Debug|x64
diff --git a/HandheldCompanion/Actions/AxisActions.cs b/HandheldCompanion/Actions/AxisActions.cs
new file mode 100644
index 000000000..40ec13ae4
--- /dev/null
+++ b/HandheldCompanion/Actions/AxisActions.cs
@@ -0,0 +1,58 @@
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Utils;
+using System;
+using System.Numerics;
+using System.Windows.Forms;
+
+namespace HandheldCompanion.Actions
+{
+ [Serializable]
+ public class AxisActions : GyroActions
+ {
+ public AxisLayoutFlags Axis;
+
+ // Axis to axis
+ public bool ImproveCircularity = false;
+ public int AxisAntiDeadZone = 0;
+ public int AxisDeadZoneInner = 0;
+ public int AxisDeadZoneOuter = 0;
+ public bool AxisRotated = false;
+ public bool AxisInverted = false;
+
+ public AxisActions()
+ {
+ this.ActionType = ActionType.Joystick;
+ this.Value = new Vector2();
+ }
+
+ public AxisActions(AxisLayoutFlags axis) : this()
+ {
+ this.Axis = axis;
+ }
+
+ public void Execute(AxisLayout layout)
+ {
+ layout.vector = InputUtils.ThumbScaledRadialInnerOuterDeadzone(layout.vector, AxisDeadZoneInner, AxisDeadZoneOuter);
+ layout.vector = InputUtils.ApplyAntiDeadzone(layout.vector, AxisAntiDeadZone);
+
+ if (ImproveCircularity)
+ layout.vector = InputUtils.ImproveCircularity(layout.vector);
+
+ if (AutoRotate)
+ layout.vector = ((Orientation & ScreenOrientation.Angle90) == ScreenOrientation.Angle90
+ ? new Vector2(layout.vector.Y, -layout.vector.X)
+ : layout.vector)
+ * ((Orientation & ScreenOrientation.Angle180) == ScreenOrientation.Angle180 ? -1.0f : 1.0f);
+ else
+ layout.vector = (AxisRotated ? new Vector2(layout.vector.Y, -layout.vector.X) : layout.vector)
+ * (AxisInverted ? -1.0f : 1.0f);
+
+ this.Value = (AxisRotated ? new(layout.vector.Y, -layout.vector.X) : layout.vector) * (AxisInverted ? -1.0f : 1.0f);
+ }
+
+ public Vector2 GetValue()
+ {
+ return (Vector2)this.Value;
+ }
+ }
+}
diff --git a/HandheldCompanion/Actions/ButtonActions.cs b/HandheldCompanion/Actions/ButtonActions.cs
new file mode 100644
index 000000000..90f46dff5
--- /dev/null
+++ b/HandheldCompanion/Actions/ButtonActions.cs
@@ -0,0 +1,59 @@
+using HandheldCompanion.Inputs;
+using System;
+
+namespace HandheldCompanion.Actions
+{
+ [Serializable]
+ public class ButtonActions : IActions
+ {
+ public ButtonFlags Button;
+
+ // runtime variables
+ private bool IsKeyDown = false;
+
+ public ButtonActions()
+ {
+ this.ActionType = ActionType.Button;
+
+ this.Value = false;
+ this.prevValue = false;
+ }
+
+ public ButtonActions(ButtonFlags button) : this()
+ {
+ this.Button = button;
+ }
+
+ public override void Execute(ButtonFlags button, bool value, int longTime)
+ {
+ base.Execute(button, value, longTime);
+
+ switch (this.Value)
+ {
+ case true:
+ {
+ if (IsKeyDown)
+ return;
+
+ IsKeyDown = true;
+ SetHaptic(button, false);
+ }
+ break;
+ case false:
+ {
+ if (!IsKeyDown)
+ return;
+
+ IsKeyDown = false;
+ SetHaptic(button, true);
+ }
+ break;
+ }
+ }
+
+ public bool GetValue()
+ {
+ return (bool)this.Value;
+ }
+ }
+}
diff --git a/HandheldCompanion/Actions/EmptyActions.cs b/HandheldCompanion/Actions/EmptyActions.cs
deleted file mode 100644
index a770173a3..000000000
--- a/HandheldCompanion/Actions/EmptyActions.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using ControllerCommon.Actions;
-
-namespace HandheldCompanion.Actions;
-
-[Serializable]
-public class EmptyActions : IActions
-{
- public EmptyActions()
- {
- ActionType = ActionType.Disabled;
- }
-}
\ No newline at end of file
diff --git a/HandheldCompanion/Actions/GyroActions.cs b/HandheldCompanion/Actions/GyroActions.cs
new file mode 100644
index 000000000..5e2724c60
--- /dev/null
+++ b/HandheldCompanion/Actions/GyroActions.cs
@@ -0,0 +1,26 @@
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Utils;
+using System;
+
+namespace HandheldCompanion.Actions
+{
+ [Serializable]
+ public class GyroActions : IActions
+ {
+ public MotionInput MotionInput = MotionInput.JoystickCamera;
+ public MotionMode MotionMode = MotionMode.Off;
+
+ public ButtonState MotionTrigger = new();
+
+ public const int DefaultAxisAntiDeadZone = 15;
+ public const AxisLayoutFlags DefaultAxisLayoutFlags = AxisLayoutFlags.RightStick;
+
+ public const MouseActionsType DefaultMouseActionsType = MouseActionsType.Move;
+ public const int DefaultSensivity = 33;
+ public const int DefaultDeadzone = 10;
+
+ public GyroActions()
+ {
+ }
+ }
+}
diff --git a/HandheldCompanion/Actions/IActions.cs b/HandheldCompanion/Actions/IActions.cs
new file mode 100644
index 000000000..fca93b499
--- /dev/null
+++ b/HandheldCompanion/Actions/IActions.cs
@@ -0,0 +1,205 @@
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Managers;
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using WindowsInput.Events;
+
+namespace HandheldCompanion.Actions
+{
+ [Serializable]
+ public enum ActionType
+ {
+ Disabled = 0,
+ Button = 1,
+ Joystick = 2,
+ Keyboard = 3,
+ Mouse = 4,
+ Trigger = 5,
+ Special = 6,
+ }
+
+ [Serializable]
+ public enum ModifierSet
+ {
+ None = 0,
+ Shift = 1,
+ Control = 2,
+ Alt = 3,
+ ShiftControl = 4,
+ ShiftAlt = 5,
+ ControlAlt = 6,
+ ShiftControlAlt = 7,
+ }
+
+ [Serializable]
+ public enum PressType
+ {
+ Short = 0,
+ Long = 1,
+ }
+
+ [Serializable]
+ public enum HapticMode
+ {
+ Off = 0,
+ Down = 1,
+ Up = 2,
+ Both = 3,
+ }
+
+ [Serializable]
+ public enum HapticStrength
+ {
+ Low = 0,
+ Medium = 1,
+ High = 2,
+ }
+
+ [Serializable]
+ public abstract class IActions : ICloneable
+ {
+ public static Dictionary ModifierMap = new()
+ {
+ { ModifierSet.None, new KeyCode[] { } },
+ { ModifierSet.Shift, new KeyCode[] { KeyCode.LShift } },
+ { ModifierSet.Control, new KeyCode[] { KeyCode.LControl } },
+ { ModifierSet.Alt, new KeyCode[] { KeyCode.LMenu } },
+ { ModifierSet.ShiftControl, new KeyCode[] { KeyCode.LShift, KeyCode.LControl } },
+ { ModifierSet.ShiftAlt, new KeyCode[] { KeyCode.LShift, KeyCode.LMenu } },
+ { ModifierSet.ControlAlt, new KeyCode[] { KeyCode.LControl, KeyCode.LMenu } },
+ { ModifierSet.ShiftControlAlt, new KeyCode[] { KeyCode.LShift, KeyCode.LControl, KeyCode.LMenu } },
+ };
+
+ public ActionType ActionType = ActionType.Disabled;
+
+ protected object Value;
+ protected object prevValue;
+
+ // values below are common for button type actions
+
+ protected int Period;
+
+ // TODO: multiple delay, delay ranges
+ public PressType PressType = PressType.Short;
+ public int LongPressTime = 450; // default value for steam
+ protected int pressTimer = -1; // -1 inactive, >= 0 active
+
+ public bool Turbo;
+ public int TurboDelay = 30;
+ protected int TurboIdx;
+ protected bool IsTurboed;
+
+ public bool Toggle;
+ protected bool IsToggled;
+
+ public HapticMode HapticMode = HapticMode.Off;
+ public HapticStrength HapticStrength = HapticStrength.Low;
+
+ protected ScreenOrientation Orientation = ScreenOrientation.Angle0;
+ public bool AutoRotate { get; set; } = false;
+
+ public IActions()
+ {
+ Period = TimerManager.GetPeriod();
+ }
+
+ public virtual void SetHaptic(ButtonFlags button, bool up)
+ {
+ if (this.HapticMode == HapticMode.Off) return;
+ if (this.HapticMode == HapticMode.Down && up) return;
+ if (this.HapticMode == HapticMode.Up && !up) return;
+
+ ControllerManager.GetTargetController()?.SetHaptic(this.HapticStrength, button);
+ }
+
+ // if longDelay == 0 no new logic will be executed
+ public virtual void Execute(ButtonFlags button, bool value, int longTime)
+ {
+ // reset failed attempts on button release
+ if (pressTimer >= 0 && !value &&
+ ((PressType == PressType.Short && pressTimer >= longTime) ||
+ (PressType == PressType.Long && pressTimer < longTime)))
+ {
+ pressTimer = -1;
+ prevValue = false;
+ return;
+ }
+
+ // some long presses exist and button was just pressed, start the timer and quit
+ if (longTime > 0 && value && !(bool)prevValue)
+ {
+ pressTimer = 0;
+ prevValue = true;
+ return;
+ }
+
+ if (pressTimer >= 0)
+ {
+ pressTimer += Period;
+
+ // conditions were met to trigger either short or long, reset state, press buttons
+ if ((!value && PressType == PressType.Short && pressTimer < longTime) ||
+ (value && PressType == PressType.Long && pressTimer >= longTime))
+ {
+ pressTimer = -1;
+ prevValue = false; // simulate a situation where the button was just pressed
+ value = true; // prev = false, current = true, this way toggle works
+ }
+ // timer active, conditions not met, carry on, maybe smth happens, maybe failed attempt
+ else
+ return;
+ }
+
+ if (Toggle)
+ {
+ if ((bool)prevValue != value && value)
+ IsToggled = !IsToggled;
+ }
+ else
+ IsToggled = false;
+
+ if (Turbo)
+ {
+ if (value || IsToggled)
+ {
+ if (TurboIdx % TurboDelay == 0)
+ IsTurboed = !IsTurboed;
+
+ TurboIdx += Period;
+ }
+ else
+ {
+ IsTurboed = false;
+ TurboIdx = 0;
+ }
+ }
+ else
+ IsTurboed = false;
+
+ // update previous value
+ prevValue = value;
+
+ // update value
+ if (Toggle && Turbo)
+ this.Value = IsToggled && IsTurboed;
+ else if (Toggle)
+ this.Value = IsToggled;
+ else if (Turbo)
+ this.Value = IsTurboed;
+ else
+ this.Value = value;
+ }
+
+ public virtual void SetOrientation(ScreenOrientation orientation)
+ {
+ Orientation = orientation;
+ }
+
+ // Improve me !
+ public object Clone()
+ {
+ return MemberwiseClone();
+ }
+ }
+}
diff --git a/HandheldCompanion/Actions/KeyboardActions.cs b/HandheldCompanion/Actions/KeyboardActions.cs
index 2653f0170..0c9acf3f1 100644
--- a/HandheldCompanion/Actions/KeyboardActions.cs
+++ b/HandheldCompanion/Actions/KeyboardActions.cs
@@ -1,100 +1,66 @@
-using System;
-using ControllerCommon.Actions;
-using ControllerCommon.Inputs;
using GregsStack.InputSimulatorStandard.Native;
+using HandheldCompanion.Inputs;
using HandheldCompanion.Simulators;
+using System;
+using WindowsInput.Events;
-namespace HandheldCompanion.Actions;
-
-[Serializable]
-public class KeyboardActions : IActions
+namespace HandheldCompanion.Actions
{
- public KeyboardActions()
+ [Serializable]
+ public class KeyboardActions : IActions
{
- ActionType = ActionType.Keyboard;
- IsKeyDown = false;
- IsKeyUp = true;
-
- Value = false;
- prevValue = false;
- }
+ public VirtualKeyCode Key;
- public KeyboardActions(VirtualKeyCode key) : this()
- {
- Key = key;
- }
+ // runtime variables
+ private bool IsKeyDown = false;
+ private KeyCode[] pressed;
- public VirtualKeyCode Key { get; set; }
- private bool IsKeyDown { get; set; }
- private bool IsKeyUp { get; set; }
+ // settings
+ public ModifierSet Modifiers = ModifierSet.None;
- public override void Execute(ButtonFlags button, bool value)
- {
- if (Toggle)
+ public KeyboardActions()
{
- if ((bool)prevValue != value && value)
- IsToggled = !IsToggled;
- }
- else
- {
- IsToggled = false;
- }
+ this.ActionType = ActionType.Keyboard;
- if (Turbo)
- {
- if (value || IsToggled)
- {
- if (TurboIdx % TurboDelay == 0)
- IsTurboed = !IsTurboed;
-
- TurboIdx += Period;
- }
- else
- {
- IsTurboed = false;
- TurboIdx = 0;
- }
+ this.Value = false;
+ this.prevValue = false;
}
- else
+
+ public KeyboardActions(VirtualKeyCode key) : this()
{
- IsTurboed = false;
+ this.Key = key;
}
- // update previous value
- prevValue = value;
-
- // update value
- if (Toggle && Turbo)
- Value = IsToggled && IsTurboed;
- else if (Toggle)
- Value = IsToggled;
- else if (Turbo)
- Value = IsTurboed;
- else
- Value = value;
-
- switch (Value)
+ public override void Execute(ButtonFlags button, bool value, int longTime)
{
- case true:
- {
- if (IsKeyDown || !IsKeyUp)
- return;
+ base.Execute(button, value, longTime);
- IsKeyDown = true;
- IsKeyUp = false;
- KeyboardSimulator.KeyDown(Key);
- }
- break;
- case false:
+ switch (this.Value)
{
- if (IsKeyUp || !IsKeyDown)
- return;
+ case true:
+ {
+ if (IsKeyDown)
+ return;
+
+ IsKeyDown = true;
+ pressed = ModifierMap[Modifiers];
+ KeyboardSimulator.KeyDown(pressed);
+ KeyboardSimulator.KeyDown(Key);
+ SetHaptic(button, false);
+ }
+ break;
+ case false:
+ {
+ if (!IsKeyDown)
+ return;
- IsKeyUp = true;
- IsKeyDown = false;
- KeyboardSimulator.KeyUp(Key);
+ IsKeyDown = false;
+ KeyboardSimulator.KeyUp(Key);
+ KeyboardSimulator.KeyUp(pressed);
+ SetHaptic(button, true);
+ }
+ break;
}
- break;
}
}
-}
\ No newline at end of file
+}
diff --git a/HandheldCompanion/Actions/MouseActions.cs b/HandheldCompanion/Actions/MouseActions.cs
index dcb82fec4..a38901699 100644
--- a/HandheldCompanion/Actions/MouseActions.cs
+++ b/HandheldCompanion/Actions/MouseActions.cs
@@ -1,222 +1,206 @@
-using System;
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Simulators;
+using System;
using System.ComponentModel;
using System.Numerics;
-using System.Windows.Forms;
-using ControllerCommon.Actions;
-using ControllerCommon.Inputs;
-using HandheldCompanion.Simulators;
-
-namespace HandheldCompanion.Actions;
-
-[Serializable]
-public enum MouseActionsType
-{
- [Description("Left Button")] LeftButton = 0,
- [Description("Right Button")] RightButton = 1,
- [Description("Middle Button")] MiddleButton = 2,
-
- [Description("Move Cursor")] Move = 3,
- [Description("Scroll Wheel")] Scroll = 4,
-
- [Description("Scroll Up")] ScrollUp = 5,
- [Description("Scroll Down")] ScrollDown = 6
-}
+using WindowsInput.Events;
-[Serializable]
-public class MouseActions : IActions
+namespace HandheldCompanion.Actions
{
- private bool IsTouched;
-
- private Vector2 prevVector;
- private Vector2 restVector;
-
- public MouseActions()
+ [Serializable]
+ public enum MouseActionsType
{
- ActionType = ActionType.Mouse;
- IsCursorDown = false;
- IsCursorUp = true;
-
- Value = false;
- prevValue = false;
+ [Description("Left Button")]
+ LeftButton = 1,
+ [Description("Right Button")]
+ RightButton = 2,
+ [Description("Middle Button")]
+ MiddleButton = 3,
+
+ [Description("Move Cursor")]
+ Move = 4,
+ [Description("Scroll Wheel")]
+ Scroll = 5,
+
+ [Description("Scroll Up")]
+ ScrollUp = 6,
+ [Description("Scroll Down")]
+ ScrollDown = 7,
}
- public MouseActions(MouseActionsType type) : this()
+ [Serializable]
+ public class MouseActions : GyroActions
{
- MouseType = type;
- }
-
- public MouseActionsType MouseType { get; set; }
-
- private bool IsCursorDown { get; set; }
- private bool IsCursorUp { get; set; }
- private int scrollAmountInClicks { get; set; } = 1;
-
- // settings
- public float Sensivity { get; set; } = 25.0f;
- public float Deadzone { get; set; } = 25.0f;
- public bool AxisInverted { get; set; } = false;
- public bool AxisRotated { get; set; } = false;
-
- public override void Execute(ButtonFlags button, bool value)
- {
- if (Toggle)
- {
- if ((bool)prevValue != value && value)
- IsToggled = !IsToggled;
- }
- else
+ public MouseActionsType MouseType;
+
+ // const settings
+ private const int scrollAmountInClicks = 20;
+ private const float FilterBeta = 0.5f;
+
+ // runtime variables
+ private bool IsCursorDown = false;
+ private bool IsTouched = false;
+ private Vector2 remainder = new();
+ private KeyCode[] pressed;
+ private OneEuroFilterPair mouseFilter;
+ private Vector2 prevVector = new();
+
+ // settings click
+ public ModifierSet Modifiers = ModifierSet.None;
+
+ // settings axis
+ public int Sensivity = 33;
+ public float Acceleration = 1.0f;
+ public int Deadzone = 10; // stick only
+ public bool Filtering = false; // pad only
+ public float FilterCutoff = 0.05f; // pad only
+ public bool AxisRotated = false;
+ public bool AxisInverted = false;
+
+ public MouseActions()
{
- IsToggled = false;
- }
+ this.ActionType = ActionType.Mouse;
- if (Turbo)
- {
- if (value || IsToggled)
- {
- if (TurboIdx % TurboDelay == 0)
- IsTurboed = !IsTurboed;
+ this.Value = false;
+ this.prevValue = false;
- TurboIdx += Period;
- }
- else
- {
- IsTurboed = false;
- TurboIdx = 0;
- }
+ mouseFilter = new(FilterCutoff, FilterBeta);
}
- else
+
+ public MouseActions(MouseActionsType type) : this()
{
- IsTurboed = false;
+ this.MouseType = type;
}
- // update previous value
- prevValue = value;
-
- // update value
- if (Toggle && Turbo)
- Value = IsToggled && IsTurboed;
- else if (Toggle)
- Value = IsToggled;
- else if (Turbo)
- Value = IsTurboed;
- else
- Value = value;
-
- switch (Value)
+ public override void Execute(ButtonFlags button, bool value, int longTime)
{
- case true:
- {
- if (IsCursorDown || !IsCursorUp)
- return;
+ base.Execute(button, value, longTime);
- IsCursorDown = true;
- IsCursorUp = false;
- MouseSimulator.MouseDown(MouseType, scrollAmountInClicks);
- }
- break;
- case false:
+ switch (this.Value)
{
- if (IsCursorUp || !IsCursorDown)
- return;
-
- IsCursorUp = true;
- IsCursorDown = false;
- MouseSimulator.MouseUp(MouseType);
+ case true:
+ {
+ if (IsCursorDown)
+ return;
+
+ IsCursorDown = true;
+ pressed = ModifierMap[Modifiers];
+ KeyboardSimulator.KeyDown(pressed);
+ MouseSimulator.MouseDown(MouseType, scrollAmountInClicks);
+ SetHaptic(button, false);
+ }
+ break;
+ case false:
+ {
+ if (!IsCursorDown)
+ return;
+
+ IsCursorDown = false;
+ MouseSimulator.MouseUp(MouseType);
+ KeyboardSimulator.KeyUp(pressed);
+ SetHaptic(button, true);
+ }
+ break;
}
- break;
}
- }
- public override void Execute(AxisFlags axis, short value)
- {
- }
-
- private bool IsNewTouch(bool value)
- {
- if (value == IsTouched)
+ private bool IsNewTouch(bool value)
+ {
+ if (value == IsTouched)
+ return false;
+ if (IsTouched = value)
+ return true;
return false;
- if (IsTouched = value)
- return true;
- return false;
- }
+ }
- public void Execute(AxisLayout layout, bool touched)
- {
- // this line needs to be before the next vector zero check
- var newTouch = IsNewTouch(touched);
+ public void Execute(AxisLayout layout, bool touched)
+ {
+ // this line needs to be before the next vector zero check
+ bool newTouch = IsNewTouch(touched);
- if (layout.vector == Vector2.Zero)
- return;
+ if (layout.vector == Vector2.Zero)
+ return;
- layout.vector.Y *= -1;
+ layout.vector.Y *= -1;
- Vector2 deltaVector;
- float sensitivityFinetune;
+ Vector2 deltaVector;
+ float sensitivityFinetune;
- switch (layout.flags)
- {
- default:
- case AxisLayoutFlags.LeftThumb:
- case AxisLayoutFlags.RightThumb:
+ switch (layout.flags)
{
- // convert to <0.0-1.0> values
- deltaVector = layout.vector / short.MaxValue;
- var deadzone = Deadzone / 100.0f;
-
- // apply deadzone
- if (deltaVector.Length() < deadzone)
- return;
-
- deltaVector *= (deltaVector.Length() - deadzone) / deltaVector.Length(); // shorten by deadzone
- deltaVector *= 1.0f / (1.0f - deadzone); // rescale to 0.0 - 1.0
+ case AxisLayoutFlags.LeftStick:
+ case AxisLayoutFlags.RightStick:
+ case AxisLayoutFlags.Gyroscope:
+ default:
+ {
+ // convert to <0.0-1.0> values
+ deltaVector = layout.vector / short.MaxValue;
+ float deadzone = Deadzone / 100.0f;
+
+ // apply deadzone
+ if (deltaVector.Length() < deadzone)
+ return;
+
+ deltaVector *= (deltaVector.Length() - deadzone) / deltaVector.Length(); // shorten by deadzone
+ deltaVector *= 1.0f / (1.0f - deadzone); // rescale to 0.0 - 1.0
+
+ sensitivityFinetune = (MouseType == MouseActionsType.Move ? 0.3f : 0.1f);
+ }
+ break;
+
+ case AxisLayoutFlags.LeftPad:
+ case AxisLayoutFlags.RightPad:
+ {
+ // touchpad was touched, update entry point for delta calculations
+ if (newTouch)
+ {
+ prevVector = layout.vector;
+ return;
+ }
+
+ // calculate delta and convert to <0.0-1.0> values
+ deltaVector = (layout.vector - prevVector) / short.MaxValue;
+ prevVector = layout.vector;
+
+ sensitivityFinetune = (MouseType == MouseActionsType.Move ? 9.0f : 3.0f);
+ }
+ break;
+ }
- sensitivityFinetune = MouseType == MouseActionsType.Move ? 0.3f : 0.1f;
+ if (Filtering)
+ {
+ mouseFilter.SetFilterCutoff(FilterCutoff);
+ deltaVector.X = (float)mouseFilter.axis1Filter.Filter(deltaVector.X, 1);
+ deltaVector.Y = (float)mouseFilter.axis2Filter.Filter(deltaVector.Y, 1);
}
- break;
- case AxisLayoutFlags.LeftPad:
- case AxisLayoutFlags.RightPad:
+ if (Acceleration != 1.0f)
{
- // touchpad was touched, update entry point for delta calculations
- if (newTouch)
- {
- prevVector = layout.vector;
- return;
- }
-
- // calculate delta and convert to <0.0-1.0> values
- deltaVector = (layout.vector - prevVector) / short.MaxValue;
- prevVector = layout.vector;
-
- sensitivityFinetune = MouseType == MouseActionsType.Move ? 9.0f : 3.0f;
+ deltaVector.X = (float)(Math.Sign(deltaVector.X) * Math.Pow(Math.Abs(deltaVector.X), Acceleration));
+ deltaVector.Y = (float)(Math.Sign(deltaVector.Y) * Math.Pow(Math.Abs(deltaVector.Y), Acceleration));
+ sensitivityFinetune = (float)Math.Pow(sensitivityFinetune, Acceleration);
}
- break;
- }
- // apply sensitivity, rotation and slider finetune
- deltaVector *= Sensivity * sensitivityFinetune;
- if (AutoRotate)
- {
- if ((Orientation & ScreenOrientation.Angle90) == ScreenOrientation.Angle90)
- deltaVector = new Vector2(-deltaVector.Y, deltaVector.X);
- deltaVector *= (Orientation & ScreenOrientation.Angle180) == ScreenOrientation.Angle180 ? -1.0f : 1.0f;
- }
- else
- {
+ // apply sensitivity, rotation and slider finetune
+ deltaVector *= Sensivity * sensitivityFinetune;
if (AxisRotated)
- deltaVector = new Vector2(-deltaVector.Y, deltaVector.X);
- deltaVector *= AxisInverted ? -1.0f : 1.0f;
- }
+ deltaVector = new(-deltaVector.Y, deltaVector.X);
+ deltaVector *= (AxisInverted ? -1.0f : 1.0f);
- // handle the fact that MoveBy()/*Scroll() are int only and we can have movement (0 < abs(delta) < 1)
- deltaVector += restVector; // add partial previous step
- Vector2 intVector = new((int)Math.Truncate(deltaVector.X), (int)Math.Truncate(deltaVector.Y));
- restVector = deltaVector - intVector; // and save the unused rest
+ // handle the fact that MoveBy()/*Scroll() are int only and we can have movement (0 < abs(delta) < 1)
+ deltaVector += remainder; // add partial previous step
+ Vector2 intVector = new((int)Math.Truncate(deltaVector.X), (int)Math.Truncate(deltaVector.Y));
+ remainder = deltaVector - intVector; // and save the unused rest
- if (MouseType == MouseActionsType.Move)
- MouseSimulator.MoveBy((int)intVector.X, (int)intVector.Y);
- else /* if (MouseType == MouseActionsType.Scroll) */
- // MouseSimulator.HorizontalScroll((int)-intVector.X);
- MouseSimulator.VerticalScroll((int)-intVector.Y);
+ if (MouseType == MouseActionsType.Move)
+ {
+ MouseSimulator.MoveBy((int)intVector.X, (int)intVector.Y);
+ }
+ else /* if (MouseType == MouseActionsType.Scroll) */
+ {
+ // MouseSimulator.HorizontalScroll((int)-intVector.X);
+ MouseSimulator.VerticalScroll((int)-intVector.Y);
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/HandheldCompanion/Actions/SpecialActions.cs b/HandheldCompanion/Actions/SpecialActions.cs
new file mode 100644
index 000000000..e71040516
--- /dev/null
+++ b/HandheldCompanion/Actions/SpecialActions.cs
@@ -0,0 +1,58 @@
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Misc;
+using HandheldCompanion.Simulators;
+using System;
+using System.ComponentModel;
+using System.Numerics;
+
+namespace HandheldCompanion.Actions
+{
+ [Serializable]
+ public enum SpecialActionsType
+ {
+ [Description("Flick Stick")]
+ FlickStick = 0,
+ }
+
+ [Serializable]
+ public class SpecialActions : IActions
+ {
+ public SpecialActionsType SpecialType;
+
+ // runtime variables
+ private FlickStick flickStick = new();
+ private float remainder = 0;
+
+ // settings
+ public float FlickSensitivity = 5.0f;
+ public float SweepSensitivity = 5.0f;
+ public float FlickThreshold = 0.75f;
+ public int FlickSpeed = 100;
+ public int FlickFrontAngleDeadzone = 15;
+
+ public SpecialActions()
+ {
+ this.ActionType = ActionType.Special;
+ }
+
+ public SpecialActions(SpecialActionsType type) : this()
+ {
+ this.SpecialType = type;
+ }
+
+ public void Execute(AxisLayout layout)
+ {
+ if (layout.vector == Vector2.Zero)
+ return;
+
+ float delta = flickStick.Handle(layout.vector, FlickSensitivity, SweepSensitivity,
+ FlickThreshold, FlickSpeed, FlickFrontAngleDeadzone);
+
+ delta += remainder;
+ int intDelta = (int)Math.Truncate(delta);
+ remainder = delta - intDelta;
+
+ MouseSimulator.MoveBy(intDelta, 0);
+ }
+ }
+}
diff --git a/HandheldCompanion/Actions/TriggerActions.cs b/HandheldCompanion/Actions/TriggerActions.cs
new file mode 100644
index 000000000..5aa394b9c
--- /dev/null
+++ b/HandheldCompanion/Actions/TriggerActions.cs
@@ -0,0 +1,42 @@
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Utils;
+using System;
+
+namespace HandheldCompanion.Actions
+{
+ [Serializable]
+ public class TriggerActions : IActions
+ {
+ public AxisLayoutFlags Axis;
+
+ // settings
+ public int AxisAntiDeadZone = 0;
+ public int AxisDeadZoneInner = 0;
+ public int AxisDeadZoneOuter = 0;
+
+ public TriggerActions()
+ {
+ this.ActionType = ActionType.Trigger;
+ this.Value = (short)0;
+ }
+
+ public TriggerActions(AxisLayoutFlags axis) : this()
+ {
+ this.Axis = axis;
+ }
+
+ public void Execute(AxisFlags axis, short value)
+ {
+ // Apply inner and outer deadzone adjustments
+ value = (short)InputUtils.InnerOuterDeadzone(value, AxisDeadZoneInner, AxisDeadZoneOuter, byte.MaxValue);
+ value = (short)InputUtils.ApplyAntiDeadzone(value, AxisAntiDeadZone, byte.MaxValue);
+
+ this.Value = value;
+ }
+
+ public short GetValue()
+ {
+ return (short)this.Value;
+ }
+ }
+}
diff --git a/HandheldCompanion/App.config b/HandheldCompanion/App.config
index dc54c04db..2fc584b12 100644
--- a/HandheldCompanion/App.config
+++ b/HandheldCompanion/App.config
@@ -41,12 +41,6 @@
0
-
- True
-
-
- True
-
1989-12-20
@@ -119,9 +113,6 @@
0
-
- 3
-
True
@@ -140,7 +131,7 @@
True
-
+
100
@@ -149,7 +140,7 @@
True
-
+
True
@@ -203,12 +194,30 @@
1
-
+
False
-
+
+ False
+
+
False
+
+ 0
+
+
+ 1
+
+
+ True
+
+
+ 26760
+
+
+ 127.0.0.1
+
\ No newline at end of file
diff --git a/HandheldCompanion/App.xaml b/HandheldCompanion/App.xaml
index 3f67cba39..0f61123f6 100644
--- a/HandheldCompanion/App.xaml
+++ b/HandheldCompanion/App.xaml
@@ -5,12 +5,11 @@
xmlns:converters="clr-namespace:HandheldCompanion.Converters"
xmlns:math="http://hexinnovation.com/math"
xmlns:presets="clr-namespace:HandheldCompanion.Presets"
- xmlns:ui="https://schemas.animasterstudios.com/lib/ui/wpf/modern">
+ xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern">
-
@@ -55,6 +54,7 @@
+
diff --git a/HandheldCompanion/App.xaml.cs b/HandheldCompanion/App.xaml.cs
index 994115ef8..8c54b7125 100644
--- a/HandheldCompanion/App.xaml.cs
+++ b/HandheldCompanion/App.xaml.cs
@@ -1,14 +1,13 @@
-using System;
+using HandheldCompanion.Managers;
+using HandheldCompanion.Utils;
+using HandheldCompanion.Views;
+using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Threading;
using System.Windows;
-using ControllerCommon.Managers;
-using ControllerCommon.Utils;
-using HandheldCompanion.Managers;
-using HandheldCompanion.Views;
-using static ControllerCommon.WinAPI;
+using static HandheldCompanion.WinAPI;
namespace HandheldCompanion;
diff --git a/HandheldCompanion/AssemblyInfo.cs b/HandheldCompanion/AssemblyInfo.cs
index 4a05c7d47..4f943deb8 100644
--- a/HandheldCompanion/AssemblyInfo.cs
+++ b/HandheldCompanion/AssemblyInfo.cs
@@ -2,9 +2,9 @@
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
- //(used if a resource is not found in the page,
- // or application resource dictionaries)
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
- //(used if a resource is not found in the page,
- // app, or any theme specific resource dictionaries)
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
)]
\ No newline at end of file
diff --git a/HandheldCompanion/Controllers/ControllerState.cs b/HandheldCompanion/Controllers/ControllerState.cs
new file mode 100644
index 000000000..4bc4c7d64
--- /dev/null
+++ b/HandheldCompanion/Controllers/ControllerState.cs
@@ -0,0 +1,37 @@
+using HandheldCompanion.Inputs;
+using System;
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace HandheldCompanion.Controllers
+{
+ [Serializable]
+ public class ControllerState : ICloneable
+ {
+ public ButtonState ButtonState = new();
+ public AxisState AxisState = new();
+ public GyroState GyroState = new();
+
+ [JsonIgnore]
+ public static readonly SortedDictionary AxisTouchButtons = new()
+ {
+ { AxisLayoutFlags.RightStick, ButtonFlags.RightStickTouch },
+ { AxisLayoutFlags.LeftStick, ButtonFlags.LeftStickTouch },
+ { AxisLayoutFlags.RightPad, ButtonFlags.RightPadTouch },
+ { AxisLayoutFlags.LeftPad, ButtonFlags.LeftPadTouch },
+ };
+
+ public ControllerState()
+ { }
+
+ public object Clone()
+ {
+ return new ControllerState()
+ {
+ ButtonState = this.ButtonState.Clone() as ButtonState,
+ AxisState = this.AxisState.Clone() as AxisState,
+ GyroState = this.GyroState.Clone() as GyroState,
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/HandheldCompanion/Controllers/DInputController.cs b/HandheldCompanion/Controllers/DInputController.cs
index 16cc54bd3..9e5bdb903 100644
--- a/HandheldCompanion/Controllers/DInputController.cs
+++ b/HandheldCompanion/Controllers/DInputController.cs
@@ -1,13 +1,10 @@
-using ControllerCommon;
-using ControllerCommon.Controllers;
-using SharpDX.DirectInput;
+using SharpDX.DirectInput;
namespace HandheldCompanion.Controllers;
public class DInputController : IController
{
public Joystick joystick;
- protected JoystickState prevState = new();
protected JoystickState State = new();
public DInputController()
@@ -41,16 +38,13 @@ public override string ToString()
var baseName = base.ToString();
if (!string.IsNullOrEmpty(baseName))
return baseName;
- if (joystick is null)
- return string.Empty;
- return joystick.Information.ProductName;
+ if (!string.IsNullOrEmpty(joystick.Information.ProductName))
+ return joystick.Information.ProductName;
+ return $"DInput Controller {UserIndex}";
}
public override void UpdateInputs(long ticks)
{
- // update states
- prevState = State;
-
base.UpdateInputs(ticks);
}
diff --git a/HandheldCompanion/Controllers/DS4Controller.cs b/HandheldCompanion/Controllers/DS4Controller.cs
index 1b8b84378..c331591f4 100644
--- a/HandheldCompanion/Controllers/DS4Controller.cs
+++ b/HandheldCompanion/Controllers/DS4Controller.cs
@@ -1,20 +1,18 @@
-using System;
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Managers;
+using HandheldCompanion.Utils;
using System.Windows.Media;
-using ControllerCommon;
-using ControllerCommon.Inputs;
-using ControllerCommon.Managers;
-using SharpDX.DirectInput;
-using SharpDX.XInput;
+using static JSL;
namespace HandheldCompanion.Controllers;
-public class DS4Controller : DInputController
+public class DS4Controller : JSController
{
public DS4Controller()
{
}
- public DS4Controller(Joystick joystick, PnPDetails details) : base(joystick, details)
+ public DS4Controller(JOY_SETTINGS settings, PnPDetails details) : base(settings, details)
{
// UI
ColoredButtons.Add(ButtonFlags.B1, new SolidColorBrush(Color.FromArgb(255, 116, 139, 255)));
@@ -24,7 +22,20 @@ public DS4Controller(Joystick joystick, PnPDetails details) : base(joystick, det
// Additional controller specific source buttons
SourceButtons.Add(ButtonFlags.LeftPadClick);
+ SourceButtons.Add(ButtonFlags.LeftPadTouch);
SourceButtons.Add(ButtonFlags.RightPadClick);
+ SourceButtons.Add(ButtonFlags.RightPadTouch);
+
+ SourceAxis.Add(AxisLayoutFlags.LeftPad);
+ SourceAxis.Add(AxisLayoutFlags.RightPad);
+ SourceAxis.Add(AxisLayoutFlags.Gyroscope);
+
+ TargetButtons.Add(ButtonFlags.LeftPadClick);
+ TargetButtons.Add(ButtonFlags.LeftPadTouch);
+ TargetButtons.Add(ButtonFlags.RightPadTouch);
+
+ TargetAxis.Add(AxisLayoutFlags.LeftPad);
+ TargetAxis.Add(AxisLayoutFlags.RightPad);
}
public override void UpdateInputs(long ticks)
@@ -33,103 +44,47 @@ public override void UpdateInputs(long ticks)
if (!IsConnected())
return;
- try
+ base.UpdateState();
+
+ // Left Pad
+ Inputs.ButtonState[ButtonFlags.LeftPadTouch] = JslGetTouchDown(UserIndex);
+ Inputs.ButtonState[ButtonFlags.LeftPadClick] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskCapture);
+
+ if (Inputs.ButtonState[ButtonFlags.LeftPadTouch])
{
- // Poll events from joystick
- joystick.Poll();
+ float joyShockX0 = JslGetTouchX(UserIndex);
+ float joyShockY0 = JslGetTouchY(UserIndex);
- // update gamepad state
- State = joystick.GetCurrentState();
+ Inputs.AxisState[AxisFlags.LeftPadX] = (short)InputUtils.MapRange(joyShockX0, 0.0f, 1.0f, short.MinValue, short.MaxValue);
+ Inputs.AxisState[AxisFlags.LeftPadY] = (short)InputUtils.MapRange(joyShockY0, 0.0f, 1.0f, short.MaxValue, short.MinValue);
}
- catch
+ else
{
+ Inputs.AxisState[AxisFlags.LeftPadX] = 0;
+ Inputs.AxisState[AxisFlags.LeftPadY] = 0;
}
- /*
- if (prevState.Buttons.Equals(State.Buttons) && prevState.PointOfViewControllers.Equals(State.PointOfViewControllers) && prevInjectedButtons.Equals(InjectedButtons))
- return;
- */
-
- Inputs.ButtonState = InjectedButtons.Clone() as ButtonState;
-
- Inputs.ButtonState[ButtonFlags.B1] = State.Buttons[1];
- Inputs.ButtonState[ButtonFlags.B2] = State.Buttons[2];
- Inputs.ButtonState[ButtonFlags.B3] = State.Buttons[0];
- Inputs.ButtonState[ButtonFlags.B4] = State.Buttons[3];
+ // Right Pad
+ Inputs.ButtonState[ButtonFlags.RightPadTouch] = JslGetTouchDown(UserIndex, true);
+ Inputs.ButtonState[ButtonFlags.RightPadClick] = Inputs.ButtonState[ButtonFlags.LeftPadClick] && Inputs.ButtonState[ButtonFlags.RightPadTouch];
- Inputs.ButtonState[ButtonFlags.Back] = State.Buttons[8];
- Inputs.ButtonState[ButtonFlags.Start] = State.Buttons[9];
-
- Inputs.ButtonState[ButtonFlags.L2] = State.Buttons[6];
- Inputs.ButtonState[ButtonFlags.R2] = State.Buttons[7];
-
- Inputs.ButtonState[ButtonFlags.LeftThumb] = State.Buttons[10];
- Inputs.ButtonState[ButtonFlags.RightThumb] = State.Buttons[11];
-
- Inputs.ButtonState[ButtonFlags.L1] = State.Buttons[4];
- Inputs.ButtonState[ButtonFlags.R1] = State.Buttons[5];
-
- Inputs.ButtonState[ButtonFlags.Special] = State.Buttons[12];
-
- Inputs.ButtonState[ButtonFlags.LeftPadClick] = State.Buttons[13];
- Inputs.ButtonState[ButtonFlags.RightPadClick] = State.Buttons[13];
+ if (Inputs.ButtonState[ButtonFlags.RightPadTouch])
+ {
+ float joyShockX1 = JslGetTouchX(UserIndex, true);
+ float joyShockY1 = JslGetTouchY(UserIndex, true);
- switch (State.PointOfViewControllers[0])
+ Inputs.AxisState[AxisFlags.RightPadX] = (short)InputUtils.MapRange(joyShockX1, 0.0f, 1.0f, short.MinValue, short.MaxValue);
+ Inputs.AxisState[AxisFlags.RightPadY] = (short)InputUtils.MapRange(joyShockY1, 0.0f, 1.0f, short.MaxValue, short.MinValue);
+ }
+ else
{
- case 0:
- Inputs.ButtonState[ButtonFlags.DPadUp] = true;
- break;
- case 4500:
- Inputs.ButtonState[ButtonFlags.DPadUp] = true;
- Inputs.ButtonState[ButtonFlags.DPadRight] = true;
- break;
- case 9000:
- Inputs.ButtonState[ButtonFlags.DPadRight] = true;
- break;
- case 13500:
- Inputs.ButtonState[ButtonFlags.DPadDown] = true;
- Inputs.ButtonState[ButtonFlags.DPadRight] = true;
- break;
- case 18000:
- Inputs.ButtonState[ButtonFlags.DPadDown] = true;
- break;
- case 22500:
- Inputs.ButtonState[ButtonFlags.DPadLeft] = true;
- Inputs.ButtonState[ButtonFlags.DPadDown] = true;
- break;
- case 27000:
- Inputs.ButtonState[ButtonFlags.DPadLeft] = true;
- break;
- case 31500:
- Inputs.ButtonState[ButtonFlags.DPadLeft] = true;
- Inputs.ButtonState[ButtonFlags.DPadUp] = true;
- break;
+ Inputs.AxisState[AxisFlags.RightPadX] = 0;
+ Inputs.AxisState[AxisFlags.RightPadY] = 0;
}
- Inputs.AxisState[AxisFlags.L2] = (short)(State.RotationX * byte.MaxValue / ushort.MaxValue);
- Inputs.AxisState[AxisFlags.R2] = (short)(State.RotationY * byte.MaxValue / ushort.MaxValue);
-
- Inputs.ButtonState[ButtonFlags.L3] = Inputs.AxisState[AxisFlags.L2] > Gamepad.TriggerThreshold * 8;
- Inputs.ButtonState[ButtonFlags.R3] = Inputs.AxisState[AxisFlags.R2] > Gamepad.TriggerThreshold * 8;
-
- Inputs.AxisState[AxisFlags.LeftThumbX] =
- (short)Math.Clamp(State.X - short.MaxValue, short.MinValue, short.MaxValue);
- Inputs.AxisState[AxisFlags.LeftThumbY] =
- (short)Math.Clamp(-State.Y + short.MaxValue, short.MinValue, short.MaxValue);
-
- Inputs.AxisState[AxisFlags.RightThumbX] =
- (short)Math.Clamp(State.Z - short.MaxValue, short.MinValue, short.MaxValue);
- Inputs.AxisState[AxisFlags.RightThumbY] =
- (short)Math.Clamp(-State.RotationZ + short.MaxValue, short.MinValue, short.MaxValue);
-
base.UpdateInputs(ticks);
}
- public override bool IsConnected()
- {
- return joystick is null ? false : !joystick.IsDisposed;
- }
-
public override void Plug()
{
TimerManager.Tick += UpdateInputs;
@@ -142,6 +97,11 @@ public override void Unplug()
base.Unplug();
}
+ public override void Cleanup()
+ {
+ TimerManager.Tick -= UpdateInputs;
+ }
+
public override string GetGlyph(ButtonFlags button)
{
switch (button)
@@ -162,18 +122,20 @@ public override string GetGlyph(ButtonFlags button)
return "\u21E6";
case ButtonFlags.Start:
return "\u21E8";
- case ButtonFlags.L2:
- return "\u21DC";
- case ButtonFlags.L3:
+ case ButtonFlags.L2Soft:
return "\u21B2";
- case ButtonFlags.R2:
- return "\u21DD";
- case ButtonFlags.R3:
+ case ButtonFlags.L2Full:
+ return "\u21B2";
+ case ButtonFlags.R2Soft:
+ return "\u21B3";
+ case ButtonFlags.R2Full:
return "\u21B3";
case ButtonFlags.Special:
return "\uE000";
case ButtonFlags.LeftPadClick:
case ButtonFlags.RightPadClick:
+ case ButtonFlags.LeftPadTouch:
+ case ButtonFlags.RightPadTouch:
return "\u21E7";
}
@@ -201,6 +163,9 @@ public override string GetGlyph(AxisLayoutFlags axis)
return "\u21B2";
case AxisLayoutFlags.R2:
return "\u21B3";
+ case AxisLayoutFlags.LeftPad:
+ case AxisLayoutFlags.RightPad:
+ return "\u21E7";
}
return base.GetGlyph(axis);
diff --git a/HandheldCompanion/Controllers/DualSenseController.cs b/HandheldCompanion/Controllers/DualSenseController.cs
new file mode 100644
index 000000000..2bbc7f202
--- /dev/null
+++ b/HandheldCompanion/Controllers/DualSenseController.cs
@@ -0,0 +1,166 @@
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Managers;
+using HandheldCompanion.Utils;
+using static JSL;
+
+namespace HandheldCompanion.Controllers;
+
+public class DualSenseController : JSController
+{
+ public DualSenseController()
+ {
+ }
+
+ public DualSenseController(JOY_SETTINGS settings, PnPDetails details) : base(settings, details)
+ {
+ // Additional controller specific source buttons
+ SourceButtons.Add(ButtonFlags.LeftPadClick);
+ SourceButtons.Add(ButtonFlags.LeftPadTouch);
+ SourceButtons.Add(ButtonFlags.RightPadClick);
+ SourceButtons.Add(ButtonFlags.RightPadTouch);
+
+ SourceAxis.Add(AxisLayoutFlags.LeftPad);
+ SourceAxis.Add(AxisLayoutFlags.RightPad);
+ SourceAxis.Add(AxisLayoutFlags.Gyroscope);
+
+ TargetButtons.Add(ButtonFlags.LeftPadClick);
+ TargetButtons.Add(ButtonFlags.LeftPadTouch);
+ TargetButtons.Add(ButtonFlags.RightPadTouch);
+
+ TargetAxis.Add(AxisLayoutFlags.LeftPad);
+ TargetAxis.Add(AxisLayoutFlags.RightPad);
+ }
+
+ public override void UpdateInputs(long ticks)
+ {
+ // skip if controller isn't connected
+ if (!IsConnected())
+ return;
+
+ base.UpdateState();
+
+ // Left Pad
+ Inputs.ButtonState[ButtonFlags.LeftPadTouch] = JslGetTouchDown(UserIndex);
+ Inputs.ButtonState[ButtonFlags.LeftPadClick] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskCapture);
+
+ if (Inputs.ButtonState[ButtonFlags.LeftPadTouch])
+ {
+ float joyShockX0 = JslGetTouchX(UserIndex);
+ float joyShockY0 = JslGetTouchY(UserIndex);
+
+ Inputs.AxisState[AxisFlags.LeftPadX] = (short)InputUtils.MapRange(joyShockX0, 0.0f, 1.0f, short.MinValue, short.MaxValue);
+ Inputs.AxisState[AxisFlags.LeftPadY] = (short)InputUtils.MapRange(joyShockY0, 0.0f, 1.0f, short.MaxValue, short.MinValue);
+ }
+ else
+ {
+ Inputs.AxisState[AxisFlags.LeftPadX] = 0;
+ Inputs.AxisState[AxisFlags.LeftPadY] = 0;
+ }
+
+ // Right Pad
+ Inputs.ButtonState[ButtonFlags.RightPadTouch] = JslGetTouchDown(UserIndex, true);
+ Inputs.ButtonState[ButtonFlags.RightPadClick] = Inputs.ButtonState[ButtonFlags.LeftPadClick] && Inputs.ButtonState[ButtonFlags.RightPadTouch];
+
+ if (Inputs.ButtonState[ButtonFlags.RightPadTouch])
+ {
+ float joyShockX1 = JslGetTouchX(UserIndex, true);
+ float joyShockY1 = JslGetTouchY(UserIndex, true);
+
+ Inputs.AxisState[AxisFlags.RightPadX] = (short)InputUtils.MapRange(joyShockX1, 0.0f, 1.0f, short.MinValue, short.MaxValue);
+ Inputs.AxisState[AxisFlags.RightPadY] = (short)InputUtils.MapRange(joyShockY1, 0.0f, 1.0f, short.MaxValue, short.MinValue);
+ }
+ else
+ {
+ Inputs.AxisState[AxisFlags.RightPadX] = 0;
+ Inputs.AxisState[AxisFlags.RightPadY] = 0;
+ }
+
+ base.UpdateInputs(ticks);
+ }
+
+ public override void Plug()
+ {
+ TimerManager.Tick += UpdateInputs;
+ base.Plug();
+ }
+
+ public override void Unplug()
+ {
+ TimerManager.Tick -= UpdateInputs;
+ base.Unplug();
+ }
+
+ public override void Cleanup()
+ {
+ TimerManager.Tick -= UpdateInputs;
+ }
+
+ public override string GetGlyph(ButtonFlags button)
+ {
+ switch (button)
+ {
+ case ButtonFlags.B1:
+ return "\u21E3"; // Cross
+ case ButtonFlags.B2:
+ return "\u21E2"; // Circle
+ case ButtonFlags.B3:
+ return "\u21E0"; // Square
+ case ButtonFlags.B4:
+ return "\u21E1"; // Triangle
+ case ButtonFlags.L1:
+ return "\u21B0";
+ case ButtonFlags.R1:
+ return "\u21B1";
+ case ButtonFlags.Back:
+ return "\u2206";
+ case ButtonFlags.Start:
+ return "\u2208";
+ case ButtonFlags.L2Soft:
+ return "\u21B2";
+ case ButtonFlags.L2Full:
+ return "\u21B2";
+ case ButtonFlags.R2Soft:
+ return "\u21B3";
+ case ButtonFlags.R2Full:
+ return "\u21B3";
+ case ButtonFlags.Special:
+ return "\uE000";
+ case ButtonFlags.LeftPadClick:
+ case ButtonFlags.RightPadClick:
+ case ButtonFlags.LeftPadTouch:
+ case ButtonFlags.RightPadTouch:
+ return "\u2207";
+ }
+
+ return base.GetGlyph(button);
+ }
+
+ public override string GetGlyph(AxisFlags axis)
+ {
+ switch (axis)
+ {
+ case AxisFlags.L2:
+ return "\u21B2";
+ case AxisFlags.R2:
+ return "\u21B3";
+ }
+
+ return base.GetGlyph(axis);
+ }
+
+ public override string GetGlyph(AxisLayoutFlags axis)
+ {
+ switch (axis)
+ {
+ case AxisLayoutFlags.L2:
+ return "\u21B2";
+ case AxisLayoutFlags.R2:
+ return "\u21B3";
+ case AxisLayoutFlags.LeftPad:
+ case AxisLayoutFlags.RightPad:
+ return "\u2207";
+ }
+
+ return base.GetGlyph(axis);
+ }
+}
\ No newline at end of file
diff --git a/HandheldCompanion/Controllers/GordonController.cs b/HandheldCompanion/Controllers/GordonController.cs
new file mode 100644
index 000000000..a30f26ecd
--- /dev/null
+++ b/HandheldCompanion/Controllers/GordonController.cs
@@ -0,0 +1,316 @@
+using HandheldCompanion.Actions;
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Managers;
+using HandheldCompanion.Utils;
+using SharpDX.XInput;
+using steam_hidapi.net;
+using steam_hidapi.net.Hid;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Windows.Media;
+
+namespace HandheldCompanion.Controllers
+{
+ public class GordonController : SteamController
+ {
+ private steam_hidapi.net.GordonController Controller;
+ private GordonControllerInputEventArgs input;
+
+ private const short TrackPadInner = short.MaxValue / 2;
+ public const ushort MaxRumbleIntensity = 2048;
+
+ public GordonController(PnPDetails details) : base()
+ {
+ if (details is null)
+ return;
+
+ Controller = new(details.attributes.VendorID, details.attributes.ProductID, details.GetMI());
+
+ // open controller
+ Open();
+
+ Details = details;
+ Details.isHooked = true;
+
+ // UI
+ ColoredButtons.Add(ButtonFlags.B1, new SolidColorBrush(Color.FromArgb(255, 81, 191, 61)));
+ ColoredButtons.Add(ButtonFlags.B2, new SolidColorBrush(Color.FromArgb(255, 217, 65, 38)));
+ ColoredButtons.Add(ButtonFlags.B3, new SolidColorBrush(Color.FromArgb(255, 26, 159, 255)));
+ ColoredButtons.Add(ButtonFlags.B4, new SolidColorBrush(Color.FromArgb(255, 255, 200, 44)));
+
+ InitializeComponent();
+ DrawControls();
+ RefreshControls();
+
+ // Additional controller specific source buttons/axes
+ SourceButtons.AddRange(new List() { ButtonFlags.L4, ButtonFlags.R4 });
+ SourceButtons.AddRange(new List() { ButtonFlags.LeftPadClick, ButtonFlags.LeftPadTouch, ButtonFlags.LeftPadClickUp, ButtonFlags.LeftPadClickDown, ButtonFlags.LeftPadClickLeft, ButtonFlags.LeftPadClickRight });
+ SourceButtons.AddRange(new List() { ButtonFlags.RightPadClick, ButtonFlags.RightPadTouch, ButtonFlags.RightPadClickUp, ButtonFlags.RightPadClickDown, ButtonFlags.RightPadClickLeft, ButtonFlags.RightPadClickRight });
+
+ SourceAxis.Add(AxisLayoutFlags.LeftPad);
+ SourceAxis.Add(AxisLayoutFlags.RightPad);
+ SourceAxis.Add(AxisLayoutFlags.Gyroscope);
+
+ TargetButtons.Add(ButtonFlags.LeftPadClick);
+ TargetButtons.Add(ButtonFlags.RightPadClick);
+ TargetButtons.Add(ButtonFlags.LeftPadTouch);
+ TargetButtons.Add(ButtonFlags.RightPadTouch);
+
+ TargetAxis.Add(AxisLayoutFlags.LeftPad);
+ TargetAxis.Add(AxisLayoutFlags.RightPad);
+
+ // This is a very original controller, it doesn't have few things
+ SourceButtons.Remove(ButtonFlags.RightStickClick);
+ SourceButtons.Remove(ButtonFlags.RightStickUp);
+ SourceButtons.Remove(ButtonFlags.RightStickDown);
+ SourceButtons.Remove(ButtonFlags.RightStickLeft);
+ SourceButtons.Remove(ButtonFlags.RightStickRight);
+
+ SourceAxis.Remove(AxisLayoutFlags.RightStick);
+ }
+
+ public override string ToString()
+ {
+ string baseName = base.ToString();
+ if (!string.IsNullOrEmpty(baseName))
+ return baseName;
+ return "Steam Controller Gordon";
+ }
+
+ public override void UpdateInputs(long ticks)
+ {
+ if (input is null)
+ return;
+
+ Inputs.ButtonState = InjectedButtons.Clone() as ButtonState;
+
+ Inputs.ButtonState[ButtonFlags.B1] = input.State.ButtonState[GordonControllerButton.BtnA];
+ Inputs.ButtonState[ButtonFlags.B2] = input.State.ButtonState[GordonControllerButton.BtnB];
+ Inputs.ButtonState[ButtonFlags.B3] = input.State.ButtonState[GordonControllerButton.BtnX];
+ Inputs.ButtonState[ButtonFlags.B4] = input.State.ButtonState[GordonControllerButton.BtnY];
+
+ Inputs.ButtonState[ButtonFlags.DPadUp] = input.State.ButtonState[GordonControllerButton.BtnDpadUp];
+ Inputs.ButtonState[ButtonFlags.DPadDown] = input.State.ButtonState[GordonControllerButton.BtnDpadDown];
+ Inputs.ButtonState[ButtonFlags.DPadLeft] = input.State.ButtonState[GordonControllerButton.BtnDpadLeft];
+ Inputs.ButtonState[ButtonFlags.DPadRight] = input.State.ButtonState[GordonControllerButton.BtnDpadRight];
+
+ Inputs.ButtonState[ButtonFlags.Start] = input.State.ButtonState[GordonControllerButton.BtnOptions];
+ Inputs.ButtonState[ButtonFlags.Back] = input.State.ButtonState[GordonControllerButton.BtnMenu];
+ Inputs.ButtonState[ButtonFlags.Special] = input.State.ButtonState[GordonControllerButton.BtnSteam];
+
+ var L2 = input.State.AxesState[GordonControllerAxis.L2];
+ var R2 = input.State.AxesState[GordonControllerAxis.R2];
+
+ Inputs.ButtonState[ButtonFlags.L2Soft] = L2 > Gamepad.TriggerThreshold;
+ Inputs.ButtonState[ButtonFlags.R2Soft] = R2 > Gamepad.TriggerThreshold;
+
+ Inputs.ButtonState[ButtonFlags.L2Full] = L2 > Gamepad.TriggerThreshold * 8;
+ Inputs.ButtonState[ButtonFlags.R2Full] = R2 > Gamepad.TriggerThreshold * 8;
+
+ Inputs.AxisState[AxisFlags.L2] = (short)L2;
+ Inputs.AxisState[AxisFlags.R2] = (short)R2;
+
+ Inputs.ButtonState[ButtonFlags.L1] = input.State.ButtonState[GordonControllerButton.BtnL1];
+ Inputs.ButtonState[ButtonFlags.R1] = input.State.ButtonState[GordonControllerButton.BtnR1];
+ Inputs.ButtonState[ButtonFlags.L4] = input.State.ButtonState[GordonControllerButton.BtnL4];
+ Inputs.ButtonState[ButtonFlags.R4] = input.State.ButtonState[GordonControllerButton.BtnR4];
+
+ // Left Stick
+ Inputs.ButtonState[ButtonFlags.LeftStickClick] = input.State.ButtonState[GordonControllerButton.BtnLStickPress];
+
+ Inputs.AxisState[AxisFlags.LeftStickX] = input.State.AxesState[GordonControllerAxis.LeftStickX];
+ Inputs.AxisState[AxisFlags.LeftStickY] = input.State.AxesState[GordonControllerAxis.LeftStickY];
+
+ Inputs.ButtonState[ButtonFlags.LeftStickLeft] = Inputs.AxisState[AxisFlags.LeftStickX] < -Gamepad.LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickRight] = Inputs.AxisState[AxisFlags.LeftStickX] > Gamepad.LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickDown] = Inputs.AxisState[AxisFlags.LeftStickY] < -Gamepad.LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickUp] = Inputs.AxisState[AxisFlags.LeftStickY] > Gamepad.LeftThumbDeadZone;
+
+ // TODO: Implement Inner/Outer Ring button mappings for sticks
+ // https://github.com/Havner/HandheldCompanion/commit/e1124ceb6c59051201756d5e95b2eb39a3bb24f6
+
+ /* float leftLength = new Vector2(Inputs.AxisState[AxisFlags.LeftThumbX], Inputs.AxisState[AxisFlags.LeftThumbY]).Length();
+ Inputs.ButtonState[ButtonFlags.LeftStickOuterRing] = leftLength >= (RingThreshold * short.MaxValue);
+ Inputs.ButtonState[ButtonFlags.LeftStickInnerRing] = leftLength >= Gamepad.LeftThumbDeadZone && leftLength < (RingThreshold * short.MaxValue); */
+
+ // Left Pad
+ Inputs.ButtonState[ButtonFlags.LeftPadTouch] = input.State.ButtonState[GordonControllerButton.BtnLPadTouch];
+ Inputs.ButtonState[ButtonFlags.LeftPadClick] = input.State.ButtonState[GordonControllerButton.BtnLPadPress];
+
+ if (Inputs.ButtonState[ButtonFlags.LeftPadTouch])
+ {
+ Inputs.AxisState[AxisFlags.LeftPadX] = input.State.AxesState[GordonControllerAxis.LeftPadX];
+ Inputs.AxisState[AxisFlags.LeftPadY] = input.State.AxesState[GordonControllerAxis.LeftPadY];
+ }
+ else
+ {
+ Inputs.AxisState[AxisFlags.LeftPadX] = 0;
+ Inputs.AxisState[AxisFlags.LeftPadY] = 0;
+ }
+
+ if (Inputs.ButtonState[ButtonFlags.LeftPadClick])
+ {
+ InputUtils.TouchToDirections(Inputs.AxisState[AxisFlags.LeftPadX], Inputs.AxisState[AxisFlags.LeftPadY], TrackPadInner, 0, out bool[] buttons);
+ Inputs.ButtonState[ButtonFlags.LeftPadClickUp] = buttons[0];
+ Inputs.ButtonState[ButtonFlags.LeftPadClickRight] = buttons[1];
+ Inputs.ButtonState[ButtonFlags.LeftPadClickDown] = buttons[2];
+ Inputs.ButtonState[ButtonFlags.LeftPadClickLeft] = buttons[3];
+ }
+ else
+ {
+ Inputs.ButtonState[ButtonFlags.LeftPadClickUp] = false;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickRight] = false;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickDown] = false;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickLeft] = false;
+ }
+
+ // Right Pad
+ Inputs.ButtonState[ButtonFlags.RightPadTouch] = input.State.ButtonState[GordonControllerButton.BtnRPadTouch];
+ Inputs.ButtonState[ButtonFlags.RightPadClick] = input.State.ButtonState[GordonControllerButton.BtnRPadPress];
+
+ if (Inputs.ButtonState[ButtonFlags.RightPadTouch])
+ {
+ Inputs.AxisState[AxisFlags.RightPadX] = input.State.AxesState[GordonControllerAxis.RightPadX];
+ Inputs.AxisState[AxisFlags.RightPadY] = input.State.AxesState[GordonControllerAxis.RightPadY];
+ }
+ else
+ {
+ Inputs.AxisState[AxisFlags.RightPadX] = 0;
+ Inputs.AxisState[AxisFlags.RightPadY] = 0;
+ }
+
+ if (Inputs.ButtonState[ButtonFlags.RightPadClick])
+ {
+ InputUtils.TouchToDirections(Inputs.AxisState[AxisFlags.RightPadX], Inputs.AxisState[AxisFlags.RightPadY], TrackPadInner, 0, out bool[] buttons);
+ Inputs.ButtonState[ButtonFlags.RightPadClickUp] = buttons[0];
+ Inputs.ButtonState[ButtonFlags.RightPadClickRight] = buttons[1];
+ Inputs.ButtonState[ButtonFlags.RightPadClickDown] = buttons[2];
+ Inputs.ButtonState[ButtonFlags.RightPadClickLeft] = buttons[3];
+ }
+ else
+ {
+ Inputs.ButtonState[ButtonFlags.RightPadClickUp] = false;
+ Inputs.ButtonState[ButtonFlags.RightPadClickRight] = false;
+ Inputs.ButtonState[ButtonFlags.RightPadClickDown] = false;
+ Inputs.ButtonState[ButtonFlags.RightPadClickLeft] = false;
+ }
+
+ // TODO: why Z/Y swapped?
+ Inputs.GyroState.Accelerometer.X = -(float)input.State.AxesState[GordonControllerAxis.GyroAccelX] / short.MaxValue * 2.0f;
+ Inputs.GyroState.Accelerometer.Y = -(float)input.State.AxesState[GordonControllerAxis.GyroAccelZ] / short.MaxValue * 2.0f;
+ Inputs.GyroState.Accelerometer.Z = -(float)input.State.AxesState[GordonControllerAxis.GyroAccelY] / short.MaxValue * 2.0f;
+
+ // TODO: why Roll/Pitch swapped?
+ Inputs.GyroState.Gyroscope.X = (float)input.State.AxesState[GordonControllerAxis.GyroPitch] / short.MaxValue * 2048.0f; // Roll
+ Inputs.GyroState.Gyroscope.Y = -(float)input.State.AxesState[GordonControllerAxis.GyroRoll] / short.MaxValue * 2048.0f; // Pitch
+ Inputs.GyroState.Gyroscope.Z = (float)input.State.AxesState[GordonControllerAxis.GyroYaw] / short.MaxValue * 2048.0f; // Yaw
+
+ base.UpdateInputs(ticks);
+ }
+
+ private void OnControllerInputReceived(GordonControllerInputEventArgs input)
+ {
+ this.input = input;
+ }
+
+ public override void Plug()
+ {
+ try
+ {
+ Controller.OnControllerInputReceived = input => Task.Run(() => OnControllerInputReceived(input));
+
+ // open controller
+ Open();
+ }
+ catch (Exception ex)
+ {
+ LogManager.LogError("Couldn't initialize GordonController. Exception: {0}", ex.Message);
+ return;
+ }
+
+ Controller.SetLizardMode(false);
+ Controller.SetGyroscope(true);
+ Controller.SetIdleTimeout(300); // ~5 min
+
+ SetVirtualMuted(SettingsManager.GetBoolean("SteamControllerMute"));
+
+ TimerManager.Tick += UpdateInputs;
+
+ base.Plug();
+ }
+
+ public override void Unplug()
+ {
+ try
+ {
+ // restore lizard state
+ Controller.SetLizardMode(true);
+ Controller.SetGyroscope(false);
+ Controller.SetIdleTimeout(0);
+ //Controller.TurnOff(); // TODO: why not?
+
+ // close controller
+ Close();
+ }
+ catch
+ {
+ return;
+ }
+
+ TimerManager.Tick -= UpdateInputs;
+ base.Unplug();
+ }
+
+ private void Open()
+ {
+ try
+ {
+ Controller.Open();
+ isConnected = true;
+ }
+ catch { }
+ }
+
+ private void Close()
+ {
+ try
+ {
+ Controller.Close();
+ isConnected = false;
+ }
+ catch { }
+ }
+
+ public override void Cleanup()
+ {
+ TimerManager.Tick -= UpdateInputs;
+ }
+
+ public ushort GetHapticIntensity(byte input, ushort maxIntensity)
+ {
+ return (ushort)(input * maxIntensity * VibrationStrength / 255);
+ }
+
+ public override void SetVibration(byte LargeMotor, byte SmallMotor)
+ {
+ ushort leftAmplitude = GetHapticIntensity(LargeMotor, MaxRumbleIntensity);
+ Controller.SetHaptic((byte)SCHapticMotor.Left, leftAmplitude, 0, 1);
+
+ ushort rightAmplitude = GetHapticIntensity(SmallMotor, MaxRumbleIntensity);
+ Controller.SetHaptic((byte)SCHapticMotor.Right, rightAmplitude, 0, 1);
+ }
+
+ public override void SetHaptic(HapticStrength strength, ButtonFlags button)
+ {
+ ushort value = strength switch
+ {
+ HapticStrength.Low => 512,
+ HapticStrength.Medium => 1024,
+ HapticStrength.High => 2048,
+ _ => 0,
+ };
+ Controller.SetHaptic((byte)GetMotorForButton(button), value, 0, 1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/HandheldCompanion/Controllers/IController.xaml b/HandheldCompanion/Controllers/IController.xaml
new file mode 100644
index 000000000..96e90617d
--- /dev/null
+++ b/HandheldCompanion/Controllers/IController.xaml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/HandheldCompanion/Controllers/IController.xaml.cs b/HandheldCompanion/Controllers/IController.xaml.cs
new file mode 100644
index 000000000..fd1331f13
--- /dev/null
+++ b/HandheldCompanion/Controllers/IController.xaml.cs
@@ -0,0 +1,541 @@
+using HandheldCompanion.Actions;
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Managers;
+using HandheldCompanion.Utils;
+using Inkore.UI.WPF.Modern.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace HandheldCompanion.Controllers
+{
+ [Flags]
+ public enum ControllerCapabilities : ushort
+ {
+ None = 0,
+ MotionSensor = 1,
+ Calibration = 2,
+ }
+
+ ///
+ /// Logique d'interaction pour IController.xaml
+ ///
+ public partial class IController : UserControl
+ {
+ // Buttons and axes we should be able to map to.
+ // When we have target controllers with different buttons (e.g. in VigEm) this will have to be moved elsewhere.
+ public static readonly List TargetButtons = new()
+ {
+ ButtonFlags.B1, ButtonFlags.B2, ButtonFlags.B3, ButtonFlags.B4,
+ ButtonFlags.DPadUp, ButtonFlags.DPadDown, ButtonFlags.DPadLeft, ButtonFlags.DPadRight,
+ ButtonFlags.Start, ButtonFlags.Back, ButtonFlags.Special,
+ ButtonFlags.L1, ButtonFlags.R1,
+ ButtonFlags.LeftStickClick, ButtonFlags.RightStickClick,
+ };
+
+ public static readonly List TargetAxis = new()
+ {
+ AxisLayoutFlags.LeftStick, AxisLayoutFlags.RightStick,
+ AxisLayoutFlags.L2, AxisLayoutFlags.R2,
+ };
+
+ public static readonly string defaultGlyph = "\u2753";
+
+ public ControllerCapabilities Capabilities = ControllerCapabilities.None;
+ protected SortedDictionary ColoredAxis = new();
+
+ protected SortedDictionary ColoredButtons = new();
+ protected FontFamily DefaultFontFamily = new("Segeo WP");
+
+ public PnPDetails Details;
+
+ // UI
+ protected FontFamily GlyphFontFamily = new("PromptFont");
+
+ public ButtonState InjectedButtons = new();
+
+ public ControllerState Inputs = new();
+ protected bool isPlugged;
+
+ protected List SourceAxis = new()
+ {
+ // same as target, we assume all controllers have those axes
+ AxisLayoutFlags.LeftStick, AxisLayoutFlags.RightStick,
+ AxisLayoutFlags.L2, AxisLayoutFlags.R2
+ };
+
+ // Buttons and axes all controllers have that we can map.
+ // Additional ones can be added per controller.
+ protected List SourceButtons = new()
+ {
+ // same as target, we assume all controllers have those buttons
+ ButtonFlags.B1, ButtonFlags.B2, ButtonFlags.B3, ButtonFlags.B4,
+ ButtonFlags.DPadUp, ButtonFlags.DPadDown, ButtonFlags.DPadLeft, ButtonFlags.DPadRight,
+ ButtonFlags.Start, ButtonFlags.Back, ButtonFlags.Special,
+ ButtonFlags.L1, ButtonFlags.R1,
+ ButtonFlags.LeftStickClick, ButtonFlags.RightStickClick,
+ // additional buttons calculated from the above
+ ButtonFlags.L2Soft, ButtonFlags.R2Soft, ButtonFlags.L2Full, ButtonFlags.R2Full,
+ ButtonFlags.LeftStickUp, ButtonFlags.LeftStickDown, ButtonFlags.LeftStickLeft, ButtonFlags.LeftStickRight,
+ ButtonFlags.RightStickUp, ButtonFlags.RightStickDown, ButtonFlags.RightStickLeft, ButtonFlags.RightStickRight
+ };
+
+ protected int UserIndex;
+ protected double VibrationStrength = 1.0d;
+
+ public IController()
+ {
+ }
+
+ public virtual void UpdateInputs(long ticks)
+ {
+ InputsUpdated?.Invoke(Inputs);
+ }
+
+ public bool HasMotionSensor()
+ {
+ return Capabilities.HasFlag(ControllerCapabilities.MotionSensor);
+ }
+
+ public bool IsVirtual()
+ {
+ if (Details is not null)
+ return Details.isVirtual;
+ return true;
+ }
+
+ public bool IsGaming()
+ {
+ if (Details is not null)
+ return Details.isGaming;
+ return false;
+ }
+
+ public int GetUserIndex()
+ {
+ return UserIndex;
+ }
+
+ public string GetInstancePath()
+ {
+ if (Details is not null)
+ return Details.deviceInstanceId;
+ return string.Empty;
+ }
+
+ public string GetContainerInstancePath()
+ {
+ if (Details is not null)
+ return Details.baseContainerDeviceInstanceId;
+ return string.Empty;
+ }
+
+ public override string ToString()
+ {
+ if (Details is not null)
+ return Details.Name;
+ return string.Empty;
+ }
+
+ protected void DrawControls()
+ {
+ // update name
+ ui_name.Text = (IsVirtual() ? Properties.Resources.Controller_Virtual : string.Empty) + ToString();
+
+ // virtual controller shouldn't be visible
+ if (IsVirtual())
+ this.Visibility = Visibility.Collapsed;
+ }
+
+ protected void RefreshControls()
+ {
+ // UI thread (async)
+ Application.Current.Dispatcher.BeginInvoke(() =>
+ {
+ ui_button_hook.Content = IsPlugged() ? Properties.Resources.Controller_Disconnect : Properties.Resources.Controller_Connect;
+ ui_button_hide.Content = IsHidden() ? Properties.Resources.Controller_Unhide : Properties.Resources.Controller_Hide;
+ ui_button_calibrate.Visibility = Capabilities.HasFlag(ControllerCapabilities.Calibration) ? Visibility.Visible : Visibility.Collapsed;
+ });
+ }
+
+ public Button GetButtonHook()
+ {
+ return ui_button_hook;
+ }
+
+ public Button GetButtonHide()
+ {
+ return ui_button_hide;
+ }
+
+ public Button GetButtonCalibrate()
+ {
+ return ui_button_calibrate;
+ }
+
+ public void InjectState(ButtonState State, bool IsKeyDown, bool IsKeyUp)
+ {
+ if (State.IsEmpty())
+ return;
+
+ foreach (var button in State.Buttons)
+ InjectedButtons[button] = IsKeyDown;
+
+ LogManager.LogDebug("Injecting {0} (IsKeyDown:{1}) (IsKeyUp:{2}) to {3}", string.Join(',', State.Buttons),
+ IsKeyDown, IsKeyUp, ToString());
+ }
+
+ public void InjectButton(ButtonFlags button, bool IsKeyDown, bool IsKeyUp)
+ {
+ if (button == ButtonFlags.None)
+ return;
+
+ InjectedButtons[button] = IsKeyDown;
+
+ LogManager.LogDebug("Injecting {0} (IsKeyDown:{1}) (IsKeyUp:{2}) to {3}", button, IsKeyDown, IsKeyUp,
+ ToString());
+ }
+
+ public virtual void SetVibrationStrength(uint value, bool rumble = false)
+ {
+ VibrationStrength = value / 100.0d;
+ if (rumble)
+ Rumble();
+ }
+
+ public virtual void SetVibration(byte LargeMotor, byte SmallMotor)
+ {
+ }
+
+ // let the controller decide itself what motor to use for a specific button
+ public virtual void SetHaptic(HapticStrength strength, ButtonFlags button)
+ { }
+
+ public virtual bool IsConnected()
+ {
+ return false;
+ }
+
+ public virtual async void Rumble(int delay = 125)
+ {
+ SetVibration(byte.MaxValue, byte.MaxValue);
+ await Task.Delay(delay);
+ SetVibration(0, 0);
+ }
+
+ public virtual bool IsPlugged()
+ {
+ return isPlugged;
+ }
+
+ // this function cannot be called twice
+ public virtual void Plug()
+ {
+ SetVibrationStrength(SettingsManager.GetUInt("VibrationStrength"));
+
+ isPlugged = true;
+
+ InjectedButtons.Clear();
+
+ RefreshControls();
+ }
+
+ // this function cannot be called twice
+ public virtual void Unplug()
+ {
+ isPlugged = false;
+
+ RefreshControls();
+ }
+
+ // like Unplug but one that can be safely called when controller is already removed
+ public virtual void Cleanup()
+ {
+ }
+
+ public bool IsHidden()
+ {
+ var hide_device = HidHide.IsRegistered(Details.deviceInstanceId);
+ var hide_base = HidHide.IsRegistered(Details.baseContainerDeviceInstanceId);
+ return /* hide_device || */ hide_base;
+ }
+
+ public void Hide(bool powerCycle = true)
+ {
+ if (IsHidden())
+ return;
+
+ // get HidHideDevice
+ HidHideDevice hideDevice = HidHide.GetHidHideDevice(Details.baseContainerDeviceInstanceId);
+ if (hideDevice is not null)
+ foreach (HidHideSubDevice subDevice in hideDevice.Devices)
+ HidHide.HidePath(subDevice.DeviceInstancePath);
+
+ HidHide.HidePath(Details.deviceInstanceId);
+ HidHide.HidePath(Details.baseContainerDeviceInstanceId);
+
+ // set flag
+ if (powerCycle)
+ {
+ ControllerManager.PowerCyclers[Details.baseContainerDeviceInstanceId] = true;
+ Details.CyclePort();
+ }
+
+ RefreshControls();
+ }
+
+ public void Unhide(bool powerCycle = true)
+ {
+ if (!IsHidden())
+ return;
+
+ // get HidHideDevice
+ HidHideDevice hideDevice = HidHide.GetHidHideDevice(Details.baseContainerDeviceInstanceId);
+ if (hideDevice is not null)
+ foreach (HidHideSubDevice subDevice in hideDevice.Devices)
+ HidHide.UnhidePath(subDevice.DeviceInstancePath);
+
+ HidHide.UnhidePath(Details.deviceInstanceId);
+ HidHide.UnhidePath(Details.baseContainerDeviceInstanceId);
+
+ // set flag
+ if (powerCycle)
+ {
+ ControllerManager.PowerCyclers[Details.baseContainerDeviceInstanceId] = true;
+ Details.CyclePort();
+ }
+
+ RefreshControls();
+ }
+
+ protected virtual void Calibrate()
+ {
+ }
+
+ protected virtual void ui_button_calibrate_Click(object sender, RoutedEventArgs e)
+ {
+ CalibrateClicked?.Invoke(this);
+ }
+
+ protected virtual void ui_button_hide_Click(object sender, RoutedEventArgs e)
+ {
+ HideClicked?.Invoke(this);
+ }
+
+ protected virtual void ui_button_hook_Click(object sender, RoutedEventArgs e)
+ {
+ HookClicked?.Invoke(this);
+ }
+
+ public virtual string GetGlyph(ButtonFlags button)
+ {
+ switch (button)
+ {
+ case ButtonFlags.DPadUp:
+ return "\u219F"; // Button A
+ case ButtonFlags.DPadDown:
+ return "\u21A1"; // Button B
+ case ButtonFlags.DPadLeft:
+ return "\u219E"; // Button X
+ case ButtonFlags.DPadRight:
+ return "\u21A0"; // Button Y
+ case ButtonFlags.LeftStickClick:
+ return "\u21BA";
+ case ButtonFlags.RightStickClick:
+ return "\u21BB";
+ case ButtonFlags.LeftStickUp:
+ return "\u21BE";
+ case ButtonFlags.LeftStickDown:
+ return "\u21C2";
+ case ButtonFlags.LeftStickLeft:
+ return "\u21BC";
+ case ButtonFlags.LeftStickRight:
+ return "\u21C0";
+ case ButtonFlags.RightStickUp:
+ return "\u21BF";
+ case ButtonFlags.RightStickDown:
+ return "\u21C3";
+ case ButtonFlags.RightStickLeft:
+ return "\u21BD";
+ case ButtonFlags.RightStickRight:
+ return "\u21C1";
+ case ButtonFlags.OEM1:
+ return "\u2780";
+ case ButtonFlags.OEM2:
+ return "\u2781";
+ case ButtonFlags.OEM3:
+ return "\u2782";
+ case ButtonFlags.OEM4:
+ return "\u2783";
+ case ButtonFlags.OEM5:
+ return "\u2784";
+ case ButtonFlags.OEM6:
+ return "\u2785";
+ case ButtonFlags.OEM7:
+ return "\u2786";
+ case ButtonFlags.OEM8:
+ return "\u2787";
+ case ButtonFlags.OEM9:
+ return "\u2788";
+ case ButtonFlags.OEM10:
+ return "\u2789";
+ case ButtonFlags.VolumeUp:
+ return "\u21fe";
+ case ButtonFlags.VolumeDown:
+ return "\u21fd";
+ }
+
+ return defaultGlyph;
+ }
+
+ public virtual string GetGlyph(AxisFlags axis)
+ {
+ switch (axis)
+ {
+ case AxisFlags.LeftStickX:
+ return "\u21C4";
+ case AxisFlags.LeftStickY:
+ return "\u21C5";
+ case AxisFlags.RightStickX:
+ return "\u21C6";
+ case AxisFlags.RightStickY:
+ return "\u21F5";
+ }
+
+ return defaultGlyph;
+ }
+
+ public virtual string GetGlyph(AxisLayoutFlags axis)
+ {
+ switch (axis)
+ {
+ case AxisLayoutFlags.LeftStick:
+ return "\u21CB";
+ case AxisLayoutFlags.RightStick:
+ return "\u21CC";
+ case AxisLayoutFlags.Gyroscope:
+ return "\u2B94";
+ }
+
+ return defaultGlyph;
+ }
+
+ public FontIcon GetFontIcon(ButtonFlags button, int FontIconSize = 14)
+ {
+ var FontIcon = new FontIcon
+ {
+ Glyph = GetGlyph(button),
+ FontSize = FontIconSize,
+ Foreground = GetGlyphColor(button)
+ };
+
+ if (FontIcon.Glyph is not null)
+ {
+ FontIcon.FontFamily = GlyphFontFamily;
+ FontIcon.FontSize = 28;
+ }
+
+ return FontIcon;
+ }
+
+ public FontIcon GetFontIcon(AxisLayoutFlags axis, int FontIconSize = 14)
+ {
+ var FontIcon = new FontIcon
+ {
+ Glyph = GetGlyph(axis),
+ FontSize = FontIconSize,
+ Foreground = GetGlyphColor(axis)
+ };
+
+ if (FontIcon.Glyph is not null)
+ {
+ FontIcon.FontFamily = GlyphFontFamily;
+ FontIcon.FontSize = 28;
+ }
+
+ return FontIcon;
+ }
+
+ public Brush GetGlyphColor(ButtonFlags button)
+ {
+ if (ColoredButtons.TryGetValue(button, out var brush))
+ return brush;
+
+ return null;
+ }
+
+ public Brush GetGlyphColor(AxisLayoutFlags axis)
+ {
+ /* if (AxisBrush.TryGetValue(axis, out Brush brush))
+ return brush; */
+
+ return null;
+ }
+
+ private static bool IsTrigger(AxisLayoutFlags axis)
+ {
+ return axis is AxisLayoutFlags.L2 || axis is AxisLayoutFlags.R2;
+ }
+
+ public static IEnumerable GetTargetButtons()
+ {
+ var buttons = Enum.GetValues(typeof(ButtonFlags)).Cast();
+
+ return buttons.Where(a => TargetButtons.Contains(a));
+ }
+
+ public static IEnumerable GetTargetAxis()
+ {
+ var axis = Enum.GetValues(typeof(AxisLayoutFlags)).Cast();
+
+ return axis.Where(a => TargetAxis.Contains(a) && !IsTrigger(a));
+ }
+
+ public static IEnumerable GetTargetTriggers()
+ {
+ var axis = Enum.GetValues(typeof(AxisLayoutFlags)).Cast();
+
+ return axis.Where(a => TargetAxis.Contains(a) && IsTrigger(a));
+ }
+
+ public bool HasSourceButton(ButtonFlags button)
+ {
+ return SourceButtons.Contains(button);
+ }
+
+ public bool HasSourceAxis(AxisLayoutFlags axis)
+ {
+ return SourceAxis.Contains(axis);
+ }
+
+ public string GetButtonName(ButtonFlags button)
+ {
+ return EnumUtils.GetDescriptionFromEnumValue(button, GetType().Name);
+ }
+
+ public string GetAxisName(AxisLayoutFlags axis)
+ {
+ return EnumUtils.GetDescriptionFromEnumValue(axis, GetType().Name);
+ }
+
+ #region events
+
+ public event InputsUpdatedEventHandler InputsUpdated;
+ public delegate void InputsUpdatedEventHandler(ControllerState Inputs);
+
+ public event HookClickedEventHandler HookClicked;
+ public delegate void HookClickedEventHandler(IController controller);
+
+ public event HideClickedEventHandler HideClicked;
+ public delegate void HideClickedEventHandler(IController controller);
+
+ public event CalibrateClickedEventHandler CalibrateClicked;
+ public delegate void CalibrateClickedEventHandler(IController controller);
+
+ #endregion
+ }
+}
diff --git a/HandheldCompanion/Controllers/JSController.cs b/HandheldCompanion/Controllers/JSController.cs
new file mode 100644
index 000000000..a538cdcda
--- /dev/null
+++ b/HandheldCompanion/Controllers/JSController.cs
@@ -0,0 +1,200 @@
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Utils;
+using System.Windows;
+using static JSL;
+using Timer = System.Timers.Timer;
+
+namespace HandheldCompanion.Controllers;
+
+public class JSController : IController
+{
+ protected JOY_SETTINGS sSETTINGS;
+ protected JOY_SHOCK_STATE sTATE;
+ protected IMU_STATE iMU_STATE;
+
+ protected float TriggerThreshold = 0.12f;
+ protected float LeftThumbDeadZone = 0.24f;
+ protected float RightThumbDeadZone = 0.265f;
+
+ protected Timer calibrateTimer = new Timer(5000) { AutoReset = false };
+
+ public JSController()
+ {
+ }
+
+ public JSController(JOY_SETTINGS settings, PnPDetails details)
+ {
+ if (string.IsNullOrEmpty(settings.path))
+ return;
+
+ this.sSETTINGS = settings;
+ this.UserIndex = settings.playerNumber;
+
+ if (details is null)
+ return;
+
+ Details = details;
+ Details.isHooked = true;
+
+ // timer(s)
+ calibrateTimer.Elapsed += CalibrateTimer_Elapsed;
+
+ // Capabilities
+ Capabilities |= ControllerCapabilities.MotionSensor;
+ Capabilities |= ControllerCapabilities.Calibration;
+
+ // UI
+ InitializeComponent();
+ DrawControls();
+ RefreshControls();
+
+ JslSetAutomaticCalibration(UserIndex, true);
+ }
+
+ public override string ToString()
+ {
+ var baseName = base.ToString();
+ if (!string.IsNullOrEmpty(baseName))
+ return baseName;
+
+ switch ((JOY_TYPE)sSETTINGS.controllerType)
+ {
+ case JOY_TYPE.DualShock4:
+ return "DualShock 4";
+ }
+
+ return $"JoyShock Controller {UserIndex}";
+ }
+
+ public override void UpdateInputs(long ticks)
+ {
+ base.UpdateInputs(ticks);
+ }
+
+ public virtual void UpdateState()
+ {
+ // skip if controller isn't connected
+ if (!IsConnected())
+ return;
+
+ Inputs.ButtonState = InjectedButtons.Clone() as ButtonState;
+
+ // pull state
+ sTATE = JslGetSimpleState(UserIndex);
+
+ Inputs.ButtonState[ButtonFlags.B1] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskS);
+ Inputs.ButtonState[ButtonFlags.B2] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskE);
+ Inputs.ButtonState[ButtonFlags.B3] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskW);
+ Inputs.ButtonState[ButtonFlags.B4] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskN);
+
+ Inputs.ButtonState[ButtonFlags.Back] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskMinus);
+ Inputs.ButtonState[ButtonFlags.Start] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskPlus);
+
+ Inputs.ButtonState[ButtonFlags.DPadUp] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskUp);
+ Inputs.ButtonState[ButtonFlags.DPadDown] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskDown);
+ Inputs.ButtonState[ButtonFlags.DPadLeft] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskLeft);
+ Inputs.ButtonState[ButtonFlags.DPadRight] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskRight);
+
+ Inputs.ButtonState[ButtonFlags.Special] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskHome);
+
+ // Triggers
+ Inputs.ButtonState[ButtonFlags.L1] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskL);
+ Inputs.ButtonState[ButtonFlags.R1] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskR);
+
+ Inputs.ButtonState[ButtonFlags.L2Soft] = sTATE.lTrigger > TriggerThreshold;
+ Inputs.ButtonState[ButtonFlags.R2Soft] = sTATE.rTrigger > TriggerThreshold;
+
+ Inputs.ButtonState[ButtonFlags.L2Full] = sTATE.lTrigger > TriggerThreshold * 8;
+ Inputs.ButtonState[ButtonFlags.R2Full] = sTATE.rTrigger > TriggerThreshold * 8;
+
+ Inputs.AxisState[AxisFlags.L2] = (short)InputUtils.MapRange(sTATE.lTrigger, 0.0f, 1.0f, byte.MinValue, byte.MaxValue);
+ Inputs.AxisState[AxisFlags.R2] = (short)InputUtils.MapRange(sTATE.rTrigger, 0.0f, 1.0f, byte.MinValue, byte.MaxValue);
+
+ // Left Stick
+ Inputs.ButtonState[ButtonFlags.LeftStickLeft] = sTATE.stickLX < -LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickRight] = sTATE.stickLX > LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickDown] = sTATE.stickLY < -LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickUp] = sTATE.stickLY > LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickClick] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskLClick);
+
+ Inputs.AxisState[AxisFlags.LeftStickX] = (short)InputUtils.MapRange(sTATE.stickLX, -1.0f, 1.0f, short.MinValue, short.MaxValue);
+ Inputs.AxisState[AxisFlags.LeftStickY] = (short)InputUtils.MapRange(sTATE.stickLY, -1.0f, 1.0f, short.MinValue, short.MaxValue);
+
+ // Right Stick
+ Inputs.ButtonState[ButtonFlags.RightStickLeft] = sTATE.stickRX < -LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.RightStickRight] = sTATE.stickRX > LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.RightStickDown] = sTATE.stickRY < -LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.RightStickUp] = sTATE.stickRY > LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.RightStickClick] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskRClick);
+
+ Inputs.AxisState[AxisFlags.RightStickX] = (short)InputUtils.MapRange(sTATE.stickRX, -1.0f, 1.0f, short.MinValue, short.MaxValue);
+ Inputs.AxisState[AxisFlags.RightStickY] = (short)InputUtils.MapRange(sTATE.stickRY, -1.0f, 1.0f, short.MinValue, short.MaxValue);
+
+ // IMU
+ iMU_STATE = JslGetIMUState(UserIndex);
+ Inputs.GyroState.Accelerometer.X = -iMU_STATE.accelX;
+ Inputs.GyroState.Accelerometer.Y = -iMU_STATE.accelY;
+ Inputs.GyroState.Accelerometer.Z = iMU_STATE.accelZ;
+
+ Inputs.GyroState.Gyroscope.X = iMU_STATE.gyroX;
+ Inputs.GyroState.Gyroscope.Y = -iMU_STATE.gyroY;
+ Inputs.GyroState.Gyroscope.Z = iMU_STATE.gyroZ;
+ }
+
+ public override bool IsConnected()
+ {
+ return JslStillConnected(UserIndex);
+ }
+
+ public override void Plug()
+ {
+ base.Plug();
+ }
+
+ public override void Unplug()
+ {
+ base.Unplug();
+ }
+
+ public override void SetVibration(byte LargeMotor, byte SmallMotor)
+ {
+ JslSetRumble(UserIndex, (byte)(SmallMotor * VibrationStrength), (byte)(LargeMotor * VibrationStrength));
+ }
+
+ protected override void Calibrate()
+ {
+ // start calibration
+ JslResetContinuousCalibration(UserIndex);
+ JslStartContinuousCalibration(UserIndex);
+
+ calibrateTimer.Start();
+
+ // UI thread (async)
+ Application.Current.Dispatcher.BeginInvoke(() =>
+ {
+ ui_button_calibrate.Content = "Calibrating";
+ ui_button_calibrate.IsEnabled = false;
+ });
+ }
+
+ protected override void ui_button_calibrate_Click(object sender, RoutedEventArgs e)
+ {
+ // start calibration
+ Calibrate();
+
+ base.ui_button_calibrate_Click(sender, e);
+ }
+
+ private void CalibrateTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
+ {
+ // stop calibration
+ JslPauseContinuousCalibration(UserIndex);
+
+ // UI thread (async)
+ Application.Current.Dispatcher.BeginInvoke(() =>
+ {
+ ui_button_calibrate.Content = "Calibrate";
+ ui_button_calibrate.IsEnabled = true;
+ });
+ }
+}
\ No newline at end of file
diff --git a/HandheldCompanion/Controllers/NeptuneController.cs b/HandheldCompanion/Controllers/NeptuneController.cs
index 5e44e59c3..dd9a7ab6a 100644
--- a/HandheldCompanion/Controllers/NeptuneController.cs
+++ b/HandheldCompanion/Controllers/NeptuneController.cs
@@ -1,53 +1,34 @@
-using System;
+using HandheldCompanion.Actions;
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Managers;
+using SharpDX.XInput;
+using steam_hidapi.net;
+using steam_hidapi.net.Hid;
+using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
-using ControllerCommon;
-using ControllerCommon.Controllers;
-using ControllerCommon.Inputs;
-using ControllerCommon.Managers;
-using ControllerCommon.Pipes;
-using HandheldCompanion.Managers;
-using neptune_hidapi.net;
-using neptune_hidapi.net.Hid;
-using SharpDX.XInput;
namespace HandheldCompanion.Controllers;
-public class NeptuneController : IController
+public class NeptuneController : SteamController
{
- private const short TrackPadInner = 21844;
-
- public const sbyte HDRumbleMinIntensity = -2;
- public const sbyte HDRumbleMaxIntensity = 10;
+ private steam_hidapi.net.NeptuneController Controller;
+ private NeptuneControllerInputEventArgs input;
- public const sbyte SDRumbleMinIntensity = 8;
- public const sbyte SDRumbleMaxIntensity = 12;
- private readonly neptune_hidapi.net.NeptuneController Controller;
+ private const short TrackPadInner = 21844;
public byte FeedbackLargeMotor;
public byte FeedbackSmallMotor;
- private readonly ushort HDRumblePeriod = 8;
- private NeptuneControllerInputEventArgs input;
-
- private bool isConnected;
- private bool isVirtualMuted;
- private bool lastLeftHaptic;
+ public const sbyte MinIntensity = -2;
+ public const sbyte MaxIntensity = 10;
- private Task lastLeftHaptic2;
- private bool lastRightHaptic;
- private Task lastRightHaptic2;
+ // TODO: why not use TimerManager.Tick?
+ private Thread rumbleThread;
+ private bool rumbleThreadRunning;
- private NeptuneControllerInputState prevState;
-
- private Thread RumbleThread;
- private bool RumbleThreadRunning;
- private readonly ushort SDRumblePeriod = 8;
-
- private bool UseHDRumble;
-
- public NeptuneController(PnPDetails details)
+ public NeptuneController(PnPDetails details) : base()
{
if (details is null)
return;
@@ -55,13 +36,9 @@ public NeptuneController(PnPDetails details)
Details = details;
Details.isHooked = true;
- Capacities |= ControllerCapacities.Gyroscope;
- Capacities |= ControllerCapacities.Accelerometer;
-
try
{
- Controller = new neptune_hidapi.net.NeptuneController();
- Controller.OnControllerInputReceived = input => Task.Run(() => OnControllerInputReceived(input));
+ Controller = new(details.attributes.VendorID, details.attributes.ProductID, details.GetMI());
// open controller
Open();
@@ -72,24 +49,15 @@ public NeptuneController(PnPDetails details)
return;
}
- // disable lizard state
- SetLizardMouse(false);
- SetLizardButtons(false);
-
- var Muted = SettingsManager.GetBoolean("SteamDeckMuteController");
- SetVirtualMuted(Muted);
-
- var HDRumble = SettingsManager.GetBoolean("SteamDeckHDRumble");
- SetHDRumble(HDRumble);
-
// UI
+ InitializeComponent();
DrawControls();
RefreshControls();
// Additional controller specific source buttons/axes
SourceButtons.AddRange(new List
{ ButtonFlags.L4, ButtonFlags.R4, ButtonFlags.L5, ButtonFlags.R5 });
- SourceButtons.AddRange(new List { ButtonFlags.LeftThumbTouch, ButtonFlags.RightThumbTouch });
+ SourceButtons.AddRange(new List { ButtonFlags.LeftStickTouch, ButtonFlags.RightStickTouch });
SourceButtons.AddRange(new List
{
ButtonFlags.LeftPadClick, ButtonFlags.LeftPadTouch, ButtonFlags.LeftPadClickUp,
@@ -103,30 +71,15 @@ public NeptuneController(PnPDetails details)
SourceAxis.Add(AxisLayoutFlags.LeftPad);
SourceAxis.Add(AxisLayoutFlags.RightPad);
+ SourceAxis.Add(AxisLayoutFlags.Gyroscope);
- HDRumblePeriod = (ushort)(TimerManager.GetPeriod() * 2);
- SDRumblePeriod = (ushort)(TimerManager.GetPeriod() * 10);
- }
-
- private async void ThreadLoop(object? obj)
- {
- while (RumbleThreadRunning)
- {
- if (GetHapticIntensity(FeedbackLargeMotor, HDRumbleMinIntensity, HDRumbleMaxIntensity,
- out var leftIntensity))
- lastLeftHaptic2 = Controller.SetHaptic2(HapticPad.Left, HapticStyle.Weak, leftIntensity);
-
- if (GetHapticIntensity(FeedbackSmallMotor, HDRumbleMinIntensity, HDRumbleMaxIntensity,
- out var rightIntensity))
- lastRightHaptic2 = Controller.SetHaptic2(HapticPad.Right, HapticStyle.Weak, rightIntensity);
+ TargetButtons.Add(ButtonFlags.LeftPadClick);
+ TargetButtons.Add(ButtonFlags.RightPadClick);
+ TargetButtons.Add(ButtonFlags.LeftPadTouch);
+ TargetButtons.Add(ButtonFlags.RightPadTouch);
- Thread.Sleep(HDRumblePeriod);
-
- if (lastLeftHaptic2 is not null)
- await lastLeftHaptic2;
- if (lastRightHaptic2 is not null)
- await lastRightHaptic2;
- }
+ TargetAxis.Add(AxisLayoutFlags.LeftPad);
+ TargetAxis.Add(AxisLayoutFlags.RightPad);
}
public override string ToString()
@@ -142,11 +95,6 @@ public override void UpdateInputs(long ticks)
if (input is null)
return;
- /*
- if (input.State.ButtonState.Equals(prevState.ButtonState) && input.State.AxesState.Equals(prevState.AxesState) && prevInjectedButtons.Equals(InjectedButtons))
- return;
- */
-
Inputs.ButtonState = InjectedButtons.Clone() as ButtonState;
Inputs.ButtonState[ButtonFlags.B1] = input.State.ButtonState[NeptuneControllerButton.BtnA];
@@ -154,6 +102,11 @@ public override void UpdateInputs(long ticks)
Inputs.ButtonState[ButtonFlags.B3] = input.State.ButtonState[NeptuneControllerButton.BtnX];
Inputs.ButtonState[ButtonFlags.B4] = input.State.ButtonState[NeptuneControllerButton.BtnY];
+ Inputs.ButtonState[ButtonFlags.DPadUp] = input.State.ButtonState[NeptuneControllerButton.BtnDpadUp];
+ Inputs.ButtonState[ButtonFlags.DPadDown] = input.State.ButtonState[NeptuneControllerButton.BtnDpadDown];
+ Inputs.ButtonState[ButtonFlags.DPadLeft] = input.State.ButtonState[NeptuneControllerButton.BtnDpadLeft];
+ Inputs.ButtonState[ButtonFlags.DPadRight] = input.State.ButtonState[NeptuneControllerButton.BtnDpadRight];
+
Inputs.ButtonState[ButtonFlags.Start] = input.State.ButtonState[NeptuneControllerButton.BtnOptions];
Inputs.ButtonState[ButtonFlags.Back] = input.State.ButtonState[NeptuneControllerButton.BtnMenu];
@@ -163,19 +116,22 @@ public override void UpdateInputs(long ticks)
var L2 = input.State.AxesState[NeptuneControllerAxis.L2] * byte.MaxValue / short.MaxValue;
var R2 = input.State.AxesState[NeptuneControllerAxis.R2] * byte.MaxValue / short.MaxValue;
- Inputs.ButtonState[ButtonFlags.L2] = L2 > Gamepad.TriggerThreshold;
- Inputs.ButtonState[ButtonFlags.R2] = R2 > Gamepad.TriggerThreshold;
+ Inputs.ButtonState[ButtonFlags.L2Soft] = L2 > Gamepad.TriggerThreshold;
+ Inputs.ButtonState[ButtonFlags.R2Soft] = R2 > Gamepad.TriggerThreshold;
- Inputs.ButtonState[ButtonFlags.L3] = L2 > Gamepad.TriggerThreshold * 8;
- Inputs.ButtonState[ButtonFlags.R3] = R2 > Gamepad.TriggerThreshold * 8;
+ Inputs.ButtonState[ButtonFlags.L2Full] = L2 > Gamepad.TriggerThreshold * 8;
+ Inputs.ButtonState[ButtonFlags.R2Full] = R2 > Gamepad.TriggerThreshold * 8;
- Inputs.ButtonState[ButtonFlags.LeftThumbTouch] =
+ Inputs.AxisState[AxisFlags.L2] = (short)L2;
+ Inputs.AxisState[AxisFlags.R2] = (short)R2;
+
+ Inputs.ButtonState[ButtonFlags.LeftStickTouch] =
input.State.ButtonState[NeptuneControllerButton.BtnLStickTouch];
- Inputs.ButtonState[ButtonFlags.RightThumbTouch] =
+ Inputs.ButtonState[ButtonFlags.RightStickTouch] =
input.State.ButtonState[NeptuneControllerButton.BtnRStickTouch];
- Inputs.ButtonState[ButtonFlags.LeftThumb] = input.State.ButtonState[NeptuneControllerButton.BtnLStickPress];
- Inputs.ButtonState[ButtonFlags.RightThumb] = input.State.ButtonState[NeptuneControllerButton.BtnRStickPress];
+ Inputs.ButtonState[ButtonFlags.LeftStickClick] = input.State.ButtonState[NeptuneControllerButton.BtnLStickPress];
+ Inputs.ButtonState[ButtonFlags.RightStickClick] = input.State.ButtonState[NeptuneControllerButton.BtnRStickPress];
Inputs.ButtonState[ButtonFlags.L1] = input.State.ButtonState[NeptuneControllerButton.BtnL1];
Inputs.ButtonState[ButtonFlags.R1] = input.State.ButtonState[NeptuneControllerButton.BtnR1];
@@ -184,40 +140,53 @@ public override void UpdateInputs(long ticks)
Inputs.ButtonState[ButtonFlags.L5] = input.State.ButtonState[NeptuneControllerButton.BtnL5];
Inputs.ButtonState[ButtonFlags.R5] = input.State.ButtonState[NeptuneControllerButton.BtnR5];
- Inputs.ButtonState[ButtonFlags.DPadUp] = input.State.ButtonState[NeptuneControllerButton.BtnDpadUp];
- Inputs.ButtonState[ButtonFlags.DPadDown] = input.State.ButtonState[NeptuneControllerButton.BtnDpadDown];
- Inputs.ButtonState[ButtonFlags.DPadLeft] = input.State.ButtonState[NeptuneControllerButton.BtnDpadLeft];
- Inputs.ButtonState[ButtonFlags.DPadRight] = input.State.ButtonState[NeptuneControllerButton.BtnDpadRight];
-
// Left Stick
- Inputs.ButtonState[ButtonFlags.LeftThumbLeft] =
+ Inputs.ButtonState[ButtonFlags.LeftStickUp] = input.State.ButtonState[NeptuneControllerButton.BtnLStickTouch];
+ Inputs.ButtonState[ButtonFlags.LeftStickClick] = input.State.ButtonState[NeptuneControllerButton.BtnLStickPress];
+
+ Inputs.AxisState[AxisFlags.LeftStickX] = input.State.AxesState[NeptuneControllerAxis.LeftStickX];
+ Inputs.AxisState[AxisFlags.LeftStickY] = input.State.AxesState[NeptuneControllerAxis.LeftStickY];
+
+ Inputs.ButtonState[ButtonFlags.LeftStickLeft] =
input.State.AxesState[NeptuneControllerAxis.LeftStickX] < -Gamepad.LeftThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.LeftThumbRight] =
+ Inputs.ButtonState[ButtonFlags.LeftStickRight] =
input.State.AxesState[NeptuneControllerAxis.LeftStickX] > Gamepad.LeftThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.LeftThumbDown] =
+ Inputs.ButtonState[ButtonFlags.LeftStickDown] =
input.State.AxesState[NeptuneControllerAxis.LeftStickY] < -Gamepad.LeftThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.LeftThumbUp] =
+ Inputs.ButtonState[ButtonFlags.LeftStickUp] =
input.State.AxesState[NeptuneControllerAxis.LeftStickY] > Gamepad.LeftThumbDeadZone;
- Inputs.AxisState[AxisFlags.LeftThumbX] = input.State.AxesState[NeptuneControllerAxis.LeftStickX];
- Inputs.AxisState[AxisFlags.LeftThumbY] = input.State.AxesState[NeptuneControllerAxis.LeftStickY];
+ // TODO: Implement Inner/Outer Ring button mappings for sticks
+ // https://github.com/Havner/HandheldCompanion/commit/e1124ceb6c59051201756d5e95b2eb39a3bb24f6
+
+ /* float leftLength = new Vector2(Inputs.AxisState[AxisFlags.LeftStickX], Inputs.AxisState[AxisFlags.LeftStickY]).Length();
+ Inputs.ButtonState[ButtonFlags.LeftStickOuterRing] = leftLength >= (RingThreshold * short.MaxValue);
+ Inputs.ButtonState[ButtonFlags.LeftStickInnerRing] = leftLength >= Gamepad.LeftThumbDeadZone && leftLength < (RingThreshold * short.MaxValue); */
// Right Stick
- Inputs.ButtonState[ButtonFlags.RightThumbLeft] =
+ Inputs.ButtonState[ButtonFlags.RightStickTouch] = input.State.ButtonState[NeptuneControllerButton.BtnRStickTouch];
+ Inputs.ButtonState[ButtonFlags.RightStickClick] = input.State.ButtonState[NeptuneControllerButton.BtnRStickPress];
+
+ Inputs.AxisState[AxisFlags.RightStickX] = input.State.AxesState[NeptuneControllerAxis.RightStickX];
+ Inputs.AxisState[AxisFlags.RightStickY] = input.State.AxesState[NeptuneControllerAxis.RightStickY];
+
+ Inputs.ButtonState[ButtonFlags.RightStickLeft] =
input.State.AxesState[NeptuneControllerAxis.RightStickX] < -Gamepad.RightThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.RightThumbRight] =
+ Inputs.ButtonState[ButtonFlags.RightStickRight] =
input.State.AxesState[NeptuneControllerAxis.RightStickX] > Gamepad.RightThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.RightThumbDown] =
+ Inputs.ButtonState[ButtonFlags.RightStickDown] =
input.State.AxesState[NeptuneControllerAxis.RightStickY] < -Gamepad.RightThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.RightThumbUp] =
+ Inputs.ButtonState[ButtonFlags.RightStickUp] =
input.State.AxesState[NeptuneControllerAxis.RightStickY] > Gamepad.RightThumbDeadZone;
- Inputs.AxisState[AxisFlags.RightThumbX] = input.State.AxesState[NeptuneControllerAxis.RightStickX];
- Inputs.AxisState[AxisFlags.RightThumbY] = input.State.AxesState[NeptuneControllerAxis.RightStickY];
+ // TODO: Implement Inner/Outer Ring button mappings for sticks
+ // https://github.com/Havner/HandheldCompanion/commit/e1124ceb6c59051201756d5e95b2eb39a3bb24f6
- Inputs.AxisState[AxisFlags.L2] = (short)L2;
- Inputs.AxisState[AxisFlags.R2] = (short)R2;
+ /* float rightLength = new Vector2(Inputs.AxisState[AxisFlags.RightStickX], Inputs.AxisState[AxisFlags.RightStickY]).Length();
+ Inputs.ButtonState[ButtonFlags.RightStickOuterRing] = rightLength >= (RingThreshold * short.MaxValue);
+ Inputs.ButtonState[ButtonFlags.RightStickInnerRing] = rightLength >= Gamepad.RightThumbDeadZone && rightLength < (RingThreshold * short.MaxValue); */
+ // Left Pad
Inputs.ButtonState[ButtonFlags.LeftPadTouch] = input.State.ButtonState[NeptuneControllerButton.BtnLPadTouch];
if (input.State.ButtonState[NeptuneControllerButton.BtnLPadTouch])
{
@@ -233,17 +202,20 @@ public override void UpdateInputs(long ticks)
Inputs.ButtonState[ButtonFlags.LeftPadClick] = input.State.ButtonState[NeptuneControllerButton.BtnLPadPress];
if (Inputs.ButtonState[ButtonFlags.LeftPadClick])
{
- if (Inputs.AxisState[AxisFlags.LeftPadY] >= TrackPadInner)
- Inputs.ButtonState[ButtonFlags.LeftPadClickUp] = true;
- else if (Inputs.AxisState[AxisFlags.LeftPadY] <= -TrackPadInner)
- Inputs.ButtonState[ButtonFlags.LeftPadClickDown] = true;
-
- if (Inputs.AxisState[AxisFlags.LeftPadX] >= TrackPadInner)
- Inputs.ButtonState[ButtonFlags.LeftPadClickRight] = true;
- else if (Inputs.AxisState[AxisFlags.LeftPadX] <= -TrackPadInner)
- Inputs.ButtonState[ButtonFlags.LeftPadClickLeft] = true;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickUp] = Inputs.AxisState[AxisFlags.LeftPadY] >= TrackPadInner;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickDown] = Inputs.AxisState[AxisFlags.LeftPadY] <= -TrackPadInner;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickRight] = Inputs.AxisState[AxisFlags.LeftPadX] >= TrackPadInner;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickLeft] = Inputs.AxisState[AxisFlags.LeftPadX] <= -TrackPadInner;
+ }
+ else
+ {
+ Inputs.ButtonState[ButtonFlags.LeftPadClickUp] = false;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickDown] = false;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickRight] = false;
+ Inputs.ButtonState[ButtonFlags.LeftPadClickLeft] = false;
}
+ // Right Pad
Inputs.ButtonState[ButtonFlags.RightPadTouch] = input.State.ButtonState[NeptuneControllerButton.BtnRPadTouch];
if (input.State.ButtonState[NeptuneControllerButton.BtnRPadTouch])
{
@@ -259,74 +231,30 @@ public override void UpdateInputs(long ticks)
Inputs.ButtonState[ButtonFlags.RightPadClick] = input.State.ButtonState[NeptuneControllerButton.BtnRPadPress];
if (Inputs.ButtonState[ButtonFlags.RightPadClick])
{
- if (Inputs.AxisState[AxisFlags.RightPadY] >= TrackPadInner)
- Inputs.ButtonState[ButtonFlags.RightPadClickUp] = true;
- else if (Inputs.AxisState[AxisFlags.RightPadY] <= -TrackPadInner)
- Inputs.ButtonState[ButtonFlags.RightPadClickDown] = true;
-
- if (Inputs.AxisState[AxisFlags.RightPadX] >= TrackPadInner)
- Inputs.ButtonState[ButtonFlags.RightPadClickRight] = true;
- else if (Inputs.AxisState[AxisFlags.RightPadX] <= -TrackPadInner)
- Inputs.ButtonState[ButtonFlags.RightPadClickLeft] = true;
+ Inputs.ButtonState[ButtonFlags.RightPadClickUp] = Inputs.AxisState[AxisFlags.RightPadY] >= TrackPadInner;
+ Inputs.ButtonState[ButtonFlags.RightPadClickDown] = Inputs.AxisState[AxisFlags.RightPadY] <= -TrackPadInner;
+ Inputs.ButtonState[ButtonFlags.RightPadClickRight] = Inputs.AxisState[AxisFlags.RightPadX] >= TrackPadInner;
+ Inputs.ButtonState[ButtonFlags.RightPadClickLeft] = Inputs.AxisState[AxisFlags.RightPadX] <= -TrackPadInner;
+ }
+ else
+ {
+ Inputs.ButtonState[ButtonFlags.RightPadClickUp] = false;
+ Inputs.ButtonState[ButtonFlags.RightPadClickDown] = false;
+ Inputs.ButtonState[ButtonFlags.RightPadClickRight] = false;
+ Inputs.ButtonState[ButtonFlags.RightPadClickLeft] = false;
}
- // update states
- prevState = input.State;
-
- base.UpdateInputs(ticks);
- }
-
- public override void UpdateMovements(long ticks)
- {
- if (input is null)
- return;
-
- Movements.GyroAccelZ = -(float)input.State.AxesState[NeptuneControllerAxis.GyroAccelY] / short.MaxValue * 2.0f;
- Movements.GyroAccelY = -(float)input.State.AxesState[NeptuneControllerAxis.GyroAccelZ] / short.MaxValue * 2.0f;
- Movements.GyroAccelX = -(float)input.State.AxesState[NeptuneControllerAxis.GyroAccelX] / short.MaxValue * 2.0f;
-
- Movements.GyroPitch = -(float)input.State.AxesState[NeptuneControllerAxis.GyroRoll] / short.MaxValue * 2000.0f;
- Movements.GyroRoll = (float)input.State.AxesState[NeptuneControllerAxis.GyroPitch] / short.MaxValue * 2000.0f;
- Movements.GyroYaw = -(float)input.State.AxesState[NeptuneControllerAxis.GyroYaw] / short.MaxValue * 2000.0f;
-
- base.UpdateMovements(ticks);
- }
-
- public override bool IsConnected()
- {
- return isConnected;
- }
-
- public bool IsLizardMouseEnabled()
- {
- return Controller.LizardMouseEnabled;
- }
+ // TODO: why Z/Y swapped?
+ Inputs.GyroState.Accelerometer.X = -(float)input.State.AxesState[NeptuneControllerAxis.GyroAccelX] / short.MaxValue * 2.0f;
+ Inputs.GyroState.Accelerometer.Y = -(float)input.State.AxesState[NeptuneControllerAxis.GyroAccelZ] / short.MaxValue * 2.0f;
+ Inputs.GyroState.Accelerometer.Z = -(float)input.State.AxesState[NeptuneControllerAxis.GyroAccelY] / short.MaxValue * 2.0f;
- public bool IsLizardButtonsEnabled()
- {
- return Controller.LizardButtonsEnabled;
- }
+ // TODO: why Roll/Pitch swapped?
+ Inputs.GyroState.Gyroscope.X = (float)input.State.AxesState[NeptuneControllerAxis.GyroPitch] / short.MaxValue * 2048.0f; // Roll
+ Inputs.GyroState.Gyroscope.Y = -(float)input.State.AxesState[NeptuneControllerAxis.GyroRoll] / short.MaxValue * 2048.0f; // Pitch
+ Inputs.GyroState.Gyroscope.Z = -(float)input.State.AxesState[NeptuneControllerAxis.GyroYaw] / short.MaxValue * 2048.0f; // Yaw
- public virtual bool IsVirtualMuted()
- {
- return isVirtualMuted;
- }
-
- public override void Rumble(int Loop = 1, byte LeftValue = byte.MaxValue, byte RightValue = byte.MaxValue,
- byte Duration = 125)
- {
- Task.Factory.StartNew(async () =>
- {
- for (var i = 0; i < Loop * 2; i++)
- {
- if (i % 2 == 0)
- SetVibration(LeftValue, RightValue);
- else
- SetVibration(0, 0);
-
- await Task.Delay(Duration);
- }
- });
+ base.UpdateInputs(ticks);
}
private void Open()
@@ -349,27 +277,40 @@ private void Close()
catch { }
}
- public override void Plug()
+ private void OnControllerInputReceived(NeptuneControllerInputEventArgs input)
{
- TimerManager.Tick += UpdateInputs;
- TimerManager.Tick += UpdateMovements;
+ this.input = input;
+ }
+ public override void Plug()
+ {
try
{
+ Controller.OnControllerInputReceived = input => Task.Run(() => OnControllerInputReceived(input));
+
// open controller
Open();
}
- catch { }
+ catch (Exception ex)
+ {
+ LogManager.LogError("Couldn't initialize GordonController. Exception: {0}", ex.Message);
+ return;
+ }
- SetHDRumble(UseHDRumble);
+ // disable lizard state
+ Controller.RequestLizardMode(false);
- PipeClient.ServerMessage += OnServerMessage;
- base.Plug();
- }
+ // manage rumble thread
+ rumbleThreadRunning = true;
+ rumbleThread = new Thread(RumbleThreadLoop);
+ rumbleThread.IsBackground = true;
+ rumbleThread.Start();
- private void OnControllerInputReceived(NeptuneControllerInputEventArgs input)
- {
- this.input = input;
+ SetVirtualMuted(SettingsManager.GetBoolean("SteamControllerMute"));
+
+ TimerManager.Tick += UpdateInputs;
+
+ base.Plug();
}
public override void Unplug()
@@ -377,8 +318,11 @@ public override void Unplug()
try
{
// restore lizard state
- SetLizardButtons(true);
- SetLizardMouse(true);
+ Controller.RequestLizardMode(true);
+
+ // kill rumble thread
+ rumbleThreadRunning = false;
+ rumbleThread.Join();
// close controller
Close();
@@ -389,15 +333,15 @@ public override void Unplug()
}
TimerManager.Tick -= UpdateInputs;
- TimerManager.Tick -= UpdateMovements;
- // kill rumble thread
- RumbleThreadRunning = false;
-
- PipeClient.ServerMessage -= OnServerMessage;
base.Unplug();
}
+ public override void Cleanup()
+ {
+ TimerManager.Tick -= UpdateInputs;
+ }
+
public bool GetHapticIntensity(byte? input, sbyte minIntensity, sbyte maxIntensity, out sbyte output)
{
output = default;
@@ -409,197 +353,35 @@ public bool GetHapticIntensity(byte? input, sbyte minIntensity, sbyte maxIntensi
return true;
}
- public override void SetVibrationStrength(double value, bool rumble)
- {
- base.SetVibrationStrength(value, rumble);
- if (rumble)
- Rumble();
- }
-
public override void SetVibration(byte LargeMotor, byte SmallMotor)
{
- FeedbackLargeMotor = LargeMotor;
- FeedbackSmallMotor = SmallMotor;
-
- if (!UseHDRumble)
- SetHaptic();
- }
-
- public void SetHaptic()
- {
- GetHapticIntensity(FeedbackLargeMotor, SDRumbleMinIntensity, SDRumbleMaxIntensity, out var leftIntensity);
- _ = Controller.SetHaptic((byte)HapticPad.Left, (ushort)leftIntensity, SDRumblePeriod, 0);
-
- GetHapticIntensity(FeedbackSmallMotor, SDRumbleMinIntensity, SDRumbleMaxIntensity, out var rightIntensity);
- _ = Controller.SetHaptic((byte)HapticPad.Right, (ushort)rightIntensity, SDRumblePeriod, 0);
- }
-
- private void OnServerMessage(PipeMessage message)
- {
- switch (message.code)
- {
- case PipeCode.SERVER_VIBRATION:
- {
- var e = (PipeClientVibration)message;
- SetVibration(e.LargeMotor, e.SmallMotor);
- }
- break;
- }
- }
-
- public void SetLizardMouse(bool lizardMode)
- {
- Controller.LizardMouseEnabled = lizardMode;
- }
-
- public void SetLizardButtons(bool lizardMode)
- {
- Controller.LizardButtonsEnabled = lizardMode;
+ this.FeedbackLargeMotor = LargeMotor;
+ this.FeedbackSmallMotor = SmallMotor;
}
- public void SetVirtualMuted(bool mute)
+ private async void RumbleThreadLoop(object? obj)
{
- isVirtualMuted = mute;
- }
-
- public void SetHDRumble(bool HDRumble)
- {
- UseHDRumble = HDRumble;
-
- if (!IsPlugged())
- return;
-
- switch (UseHDRumble)
- {
- // new engine
- default:
- case true:
- {
- if (RumbleThreadRunning)
- return;
-
- RumbleThreadRunning = true;
-
- // Create Haptic2 rumble thread
- RumbleThread = new Thread(ThreadLoop)
- {
- IsBackground = true
- };
-
- RumbleThread.Start();
- }
- break;
-
- // old engine
- case false:
- {
- if (!RumbleThreadRunning)
- return;
-
- RumbleThreadRunning = false;
- }
- break;
- }
- }
-
- public override string GetGlyph(ButtonFlags button)
- {
- switch (button)
+ while (rumbleThreadRunning)
{
- case ButtonFlags.B1:
- return "\u21D3"; // Button A
- case ButtonFlags.B2:
- return "\u21D2"; // Button B
- case ButtonFlags.B3:
- return "\u21D0"; // Button X
- case ButtonFlags.B4:
- return "\u21D1"; // Button Y
- case ButtonFlags.L1:
- return "\u21B0";
- case ButtonFlags.R1:
- return "\u21B1";
- case ButtonFlags.Back:
- return "\u21FA";
- case ButtonFlags.Start:
- return "\u21FB";
- case ButtonFlags.L2:
- case ButtonFlags.L3:
- return "\u21B2";
- case ButtonFlags.R2:
- case ButtonFlags.R3:
- return "\u21B3";
- case ButtonFlags.L4:
- return "\u219c\u24f8";
- case ButtonFlags.L5:
- return "\u219c\u24f9";
- case ButtonFlags.R4:
- return "\u219d\u24f8";
- case ButtonFlags.R5:
- return "\u219d\u24f9";
- case ButtonFlags.Special:
- return "\u21E4";
- case ButtonFlags.OEM1:
- return "\u21E5";
- case ButtonFlags.LeftThumbTouch:
- return "\u21DA";
- case ButtonFlags.RightThumbTouch:
- return "\u21DB";
- case ButtonFlags.LeftPadTouch:
- return "\u2268";
- case ButtonFlags.RightPadTouch:
- return "\u2269";
- case ButtonFlags.LeftPadClick:
- return "\u2266";
- case ButtonFlags.RightPadClick:
- return "\u2267";
- case ButtonFlags.LeftPadClickUp:
- return "\u2270";
- case ButtonFlags.LeftPadClickDown:
- return "\u2274";
- case ButtonFlags.LeftPadClickLeft:
- return "\u226E";
- case ButtonFlags.LeftPadClickRight:
- return "\u2272";
- case ButtonFlags.RightPadClickUp:
- return "\u2271";
- case ButtonFlags.RightPadClickDown:
- return "\u2275";
- case ButtonFlags.RightPadClickLeft:
- return "\u226F";
- case ButtonFlags.RightPadClickRight:
- return "\u2273";
- }
+ if (GetHapticIntensity(FeedbackLargeMotor, MinIntensity, MaxIntensity, out var leftIntensity))
+ Controller.SetHaptic2(SCHapticMotor.Left, NCHapticStyle.Weak, leftIntensity);
- return base.GetGlyph(button);
- }
+ if (GetHapticIntensity(FeedbackSmallMotor, MinIntensity, MaxIntensity, out var rightIntensity))
+ Controller.SetHaptic2(SCHapticMotor.Right, NCHapticStyle.Weak, rightIntensity);
- public override string GetGlyph(AxisFlags axis)
- {
- switch (axis)
- {
- case AxisFlags.L2:
- return "\u2196";
- case AxisFlags.R2:
- return "\u2197";
+ await Task.Delay(TimerManager.GetPeriod() * 2);
}
-
- return base.GetGlyph(axis);
}
- public override string GetGlyph(AxisLayoutFlags axis)
+ public override void SetHaptic(HapticStrength strength, ButtonFlags button)
{
- switch (axis)
+ ushort value = strength switch
{
- case AxisLayoutFlags.L2:
- return "\u2196";
- case AxisLayoutFlags.R2:
- return "\u2197";
- case AxisLayoutFlags.LeftPad:
- return "\u2264";
- case AxisLayoutFlags.RightPad:
- return "\u2265";
- }
-
- return base.GetGlyph(axis);
+ HapticStrength.Low => 512,
+ HapticStrength.Medium => 1024,
+ HapticStrength.High => 2048,
+ _ => 0,
+ };
+ Controller.SetHaptic((byte)GetMotorForButton(button), value, 0, 1);
}
}
\ No newline at end of file
diff --git a/HandheldCompanion/Controllers/ProController.cs b/HandheldCompanion/Controllers/ProController.cs
new file mode 100644
index 000000000..7e3dda98b
--- /dev/null
+++ b/HandheldCompanion/Controllers/ProController.cs
@@ -0,0 +1,118 @@
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Managers;
+using HandheldCompanion.Utils;
+using static JSL;
+
+namespace HandheldCompanion.Controllers;
+
+public class ProController : JSController
+{
+ public ProController()
+ {
+ }
+
+ public ProController(JOY_SETTINGS settings, PnPDetails details) : base(settings, details)
+ {
+ // Additional controller specific source buttons
+ SourceButtons.Add(ButtonFlags.Special2);
+ SourceAxis.Add(AxisLayoutFlags.Gyroscope);
+ }
+
+ public override void UpdateInputs(long ticks)
+ {
+ // skip if controller isn't connected
+ if (!IsConnected())
+ return;
+
+ base.UpdateState();
+
+ Inputs.ButtonState[ButtonFlags.Special2] = BitwiseUtils.HasByteSet(sTATE.buttons, ButtonMaskCapture);
+
+ base.UpdateInputs(ticks);
+ }
+
+ public override void Plug()
+ {
+ TimerManager.Tick += UpdateInputs;
+ base.Plug();
+ }
+
+ public override void Unplug()
+ {
+ TimerManager.Tick -= UpdateInputs;
+ base.Unplug();
+ }
+
+ public override void Cleanup()
+ {
+ TimerManager.Tick -= UpdateInputs;
+ }
+
+ public override void SetVibration(byte LargeMotor, byte SmallMotor)
+ {
+ // HD rumble isn't yet supported
+ }
+
+ public override string GetGlyph(ButtonFlags button)
+ {
+ switch (button)
+ {
+ case ButtonFlags.B1:
+ return "\u21D2"; // B
+ case ButtonFlags.B2:
+ return "\u21D3"; // A
+ case ButtonFlags.B3:
+ return "\u21D1"; // Y
+ case ButtonFlags.B4:
+ return "\u21D0"; // X
+ case ButtonFlags.L1:
+ return "\u219C";
+ case ButtonFlags.R1:
+ return "\u219D";
+ case ButtonFlags.Back:
+ return "\u21FD";
+ case ButtonFlags.Start:
+ return "\u21FE";
+ case ButtonFlags.L2Soft:
+ return "\u219A";
+ case ButtonFlags.L2Full:
+ return "\u219A";
+ case ButtonFlags.R2Soft:
+ return "\u219B";
+ case ButtonFlags.R2Full:
+ return "\u219B";
+ case ButtonFlags.Special:
+ return "\u21F9";
+ case ButtonFlags.Special2:
+ return "\u21FA";
+ }
+
+ return base.GetGlyph(button);
+ }
+
+ public override string GetGlyph(AxisFlags axis)
+ {
+ switch (axis)
+ {
+ case AxisFlags.L2:
+ return "\u219A";
+ case AxisFlags.R2:
+ return "\u219B";
+ }
+
+ return base.GetGlyph(axis);
+ }
+
+ public override string GetGlyph(AxisLayoutFlags axis)
+ {
+ switch (axis)
+ {
+ case AxisLayoutFlags.L2:
+ return "\u219A";
+ case AxisLayoutFlags.R2:
+ return "\u219B";
+ }
+
+ return base.GetGlyph(axis);
+ }
+}
\ No newline at end of file
diff --git a/HandheldCompanion/Controllers/SteamController.cs b/HandheldCompanion/Controllers/SteamController.cs
new file mode 100644
index 000000000..59283f53a
--- /dev/null
+++ b/HandheldCompanion/Controllers/SteamController.cs
@@ -0,0 +1,203 @@
+using HandheldCompanion.Inputs;
+using steam_hidapi.net.Hid;
+
+namespace HandheldCompanion.Controllers
+{
+ public abstract class SteamController : IController
+ {
+ protected bool isConnected = false;
+ protected bool isVirtualMuted = false;
+
+ public SteamController() : base()
+ {
+ Capabilities |= ControllerCapabilities.MotionSensor;
+ }
+
+ public override bool IsConnected()
+ {
+ return isConnected;
+ }
+
+ public virtual bool IsVirtualMuted()
+ {
+ return isVirtualMuted;
+ }
+
+ public virtual void SetVirtualMuted(bool mute)
+ {
+ isVirtualMuted = mute;
+ }
+
+ public override string GetGlyph(ButtonFlags button)
+ {
+ switch (button)
+ {
+ case ButtonFlags.B1:
+ return "\u21D3"; // Button A
+ case ButtonFlags.B2:
+ return "\u21D2"; // Button B
+ case ButtonFlags.B3:
+ return "\u21D0"; // Button X
+ case ButtonFlags.B4:
+ return "\u21D1"; // Button Y
+ case ButtonFlags.L1:
+ return "\u21B0";
+ case ButtonFlags.R1:
+ return "\u21B1";
+ case ButtonFlags.Back:
+ return "\u21FA";
+ case ButtonFlags.Start:
+ return "\u21FB";
+ case ButtonFlags.L2Soft:
+ case ButtonFlags.L2Full:
+ return "\u21B2";
+ case ButtonFlags.R2Soft:
+ case ButtonFlags.R2Full:
+ return "\u21B3";
+ case ButtonFlags.L4:
+ return "\u219c\u24f8";
+ case ButtonFlags.L5:
+ return "\u219c\u24f9";
+ case ButtonFlags.R4:
+ return "\u219d\u24f8";
+ case ButtonFlags.R5:
+ return "\u219d\u24f9";
+ case ButtonFlags.Special:
+ return "\u21E4";
+ case ButtonFlags.OEM1:
+ return "\u21E5";
+ case ButtonFlags.LeftStickTouch:
+ return "\u21DA";
+ case ButtonFlags.RightStickTouch:
+ return "\u21DB";
+ case ButtonFlags.LeftPadTouch:
+ return "\u2268";
+ case ButtonFlags.RightPadTouch:
+ return "\u2269";
+ case ButtonFlags.LeftPadClick:
+ return "\u2266";
+ case ButtonFlags.RightPadClick:
+ return "\u2267";
+ case ButtonFlags.LeftPadClickUp:
+ return "\u2270";
+ case ButtonFlags.LeftPadClickDown:
+ return "\u2274";
+ case ButtonFlags.LeftPadClickLeft:
+ return "\u226E";
+ case ButtonFlags.LeftPadClickRight:
+ return "\u2272";
+ case ButtonFlags.RightPadClickUp:
+ return "\u2271";
+ case ButtonFlags.RightPadClickDown:
+ return "\u2275";
+ case ButtonFlags.RightPadClickLeft:
+ return "\u226F";
+ case ButtonFlags.RightPadClickRight:
+ return "\u2273";
+ }
+
+ return base.GetGlyph(button);
+ }
+
+ public override string GetGlyph(AxisFlags axis)
+ {
+ switch (axis)
+ {
+ case AxisFlags.L2:
+ return "\u2196";
+ case AxisFlags.R2:
+ return "\u2197";
+ }
+
+ return base.GetGlyph(axis);
+ }
+
+ public override string GetGlyph(AxisLayoutFlags axis)
+ {
+ switch (axis)
+ {
+ case AxisLayoutFlags.L2:
+ return "\u2196";
+ case AxisLayoutFlags.R2:
+ return "\u2197";
+ case AxisLayoutFlags.LeftPad:
+ return "\u2264";
+ case AxisLayoutFlags.RightPad:
+ return "\u2265";
+ case AxisLayoutFlags.Gyroscope:
+ return "\u2B94";
+ }
+
+ return base.GetGlyph(axis);
+ }
+
+ protected virtual SCHapticMotor GetMotorForButton(ButtonFlags button)
+ {
+ switch (button)
+ {
+ case ButtonFlags.DPadUp:
+ case ButtonFlags.DPadDown:
+ case ButtonFlags.DPadLeft:
+ case ButtonFlags.DPadRight:
+ case ButtonFlags.L1:
+ case ButtonFlags.L2Soft:
+ case ButtonFlags.L2Full:
+ case ButtonFlags.L4:
+ case ButtonFlags.L5:
+
+ case ButtonFlags.Back:
+ case ButtonFlags.Special:
+
+ case ButtonFlags.LeftStickTouch:
+ case ButtonFlags.LeftStickClick:
+ case ButtonFlags.LeftStickUp:
+ case ButtonFlags.LeftStickDown:
+ case ButtonFlags.LeftStickLeft:
+ case ButtonFlags.LeftStickRight:
+
+ case ButtonFlags.LeftPadTouch:
+ case ButtonFlags.LeftPadClick:
+ case ButtonFlags.LeftPadClickUp:
+ case ButtonFlags.LeftPadClickDown:
+ case ButtonFlags.LeftPadClickLeft:
+ case ButtonFlags.LeftPadClickRight:
+
+ return SCHapticMotor.Left;
+
+ case ButtonFlags.B1:
+ case ButtonFlags.B2:
+ case ButtonFlags.B3:
+ case ButtonFlags.B4:
+
+ case ButtonFlags.R1:
+ case ButtonFlags.R2Soft:
+ case ButtonFlags.R2Full:
+ case ButtonFlags.R4:
+ case ButtonFlags.R5:
+
+ case ButtonFlags.Start:
+ case ButtonFlags.OEM1: // STEAM
+
+ case ButtonFlags.RightStickTouch:
+ case ButtonFlags.RightStickClick:
+ case ButtonFlags.RightStickUp:
+ case ButtonFlags.RightStickDown:
+ case ButtonFlags.RightStickLeft:
+ case ButtonFlags.RightStickRight:
+
+ case ButtonFlags.RightPadTouch:
+ case ButtonFlags.RightPadClick:
+ case ButtonFlags.RightPadClickUp:
+ case ButtonFlags.RightPadClickDown:
+ case ButtonFlags.RightPadClickLeft:
+ case ButtonFlags.RightPadClickRight:
+
+ return SCHapticMotor.Right;
+
+ default:
+ throw new System.Exception(string.Format("Button 2 Rumble button missing: {0}", button.ToString()));
+
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/HandheldCompanion/Controllers/XInputController.cs b/HandheldCompanion/Controllers/XInputController.cs
index b090a39f1..a35718e67 100644
--- a/HandheldCompanion/Controllers/XInputController.cs
+++ b/HandheldCompanion/Controllers/XInputController.cs
@@ -1,19 +1,16 @@
+using HandheldCompanion.Inputs;
+using HandheldCompanion.Managers;
+using SharpDX.XInput;
using System;
using System.Linq;
using System.Runtime.InteropServices;
-using System.Threading.Tasks;
using System.Windows.Media;
-using ControllerCommon.Controllers;
-using ControllerCommon.Inputs;
-using ControllerCommon.Managers;
-using ControllerCommon.Pipes;
-using SharpDX.XInput;
namespace HandheldCompanion.Controllers;
public class XInputController : IController
{
- private readonly Controller Controller;
+ private Controller Controller;
private Gamepad Gamepad;
private GamepadButtonFlags prevButtons;
@@ -23,14 +20,9 @@ public class XInputController : IController
public XInputController()
{
- // UI
- ColoredButtons.Add(ButtonFlags.B1, new SolidColorBrush(Color.FromArgb(255, 81, 191, 61)));
- ColoredButtons.Add(ButtonFlags.B2, new SolidColorBrush(Color.FromArgb(255, 217, 65, 38)));
- ColoredButtons.Add(ButtonFlags.B3, new SolidColorBrush(Color.FromArgb(255, 26, 159, 255)));
- ColoredButtons.Add(ButtonFlags.B4, new SolidColorBrush(Color.FromArgb(255, 255, 200, 44)));
}
- public XInputController(Controller controller) : this()
+ public XInputController(Controller controller, PnPDetails details) : this()
{
Controller = controller;
UserIndex = (int)controller.UserIndex;
@@ -38,33 +30,29 @@ public XInputController(Controller controller) : this()
if (!IsConnected())
return;
- // pull data from xinput
- var CapabilitiesEx = new XInputCapabilitiesEx();
-
- if (XInputGetCapabilitiesEx(1, UserIndex, 0, ref CapabilitiesEx) == 0)
- {
- var ProductId = CapabilitiesEx.ProductId.ToString("X4");
- var VendorId = CapabilitiesEx.VendorId.ToString("X4");
-
- var devices = DeviceManager.GetDetails(CapabilitiesEx.VendorId, CapabilitiesEx.ProductId);
- Details = devices.FirstOrDefault();
- }
-
- var BusInformation = new XInputBaseBusInformation();
-
- if (XInputGetBaseBusInformation(UserIndex, ref BusInformation) == 0)
- {
- }
-
+ this.Details = details;
if (Details is null)
return;
Details.isHooked = true;
+ // UI
+ ColoredButtons.Add(ButtonFlags.B1, new SolidColorBrush(Color.FromArgb(255, 81, 191, 61)));
+ ColoredButtons.Add(ButtonFlags.B2, new SolidColorBrush(Color.FromArgb(255, 217, 65, 38)));
+ ColoredButtons.Add(ButtonFlags.B3, new SolidColorBrush(Color.FromArgb(255, 26, 159, 255)));
+ ColoredButtons.Add(ButtonFlags.B4, new SolidColorBrush(Color.FromArgb(255, 255, 200, 44)));
+
+ InitializeComponent();
DrawControls();
RefreshControls();
}
+ public void UpdateController(Controller controller)
+ {
+ Controller = controller;
+ UserIndex = (int)controller.UserIndex;
+ }
+
public override string ToString()
{
var baseName = base.ToString();
@@ -79,70 +67,74 @@ public override void UpdateInputs(long ticks)
if (!IsConnected())
return;
- // update gamepad state
- Gamepad = Controller.GetState().Gamepad;
+ try
+ {
+ // update gamepad state
+ Gamepad = Controller.GetState().Gamepad;
- // update secret state
- XInputGetStateSecret14(UserIndex, out State);
+ // update secret state
+ XInputGetStateSecret14(UserIndex, out State);
- /*
- if (prevButtons.Equals(Gamepad.Buttons) && State.wButtons.Equals(prevState.wButtons) && prevInjectedButtons.Equals(InjectedButtons))
- return;
- */
+ /*
+ if (prevButtons.Equals(Gamepad.Buttons) && State.wButtons.Equals(prevState.wButtons) && prevInjectedButtons.Equals(InjectedButtons))
+ return;
+ */
- Inputs.ButtonState = InjectedButtons.Clone() as ButtonState;
+ Inputs.ButtonState = InjectedButtons.Clone() as ButtonState;
- Inputs.ButtonState[ButtonFlags.B1] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.A);
- Inputs.ButtonState[ButtonFlags.B2] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.B);
- Inputs.ButtonState[ButtonFlags.B3] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.X);
- Inputs.ButtonState[ButtonFlags.B4] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.Y);
+ Inputs.ButtonState[ButtonFlags.B1] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.A);
+ Inputs.ButtonState[ButtonFlags.B2] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.B);
+ Inputs.ButtonState[ButtonFlags.B3] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.X);
+ Inputs.ButtonState[ButtonFlags.B4] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.Y);
- Inputs.ButtonState[ButtonFlags.Start] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.Start);
- Inputs.ButtonState[ButtonFlags.Back] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.Back);
+ Inputs.ButtonState[ButtonFlags.Start] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.Start);
+ Inputs.ButtonState[ButtonFlags.Back] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.Back);
- Inputs.ButtonState[ButtonFlags.L2] = Gamepad.LeftTrigger > Gamepad.TriggerThreshold;
- Inputs.ButtonState[ButtonFlags.R2] = Gamepad.RightTrigger > Gamepad.TriggerThreshold;
+ Inputs.ButtonState[ButtonFlags.L2Soft] = Gamepad.LeftTrigger > Gamepad.TriggerThreshold;
+ Inputs.ButtonState[ButtonFlags.R2Soft] = Gamepad.RightTrigger > Gamepad.TriggerThreshold;
- Inputs.ButtonState[ButtonFlags.L3] = Gamepad.LeftTrigger > Gamepad.TriggerThreshold * 8;
- Inputs.ButtonState[ButtonFlags.R3] = Gamepad.RightTrigger > Gamepad.TriggerThreshold * 8;
+ Inputs.ButtonState[ButtonFlags.L2Full] = Gamepad.LeftTrigger > Gamepad.TriggerThreshold * 8;
+ Inputs.ButtonState[ButtonFlags.R2Full] = Gamepad.RightTrigger > Gamepad.TriggerThreshold * 8;
- Inputs.ButtonState[ButtonFlags.LeftThumb] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.LeftThumb);
- Inputs.ButtonState[ButtonFlags.RightThumb] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.RightThumb);
+ Inputs.ButtonState[ButtonFlags.LeftStickClick] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.LeftThumb);
+ Inputs.ButtonState[ButtonFlags.RightStickClick] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.RightThumb);
- Inputs.ButtonState[ButtonFlags.L1] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.LeftShoulder);
- Inputs.ButtonState[ButtonFlags.R1] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.RightShoulder);
+ Inputs.ButtonState[ButtonFlags.L1] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.LeftShoulder);
+ Inputs.ButtonState[ButtonFlags.R1] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.RightShoulder);
- Inputs.ButtonState[ButtonFlags.DPadUp] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.DPadUp);
- Inputs.ButtonState[ButtonFlags.DPadDown] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.DPadDown);
- Inputs.ButtonState[ButtonFlags.DPadLeft] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.DPadLeft);
- Inputs.ButtonState[ButtonFlags.DPadRight] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.DPadRight);
+ Inputs.ButtonState[ButtonFlags.DPadUp] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.DPadUp);
+ Inputs.ButtonState[ButtonFlags.DPadDown] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.DPadDown);
+ Inputs.ButtonState[ButtonFlags.DPadLeft] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.DPadLeft);
+ Inputs.ButtonState[ButtonFlags.DPadRight] = Gamepad.Buttons.HasFlag(GamepadButtonFlags.DPadRight);
- // Left Stick
- Inputs.ButtonState[ButtonFlags.LeftThumbLeft] = Gamepad.LeftThumbX < -Gamepad.LeftThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.LeftThumbRight] = Gamepad.LeftThumbX > Gamepad.LeftThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.LeftThumbDown] = Gamepad.LeftThumbY < -Gamepad.LeftThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.LeftThumbUp] = Gamepad.LeftThumbY > Gamepad.LeftThumbDeadZone;
+ // Left Stick
+ Inputs.ButtonState[ButtonFlags.LeftStickLeft] = Gamepad.LeftThumbX < -Gamepad.LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickRight] = Gamepad.LeftThumbX > Gamepad.LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickDown] = Gamepad.LeftThumbY < -Gamepad.LeftThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.LeftStickUp] = Gamepad.LeftThumbY > Gamepad.LeftThumbDeadZone;
- Inputs.AxisState[AxisFlags.LeftThumbX] = Gamepad.LeftThumbX;
- Inputs.AxisState[AxisFlags.LeftThumbY] = Gamepad.LeftThumbY;
+ Inputs.AxisState[AxisFlags.LeftStickX] = Gamepad.LeftThumbX;
+ Inputs.AxisState[AxisFlags.LeftStickY] = Gamepad.LeftThumbY;
- // Right Stick
- Inputs.ButtonState[ButtonFlags.RightThumbLeft] = Gamepad.RightThumbX < -Gamepad.RightThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.RightThumbRight] = Gamepad.RightThumbX > Gamepad.RightThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.RightThumbDown] = Gamepad.RightThumbY < -Gamepad.RightThumbDeadZone;
- Inputs.ButtonState[ButtonFlags.RightThumbUp] = Gamepad.RightThumbY > Gamepad.RightThumbDeadZone;
+ // Right Stick
+ Inputs.ButtonState[ButtonFlags.RightStickLeft] = Gamepad.RightThumbX < -Gamepad.RightThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.RightStickRight] = Gamepad.RightThumbX > Gamepad.RightThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.RightStickDown] = Gamepad.RightThumbY < -Gamepad.RightThumbDeadZone;
+ Inputs.ButtonState[ButtonFlags.RightStickUp] = Gamepad.RightThumbY > Gamepad.RightThumbDeadZone;
- Inputs.AxisState[AxisFlags.RightThumbX] = Gamepad.RightThumbX;
- Inputs.AxisState[AxisFlags.RightThumbY] = Gamepad.RightThumbY;
+ Inputs.AxisState[AxisFlags.RightStickX] = Gamepad.RightThumbX;
+ Inputs.AxisState[AxisFlags.RightStickY] = Gamepad.RightThumbY;
- Inputs.ButtonState[ButtonFlags.Special] = State.wButtons.HasFlag(XInputStateButtons.Xbox);
+ Inputs.ButtonState[ButtonFlags.Special] = State.wButtons.HasFlag(XInputStateButtons.Xbox);
- Inputs.AxisState[AxisFlags.L2] = Gamepad.LeftTrigger;
- Inputs.AxisState[AxisFlags.R2] = Gamepad.RightTrigger;
+ Inputs.AxisState[AxisFlags.L2] = Gamepad.LeftTrigger;
+ Inputs.AxisState[AxisFlags.R2] = Gamepad.RightTrigger;
- // update states
- prevButtons = Gamepad.Buttons;
- prevState = State;
+ // update states
+ prevButtons = Gamepad.Buttons;
+ prevState = State;
+ }
+ catch { }
base.UpdateInputs(ticks);
}
@@ -154,13 +146,6 @@ public override bool IsConnected()
return false;
}
- public override void SetVibrationStrength(double value, bool rumble)
- {
- base.SetVibrationStrength(value, rumble);
- if (rumble)
- Rumble();
- }
-
public override void SetVibration(byte LargeMotor, byte SmallMotor)
{
if (!IsConnected())
@@ -173,48 +158,41 @@ public override void SetVibration(byte LargeMotor, byte SmallMotor)
Controller.SetVibration(vibration);
}
- public override void Rumble(int Loop = 1, byte LeftValue = byte.MaxValue, byte RightValue = byte.MaxValue,
- byte Duration = 125)
- {
- Task.Factory.StartNew(async () =>
- {
- for (var i = 0; i < Loop * 2; i++)
- {
- if (i % 2 == 0)
- SetVibration(LeftValue, RightValue);
- else
- SetVibration(0, 0);
-
- await Task.Delay(Duration);
- }
- });
- }
-
public override void Plug()
{
TimerManager.Tick += UpdateInputs;
- PipeClient.ServerMessage += OnServerMessage;
base.Plug();
}
public override void Unplug()
{
TimerManager.Tick -= UpdateInputs;
- PipeClient.ServerMessage -= OnServerMessage;
base.Unplug();
}
- private void OnServerMessage(PipeMessage message)
+ public override void Cleanup()
+ {
+ TimerManager.Tick -= UpdateInputs;
+ }
+
+ public static UserIndex TryGetUserIndex(PnPDetails details)
{
- switch (message.code)
+ XInputCapabilitiesEx capabilitiesEx = new();
+
+ for (int idx = 0; idx < 4; idx++)
{
- case PipeCode.SERVER_VIBRATION:
+ if (XInputGetCapabilitiesEx(1, idx, 0, ref capabilitiesEx) == 0)
{
- var e = (PipeClientVibration)message;
- SetVibration(e.LargeMotor, e.SmallMotor);
+ if (capabilitiesEx.ProductId != details.attributes.ProductID || capabilitiesEx.VendorId != details.attributes.VendorID)
+ continue;
+
+ var devices = DeviceManager.GetDetails(capabilitiesEx.VendorId, capabilitiesEx.ProductId);
+ if (devices.FirstOrDefault() is not null)
+ return (UserIndex)idx;
}
- break;
}
+
+ return SharpDX.XInput.UserIndex.Any;
}
public override string GetGlyph(ButtonFlags button)
@@ -237,13 +215,13 @@ public override string GetGlyph(ButtonFlags button)
return "\u21FA";
case ButtonFlags.Start:
return "\u21FB";
- case ButtonFlags.L2:
+ case ButtonFlags.L2Soft:
return "\u21DC";
- case ButtonFlags.L3:
+ case ButtonFlags.L2Full:
return "\u2196";
- case ButtonFlags.R2:
+ case ButtonFlags.R2Soft:
return "\u21DD";
- case ButtonFlags.R3:
+ case ButtonFlags.R2Full:
return "\u2197";
case ButtonFlags.Special:
return "\uE001";
@@ -283,25 +261,32 @@ public override string GetGlyph(AxisLayoutFlags axis)
[StructLayout(LayoutKind.Explicit)]
protected struct XInputGamepad
{
- [MarshalAs(UnmanagedType.I2)] [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.I2)]
+ [FieldOffset(0)]
public short wButtons;
- [MarshalAs(UnmanagedType.I1)] [FieldOffset(2)]
+ [MarshalAs(UnmanagedType.I1)]
+ [FieldOffset(2)]
public byte bLeftTrigger;
- [MarshalAs(UnmanagedType.I1)] [FieldOffset(3)]
+ [MarshalAs(UnmanagedType.I1)]
+ [FieldOffset(3)]
public byte bRightTrigger;
- [MarshalAs(UnmanagedType.I2)] [FieldOffset(4)]
+ [MarshalAs(UnmanagedType.I2)]
+ [FieldOffset(4)]
public short sThumbLX;
- [MarshalAs(UnmanagedType.I2)] [FieldOffset(6)]
+ [MarshalAs(UnmanagedType.I2)]
+ [FieldOffset(6)]
public short sThumbLY;
- [MarshalAs(UnmanagedType.I2)] [FieldOffset(8)]
+ [MarshalAs(UnmanagedType.I2)]
+ [FieldOffset(8)]
public short sThumbRX;
- [MarshalAs(UnmanagedType.I2)] [FieldOffset(10)]
+ [MarshalAs(UnmanagedType.I2)]
+ [FieldOffset(10)]
public short sThumbRY;
}
@@ -316,13 +301,16 @@ protected struct XInputVibration
[StructLayout(LayoutKind.Explicit)]
protected struct XInputCapabilities
{
- [MarshalAs(UnmanagedType.I1)] [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.I1)]
+ [FieldOffset(0)]
private readonly byte Type;
- [MarshalAs(UnmanagedType.I1)] [FieldOffset(1)]
+ [MarshalAs(UnmanagedType.I1)]
+ [FieldOffset(1)]
public byte SubType;
- [MarshalAs(UnmanagedType.I2)] [FieldOffset(2)]
+ [MarshalAs(UnmanagedType.I2)]
+ [FieldOffset(2)]
public short Flags;
[FieldOffset(4)] public XInputGamepad Gamepad;
@@ -353,6 +341,27 @@ protected struct XInputStateSecret
public short sThumbRY;
}
+ [StructLayout(LayoutKind.Sequential)]
+ protected struct XInputBaseBusInformation
+ {
+ [MarshalAs(UnmanagedType.U2)]
+ UInt16 VID;
+ [MarshalAs(UnmanagedType.U2)]
+ UInt16 PID;
+ [MarshalAs(UnmanagedType.U4)]
+ UInt32 a3;
+ [MarshalAs(UnmanagedType.U4)]
+ UInt32 Flags; // probably
+ [MarshalAs(UnmanagedType.U1)]
+ byte a4;
+ [MarshalAs(UnmanagedType.U1)]
+ byte a5;
+ [MarshalAs(UnmanagedType.U1)]
+ byte a6;
+ [MarshalAs(UnmanagedType.U1)]
+ byte reserved;
+ }
+
[Flags]
protected enum XInputStateButtons : ushort
{
@@ -380,27 +389,6 @@ ref XInputCapabilitiesEx pCapabilities // [out] Receives the capabilities
protected static extern int XInputGetStateSecret14(int playerIndex, out XInputStateSecret struc);
[DllImport("xinput1_4.dll", EntryPoint = "#104")]
- public static extern int XInputGetBaseBusInformation(int dwUserIndex, ref XInputBaseBusInformation pInfo);
-
- [StructLayout(LayoutKind.Sequential)]
- public struct XInputBaseBusInformation
- {
- [MarshalAs(UnmanagedType.U2)]
- UInt16 VID;
- [MarshalAs(UnmanagedType.U2)]
- UInt16 PID;
- [MarshalAs(UnmanagedType.U4)]
- UInt32 a3;
- [MarshalAs(UnmanagedType.U4)]
- UInt32 Flags; // probably
- [MarshalAs(UnmanagedType.U1)]
- byte a4;
- [MarshalAs(UnmanagedType.U1)]
- byte a5;
- [MarshalAs(UnmanagedType.U1)]
- byte a6;
- [MarshalAs(UnmanagedType.U1)]
- byte reserved;
- }
+ protected static extern int XInputGetBaseBusInformation(int dwUserIndex, ref XInputBaseBusInformation pInfo);
#endregion
}
\ No newline at end of file
diff --git a/HandheldCompanion/Controls/Hotkey/HotkeyControl.xaml b/HandheldCompanion/Controls/Hotkey/HotkeyControl.xaml
index 75fc01c91..258fef6dd 100644
--- a/HandheldCompanion/Controls/Hotkey/HotkeyControl.xaml
+++ b/HandheldCompanion/Controls/Hotkey/HotkeyControl.xaml
@@ -5,7 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:HandheldCompanion.Properties"
- xmlns:ui="https://schemas.animasterstudios.com/lib/ui/wpf/modern"
+ xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
d:Background="White"
d:DesignWidth="800"
mc:Ignorable="d">
diff --git a/HandheldCompanion/Controls/Hotkey/HotkeyQuickControl.xaml b/HandheldCompanion/Controls/Hotkey/HotkeyQuickControl.xaml
index e720fd550..013c626ab 100644
--- a/HandheldCompanion/Controls/Hotkey/HotkeyQuickControl.xaml
+++ b/HandheldCompanion/Controls/Hotkey/HotkeyQuickControl.xaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="https://schemas.animasterstudios.com/lib/ui/wpf/modern"
+ xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
d:Background="White"
d:DesignWidth="120"
mc:Ignorable="d">
diff --git a/HandheldCompanion/Controls/Layout/LayoutTemplate.xaml b/HandheldCompanion/Controls/Layout/LayoutTemplate.xaml
index 8f98fffb3..3e7ee7832 100644
--- a/HandheldCompanion/Controls/Layout/LayoutTemplate.xaml
+++ b/HandheldCompanion/Controls/Layout/LayoutTemplate.xaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="https://schemas.animasterstudios.com/lib/ui/wpf/modern"
+ xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
d:Background="White"
d:DesignHeight="80"
d:DesignWidth="800"
diff --git a/HandheldCompanion/Controls/Layout/LayoutTemplate.xaml.cs b/HandheldCompanion/Controls/Layout/LayoutTemplate.xaml.cs
index cde13103a..6545c0ed4 100644
--- a/HandheldCompanion/Controls/Layout/LayoutTemplate.xaml.cs
+++ b/HandheldCompanion/Controls/Layout/LayoutTemplate.xaml.cs
@@ -1,14 +1,12 @@
-using System;
-using System.Collections.Generic;
-using System.Windows;
-using System.Windows.Controls;
-using ControllerCommon;
-using ControllerCommon.Actions;
-using ControllerCommon.Inputs;
-using GregsStack.InputSimulatorStandard.Native;
+using GregsStack.InputSimulatorStandard.Native;
using HandheldCompanion.Actions;
using HandheldCompanion.Controllers;
+using HandheldCompanion.Inputs;
using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Controls;
namespace HandheldCompanion.Controls;
@@ -68,128 +66,126 @@ private LayoutTemplate(string name, string description, string author, bool isIn
switch (Name)
{
case "Desktop":
- {
- Layout.AxisLayout = new SortedDictionary
{
+ Layout.AxisLayout = new SortedDictionary
{
- AxisLayoutFlags.LeftThumb,
- new MouseActions { MouseType = MouseActionsType.Scroll, Sensivity = 25.0f }
- },
- {
- AxisLayoutFlags.RightThumb,
- new MouseActions { MouseType = MouseActionsType.Move, Sensivity = 25.0f }
- },
+ {
+ AxisLayoutFlags.LeftStick,
+ new MouseActions { MouseType = MouseActionsType.Scroll }
+ },
+ {
+ AxisLayoutFlags.RightStick,
+ new MouseActions { MouseType = MouseActionsType.Move }
+ },
+ {
+ AxisLayoutFlags.LeftPad,
+ new MouseActions { MouseType = MouseActionsType.Scroll }
+ },
+ {
+ AxisLayoutFlags.RightPad,
+ new MouseActions { MouseType = MouseActionsType.Move }
+ }
+ };
+
+ Layout.ButtonLayout = new()
{
- AxisLayoutFlags.LeftPad,
- new MouseActions { MouseType = MouseActionsType.Scroll, Sensivity = 25.0f }
- },
- {
- AxisLayoutFlags.RightPad,
- new MouseActions { MouseType = MouseActionsType.Move, Sensivity = 25.0f }
- }
- };
-
- Layout.ButtonLayout = new SortedDictionary
- {
- { ButtonFlags.B1, new KeyboardActions { Key = VirtualKeyCode.RETURN } },
- { ButtonFlags.B2, new KeyboardActions { Key = VirtualKeyCode.ESCAPE } },
- { ButtonFlags.B3, new KeyboardActions { Key = VirtualKeyCode.PRIOR } },
- { ButtonFlags.B4, new KeyboardActions { Key = VirtualKeyCode.NEXT } },
+ { ButtonFlags.B1, new List() { new KeyboardActions { Key = VirtualKeyCode.RETURN } } },
+ { ButtonFlags.B2, new List() { new KeyboardActions { Key = VirtualKeyCode.ESCAPE } } },
+ { ButtonFlags.B3, new List() { new KeyboardActions { Key = VirtualKeyCode.PRIOR } } },
+ { ButtonFlags.B4, new List() { new KeyboardActions { Key = VirtualKeyCode.NEXT } } },
- { ButtonFlags.L1, new KeyboardActions { Key = VirtualKeyCode.BACK } },
- { ButtonFlags.R1, new KeyboardActions { Key = VirtualKeyCode.SPACE } },
+ { ButtonFlags.L1, new List() { new KeyboardActions { Key = VirtualKeyCode.BACK } } },
+ { ButtonFlags.R1, new List() { new KeyboardActions { Key = VirtualKeyCode.SPACE } } },
- { ButtonFlags.Back, new KeyboardActions { Key = VirtualKeyCode.MENU } },
- { ButtonFlags.Start, new KeyboardActions { Key = VirtualKeyCode.TAB } },
+ { ButtonFlags.Back, new List { new KeyboardActions() { Key = VirtualKeyCode.TAB, Modifiers = ModifierSet.Alt } } },
+ { ButtonFlags.Start, new List() { new KeyboardActions { Key = VirtualKeyCode.TAB } } },
- { ButtonFlags.DPadUp, new KeyboardActions { Key = VirtualKeyCode.UP } },
- { ButtonFlags.DPadDown, new KeyboardActions { Key = VirtualKeyCode.DOWN } },
- { ButtonFlags.DPadLeft, new KeyboardActions { Key = VirtualKeyCode.LEFT } },
- { ButtonFlags.DPadRight, new KeyboardActions { Key = VirtualKeyCode.RIGHT } },
+ { ButtonFlags.DPadUp, new List() { new KeyboardActions { Key = VirtualKeyCode.UP } } },
+ { ButtonFlags.DPadDown, new List() { new KeyboardActions { Key = VirtualKeyCode.DOWN } } },
+ { ButtonFlags.DPadLeft, new List() { new KeyboardActions { Key = VirtualKeyCode.LEFT } } },
+ { ButtonFlags.DPadRight, new List() { new KeyboardActions { Key = VirtualKeyCode.RIGHT } } },
- { ButtonFlags.L2, new MouseActions { MouseType = MouseActionsType.RightButton } },
- { ButtonFlags.R2, new MouseActions { MouseType = MouseActionsType.LeftButton } },
+ { ButtonFlags.L2Soft, new List() { new MouseActions { MouseType = MouseActionsType.RightButton } } },
+ { ButtonFlags.R2Soft, new List() { new MouseActions { MouseType = MouseActionsType.LeftButton } } },
- { ButtonFlags.LeftPadClick, new MouseActions { MouseType = MouseActionsType.RightButton } },
- { ButtonFlags.RightPadClick, new MouseActions { MouseType = MouseActionsType.LeftButton } }
- };
- }
+ { ButtonFlags.LeftPadClick, new List() { new MouseActions { MouseType = MouseActionsType.RightButton } } },
+ { ButtonFlags.RightPadClick, new List() { new MouseActions { MouseType = MouseActionsType.LeftButton } } }
+ };
+ }
break;
case "Gamepad (Nintendo)":
- {
- Layout.ButtonLayout[ButtonFlags.B1] = new ButtonActions { Button = ButtonFlags.B2 };
- Layout.ButtonLayout[ButtonFlags.B2] = new ButtonActions { Button = ButtonFlags.B1 };
- Layout.ButtonLayout[ButtonFlags.B3] = new ButtonActions { Button = ButtonFlags.B4 };
- Layout.ButtonLayout[ButtonFlags.B4] = new ButtonActions { Button = ButtonFlags.B3 };
- }
+ {
+ Layout.ButtonLayout[ButtonFlags.B1] = new List() { new ButtonActions { Button = ButtonFlags.B2 } };
+ Layout.ButtonLayout[ButtonFlags.B2] = new List() { new ButtonActions { Button = ButtonFlags.B1 } };
+ Layout.ButtonLayout[ButtonFlags.B3] = new List() { new ButtonActions { Button = ButtonFlags.B4 } };
+ Layout.ButtonLayout[ButtonFlags.B4] = new List() { new ButtonActions { Button = ButtonFlags.B3 } };
+ }
break;
case "Keyboard (WASD) and Mouse":
- {
- Layout.AxisLayout = new SortedDictionary
{
- { AxisLayoutFlags.LeftThumb, new EmptyActions() },
+ Layout.AxisLayout = new SortedDictionary
{
- AxisLayoutFlags.RightThumb,
- new MouseActions { MouseType = MouseActionsType.Move, Sensivity = 25.0f }
- },
- { AxisLayoutFlags.LeftPad, new EmptyActions() },
+ {
+ AxisLayoutFlags.RightStick,
+ new MouseActions { MouseType = MouseActionsType.Move }
+ },
+ {
+ AxisLayoutFlags.RightPad,
+ new MouseActions { MouseType = MouseActionsType.Move }
+ }
+ };
+
+ Layout.ButtonLayout = new()
{
- AxisLayoutFlags.RightPad,
- new MouseActions { MouseType = MouseActionsType.Move, Sensivity = 25.0f }
- }
- };
+ { ButtonFlags.B1, new List() { new KeyboardActions { Key = VirtualKeyCode.SPACE } } },
+ { ButtonFlags.B2, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_E } } },
+ { ButtonFlags.B3, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_R } } },
+ { ButtonFlags.B4, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_F } } },
- Layout.ButtonLayout = new SortedDictionary
- {
- { ButtonFlags.B1, new KeyboardActions { Key = VirtualKeyCode.SPACE } },
- { ButtonFlags.B2, new KeyboardActions { Key = VirtualKeyCode.VK_E } },
- { ButtonFlags.B3, new KeyboardActions { Key = VirtualKeyCode.VK_R } },
- { ButtonFlags.B4, new KeyboardActions { Key = VirtualKeyCode.VK_F } },
+ { ButtonFlags.L1, new List() { new MouseActions { MouseType = MouseActionsType.ScrollDown } } },
+ { ButtonFlags.R1, new List() { new MouseActions { MouseType = MouseActionsType.ScrollUp } } },
- { ButtonFlags.L1, new MouseActions { MouseType = MouseActionsType.ScrollDown, Sensivity = 25.0f } },
- { ButtonFlags.R1, new MouseActions { MouseType = MouseActionsType.ScrollUp, Sensivity = 25.0f } },
+ { ButtonFlags.Back, new List() { new KeyboardActions { Key = VirtualKeyCode.TAB } } },
+ { ButtonFlags.Start, new List() { new KeyboardActions { Key = VirtualKeyCode.ESCAPE } } },
- { ButtonFlags.Back, new KeyboardActions { Key = VirtualKeyCode.TAB } },
- { ButtonFlags.Start, new KeyboardActions { Key = VirtualKeyCode.ESCAPE } },
+ { ButtonFlags.DPadUp, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_1 } } },
+ { ButtonFlags.DPadDown, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_3 } } },
+ { ButtonFlags.DPadLeft, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_4 } } },
+ { ButtonFlags.DPadRight, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_2 } } },
- { ButtonFlags.DPadUp, new KeyboardActions { Key = VirtualKeyCode.VK_1 } },
- { ButtonFlags.DPadDown, new KeyboardActions { Key = VirtualKeyCode.VK_3 } },
- { ButtonFlags.DPadLeft, new KeyboardActions { Key = VirtualKeyCode.VK_4 } },
- { ButtonFlags.DPadRight, new KeyboardActions { Key = VirtualKeyCode.VK_2 } },
+ { ButtonFlags.L2Soft, new List() { new MouseActions { MouseType = MouseActionsType.RightButton } } },
+ { ButtonFlags.R2Soft, new List() { new MouseActions { MouseType = MouseActionsType.LeftButton } } },
- { ButtonFlags.L2, new MouseActions { MouseType = MouseActionsType.RightButton } },
- { ButtonFlags.R2, new MouseActions { MouseType = MouseActionsType.LeftButton } },
+ { ButtonFlags.LeftStickUp, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_W } } },
+ { ButtonFlags.LeftStickDown, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_S } } },
+ { ButtonFlags.LeftStickLeft, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_A } } },
+ { ButtonFlags.LeftStickRight, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_D } } },
- { ButtonFlags.LeftThumbUp, new KeyboardActions { Key = VirtualKeyCode.VK_W } },
- { ButtonFlags.LeftThumbDown, new KeyboardActions { Key = VirtualKeyCode.VK_S } },
- { ButtonFlags.LeftThumbLeft, new KeyboardActions { Key = VirtualKeyCode.VK_A } },
- { ButtonFlags.LeftThumbRight, new KeyboardActions { Key = VirtualKeyCode.VK_D } },
+ { ButtonFlags.LeftStickClick, new List() { new KeyboardActions { Key = VirtualKeyCode.LSHIFT } } },
+ { ButtonFlags.RightStickClick, new List() { new MouseActions { MouseType = MouseActionsType.LeftButton } } },
- { ButtonFlags.LeftThumb, new KeyboardActions { Key = VirtualKeyCode.LSHIFT } },
- { ButtonFlags.RightThumb, new MouseActions { MouseType = MouseActionsType.LeftButton } },
+ { ButtonFlags.LeftPadClickUp, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_1 } } },
+ { ButtonFlags.LeftPadClickDown, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_3 } } },
+ { ButtonFlags.LeftPadClickLeft, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_4 } } },
+ { ButtonFlags.LeftPadClickRight, new List() { new KeyboardActions { Key = VirtualKeyCode.VK_2 } } },
- { ButtonFlags.LeftPadClickUp, new KeyboardActions { Key = VirtualKeyCode.VK_1 } },
- { ButtonFlags.LeftPadClickDown, new KeyboardActions { Key = VirtualKeyCode.VK_3 } },
- { ButtonFlags.LeftPadClickLeft, new KeyboardActions { Key = VirtualKeyCode.VK_4 } },
- { ButtonFlags.LeftPadClickRight, new KeyboardActions { Key = VirtualKeyCode.VK_2 } },
-
- { ButtonFlags.RightPadClick, new MouseActions { MouseType = MouseActionsType.LeftButton } }
- };
- }
+ { ButtonFlags.RightPadClick, new List() { new MouseActions { MouseType = MouseActionsType.LeftButton } } }
+ };
+ }
break;
case "Gamepad with Mouse Trackpad":
- {
- Layout.AxisLayout[AxisLayoutFlags.RightPad] = new MouseActions { MouseType = MouseActionsType.Move };
- }
+ {
+ Layout.AxisLayout[AxisLayoutFlags.RightPad] = new MouseActions { MouseType = MouseActionsType.Move };
+ }
break;
case "Gamepad with Joystick Trackpad":
- {
- Layout.AxisLayout[AxisLayoutFlags.RightPad] = new AxisActions { Axis = AxisLayoutFlags.RightThumb };
- }
+ {
+ Layout.AxisLayout[AxisLayoutFlags.RightPad] = new AxisActions { Axis = AxisLayoutFlags.RightStick };
+ }
break;
}
}
@@ -242,6 +238,11 @@ public int CompareTo(object obj)
return profile.Name.CompareTo(Name);
}
+ public void ClearDelegates()
+ {
+ Updated = null;
+ }
+
private void Layout_Updated(Layout layout)
{
Updated?.Invoke(this);
diff --git a/HandheldCompanion/Controls/Mapping/AxisMapping.xaml b/HandheldCompanion/Controls/Mapping/AxisMapping.xaml
index afd4488fc..236ea07ef 100644
--- a/HandheldCompanion/Controls/Mapping/AxisMapping.xaml
+++ b/HandheldCompanion/Controls/Mapping/AxisMapping.xaml
@@ -5,20 +5,18 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HandheldCompanion.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="https://schemas.animasterstudios.com/lib/ui/wpf/modern"
+ xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
d:Background="White"
- d:DesignHeight="1000"
+ d:DesignHeight="1500"
d:DesignWidth="800"
- d:Visibility="Visible"
- Visibility="Collapsed"
mc:Ignorable="d">
-
+
-
-
+
+
@@ -70,7 +68,7 @@
d:Visibility="Visible"
Visibility="{Binding ElementName=ActionComboBox, Path=SelectedIndex, Converter={StaticResource IndexToVisibilityConverter}, ConverterParameter=2}">
-
+
@@ -198,7 +196,7 @@
BorderThickness="0,1,0,0"
Opacity="0.25" />
-
+
@@ -234,7 +232,7 @@
BorderThickness="0,1,0,0"
Opacity="0.25" />
-
+
@@ -279,7 +277,7 @@
d:Visibility="Visible"
Visibility="{Binding ElementName=ActionComboBox, Path=SelectedIndex, Converter={StaticResource IndexToVisibilityConverter}, ConverterParameter=4}">
-
+
@@ -370,7 +368,45 @@
ScrollViewer.PanningMode="HorizontalOnly"
Style="{DynamicResource SliderStyle1}"
TickFrequency="1"
- ValueChanged="Axis2MousePointerSpeed_ValueChanged" />
+ ValueChanged="Axis2MousePointerSpeed_ValueChanged"
+ Value="33" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -380,6 +416,70 @@
BorderThickness="0,1,0,0"
Opacity="0.25" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -388,7 +488,7 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}"
- Text="Deadzone" />
+ Text="Deadzone (joystick only)" />
+ ValueChanged="Axis2MouseDeadzone_ValueChanged"
+ Value="10" />
diff --git a/HandheldCompanion/Controls/Mapping/AxisMapping.xaml.cs b/HandheldCompanion/Controls/Mapping/AxisMapping.xaml.cs
index 91fa5abb8..bc5abbc14 100644
--- a/HandheldCompanion/Controls/Mapping/AxisMapping.xaml.cs
+++ b/HandheldCompanion/Controls/Mapping/AxisMapping.xaml.cs
@@ -1,14 +1,12 @@
-using System;
-using System.Threading;
-using System.Windows;
-using System.Windows.Controls;
-using ControllerCommon.Actions;
-using ControllerCommon.Controllers;
-using ControllerCommon.Inputs;
-using ControllerCommon.Utils;
-using HandheldCompanion.Actions;
+using HandheldCompanion.Actions;
+using HandheldCompanion.Controllers;
+using HandheldCompanion.Inputs;
using HandheldCompanion.Managers;
+using HandheldCompanion.Utils;
using Inkore.UI.WPF.Modern.Controls;
+using System;
+using System.Windows;
+using System.Windows.Controls;
namespace HandheldCompanion.Controls;
@@ -25,7 +23,6 @@ public AxisMapping()
public AxisMapping(AxisLayoutFlags axis) : this()
{
Value = axis;
- prevValue = axis;
Icon.Glyph = axis.ToString();
}
@@ -42,8 +39,11 @@ public void UpdateIcon(FontIcon newIcon, string newLabel)
Icon.Foreground = newIcon.Foreground;
else
Icon.SetResourceReference(ForegroundProperty, "SystemControlForegroundBaseMediumBrush");
+ }
- Update();
+ public void UpdateSelections()
+ {
+ Action_SelectionChanged(null, null);
}
internal void SetIActions(IActions actions)
@@ -65,10 +65,6 @@ private void Action_SelectionChanged(object sender, SelectionChangedEventArgs e)
if (TargetComboBox is null)
return;
- // we're busy
- if (!Monitor.TryEnter(updateLock))
- return;
-
// clear current dropdown values
TargetComboBox.Items.Clear();
TargetComboBox.IsEnabled = ActionComboBox.SelectedIndex != 0;
@@ -134,7 +130,7 @@ private void Action_SelectionChanged(object sender, SelectionChangedEventArgs e)
// create a label, store MouseActionsType as Tag and Label as controller specific string
var buttonLabel = new Label
- { Tag = mouseType, Content = EnumUtils.GetDescriptionFromEnumValue(mouseType) };
+ { Tag = mouseType, Content = EnumUtils.GetDescriptionFromEnumValue(mouseType) };
TargetComboBox.Items.Add(buttonLabel);
if (mouseType.Equals(((MouseActions)Actions).MouseType))
@@ -147,6 +143,9 @@ private void Action_SelectionChanged(object sender, SelectionChangedEventArgs e)
Axis2MouseRotation.Value = (((MouseActions)Actions).AxisInverted ? 180 : 0) +
(((MouseActions)Actions).AxisRotated ? 90 : 0);
Axis2MouseDeadzone.Value = ((MouseActions)Actions).Deadzone;
+ Axis2MouseAcceleration.Value = ((MouseActions)this.Actions).Acceleration;
+ Axis2MouseFiltering.IsOn = ((MouseActions)this.Actions).Filtering;
+ Axis2MouseFilterCutoff.Value = ((MouseActions)this.Actions).FilterCutoff;
}
base.Update();
@@ -160,46 +159,31 @@ private void Target_SelectionChanged(object sender, SelectionChangedEventArgs e)
if (TargetComboBox.SelectedItem is null)
return;
- // we're busy
- if (!Monitor.TryEnter(updateLock))
- return;
-
// generate IActions based on settings
switch (Actions.ActionType)
{
case ActionType.Joystick:
- {
- var buttonLabel = TargetComboBox.SelectedItem as Label;
- ((AxisActions)Actions).Axis = (AxisLayoutFlags)buttonLabel.Tag;
- }
+ {
+ var buttonLabel = TargetComboBox.SelectedItem as Label;
+ ((AxisActions)Actions).Axis = (AxisLayoutFlags)buttonLabel.Tag;
+ }
break;
case ActionType.Mouse:
- {
- var buttonLabel = TargetComboBox.SelectedItem as Label;
- ((MouseActions)Actions).MouseType = (MouseActionsType)buttonLabel.Tag;
- }
+ {
+ var buttonLabel = TargetComboBox.SelectedItem as Label;
+ ((MouseActions)Actions).MouseType = (MouseActionsType)buttonLabel.Tag;
+ }
break;
}
base.Update();
}
- private void Update()
- {
- // force full update
- Action_SelectionChanged(null, null);
- Target_SelectionChanged(null, null);
- }
-
public void Reset()
{
- if (Monitor.TryEnter(updateLock))
- {
- ActionComboBox.SelectedIndex = 0;
- TargetComboBox.SelectedItem = null;
- Monitor.Exit(updateLock);
- }
+ ActionComboBox.SelectedIndex = 0;
+ TargetComboBox.SelectedItem = null;
}
private void Axis2AxisAutoRotate_Toggled(object sender, RoutedEventArgs e)
@@ -353,4 +337,50 @@ private void Axis2MouseDeadzone_ValueChanged(object sender, RoutedPropertyChange
base.Update();
}
+
+ private void Axis2MouseAcceleration_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (this.Actions is null)
+ return;
+
+ switch (this.Actions.ActionType)
+ {
+ case ActionType.Mouse:
+ ((MouseActions)this.Actions).Acceleration = (float)Axis2MouseAcceleration.Value;
+ break;
+ }
+
+ base.Update();
+ }
+
+ // TODO: artificially convert to something more human readable?
+ private void Axis2MouseFiltering_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (this.Actions is null)
+ return;
+
+ switch (this.Actions.ActionType)
+ {
+ case ActionType.Mouse:
+ ((MouseActions)this.Actions).Filtering = Axis2MouseFiltering.IsOn;
+ break;
+ }
+
+ base.Update();
+ }
+
+ private void Axis2MouseFilterCutoff_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (this.Actions is null)
+ return;
+
+ switch (this.Actions.ActionType)
+ {
+ case ActionType.Mouse:
+ ((MouseActions)this.Actions).FilterCutoff = (float)Axis2MouseFilterCutoff.Value;
+ break;
+ }
+
+ base.Update();
+ }
}
\ No newline at end of file
diff --git a/HandheldCompanion/Controls/Mapping/ButtonMapping.xaml b/HandheldCompanion/Controls/Mapping/ButtonMapping.xaml
index 98edc11c2..d5277e8bc 100644
--- a/HandheldCompanion/Controls/Mapping/ButtonMapping.xaml
+++ b/HandheldCompanion/Controls/Mapping/ButtonMapping.xaml
@@ -5,42 +5,53 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HandheldCompanion.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:ui="https://schemas.animasterstudios.com/lib/ui/wpf/modern"
+ xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
d:Background="White"
d:DesignHeight="1000"
d:DesignWidth="800"
- d:Visibility="Visible"
- Visibility="Collapsed"
mc:Ignorable="d">
-
+
-
+
-
-
+
+
+
+
+
+ SelectedIndex="0"
+ SelectionChanged="Press_SelectionChanged">
+
+
+
@@ -63,14 +74,107 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -98,8 +202,7 @@
Opacity="0.25" />
-
+
@@ -126,7 +229,7 @@
Style="{DynamicResource SliderStyle1}"
TickFrequency="5"
ValueChanged="Turbo_Slider_ValueChanged"
- Value="90" />
+ Value="30" />
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HandheldCompanion/Controls/Mapping/ButtonMapping.xaml.cs b/HandheldCompanion/Controls/Mapping/ButtonMapping.xaml.cs
index 44233ffd5..272f1d223 100644
--- a/HandheldCompanion/Controls/Mapping/ButtonMapping.xaml.cs
+++ b/HandheldCompanion/Controls/Mapping/ButtonMapping.xaml.cs
@@ -1,16 +1,14 @@
-using System;
-using System.Threading;
-using System.Windows;
-using System.Windows.Controls;
-using ControllerCommon.Actions;
-using ControllerCommon.Controllers;
-using ControllerCommon.Inputs;
-using ControllerCommon.Utils;
-using GregsStack.InputSimulatorStandard.Native;
+using GregsStack.InputSimulatorStandard.Native;
using HandheldCompanion.Actions;
+using HandheldCompanion.Controllers;
+using HandheldCompanion.Inputs;
using HandheldCompanion.Managers;
-using HandheldCompanion.Simulators;
+using HandheldCompanion.Utils;
using Inkore.UI.WPF.Modern.Controls;
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Controls;
namespace HandheldCompanion.Controls;
@@ -19,17 +17,28 @@ namespace HandheldCompanion.Controls;
///
public partial class ButtonMapping : IMapping
{
+ private static List