Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gyroscope Joystick Emulation #554

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BetterJoyForCemu/3rdPartyControllers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public override int GetHashCode() {
}

public override string ToString() {
return name ?? $"Unidentified Device ({this.product_id})";
return name;
}

public string Serialise() {
Expand Down
116 changes: 79 additions & 37 deletions BetterJoyForCemu/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>

<!--NOTE: You can change these settings in app if you click the arrow on the right of the window-->
<!--Doing so will erase these comments explaining the settings-->

<!--Motion Server IP: the default is localhost; you can change it to 0.0.0.0 (all interfaces) or a specific LAN IP
which is **useful if you want to access the server from another computer in a network.** Default: 127.0.0.1-->
<add key="IP" value="127.0.0.1" />
Expand All @@ -25,60 +29,67 @@
<!--On is "true"; off is "false". Default: true -->
<add key="EnableRumble" value="true" />

<!--Enables a input when shaking a controller, only works with DS4 for now, replaces the touchpad input (Button 13 on DirectInput)-->
<!--On is "true"; off is "false". Default: false -->
<add key="EnableShakeInput" value="false" />
<!--How sensitve the shake detection should be. Default: 10-->
<add key="ShakeInputSensitivity" value="10" />
<!--How often should the shake input run in milliseconds. -->
<!--Don't set this lower than 15 -->
<!-- Default: 200 -->
<add key="ShakeInputDelay" value="200" />

<!--Swap A-B buttons; if on, this mimicks the (half of) Xbox layout by the button name, rather than by the physical layout.-->
<!--Swap A-B buttons-->
<!--Also swaps buttons when using "Also use for buttons/axes"-->
<!--On is "true"; off is "false". Default: false -->
<add key="SwapAB" value="false" />
<!--Swap X-Y buttons; if on, this mimicks the (other half of) Xbox layout by the button name, rather than by the physical layout.-->
<!--Swap X-Y buttons-->
<!--Also swaps buttons when using "Also use for buttons/axes"-->
<!--On is "true"; off is "false". Default: false -->
<add key="SwapXY" value="false" />
<!--When true, SR on the joycon will force the controller to recconect-->
<!--Useful if switching between mouse mode and gamepad on GPD Win Max-->
<!--Default: true -->
<add key="SRReconnectXinput" value="true" />

<!--When true, sets gyro X axis to -Y and Y axis to X to account for the different orientation of the modless joycon attatchment point-->
<!--NOTE: This does not work properly for GyroAnalog Sliders, reccomend manually chosing inverted "y" for forward and back and "x" for side to side-->
<!--Default: "false" -->
<add key="ModFreeGyro" value="false" />

<!--Allows use of gyroscope tilting to get full control of the slider values (big triggers)-->
<!--Works on pro controller and joined joycons (pro controller case - triggers combined, joycons case - separate tilt)-->
<!--Win Max version supports a sigle joycon and combines triggers like on the pro controller (use 2 diferent axis if you want them split) -->
<!--Default: false -->
<add key="GyroAnalogSliders" value="false" />
<!--Change to -20 to change direction of tilt needed. Positive is ramp up if pointing up-->
<!--Default: 20 -->
<add key="GyroAnalogSensitivity" value="20" />

<!-- Determines whether or not the program should purge the affected devices list upon exit -->
<!-- Should prevent any more issues of the controller being unusable after the program (even though this can be fixed if you read the README) -->
<!-- Default: true -->
<add key="PurgeAffectedDevices" value="false" />
<!-- Determines whether or not HidGuardian's process whitelist is purged on start-up -->
<!-- Can interfere with other programs using HidGuardian, but prevents whitelist from being clogged from crashed instances -->
<!-- Default: true -->
<add key="PurgeWhitelist" value="false" />
<!-- Determines whether or not to use HidGuardian (improves compatibility with other programs, like Steam, when set to "false") -->
<!-- When "true", BetterJoy will hide the Pro/Joycons from other programs to prevent glitching out on exit and to prevent DI/XI clashes in certain programs -->
<!-- Default: false -->
<add key="UseHIDG" value="false" />

<!-- Determines whether or not to enable (experimental - currently default controller to pro) support for 3rd-party controllers. Adds a "Calibrate" button. -->
<!-- When "true", click "Calibrate" button once to get gyro calibrate data. -->
<!-- When enabled, can only calibrate one controller at a time. -->
<!-- Default: false -->
<add key="NonOriginalController" value="false" />
<!-- The program will keep the HOME button LED ring light on at all times. -->
<!-- Default: true -->
<add key="HomeLEDOn" value="true"/>
<!--Sets the gyroscope axis for the left analog trigger (L2)-->
<!--"x" "y" "z" all set their respective axis, "none" will make the trigger act as a normal button but still allows gyro on the other trigger-->
<!--On Win Max Rumble Mod, "x" is tilting forward and back, "Y" is tilting side to side, "z" looking around-->
<!--On Mod Free attatchment, "x" is tilting side to side, "y" is tilting forward and back(inverted), "z" looking around-->
<!--Default: "none" -->
<add key="GyroAnalogLeftAxis" value="none" />
<!--When true, inverts the direction of movement on the axis-->
<!--Default: "false" -->
<add key="GyroAnalogInvertLeftAxis" value="false" />
<!--Sets the gyroscope axis for the right analog trigger (R2)-->
<!--"x" "y" "z" all set their respective axis, "none" will make the trigger act as a normal button but still allows gyro on the other trigger-->
<!--On Win Max Rumble Mod, "x" is tilting forward and back, "Y" is tilting side to side "z" looking around-->
<!--On Mod Free attatchment, "x" is tilting side to side, "y" is tilting forward and back(inverted), "z" looking around-->
<!--Default: "x" -->
<add key="GyroAnalogRightAxis" value="x" />
<!--When true, inverts the direction of movement on the axis-->
<!--Default: "false" -->
<add key="GyroAnalogInvertRightAxis" value="false" />

<!-- Determines whether or not to translate gyro movements into joystick ("joy") or mouse movement ("mouse"), or have no effect ("none") -->
<!-- When "joy", turn gyro movements into joystick movement (left/right depends on setting) [not yet implemented]-->
<!-- When "joy", turn gyro movements into joystick movement (left/right depends on setting) [implemented only for Win Max Mod]-->
<!-- When "mouse", turn gyro movements into mouse movement. Press either stick-button to reset to middle of primary display -->
<!-- Default: none -->
<add key="GyroToJoyOrMouse" value="none"/>
<!-- Choses which analog stick to map gyro movements to "left" or "right" -->
<!-- Default: right -->
<add key="GyroJoyStick" value="right"/>
<!-- Choses method of mapping movement to the analog stick "camera" or "steer" -->
<!-- "camera" will only move the stick while the gyro is registering movement, great for camera controls -->
<!-- "steer" will keep the joystick held in the direction the gyro registers relative to the center position (steering controls) -->
<!-- Default: camera -->
<add key="GyroJoyMoveMode" value="camera"/>
<!-- Sensitivity of gyro-to-joy movements -->
<!-- Default: 50 (higher value is more sensitive) -->
<add key="GyroJoySensitivity" value="50"/>
<!-- Sensitivity of gyro-to-mouse movements -->
<!-- Default: 50 -->
<add key="GyroMouseSensitivity" value="50"/>
Expand All @@ -93,19 +104,50 @@
<!-- Default: false -->
<add key="DragToggle" value="false"/>

<!-- Determines whether or not the program should purge the affected devices list upon exit -->
<!-- Should prevent any more issues of the controller being unusable after the program (even though this can be fixed if you read the README) -->
<!-- WARNING! Enabling this setting will unhide the Win Max controller, will require manual re-enable -->
<!-- Default: false -->
<add key="PurgeAffectedDevices" value="false" />
<!-- Determines whether or not HidGuardian's process whitelist is purged on start-up -->
<!-- Can interfere with other programs using HidGuardian, but prevents whitelist from being clogged from crashed instances -->
<!-- WARNING! Enabling this setting will unhide the Win Max controller, will require manual re-enable -->
<!-- Default: false -->
<add key="PurgeWhitelist" value="false" />
<!-- Determines whether or not to use HidGuardian -->
<!-- When "true", BetterJoy will hide the Pro/Joycons from other programs to prevent glitching out on exit and to prevent DI/XI clashes in certain programs -->
<!-- Default: true -->
<add key="UseHIDG" value="true" />

<!-- Forces any controller connected to be treated as a pro controller by the code -->
<!-- This is required for the Win Max Rumble and Gyro Mod to work as originally intended -->
<!-- Only added an option to disable this override for people who may want to use the program for different reasons -->
<!-- Default: true -->
<add key="ProControllerOverride" value="true" />
<!-- Determines whether or not to enable (experimental - currently default controller to pro) support for 3rd-party controllers. Adds a "Calibrate" button. -->
<!-- When "true", click "Calibrate" button once to get gyro calibrate data. -->
<!-- When enabled, can only calibrate one controller at a time. -->
<!-- Default: false -->
<add key="NonOriginalController" value="false" />
<!-- The program will keep the HOME button LED ring light on at all times. -->
<!-- This used to be on by default in the original code. This feature is enterly pointless and also broken as it will stay lit after disconnect -->
<!-- I turned it off for you. You're welcome. If you really want to, you can turn it back on with this setting -->
<!-- Default: false -->
<add key="HomeLEDOn" value="false"/>

<!-- Determines whether or not the program will expose detected controllers as Xbox 360 controllers -->
<!-- When "false", BetterJoy is only usable with CEMU. -->
<!-- Default: true -->
<add key="ShowAsXInput" value="true" />
<!-- Have ShowAsXInput as false if using this -->
<!-- Have ShowAsXInput as false if using this, program will show detected controllers as Dualshock 4 controllers -->
<!-- Default: false -->
<add key="ShowAsDS4" value="false"/>

<!-- Automatically power off controllers at program exit -->
<!-- Default: false -->
<add key="AutoPowerOff" value="false" />
<!-- Automatically power off controllers after a period of inactivity (in minutes) -->
<!-- Default: 30 (-1 indicates infinite time) -->
<!-- Default: -1 (-1 indicates infinite time) -->
<add key="PowerOffInactivity" value="-1" />
<!-- Power off controllers when Capture (left only) or Home (right only or combined) buttons are pressed for a long interval (2s) -->
<!-- Default: true -->
Expand Down
15 changes: 11 additions & 4 deletions BetterJoyForCemu/BetterJoy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,22 @@
<Reference Include="Nefarius.ViGEm.Client, Version=1.16.150.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nefarius.ViGEm.Client.1.16.150\lib\net452\Nefarius.ViGEm.Client.dll</HintPath>
</Reference>
<Reference Include="SharpDX, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\packages\SharpDX.4.2.0\lib\net45\SharpDX.dll</HintPath>
</Reference>
<Reference Include="SharpDX.XInput, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\packages\SharpDX.XInput.4.2.0\lib\net45\SharpDX.XInput.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Numerics" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
Expand Down Expand Up @@ -155,6 +164,7 @@
<DependentUpon>Reassign.cs</DependentUpon>
</Compile>
<Compile Include="UpdServer.cs" />
<Compile Include="XInputController.cs" />
</ItemGroup>
<ItemGroup>
<None Include="! Install the drivers in the Drivers folder">
Expand Down Expand Up @@ -236,10 +246,7 @@
<Content Include="Icons\snes.png" />
<None Include="Properties\app.manifest" />
<Content Include="Icons\betterjoyforcemu_icon.ico" />
<Content Include="x86\hidapi.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="x64\hidapi.dll">
<Content Include="hidapi.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Icons\cross.png" />
Expand Down
38 changes: 13 additions & 25 deletions BetterJoyForCemu/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
using System.Collections.Generic;
using System.IO;

//Too lazy to work this out, just manually edited config after build for Win Max version -MYCRAFT
namespace BetterJoyForCemu {
public static class Config { // stores dynamic configuration, including
const string PATH = "settings";
static Dictionary<string, string> variables = new Dictionary<string, string>();

const int settingsNum = 11; // currently - ProgressiveScan, StartInTray + special buttons
const int settingsNum = 10; // currently - ProgressiveScan, StartInTray + special buttons

public static string GetDefaultValue(string s) {
switch (s) {
Expand All @@ -21,36 +22,15 @@ public static string GetDefaultValue(string s) {
return "0";
}

// Helper function to count how many lines are in a file
// https://www.dotnetperls.com/line-count
static long CountLinesInFile(string f) {
// Zero based count
long count = -1;
using (StreamReader r = new StreamReader(f)) {
string line;
while ((line = r.ReadLine()) != null) {
count++;
}
}
return count;
}

public static void Init(List<KeyValuePair<string, float[]>> caliData) {
foreach (string s in new string[] { "ProgressiveScan", "StartInTray", "capture", "home", "sl_l", "sl_r", "sr_l", "sr_r", "shake", "reset_mouse", "active_gyro" })
foreach (string s in new string[] { "ProgressiveScan", "StartInTray", "capture", "home", "sl_l", "sl_r", "sr_l", "sr_r", "reset_mouse", "active_gyro" })
variables[s] = GetDefaultValue(s);

if (File.Exists(PATH)) {

// Reset settings file if old settings
if (CountLinesInFile(PATH) < settingsNum) {
File.Delete(PATH);
Init(caliData);
return;
}

int lineNO = 0;
using (StreamReader file = new StreamReader(PATH)) {
string line = String.Empty;
int lineNO = 0;

while ((line = file.ReadLine()) != null) {
string[] vs = line.Split();
try {
Expand All @@ -73,6 +53,14 @@ public static void Init(List<KeyValuePair<string, float[]>> caliData) {
} catch { }
lineNO++;
}


}

// if old settings
if (lineNO < settingsNum) {
File.Delete(PATH);
Init(caliData);
}
} else {
using (StreamWriter file = new StreamWriter(PATH)) {
Expand Down
Binary file added BetterJoyForCemu/Icons/jc_left.pdn
Binary file not shown.
Binary file modified BetterJoyForCemu/Icons/jc_left.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified BetterJoyForCemu/Icons/jc_left_s.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified BetterJoyForCemu/Icons/jc_right.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified BetterJoyForCemu/Icons/jc_right_s.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading