Compare commits

..

1 commit

Author SHA1 Message Date
David Khachaturov
488d152508
Update README.md 2020-05-06 13:31:01 +01:00
32 changed files with 3685 additions and 5206 deletions

View file

@ -1,18 +0,0 @@
---
name: Bug Report / Problems
about: PLEASE USE THE ISSUE SEARCH FUNCTION FIRST BEFORE MAKING A NEW ISSUE
title: "[BUG]"
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Controller (please complete the following information):**
- Type: [e.g. Pro/Split Joycons]
- Connection: [e.g. USB/BT]

View file

@ -1,14 +0,0 @@
---
name: Feature Request
about: Suggest an idea for this project
title: "[ENHANCEMENT]"
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.

View file

@ -1,120 +0,0 @@
# To learn more about .editorconfig see https://aka.ms/editorconfigdocs
###############################
# Core EditorConfig Options #
###############################
root = true
# All files
[*]
indent_size = 4
indent_style = space
# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
end_of_line = crlf
insert_final_newline = true
charset = utf-8-bom
###############################
# .NET Coding Conventions #
###############################
[*.{cs,vb}]
# Organize usings
dotnet_sort_system_directives_first = true
# this. preferences
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_property = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_event = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
###############################
# Naming Conventions #
###############################
# Style Definitions
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# Use PascalCase for constant fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
dotnet_naming_symbols.constant_fields.required_modifiers = const
###############################
# C# Coding Conventions #
###############################
[*.cs]
# var preferences
csharp_style_var_for_built_in_types = true:silent
csharp_style_var_when_type_is_apparent = true:silent
csharp_style_var_elsewhere = true:silent
# Expression-bodied members
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
# Null-checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
# Expression-level preferences
csharp_prefer_braces = true:silent
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
###############################
# C# Formatting Rules #
###############################
# New line preferences
csharp_new_line_before_open_brace = false
csharp_new_line_before_else = false
csharp_new_line_before_catch = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
# Space preferences
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
# Wrapping preferences
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true

View file

@ -30,8 +30,8 @@
this.btn_add = new System.Windows.Forms.Button();
this.btn_remove = new System.Windows.Forms.Button();
this.group_props = new System.Windows.Forms.GroupBox();
this.label2 = new System.Windows.Forms.Label();
this.chooseType = new System.Windows.Forms.ComboBox();
this.chk_isLeft = new System.Windows.Forms.CheckBox();
this.chk_isPro = new System.Windows.Forms.CheckBox();
this.btn_applyAndClose = new System.Windows.Forms.Button();
this.btn_apply = new System.Windows.Forms.Button();
this.lbl_all = new System.Windows.Forms.Label();
@ -83,8 +83,8 @@
//
// group_props
//
this.group_props.Controls.Add(this.label2);
this.group_props.Controls.Add(this.chooseType);
this.group_props.Controls.Add(this.chk_isLeft);
this.group_props.Controls.Add(this.chk_isPro);
this.group_props.Location = new System.Drawing.Point(122, 142);
this.group_props.Name = "group_props";
this.group_props.Size = new System.Drawing.Size(150, 81);
@ -92,23 +92,29 @@
this.group_props.TabStop = false;
this.group_props.Text = "Settings";
//
// label2
// chk_isLeft
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(10, 22);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(31, 13);
this.label2.TabIndex = 1;
this.label2.Text = "Type";
this.chk_isLeft.AutoSize = true;
this.chk_isLeft.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.chk_isLeft.Location = new System.Drawing.Point(6, 42);
this.chk_isLeft.Name = "chk_isLeft";
this.chk_isLeft.Size = new System.Drawing.Size(96, 17);
this.chk_isLeft.TabIndex = 1;
this.chk_isLeft.Text = "Left Joycon? ";
this.chk_isLeft.UseVisualStyleBackColor = true;
this.chk_isLeft.CheckedChanged += new System.EventHandler(this.chk_isLeft_CheckedChanged);
//
// chooseType
// chk_isPro
//
this.chooseType.FormattingEnabled = true;
this.chooseType.Location = new System.Drawing.Point(47, 19);
this.chooseType.Name = "chooseType";
this.chooseType.Size = new System.Drawing.Size(97, 21);
this.chooseType.TabIndex = 0;
this.chooseType.SelectedValueChanged += new System.EventHandler(this.chooseType_SelectedValueChanged);
this.chk_isPro.AutoSize = true;
this.chk_isPro.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.chk_isPro.Location = new System.Drawing.Point(6, 19);
this.chk_isPro.Name = "chk_isPro";
this.chk_isPro.Size = new System.Drawing.Size(95, 17);
this.chk_isPro.TabIndex = 0;
this.chk_isPro.Text = "Pro Controller?";
this.chk_isPro.UseVisualStyleBackColor = true;
this.chk_isPro.CheckedChanged += new System.EventHandler(this.chk_isPro_CheckedChanged);
//
// btn_applyAndClose
//
@ -197,10 +203,10 @@
private System.Windows.Forms.Button btn_applyAndClose;
private System.Windows.Forms.Button btn_apply;
private System.Windows.Forms.Label lbl_all;
private System.Windows.Forms.CheckBox chk_isPro;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.CheckBox chk_isLeft;
private System.Windows.Forms.ToolTip tip_device;
private System.Windows.Forms.Button btn_refresh;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.ComboBox chooseType;
}
}
}

View file

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
@ -14,92 +13,27 @@ using static BetterJoyForCemu.HIDapi;
namespace BetterJoyForCemu {
public partial class _3rdPartyControllers : Form {
public class SController {
public String name;
public ushort product_id;
public ushort vendor_id;
public string serial_number;
public byte type; // 1 is pro, 2 is left joy, 3 is right joy
public SController(String name, ushort vendor_id, ushort product_id, byte type, string serial_number) {
this.product_id = product_id; this.vendor_id = vendor_id; this.type = type;
this.serial_number = serial_number;
this.name = name;
}
public override bool Equals(object obj) {
//Check for null and compare run-time types.
if ((obj == null) || !this.GetType().Equals(obj.GetType())) {
return false;
} else {
SController s = (SController)obj;
return (s.product_id == product_id) && (s.vendor_id == vendor_id) && (s.serial_number == serial_number);
}
}
public override int GetHashCode() {
return Tuple.Create(product_id, vendor_id, serial_number).GetHashCode();
}
public override string ToString() {
return name ?? $"Unidentified Device ({this.product_id})";
}
public string Serialise() {
return String.Format("{0}|{1}|{2}|{3}|{4}", name, vendor_id, product_id, type, serial_number);
}
}
static readonly string path;
static _3rdPartyControllers() {
path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
+ "\\3rdPartyControllers";
}
public _3rdPartyControllers() {
InitializeComponent();
list_allControllers.HorizontalScrollbar = true; list_customControllers.HorizontalScrollbar = true;
list_allControllers.DisplayMember = "Text";
list_allControllers.ValueMember = "Value";
list_customControllers.DisplayMember = "Text";
list_customControllers.ValueMember = "Value";
chooseType.Items.AddRange(new String[] { "Pro Controller", "Left Joycon", "Right Joycon" });
chooseType.FormattingEnabled = true;
group_props.Controls.Add(chooseType);
group_props.Enabled = false;
if (File.Exists(path)) {
using (StreamReader file = new StreamReader(path)) {
string line = String.Empty;
while ((line = file.ReadLine()) != null && (line != String.Empty)) {
String[] split = line.Split('|');
//won't break existing config file
String serial_number = "";
if (split.Length > 4) {
serial_number = split[4];
}
list_customControllers.Items.Add(new SController(split[0], ushort.Parse(split[1]), ushort.Parse(split[2]), byte.Parse(split[3]), serial_number));
}
}
}
CopyCustomControllers();
RefreshControllerList();
}
public void CopyCustomControllers() {
Program.thirdPartyCons.Clear();
foreach (SController v in list_customControllers.Items) {
Program.thirdPartyCons.Add(v);
}
group_props.Controls.Add(chk_isLeft);
group_props.Controls.Add(chk_isPro);
group_props.Enabled = false;
}
private bool ContainsText(ListBox a, String manu) {
foreach (SController v in a.Items) {
if (v == null)
foreach (var v in a.Items)
{
dynamic d = v as dynamic;
if (d.Text == null)
continue;
if (v.name == null)
continue;
if (v.name.Equals(manu))
if (d.Text.Equals(manu))
return true;
}
return false;
@ -114,29 +48,17 @@ namespace BetterJoyForCemu {
while (ptr != IntPtr.Zero) {
enumerate = (hid_device_info)Marshal.PtrToStructure(ptr, typeof(hid_device_info));
if (enumerate.serial_number == null) {
ptr = enumerate.next;
continue;
}
// TODO: try checking against interface number instead
String name = enumerate.product_string + '(' + enumerate.vendor_id + '-' + enumerate.product_id + '-'+enumerate.serial_number+')';
if (!ContainsText(list_customControllers, name) && !ContainsText(list_allControllers, name)) {
list_allControllers.Items.Add(new SController(name, enumerate.vendor_id, enumerate.product_id, 0, enumerate.serial_number));
// 0 type is undefined
Console.WriteLine("Found controller "+ name);
}
if (!ContainsText(list_customControllers, enumerate.product_string) && !ContainsText(list_allControllers, enumerate.product_string))
list_allControllers.Items.Add(new { Text = enumerate.product_string, Value = enumerate });
ptr = enumerate.next;
}
HIDapi.hid_free_enumeration(top_ptr);
}
private void btn_add_Click(object sender, EventArgs e) {
if (list_allControllers.SelectedItem != null) {
list_customControllers.Items.Add(list_allControllers.SelectedItem);
list_allControllers.Items.Remove(list_allControllers.SelectedItem);
list_allControllers.ClearSelected();
}
}
@ -145,18 +67,20 @@ namespace BetterJoyForCemu {
if (list_customControllers.SelectedItem != null) {
list_allControllers.Items.Add(list_customControllers.SelectedItem);
list_customControllers.Items.Remove(list_customControllers.SelectedItem);
list_customControllers.ClearSelected();
}
}
private void chk_isPro_CheckedChanged(object sender, EventArgs e) {
}
private void chk_isLeft_CheckedChanged(object sender, EventArgs e) {
}
private void btn_apply_Click(object sender, EventArgs e) {
String sc = "";
foreach (SController v in list_customControllers.Items) {
sc += v.Serialise() + "\r\n";
}
File.WriteAllText(path, sc);
CopyCustomControllers();
}
private void btn_applyAndClose_Click(object sender, EventArgs e) {
@ -174,21 +98,15 @@ namespace BetterJoyForCemu {
private void list_allControllers_SelectedValueChanged(object sender, EventArgs e) {
if (list_allControllers.SelectedItem != null)
tip_device.Show((list_allControllers.SelectedItem as SController).name, list_allControllers);
tip_device.Show((list_allControllers.SelectedItem as dynamic).Text, list_allControllers);
}
private void list_customControllers_SelectedValueChanged(object sender, EventArgs e) {
if (list_customControllers.SelectedItem != null) {
SController v = (list_customControllers.SelectedItem as SController);
tip_device.Show(v.name, list_customControllers);
chooseType.SelectedIndex = v.type - 1;
tip_device.Show((list_customControllers.SelectedItem as dynamic).Text, list_customControllers);
group_props.Enabled = true;
} else {
chooseType.SelectedIndex = -1;
} else
group_props.Enabled = false;
}
}
private void list_customControllers_MouseDown(object sender, MouseEventArgs e) {
@ -200,12 +118,5 @@ namespace BetterJoyForCemu {
if (e.Y > list_allControllers.ItemHeight * list_allControllers.Items.Count)
list_allControllers.SelectedItems.Clear();
}
private void chooseType_SelectedValueChanged(object sender, EventArgs e) {
if (list_customControllers.SelectedItem != null) {
SController v = (list_customControllers.SelectedItem as SController);
v.type = (byte)(chooseType.SelectedIndex + 1);
}
}
}
}

View file

@ -1,160 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
<appSettings>
<!--Motion Server IP: the default is localhost; you can change it to 0.0.0.0 (all interfaces) or a specific LAN IP
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<!--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" />
<!--Motion Server port: the default is 26760; if it conflicts with another server set it to anything valid
<add key="IP" value="127.0.0.1" />
<!--Motion Server port: the default is 26760; if it conflicts with another server set it to anything valid
but in that case also change the port in PadTest and cemuhook.ini accordingly. Default: 26760 -->
<add key="Port" value="26760" />
<!--Whether the Motion Server is enabled or not. Default: true -->
<add key="MotionServer" value="true" />
<add key="Port" value="26760" />
<!--Whether the Motion Server is enabled or not. Default: true -->
<add key="MotionServer" value="true" />
<!--Rumble motor period in millisec. Lower means more granular vibration, higher is more stable.-->
<!--The response of rumble does not only depend on this setting and it's always high. Default: 300 -->
<add key="RumblePeriod" value="300" />
<!--The controller's HD rumble settings for the low/high frequency rumble. Change to change the pitch of the rumble.-->
<!--Don't set above ~1200. Default: 20 and 20 -->
<add key="LowFreqRumble" value="20" />
<add key="HighFreqRumble" value="20" />
<!--Rumble Setting. Turns rumble on or off.-->
<!--On is "true"; off is "false". Default: true -->
<add key="EnableRumble" value="true" />
<!--Swap A-B buttons; if on, this mimicks the (half of) Xbox layout by the button name, rather than by the physical layout.-->
<!--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.-->
<!--Also swaps buttons when using "Also use for buttons/axes"-->
<!--On is "true"; off is "false". Default: false -->
<add key="SwapXY" value="false" />
<!--The controller's HD rumble settings for the low/high frequency rumble. Change to change the pitch of the rumble.-->
<!--Don't set above ~1200. Default: 40 and 120 -->
<!--To have "stronger" rumble, try setting the low/high to 160/320-->
<add key="LowFreqRumble" value="40" />
<add key="HighFreqRumble" value="120" />
<!--Rumble Setting. Turns rumble on or off.-->
<!--On is "true"; off is "false". Default: true -->
<add key="EnableRumble" value="true" />
<!-- 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", BetterJoyForCemu 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="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.-->
<!--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.-->
<!--Also swaps buttons when using "Also use for buttons/axes"-->
<!--On is "true"; off is "false". Default: false -->
<add key="SwapXY" 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"/>
<!-- Allows for calibration of the controller's gyro. Adds a "Calibrate" button.-->
<!-- When "true", click the "Calibrate" button once to get gyro calibrate data.-->
<!-- When enabled, can only calibrate one controller at a time.-->
<!-- Default: false -->
<add key="AllowCalibration" value="false" />
<!-- Allows to emulate the n64 range of joystick (.8, .8) instead of real xbox360 (1, 1). -->
<add key="N64Range" value="true" />
<!-- Default calibration; used for third party controller -->
<add key="acc_sensiti" value="16384,16384,16384"/>
<add key="gyr_sensiti" value="18642,18642,18642"/>
<add key="stick_cal" value="0x780,0x780,0x780,0x830,0x780,0x780"/>
<add key="deadzone" value="200"/>
<add key="stick2_cal" value="0x780,0x780,0x780,0x830,0x780,0x780"/>
<add key="deadzone2" value="200"/>
<!-- 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 "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"/>
<!-- Sensitivity of gyro-to-mouse movements -->
<!-- Default: 50 -->
<add key="GyroMouseSensitivity" value="50"/>
<!-- When two joycons are connected, it would take the gyro movement of the right joycon for mouse movement. This swaps that -->
<!-- Default: false -->
<add key="GyroMouseLeftHanded" value="false"/>
<!-- Changes drag behaviour. -->
<!-- Will only apply to mouse buttons being mapped -->
<!-- Default: false -->
<add key="DragToggle" value="false"/>
<!-- Scales the xy coordinates each of the joysticks report. Increase this if you can't push the stick to its maximum. -->
<add key="StickScalingFactor" value="1.00" />
<add key="StickScalingFactor2" value="1.00" />
<!-- 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)-->
<!-- Default: false -->
<add key="GyroAnalogSliders" value="false" />
<!-- Change to -400 to change direction of tilt needed. Positive is ramp up if pointing up-->
<!-- Default: 400 -->
<add key="GyroAnalogSensitivity" value="400" />
<!-- 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" />
<!-- The program will keep the HOME button LED ring light on at all times. -->
<!-- Default: true -->
<add key="HomeLEDOn" value="true"/>
<!-- Will use multiple lights to display the current player rather than a single LED-->
<add key="UseIncrementalLights" value="true" />
<!-- Determines whether or not to translate gyro movements into joystick ("joy") or mouse movement ("mouse"), or have no effect ("none") -->
<!-- When "joy_left" or "joy_right", turn gyro movements into respective left/right joystick (mouse-like) movements -->
<!-- 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="false"/>
<!-- Whether to use filtered IMU or raw gyro values (the latter is more responsive) -->
<!-- Default: true -->
<add key="UseFilteredIMU" value="true"/>
<!-- Beta value of AHRS. Affects divergence of filter -->
<!-- Default: 0.05 -->
<add key="AHRS_beta" value="0.05"/>
<!-- Sensitivity of gyro-to-mouse movements -->
<!-- Default: 1200; 800 (if using raw values, decrease by a factor of ~15) -->
<add key="GyroMouseSensitivityX" value="1200"/>
<add key="GyroMouseSensitivityY" value="800"/>
<!-- Sensitivity of gyro-to-joystick movements -->
<!-- Default: 40.0; 10.0 (if using raw values, decrease by a factor of ~15: eg 2.6, 0.6) -->
<add key="GyroStickSensitivityX" value="40.0"/>
<add key="GyroStickSensitivityY" value="10.0"/>
<!-- Stick range reduction when gyro-to-joystick is enabled and active; divides range by factor (so 1 is no change; 1.5 is halved range (with deadzone in mind)) -->
<!-- Default: 1.5 -->
<add key="GyroStickReduction" value="1.5"/>
<!-- Gyro Hold/Toggle activation; true will require the mapped button to be continuously held down to keep gyro active -->
<!-- Default: true [hold], false [toggle] -->
<add key="GyroHoldToggle" value="true"/>
<!-- When two joycons are connected, it would take the gyro movement of the right joycon for mouse movement. This swaps that -->
<!-- Default: false -->
<add key="GyroMouseLeftHanded" value="false"/>
<!-- Changes drag behaviour. -->
<!-- Will only apply to mouse buttons being mapped -->
<!-- Default: false -->
<add key="DragToggle" value="false"/>
<!-- Determines whether or not the program will expose detected controllers as Xbox 360 controllers -->
<!-- When "false", BetterJoy is only usable with programs that support UDPServer. -->
<!-- Default: true -->
<add key="ShowAsXInput" value="true" />
<!-- Have ShowAsXInput as false if using this -->
<!-- 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) -->
<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 -->
<add key="HomeLongPowerOff" value="true" />
<!-- Double click sticks on joycons (L3, R3) to change joycon orientation -->
<!-- Default: true -->
<add key="ChangeOrientationDoubleClick" value="true" />
<!-- Do not rejoin joycons once split via clicking on their icon -->
<!-- When 'true' allows you to double-click the joycons to split them and then change their orientation to vertical -->
<!-- Default: false -->
<add key="DoNotRejoinJoycons" value="false" />
<!-- Determines what type of debugging information to be printed -->
<!-- None = 0 -->
<!-- All = 1 -->
<!-- Comms = 2 -->
<!-- Threading = 3 -->
<!-- IMU = 4 -->
<!-- Rumble = 5 -->
<!-- Shake Input = 6 -->
<!-- Default: 0 -->
<add key="DebugType" value="0" />
</appSettings>
<!-- Determines whether or not the program will expose detected controllers as Xbox 360 controllers -->
<!-- When "false", BetterJoyForCemu is only usable with CEMU. -->
<!-- Default: true -->
<add key="ShowAsXInput" value="true" />
<!-- Have ShowAsXInput as false if using this -->
<!-- Default: false -->
<add key="ShowAsDS4" value="false"/>
</appSettings>
</configuration>

View file

@ -102,8 +102,8 @@
<Reference Include="JetBrains.Annotations, Version=2020.1.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
<HintPath>..\packages\JetBrains.Annotations.2020.1.0\lib\net20\JetBrains.Annotations.dll</HintPath>
</Reference>
<Reference Include="Nefarius.ViGEm.Client, Version=1.17.178.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nefarius.ViGEm.Client.1.17.178\lib\net452\Nefarius.ViGEm.Client.dll</HintPath>
<Reference Include="Nefarius.ViGEm.Client, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nefarius.ViGEm.Client.1.0.0\lib\net452\Nefarius.ViGEm.Client.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
@ -119,8 +119,8 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsInput, Version=6.3.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\WindowsInput.6.3.0\lib\net461\WindowsInput.dll</HintPath>
<Reference Include="WindowsInput, Version=6.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\WindowsInput.6.1.1\lib\net461\WindowsInput.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@ -130,13 +130,9 @@
<Compile Include="3rdPartyControllers.Designer.cs">
<DependentUpon>3rdPartyControllers.cs</DependentUpon>
</Compile>
<Compile Include="Collections\ConcurrentList.cs" />
<Compile Include="Config.cs" />
<Compile Include="Controller\OutputControllerDualShock4.cs" />
<Compile Include="Controller\OutputControllerXbox360.cs" />
<Compile Include="HIDapi.cs" />
<Compile Include="Joycon.cs" />
<Compile Include="MadgwickAHRS.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
@ -180,12 +176,6 @@
<None Include="Drivers\HIDGuardian\_drivers\HidGuardian\HidGuardian.sys">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="Drivers\ViGEmBusSetup_x64.msi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Drivers\ViGEmBusSetup_x86.msi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
@ -238,14 +228,13 @@
<Content Include="Drivers\README.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Icons\snes.png" />
<Content Include="Icons\ultra.png" />
<None Include="Properties\app.manifest" />
<Content Include="Icons\betterjoyforcemu_icon.ico" />
<Content Include="x86\hidapi.dll">
<Content Include="Drivers\ViGEmBus_Setup_1.16.116.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="x64\hidapi.dll">
<Content Include="Icons\snes.png" />
<None Include="Properties\app.manifest" />
<Content Include="Icons\betterjoyforcemu_icon.ico" />
<Content Include="hidapi.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Icons\cross.png" />

View file

@ -1,116 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace BetterJoyForCemu.Collections {
// https://codereview.stackexchange.com/a/125341
public class ConcurrentList<T> : IList<T> {
#region Fields
private IList<T> _internalList;
private readonly object lockObject = new object();
#endregion
#region ctor
public ConcurrentList() {
_internalList = new List<T>();
}
public ConcurrentList(int capacity) {
_internalList = new List<T>(capacity);
}
public ConcurrentList(IEnumerable<T> list) {
_internalList = new List<T>();
foreach (T item in list) {
_internalList.Add(item);
}
}
#endregion
public T this[int index] {
get {
return LockInternalListAndGet(l => l[index]);
}
set {
LockInternalListAndCommand(l => l[index] = value);
}
}
public int Count {
get {
return LockInternalListAndQuery(l => l.Count);
}
}
public bool IsReadOnly => false;
public void Add(T item) {
LockInternalListAndCommand(l => l.Add(item));
}
public void Clear() {
LockInternalListAndCommand(l => l.Clear());
}
public bool Contains(T item) {
return LockInternalListAndQuery(l => l.Contains(item));
}
public void CopyTo(T[] array, int arrayIndex) {
LockInternalListAndCommand(l => l.CopyTo(array, arrayIndex));
}
public IEnumerator<T> GetEnumerator() {
return LockInternalListAndQuery(l => l.GetEnumerator());
}
public int IndexOf(T item) {
return LockInternalListAndQuery(l => l.IndexOf(item));
}
public void Insert(int index, T item) {
LockInternalListAndCommand(l => l.Insert(index, item));
}
public bool Remove(T item) {
return LockInternalListAndQuery(l => l.Remove(item));
}
public void RemoveAt(int index) {
LockInternalListAndCommand(l => l.RemoveAt(index));
}
IEnumerator IEnumerable.GetEnumerator() {
return LockInternalListAndQuery(l => l.GetEnumerator());
}
#region Utilities
protected virtual void LockInternalListAndCommand(Action<IList<T>> action) {
lock (lockObject) {
action(_internalList);
}
}
protected virtual T LockInternalListAndGet(Func<IList<T>, T> func) {
lock (lockObject) {
return func(_internalList);
}
}
protected virtual TObject LockInternalListAndQuery<TObject>(Func<IList<T>, TObject> query) {
lock (lockObject) {
return query(_internalList);
}
}
#endregion
}
}

View file

@ -1,20 +1,19 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterJoyForCemu {
public static class Config { // stores dynamic configuration, including
static readonly string path;
const string PATH = "settings";
static Dictionary<string, string> variables = new Dictionary<string, string>();
const int settingsNum = 11; // currently - ProgressiveScan, StartInTray + special buttons
static Config() {
path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\settings";
}
const int settingsNum = 10; // currently - ProgressiveScan, StartInTray + special buttons
public static string GetDefaultValue(string s) {
switch (s) {
switch(s) {
case "ProgressiveScan":
return "1";
case "capture":
@ -25,36 +24,15 @@ namespace BetterJoyForCemu {
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;
}
using (StreamReader file = new StreamReader(path)) {
if (File.Exists(PATH)) {
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 {
@ -77,9 +55,17 @@ namespace BetterJoyForCemu {
} catch { }
lineNO++;
}
}
// if old settings
if (lineNO < settingsNum) {
File.Delete(PATH);
Init(caliData);
}
} else {
using (StreamWriter file = new StreamWriter(path)) {
using (StreamWriter file = new StreamWriter(PATH)) {
foreach (string k in variables.Keys)
file.WriteLine(String.Format("{0} {1}", k, variables[k]));
string caliStr = "";
@ -115,7 +101,7 @@ namespace BetterJoyForCemu {
}
public static void SaveCaliData(List<KeyValuePair<string, float[]>> caliData) {
string[] txt = File.ReadAllLines(path);
string[] txt = File.ReadAllLines(PATH);
if (txt.Length < settingsNum + 1) // no custom calibrations yet
Array.Resize(ref txt, txt.Length + 1);
@ -125,18 +111,18 @@ namespace BetterJoyForCemu {
if (i == 0) space = "";
caliStr += space + caliData[i].Key + "," + String.Join(",", caliData[i].Value);
}
txt[settingsNum] = caliStr;
File.WriteAllLines(path, txt);
txt[2] = caliStr;
File.WriteAllLines(PATH, txt);
}
public static void Save() {
string[] txt = File.ReadAllLines(path);
string[] txt = File.ReadAllLines(PATH);
int NO = 0;
foreach (string k in variables.Keys) {
txt[NO] = String.Format("{0} {1}", k, variables[k]);
NO++;
}
File.WriteAllLines(path, txt);
File.WriteAllLines(PATH, txt);
}
}
}
}

View file

@ -1,173 +0,0 @@
using System;
using Nefarius.ViGEm.Client.Targets;
using Nefarius.ViGEm.Client.Targets.DualShock4;
namespace BetterJoyForCemu.Controller {
public enum DpadDirection {
None,
Northwest,
West,
Southwest,
South,
Southeast,
East,
Northeast,
North,
}
public struct OutputControllerDualShock4InputState {
public bool triangle;
public bool circle;
public bool cross;
public bool square;
public bool trigger_left;
public bool trigger_right;
public bool shoulder_left;
public bool shoulder_right;
public bool options;
public bool share;
public bool ps;
public bool touchpad;
public bool thumb_left;
public bool thumb_right;
public DpadDirection dPad;
public byte thumb_left_x;
public byte thumb_left_y;
public byte thumb_right_x;
public byte thumb_right_y;
public byte trigger_left_value;
public byte trigger_right_value;
public bool IsEqual(OutputControllerDualShock4InputState other) {
bool buttons = triangle == other.triangle
&& circle == other.circle
&& cross == other.cross
&& square == other.square
&& trigger_left == other.trigger_left
&& trigger_right == other.trigger_right
&& shoulder_left == other.shoulder_left
&& shoulder_right == other.shoulder_right
&& options == other.options
&& share == other.share
&& ps == other.ps
&& touchpad == other.touchpad
&& thumb_left == other.thumb_left
&& thumb_right == other.thumb_right
&& dPad == other.dPad;
bool axis = thumb_left_x == other.thumb_left_x
&& thumb_left_y == other.thumb_left_y
&& thumb_right_x == other.thumb_right_x
&& thumb_right_y == other.thumb_right_y;
bool triggers = trigger_left_value == other.trigger_left_value
&& trigger_right_value == other.trigger_right_value;
return buttons && axis && triggers;
}
}
public class OutputControllerDualShock4 {
private IDualShock4Controller controller;
private OutputControllerDualShock4InputState current_state;
public delegate void DualShock4FeedbackReceivedEventHandler(DualShock4FeedbackReceivedEventArgs e);
public event DualShock4FeedbackReceivedEventHandler FeedbackReceived;
public OutputControllerDualShock4() {
controller = Program.emClient.CreateDualShock4Controller();
Init();
}
public OutputControllerDualShock4(ushort vendor_id, ushort product_id) {
controller = Program.emClient.CreateDualShock4Controller(vendor_id, product_id);
Init();
}
private void Init() {
controller.AutoSubmitReport = false;
controller.FeedbackReceived += FeedbackReceivedRcv;
}
private void FeedbackReceivedRcv(object _sender, DualShock4FeedbackReceivedEventArgs e) {
FeedbackReceived(e);
}
public void Connect() {
controller.Connect();
}
public void Disconnect() {
controller.Disconnect();
}
public bool UpdateInput(OutputControllerDualShock4InputState new_state) {
if (current_state.IsEqual(new_state)) {
return false;
}
DoUpdateInput(new_state);
return true;
}
private void DoUpdateInput(OutputControllerDualShock4InputState new_state) {
controller.SetButtonState(DualShock4Button.Triangle, new_state.triangle);
controller.SetButtonState(DualShock4Button.Circle, new_state.circle);
controller.SetButtonState(DualShock4Button.Cross, new_state.cross);
controller.SetButtonState(DualShock4Button.Square, new_state.square);
controller.SetButtonState(DualShock4Button.ShoulderLeft, new_state.shoulder_left);
controller.SetButtonState(DualShock4Button.ShoulderRight, new_state.shoulder_right);
controller.SetButtonState(DualShock4Button.TriggerLeft, new_state.trigger_left);
controller.SetButtonState(DualShock4Button.TriggerRight, new_state.trigger_right);
controller.SetButtonState(DualShock4Button.ThumbLeft, new_state.thumb_left);
controller.SetButtonState(DualShock4Button.ThumbRight, new_state.thumb_right);
controller.SetButtonState(DualShock4Button.Share, new_state.share);
controller.SetButtonState(DualShock4Button.Options, new_state.options);
controller.SetButtonState(DualShock4SpecialButton.Ps, new_state.ps);
controller.SetButtonState(DualShock4SpecialButton.Touchpad, new_state.touchpad);
controller.SetDPadDirection(MapDPadDirection(new_state.dPad));
controller.SetAxisValue(DualShock4Axis.LeftThumbX, new_state.thumb_left_x);
controller.SetAxisValue(DualShock4Axis.LeftThumbY, new_state.thumb_left_y);
controller.SetAxisValue(DualShock4Axis.RightThumbX, new_state.thumb_right_x);
controller.SetAxisValue(DualShock4Axis.RightThumbY, new_state.thumb_right_y);
controller.SetSliderValue(DualShock4Slider.LeftTrigger, new_state.trigger_left_value);
controller.SetSliderValue(DualShock4Slider.RightTrigger, new_state.trigger_right_value);
controller.SubmitReport();
current_state = new_state;
}
private DualShock4DPadDirection MapDPadDirection(DpadDirection dPad) {
switch (dPad) {
case DpadDirection.None: return DualShock4DPadDirection.None;
case DpadDirection.North: return DualShock4DPadDirection.North;
case DpadDirection.Northeast: return DualShock4DPadDirection.Northeast;
case DpadDirection.East: return DualShock4DPadDirection.East;
case DpadDirection.Southeast: return DualShock4DPadDirection.Southeast;
case DpadDirection.South: return DualShock4DPadDirection.South;
case DpadDirection.Southwest: return DualShock4DPadDirection.Southwest;
case DpadDirection.West: return DualShock4DPadDirection.West;
case DpadDirection.Northwest: return DualShock4DPadDirection.Northwest;
default: throw new NotImplementedException();
}
}
}
}

View file

@ -1,151 +0,0 @@
using Nefarius.ViGEm.Client.Targets;
using Nefarius.ViGEm.Client.Targets.Xbox360;
namespace BetterJoyForCemu.Controller {
public struct OutputControllerXbox360InputState {
// buttons
public bool thumb_stick_left;
public bool thumb_stick_right;
public bool y;
public bool x;
public bool b;
public bool a;
public bool start;
public bool back;
public bool guide;
public bool shoulder_left;
public bool shoulder_right;
// dpad
public bool dpad_up;
public bool dpad_right;
public bool dpad_down;
public bool dpad_left;
// axis
public short axis_left_x;
public short axis_left_y;
public short axis_right_x;
public short axis_right_y;
// triggers
public byte trigger_left;
public byte trigger_right;
public bool IsEqual(OutputControllerXbox360InputState other) {
bool buttons = thumb_stick_left == other.thumb_stick_left
&& thumb_stick_right == other.thumb_stick_right
&& y == other.y
&& x == other.x
&& b == other.b
&& a == other.a
&& start == other.start
&& back == other.back
&& guide == other.guide
&& shoulder_left == other.shoulder_left
&& shoulder_right == other.shoulder_right;
bool dpad = dpad_up == other.dpad_up
&& dpad_right == other.dpad_right
&& dpad_down == other.dpad_down
&& dpad_left == other.dpad_left;
bool axis = axis_left_x == other.axis_left_x
&& axis_left_y == other.axis_left_y
&& axis_right_x == other.axis_right_x
&& axis_right_y == other.axis_right_y;
bool triggers = trigger_left == other.trigger_left
&& trigger_right == other.trigger_right;
return buttons && dpad && axis && triggers;
}
}
public class OutputControllerXbox360 {
private IXbox360Controller xbox_controller;
private OutputControllerXbox360InputState current_state;
public delegate void Xbox360FeedbackReceivedEventHandler(Xbox360FeedbackReceivedEventArgs e);
public event Xbox360FeedbackReceivedEventHandler FeedbackReceived;
public OutputControllerXbox360() {
xbox_controller = Program.emClient.CreateXbox360Controller();
Init();
}
public OutputControllerXbox360(ushort vendor_id, ushort product_id) {
xbox_controller = Program.emClient.CreateXbox360Controller(vendor_id, product_id);
Init();
}
private void Init() {
xbox_controller.FeedbackReceived += FeedbackReceivedRcv;
xbox_controller.AutoSubmitReport = false;
}
private void FeedbackReceivedRcv(object _sender, Xbox360FeedbackReceivedEventArgs e) {
if(FeedbackReceived!=null)
FeedbackReceived(e);
}
public bool UpdateInput(OutputControllerXbox360InputState new_state) {
if (current_state.IsEqual(new_state)) {
return false;
}
DoUpdateInput(new_state);
return true;
}
public void Connect() {
xbox_controller.Connect();
DoUpdateInput(new OutputControllerXbox360InputState());
}
public void Disconnect() {
xbox_controller.Disconnect();
}
private void DoUpdateInput(OutputControllerXbox360InputState new_state) {
xbox_controller.SetButtonState(Xbox360Button.LeftThumb, new_state.thumb_stick_left);
xbox_controller.SetButtonState(Xbox360Button.RightThumb, new_state.thumb_stick_right);
xbox_controller.SetButtonState(Xbox360Button.Y, new_state.y);
xbox_controller.SetButtonState(Xbox360Button.X, new_state.x);
xbox_controller.SetButtonState(Xbox360Button.B, new_state.b);
xbox_controller.SetButtonState(Xbox360Button.A, new_state.a);
xbox_controller.SetButtonState(Xbox360Button.Start, new_state.start);
xbox_controller.SetButtonState(Xbox360Button.Back, new_state.back);
xbox_controller.SetButtonState(Xbox360Button.Guide, new_state.guide);
xbox_controller.SetButtonState(Xbox360Button.Up, new_state.dpad_up);
xbox_controller.SetButtonState(Xbox360Button.Right, new_state.dpad_right);
xbox_controller.SetButtonState(Xbox360Button.Down, new_state.dpad_down);
xbox_controller.SetButtonState(Xbox360Button.Left, new_state.dpad_left);
xbox_controller.SetButtonState(Xbox360Button.LeftShoulder, new_state.shoulder_left);
xbox_controller.SetButtonState(Xbox360Button.RightShoulder, new_state.shoulder_right);
xbox_controller.SetAxisValue(Xbox360Axis.LeftThumbX, new_state.axis_left_x);
xbox_controller.SetAxisValue(Xbox360Axis.LeftThumbY, new_state.axis_left_y);
xbox_controller.SetAxisValue(Xbox360Axis.RightThumbX, new_state.axis_right_x);
xbox_controller.SetAxisValue(Xbox360Axis.RightThumbY, new_state.axis_right_y);
xbox_controller.SetSliderValue(Xbox360Slider.LeftTrigger, new_state.trigger_left);
xbox_controller.SetSliderValue(Xbox360Slider.RightTrigger, new_state.trigger_right);
xbox_controller.SubmitReport();
current_state = new_state;
}
}
}

Binary file not shown.

View file

@ -3,11 +3,11 @@ using System.Runtime.InteropServices;
namespace BetterJoyForCemu {
public class HIDapi {
#if LINUX
const string dll = "libhidapi.so";
#else
const string dll = "hidapi.dll";
#endif
#if LINUX
const string dll = "libhidapi.so";
#else
const string dll = "hidapi.dll";
#endif
public struct hid_device_info {
[MarshalAs(UnmanagedType.LPStr)]
@ -40,10 +40,10 @@ namespace BetterJoyForCemu {
public static extern void hid_free_enumeration(IntPtr phid_device_info);
[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr hid_open(ushort vendor_id, ushort product_id, [MarshalAs(UnmanagedType.LPWStr)] string serial_number);
public static extern IntPtr hid_open(ushort vendor_id, ushort product_id, [MarshalAs(UnmanagedType.LPWStr)]string serial_number);
[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr hid_open_path([MarshalAs(UnmanagedType.LPStr)] string path);
public static extern IntPtr hid_open_path([MarshalAs(UnmanagedType.LPStr)]string path);
[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
public static extern int hid_write(IntPtr device, byte[] data, UIntPtr length);
@ -67,16 +67,16 @@ namespace BetterJoyForCemu {
public static extern void hid_close(IntPtr device);
[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
public static extern int hid_get_manufacturer_string(IntPtr device, [MarshalAs(UnmanagedType.LPWStr)] string string_, UIntPtr maxlen);
public static extern int hid_get_manufacturer_string(IntPtr device, [MarshalAs(UnmanagedType.LPWStr)]string string_, UIntPtr maxlen);
[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
public static extern int hid_get_product_string(IntPtr device, [MarshalAs(UnmanagedType.LPWStr)] string string_, UIntPtr maxlen);
public static extern int hid_get_product_string(IntPtr device, [MarshalAs(UnmanagedType.LPWStr)]string string_, UIntPtr maxlen);
[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
public static extern int hid_get_serial_number_string(IntPtr device, [MarshalAs(UnmanagedType.LPWStr)] string string_, UIntPtr maxlen);
public static extern int hid_get_serial_number_string(IntPtr device, [MarshalAs(UnmanagedType.LPWStr)]string string_, UIntPtr maxlen);
[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
public static extern int hid_get_indexed_string(IntPtr device, int string_index, [MarshalAs(UnmanagedType.LPWStr)] string string_, UIntPtr maxlen);
public static extern int hid_get_indexed_string(IntPtr device, int string_index, [MarshalAs(UnmanagedType.LPWStr)]string string_, UIntPtr maxlen);
[DllImport(dll, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.LPWStr)]
@ -112,4 +112,4 @@ namespace BetterJoyForCemu {
return _getDevicePath(hid_enumerate(vendorId, productId), usagePage, usage);
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because it is too large Load diff

View file

@ -1,162 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// source: https://github.com/xioTechnologies/Open-Source-AHRS-With-x-IMU/blob/master/x-IMU%20IMU%20and%20AHRS%20Algorithms/x-IMU%20IMU%20and%20AHRS%20Algorithms/AHRS/MadgwickAHRS.cs
namespace BetterJoyForCemu {
/// <summary>
/// MadgwickAHRS class. Implementation of Madgwick's IMU and AHRS algorithms.
/// </summary>
/// <remarks>
/// See: http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms
/// </remarks>
public class MadgwickAHRS {
/// <summary>
/// Gets or sets the sample period.
/// </summary>
public float SamplePeriod { get; set; }
/// <summary>
/// Gets or sets the algorithm gain beta.
/// </summary>
public float Beta { get; set; }
/// <summary>
/// Gets or sets the Quaternion output.
/// </summary>
public float[] Quaternion { get; set; }
public float[] old_pitchYawRoll { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MadgwickAHRS"/> class.
/// </summary>
/// <param name="samplePeriod">
/// Sample period.
/// </param>
public MadgwickAHRS(float samplePeriod)
: this(samplePeriod, 1f) {
}
/// <summary>
/// Initializes a new instance of the <see cref="MadgwickAHRS"/> class.
/// </summary>
/// <param name="samplePeriod">
/// Sample period.
/// </param>
/// <param name="beta">
/// Algorithm gain beta.
/// </param>
public MadgwickAHRS(float samplePeriod, float beta) {
SamplePeriod = samplePeriod;
Beta = beta;
Quaternion = new float[] { 1f, 0f, 0f, 0f };
old_pitchYawRoll = new float[] { 0f, 0f, 0f };
}
/// <summary>
/// Algorithm IMU update method. Requires only gyroscope and accelerometer data.
/// </summary>
/// <param name="gx">
/// Gyroscope x axis measurement in radians/s.
/// </param>
/// <param name="gy">
/// Gyroscope y axis measurement in radians/s.
/// </param>
/// <param name="gz">
/// Gyroscope z axis measurement in radians/s.
/// </param>
/// <param name="ax">
/// Accelerometer x axis measurement in any calibrated units.
/// </param>
/// <param name="ay">
/// Accelerometer y axis measurement in any calibrated units.
/// </param>
/// <param name="az">
/// Accelerometer z axis measurement in any calibrated units.
/// </param>
/// <remarks>
/// Optimised for minimal arithmetic.
/// Total ±: 45
/// Total *: 85
/// Total /: 3
/// Total sqrt: 3
/// </remarks>
public void Update(float gx, float gy, float gz, float ax, float ay, float az) {
float q1 = Quaternion[0], q2 = Quaternion[1], q3 = Quaternion[2], q4 = Quaternion[3]; // short name local variable for readability
float norm;
float s1, s2, s3, s4;
float qDot1, qDot2, qDot3, qDot4;
// Auxiliary variables to avoid repeated arithmetic
float _2q1 = 2f * q1;
float _2q2 = 2f * q2;
float _2q3 = 2f * q3;
float _2q4 = 2f * q4;
float _4q1 = 4f * q1;
float _4q2 = 4f * q2;
float _4q3 = 4f * q3;
float _8q2 = 8f * q2;
float _8q3 = 8f * q3;
float q1q1 = q1 * q1;
float q2q2 = q2 * q2;
float q3q3 = q3 * q3;
float q4q4 = q4 * q4;
// Normalise accelerometer measurement
norm = (float)Math.Sqrt(ax * ax + ay * ay + az * az);
if (norm == 0f) return; // handle NaN
norm = 1 / norm; // use reciprocal for division
ax *= norm;
ay *= norm;
az *= norm;
// Gradient decent algorithm corrective step
s1 = _4q1 * q3q3 + _2q3 * ax + _4q1 * q2q2 - _2q2 * ay;
s2 = _4q2 * q4q4 - _2q4 * ax + 4f * q1q1 * q2 - _2q1 * ay - _4q2 + _8q2 * q2q2 + _8q2 * q3q3 + _4q2 * az;
s3 = 4f * q1q1 * q3 + _2q1 * ax + _4q3 * q4q4 - _2q4 * ay - _4q3 + _8q3 * q2q2 + _8q3 * q3q3 + _4q3 * az;
s4 = 4f * q2q2 * q4 - _2q2 * ax + 4f * q3q3 * q4 - _2q3 * ay;
norm = 1f / (float)Math.Sqrt(s1 * s1 + s2 * s2 + s3 * s3 + s4 * s4); // normalise step magnitude
s1 *= norm;
s2 *= norm;
s3 *= norm;
s4 *= norm;
// Compute rate of change of quaternion
qDot1 = 0.5f * (-q2 * gx - q3 * gy - q4 * gz) - Beta * s1;
qDot2 = 0.5f * (q1 * gx + q3 * gz - q4 * gy) - Beta * s2;
qDot3 = 0.5f * (q1 * gy - q2 * gz + q4 * gx) - Beta * s3;
qDot4 = 0.5f * (q1 * gz + q2 * gy - q3 * gx) - Beta * s4;
// Integrate to yield quaternion
q1 += qDot1 * SamplePeriod;
q2 += qDot2 * SamplePeriod;
q3 += qDot3 * SamplePeriod;
q4 += qDot4 * SamplePeriod;
norm = 1f / (float)Math.Sqrt(q1 * q1 + q2 * q2 + q3 * q3 + q4 * q4); // normalise quaternion
Quaternion[0] = q1 * norm;
Quaternion[1] = q2 * norm;
Quaternion[2] = q3 * norm;
Quaternion[3] = q4 * norm;
}
public float[] GetEulerAngles() {
float[] pitchYawRoll = new float[3];
float q0 = Quaternion[0], q1 = Quaternion[1], q2 = Quaternion[2], q3 = Quaternion[3];
float sq1 = q1 * q1, sq2 = q2 * q2, sq3 = q3 * q3;
pitchYawRoll[0] = (float)Math.Asin(2f * (q0 * q2 - q3 * q1)); // Pitch
pitchYawRoll[1] = (float)Math.Atan2(2f * (q0 * q3 + q1 * q2), 1 - 2f * (sq2 + sq3)); // Yaw
pitchYawRoll[2] = (float)Math.Atan2(2f * (q0 * q1 + q2 * q3), 1 - 2f * (sq1 + sq2)); // Roll
float[] returnAngles = new float[6];
Array.Copy(pitchYawRoll, returnAngles, 3);
Array.Copy(old_pitchYawRoll, 0, returnAngles, 3, 3);
old_pitchYawRoll = pitchYawRoll;
return returnAngles;
}
}
}

View file

@ -1,381 +1,393 @@
namespace BetterJoyForCemu {
partial class MainForm {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
partial class MainForm {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.console = new System.Windows.Forms.TextBox();
this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
this.contextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.version_lbl = new System.Windows.Forms.Label();
this.passiveScanBox = new System.Windows.Forms.CheckBox();
this.donationLink = new System.Windows.Forms.LinkLabel();
this.conCntrls = new System.Windows.Forms.GroupBox();
this.loc4 = new System.Windows.Forms.Button();
this.loc3 = new System.Windows.Forms.Button();
this.loc2 = new System.Windows.Forms.Button();
this.loc1 = new System.Windows.Forms.Button();
this.con4 = new System.Windows.Forms.Button();
this.con3 = new System.Windows.Forms.Button();
this.con2 = new System.Windows.Forms.Button();
this.con1 = new System.Windows.Forms.Button();
this.btnTip = new System.Windows.Forms.ToolTip(this.components);
this.foldLbl = new System.Windows.Forms.Label();
this.startInTrayBox = new System.Windows.Forms.CheckBox();
this.btn_open3rdP = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.settingsTable = new System.Windows.Forms.TableLayoutPanel();
this.rightPanel = new System.Windows.Forms.Panel();
this.settingsApply = new System.Windows.Forms.Button();
this.AutoCalibrate = new System.Windows.Forms.Button();
this.btn_reassign_open = new System.Windows.Forms.Button();
this.contextMenu.SuspendLayout();
this.conCntrls.SuspendLayout();
this.groupBox1.SuspendLayout();
this.rightPanel.SuspendLayout();
this.SuspendLayout();
//
// console
//
this.console.Location = new System.Drawing.Point(12, 132);
this.console.Multiline = true;
this.console.Name = "console";
this.console.ReadOnly = true;
this.console.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.console.Size = new System.Drawing.Size(262, 100);
this.console.TabIndex = 2;
//
// notifyIcon
//
this.notifyIcon.BalloonTipText = "Double click the tray icon to maximise!";
this.notifyIcon.BalloonTipTitle = "BetterJoy";
this.notifyIcon.ContextMenuStrip = this.contextMenu;
this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon")));
this.notifyIcon.Text = "BetterJoy";
this.notifyIcon.Visible = true;
this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon_MouseDoubleClick);
//
// contextMenu
//
this.contextMenu.ImageScalingSize = new System.Drawing.Size(24, 24);
this.contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.console = new System.Windows.Forms.TextBox();
this.console_lbl = new System.Windows.Forms.Label();
this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
this.contextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.version_lbl = new System.Windows.Forms.Label();
this.passiveScanBox = new System.Windows.Forms.CheckBox();
this.donationLink = new System.Windows.Forms.LinkLabel();
this.conCntrls = new System.Windows.Forms.GroupBox();
this.loc4 = new System.Windows.Forms.Button();
this.loc3 = new System.Windows.Forms.Button();
this.loc2 = new System.Windows.Forms.Button();
this.loc1 = new System.Windows.Forms.Button();
this.con4 = new System.Windows.Forms.Button();
this.con3 = new System.Windows.Forms.Button();
this.con2 = new System.Windows.Forms.Button();
this.con1 = new System.Windows.Forms.Button();
this.btnTip = new System.Windows.Forms.ToolTip(this.components);
this.foldLbl = new System.Windows.Forms.Label();
this.startInTrayBox = new System.Windows.Forms.CheckBox();
this.btn_open3rdP = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.settingsTable = new System.Windows.Forms.TableLayoutPanel();
this.rightPanel = new System.Windows.Forms.Panel();
this.settingsApply = new System.Windows.Forms.Button();
this.AutoCalibrate = new System.Windows.Forms.Button();
this.btn_reassign_open = new System.Windows.Forms.Button();
this.contextMenu.SuspendLayout();
this.conCntrls.SuspendLayout();
this.groupBox1.SuspendLayout();
this.rightPanel.SuspendLayout();
this.SuspendLayout();
//
// console
//
this.console.Location = new System.Drawing.Point(12, 132);
this.console.Multiline = true;
this.console.Name = "console";
this.console.ReadOnly = true;
this.console.Size = new System.Drawing.Size(262, 100);
this.console.TabIndex = 2;
//
// console_lbl
//
this.console_lbl.AutoSize = true;
this.console_lbl.Location = new System.Drawing.Point(9, 116);
this.console_lbl.Name = "console_lbl";
this.console_lbl.Size = new System.Drawing.Size(80, 13);
this.console_lbl.TabIndex = 1;
this.console_lbl.Text = "Console Output";
this.console_lbl.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// notifyIcon
//
this.notifyIcon.BalloonTipText = "Double click the tray icon to maximise";
this.notifyIcon.BalloonTipTitle = "BetterJoyForCemu";
this.notifyIcon.ContextMenuStrip = this.contextMenu;
this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon")));
this.notifyIcon.Text = "BetterJoyForCemu";
this.notifyIcon.Visible = true;
this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon_MouseDoubleClick);
//
// contextMenu
//
this.contextMenu.ImageScalingSize = new System.Drawing.Size(24, 24);
this.contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.exitToolStripMenuItem});
this.contextMenu.Name = "contextMenu";
this.contextMenu.Size = new System.Drawing.Size(94, 26);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(93, 22);
this.exitToolStripMenuItem.Text = "Exit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// version_lbl
//
this.version_lbl.AutoSize = true;
this.version_lbl.Location = new System.Drawing.Point(246, 239);
this.version_lbl.Name = "version_lbl";
this.version_lbl.Size = new System.Drawing.Size(28, 13);
this.version_lbl.TabIndex = 2;
this.version_lbl.Text = "v7.1";
//
// passiveScanBox
//
this.passiveScanBox.AutoSize = true;
this.passiveScanBox.Checked = true;
this.passiveScanBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.passiveScanBox.Location = new System.Drawing.Point(12, 238);
this.passiveScanBox.Name = "passiveScanBox";
this.passiveScanBox.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
this.passiveScanBox.Size = new System.Drawing.Size(91, 17);
this.passiveScanBox.TabIndex = 4;
this.passiveScanBox.Text = "Passive Scan";
this.passiveScanBox.UseVisualStyleBackColor = true;
this.passiveScanBox.CheckedChanged += new System.EventHandler(this.passiveScanBox_CheckedChanged);
//
// donationLink
//
this.donationLink.AutoSize = true;
this.donationLink.Location = new System.Drawing.Point(196, 239);
this.donationLink.Name = "donationLink";
this.donationLink.Size = new System.Drawing.Size(42, 13);
this.donationLink.TabIndex = 5;
this.donationLink.TabStop = true;
this.donationLink.Text = "Donate";
this.donationLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
//
// conCntrls
//
this.conCntrls.Controls.Add(this.loc4);
this.conCntrls.Controls.Add(this.loc3);
this.conCntrls.Controls.Add(this.loc2);
this.conCntrls.Controls.Add(this.loc1);
this.conCntrls.Controls.Add(this.con4);
this.conCntrls.Controls.Add(this.con3);
this.conCntrls.Controls.Add(this.con2);
this.conCntrls.Controls.Add(this.con1);
this.conCntrls.Location = new System.Drawing.Point(12, 12);
this.conCntrls.Name = "conCntrls";
this.conCntrls.Size = new System.Drawing.Size(262, 100);
this.conCntrls.TabIndex = 0;
this.conCntrls.TabStop = false;
this.conCntrls.Text = "Connected Controllers";
//
// loc4
//
this.loc4.Location = new System.Drawing.Point(198, 80);
this.loc4.Name = "loc4";
this.loc4.Size = new System.Drawing.Size(58, 20);
this.loc4.TabIndex = 7;
this.loc4.Text = "Locate";
this.loc4.UseVisualStyleBackColor = true;
//
// loc3
//
this.loc3.Location = new System.Drawing.Point(134, 80);
this.loc3.Name = "loc3";
this.loc3.Size = new System.Drawing.Size(58, 20);
this.loc3.TabIndex = 6;
this.loc3.Text = "Locate";
this.loc3.UseVisualStyleBackColor = true;
//
// loc2
//
this.loc2.Location = new System.Drawing.Point(70, 80);
this.loc2.Name = "loc2";
this.loc2.Size = new System.Drawing.Size(58, 20);
this.loc2.TabIndex = 5;
this.loc2.Text = "Locate";
this.loc2.UseVisualStyleBackColor = true;
//
// loc1
//
this.loc1.Location = new System.Drawing.Point(6, 80);
this.loc1.Name = "loc1";
this.loc1.Size = new System.Drawing.Size(58, 20);
this.loc1.TabIndex = 4;
this.loc1.Text = "Locate";
this.loc1.UseVisualStyleBackColor = true;
//
// con4
//
this.con4.BackgroundImage = global::BetterJoyForCemu.Properties.Resources.cross;
this.con4.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.con4.Enabled = false;
this.con4.Location = new System.Drawing.Point(198, 20);
this.con4.Name = "con4";
this.con4.Size = new System.Drawing.Size(58, 59);
this.con4.TabIndex = 3;
this.con4.TabStop = false;
this.con4.UseVisualStyleBackColor = true;
//
// con3
//
this.con3.BackgroundImage = global::BetterJoyForCemu.Properties.Resources.cross;
this.con3.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.con3.Enabled = false;
this.con3.Location = new System.Drawing.Point(134, 20);
this.con3.Name = "con3";
this.con3.Size = new System.Drawing.Size(58, 59);
this.con3.TabIndex = 2;
this.con3.TabStop = false;
this.con3.UseVisualStyleBackColor = true;
//
// con2
//
this.con2.BackgroundImage = global::BetterJoyForCemu.Properties.Resources.cross;
this.con2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.con2.Enabled = false;
this.con2.Location = new System.Drawing.Point(70, 20);
this.con2.Name = "con2";
this.con2.Size = new System.Drawing.Size(58, 59);
this.con2.TabIndex = 1;
this.con2.TabStop = false;
this.con2.UseVisualStyleBackColor = true;
//
// con1
//
this.con1.BackgroundImage = global::BetterJoyForCemu.Properties.Resources.cross;
this.con1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.con1.Enabled = false;
this.con1.Location = new System.Drawing.Point(6, 20);
this.con1.Name = "con1";
this.con1.Size = new System.Drawing.Size(58, 59);
this.con1.TabIndex = 0;
this.con1.TabStop = false;
this.btnTip.SetToolTip(this.con1, "Click on Joycons to join/split them");
this.con1.UseVisualStyleBackColor = true;
//
// foldLbl
//
this.foldLbl.Location = new System.Drawing.Point(274, 20);
this.foldLbl.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.foldLbl.Name = "foldLbl";
this.foldLbl.Size = new System.Drawing.Size(13, 231);
this.foldLbl.TabIndex = 12;
this.foldLbl.Text = ">";
this.foldLbl.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.btnTip.SetToolTip(this.foldLbl, "Config");
this.foldLbl.Click += new System.EventHandler(this.foldLbl_Click);
//
// startInTrayBox
//
this.startInTrayBox.AutoSize = true;
this.startInTrayBox.Location = new System.Drawing.Point(107, 238);
this.startInTrayBox.Name = "startInTrayBox";
this.startInTrayBox.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
this.startInTrayBox.Size = new System.Drawing.Size(83, 17);
this.startInTrayBox.TabIndex = 6;
this.startInTrayBox.Text = "Start in Tray";
this.startInTrayBox.UseVisualStyleBackColor = true;
this.startInTrayBox.CheckedChanged += new System.EventHandler(this.startInTrayBox_CheckedChanged);
//
// btn_open3rdP
//
this.btn_open3rdP.Location = new System.Drawing.Point(93, 112);
this.btn_open3rdP.Name = "btn_open3rdP";
this.btn_open3rdP.Size = new System.Drawing.Size(86, 20);
this.btn_open3rdP.TabIndex = 7;
this.btn_open3rdP.Text = "Add Controllers";
this.btn_open3rdP.UseVisualStyleBackColor = true;
this.btn_open3rdP.Click += new System.EventHandler(this.btn_open3rdP_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.settingsTable);
this.groupBox1.Location = new System.Drawing.Point(3, 11);
this.groupBox1.Margin = new System.Windows.Forms.Padding(2);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Padding = new System.Windows.Forms.Padding(2);
this.groupBox1.Size = new System.Drawing.Size(304, 242);
this.groupBox1.TabIndex = 9;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Config";
//
// settingsTable
//
this.settingsTable.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
this.contextMenu.Name = "contextMenu";
this.contextMenu.Size = new System.Drawing.Size(94, 26);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(93, 22);
this.exitToolStripMenuItem.Text = "Exit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
// version_lbl
//
this.version_lbl.AutoSize = true;
this.version_lbl.Location = new System.Drawing.Point(246, 239);
this.version_lbl.Name = "version_lbl";
this.version_lbl.Size = new System.Drawing.Size(28, 13);
this.version_lbl.TabIndex = 2;
this.version_lbl.Text = "v6.0";
//
// passiveScanBox
//
this.passiveScanBox.AutoSize = true;
this.passiveScanBox.Checked = true;
this.passiveScanBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.passiveScanBox.Location = new System.Drawing.Point(12, 238);
this.passiveScanBox.Name = "passiveScanBox";
this.passiveScanBox.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
this.passiveScanBox.Size = new System.Drawing.Size(91, 17);
this.passiveScanBox.TabIndex = 4;
this.passiveScanBox.Text = "Passive Scan";
this.passiveScanBox.UseVisualStyleBackColor = true;
this.passiveScanBox.CheckedChanged += new System.EventHandler(this.passiveScanBox_CheckedChanged);
//
// donationLink
//
this.donationLink.AutoSize = true;
this.donationLink.Location = new System.Drawing.Point(196, 239);
this.donationLink.Name = "donationLink";
this.donationLink.Size = new System.Drawing.Size(42, 13);
this.donationLink.TabIndex = 5;
this.donationLink.TabStop = true;
this.donationLink.Text = "Donate";
this.donationLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
//
// conCntrls
//
this.conCntrls.Controls.Add(this.loc4);
this.conCntrls.Controls.Add(this.loc3);
this.conCntrls.Controls.Add(this.loc2);
this.conCntrls.Controls.Add(this.loc1);
this.conCntrls.Controls.Add(this.con4);
this.conCntrls.Controls.Add(this.con3);
this.conCntrls.Controls.Add(this.con2);
this.conCntrls.Controls.Add(this.con1);
this.conCntrls.Location = new System.Drawing.Point(12, 12);
this.conCntrls.Name = "conCntrls";
this.conCntrls.Size = new System.Drawing.Size(262, 100);
this.conCntrls.TabIndex = 0;
this.conCntrls.TabStop = false;
this.conCntrls.Text = "Connected Controllers";
//
// loc4
//
this.loc4.Location = new System.Drawing.Point(198, 80);
this.loc4.Name = "loc4";
this.loc4.Size = new System.Drawing.Size(58, 20);
this.loc4.TabIndex = 7;
this.loc4.Text = "Locate";
this.loc4.UseVisualStyleBackColor = true;
//
// loc3
//
this.loc3.Location = new System.Drawing.Point(134, 80);
this.loc3.Name = "loc3";
this.loc3.Size = new System.Drawing.Size(58, 20);
this.loc3.TabIndex = 6;
this.loc3.Text = "Locate";
this.loc3.UseVisualStyleBackColor = true;
//
// loc2
//
this.loc2.Location = new System.Drawing.Point(70, 80);
this.loc2.Name = "loc2";
this.loc2.Size = new System.Drawing.Size(58, 20);
this.loc2.TabIndex = 5;
this.loc2.Text = "Locate";
this.loc2.UseVisualStyleBackColor = true;
//
// loc1
//
this.loc1.Location = new System.Drawing.Point(6, 80);
this.loc1.Name = "loc1";
this.loc1.Size = new System.Drawing.Size(58, 20);
this.loc1.TabIndex = 4;
this.loc1.Text = "Locate";
this.loc1.UseVisualStyleBackColor = true;
//
// con4
//
this.con4.BackgroundImage = global::BetterJoyForCemu.Properties.Resources.cross;
this.con4.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.con4.Enabled = false;
this.con4.Location = new System.Drawing.Point(198, 20);
this.con4.Name = "con4";
this.con4.Size = new System.Drawing.Size(58, 59);
this.con4.TabIndex = 3;
this.con4.TabStop = false;
this.con4.UseVisualStyleBackColor = true;
//
// con3
//
this.con3.BackgroundImage = global::BetterJoyForCemu.Properties.Resources.cross;
this.con3.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.con3.Enabled = false;
this.con3.Location = new System.Drawing.Point(134, 20);
this.con3.Name = "con3";
this.con3.Size = new System.Drawing.Size(58, 59);
this.con3.TabIndex = 2;
this.con3.TabStop = false;
this.con3.UseVisualStyleBackColor = true;
//
// con2
//
this.con2.BackgroundImage = global::BetterJoyForCemu.Properties.Resources.cross;
this.con2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.con2.Enabled = false;
this.con2.Location = new System.Drawing.Point(70, 20);
this.con2.Name = "con2";
this.con2.Size = new System.Drawing.Size(58, 59);
this.con2.TabIndex = 1;
this.con2.TabStop = false;
this.con2.UseVisualStyleBackColor = true;
//
// con1
//
this.con1.BackgroundImage = global::BetterJoyForCemu.Properties.Resources.cross;
this.con1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.con1.Enabled = false;
this.con1.Location = new System.Drawing.Point(6, 20);
this.con1.Name = "con1";
this.con1.Size = new System.Drawing.Size(58, 59);
this.con1.TabIndex = 0;
this.con1.TabStop = false;
this.btnTip.SetToolTip(this.con1, "Click on Joycons to join/split them");
this.con1.UseVisualStyleBackColor = true;
//
// foldLbl
//
this.foldLbl.Location = new System.Drawing.Point(274, 20);
this.foldLbl.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.foldLbl.Name = "foldLbl";
this.foldLbl.Size = new System.Drawing.Size(13, 231);
this.foldLbl.TabIndex = 12;
this.foldLbl.Text = ">";
this.foldLbl.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.btnTip.SetToolTip(this.foldLbl, "Config");
this.foldLbl.Click += new System.EventHandler(this.foldLbl_Click);
//
// startInTrayBox
//
this.startInTrayBox.AutoSize = true;
this.startInTrayBox.Location = new System.Drawing.Point(107, 238);
this.startInTrayBox.Name = "startInTrayBox";
this.startInTrayBox.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
this.startInTrayBox.Size = new System.Drawing.Size(83, 17);
this.startInTrayBox.TabIndex = 6;
this.startInTrayBox.Text = "Start in Tray";
this.startInTrayBox.UseVisualStyleBackColor = true;
this.startInTrayBox.CheckedChanged += new System.EventHandler(this.startInTrayBox_CheckedChanged);
//
// btn_open3rdP
//
this.btn_open3rdP.Location = new System.Drawing.Point(188, 112);
this.btn_open3rdP.Name = "btn_open3rdP";
this.btn_open3rdP.Size = new System.Drawing.Size(86, 20);
this.btn_open3rdP.TabIndex = 7;
this.btn_open3rdP.Text = "Add Controllers";
this.btn_open3rdP.UseVisualStyleBackColor = true;
this.btn_open3rdP.Click += new System.EventHandler(this.btn_open3rdP_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.settingsTable);
this.groupBox1.Location = new System.Drawing.Point(3, 11);
this.groupBox1.Margin = new System.Windows.Forms.Padding(2);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Padding = new System.Windows.Forms.Padding(2);
this.groupBox1.Size = new System.Drawing.Size(227, 242);
this.groupBox1.TabIndex = 9;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Config";
//
// settingsTable
//
this.settingsTable.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.settingsTable.AutoScroll = true;
this.settingsTable.ColumnCount = 2;
this.settingsTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.90411F));
this.settingsTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.09589F));
this.settingsTable.Location = new System.Drawing.Point(4, 17);
this.settingsTable.Margin = new System.Windows.Forms.Padding(2);
this.settingsTable.Name = "settingsTable";
this.settingsTable.RowCount = 1;
this.settingsTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.settingsTable.Size = new System.Drawing.Size(300, 219);
this.settingsTable.TabIndex = 1;
//
// rightPanel
//
this.rightPanel.Controls.Add(this.settingsApply);
this.rightPanel.Controls.Add(this.groupBox1);
this.rightPanel.Location = new System.Drawing.Point(289, 1);
this.rightPanel.Margin = new System.Windows.Forms.Padding(2, 2, 12, 2);
this.rightPanel.Name = "rightPanel";
this.rightPanel.Size = new System.Drawing.Size(312, 273);
this.rightPanel.TabIndex = 11;
this.rightPanel.Visible = false;
//
// settingsApply
//
this.settingsApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.settingsApply.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.settingsApply.Location = new System.Drawing.Point(246, 252);
this.settingsApply.Margin = new System.Windows.Forms.Padding(2);
this.settingsApply.Name = "settingsApply";
this.settingsApply.Size = new System.Drawing.Size(61, 21);
this.settingsApply.TabIndex = 10;
this.settingsApply.Text = "Apply";
this.settingsApply.UseVisualStyleBackColor = true;
this.settingsApply.Click += new System.EventHandler(this.settingsApply_Click);
//
// AutoCalibrate
//
this.AutoCalibrate.Location = new System.Drawing.Point(203, 112);
this.AutoCalibrate.Name = "AutoCalibrate";
this.AutoCalibrate.Size = new System.Drawing.Size(71, 20);
this.AutoCalibrate.TabIndex = 8;
this.AutoCalibrate.Text = "Calibrate";
this.AutoCalibrate.UseVisualStyleBackColor = true;
this.AutoCalibrate.Click += new System.EventHandler(this.StartCalibrate);
//
// btn_reassign_open
//
this.btn_reassign_open.Location = new System.Drawing.Point(12, 112);
this.btn_reassign_open.Name = "btn_reassign_open";
this.btn_reassign_open.Size = new System.Drawing.Size(75, 20);
this.btn_reassign_open.TabIndex = 13;
this.btn_reassign_open.Text = "Map Buttons";
this.btn_reassign_open.UseVisualStyleBackColor = true;
this.btn_reassign_open.Click += new System.EventHandler(this.btn_reassign_open_Click);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ClientSize = new System.Drawing.Size(615, 308);
this.Controls.Add(this.btn_reassign_open);
this.Controls.Add(this.foldLbl);
this.Controls.Add(this.rightPanel);
this.Controls.Add(this.AutoCalibrate);
this.Controls.Add(this.btn_open3rdP);
this.Controls.Add(this.startInTrayBox);
this.Controls.Add(this.conCntrls);
this.Controls.Add(this.donationLink);
this.Controls.Add(this.passiveScanBox);
this.Controls.Add(this.version_lbl);
this.Controls.Add(this.console);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "MainForm";
this.Text = "BetterJoy";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
this.Load += new System.EventHandler(this.MainForm_Load);
this.Resize += new System.EventHandler(this.MainForm_Resize);
this.contextMenu.ResumeLayout(false);
this.conCntrls.ResumeLayout(false);
this.groupBox1.ResumeLayout(false);
this.rightPanel.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
this.settingsTable.AutoScroll = true;
this.settingsTable.ColumnCount = 2;
this.settingsTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.90411F));
this.settingsTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.09589F));
this.settingsTable.Location = new System.Drawing.Point(4, 17);
this.settingsTable.Margin = new System.Windows.Forms.Padding(2);
this.settingsTable.Name = "settingsTable";
this.settingsTable.RowCount = 1;
this.settingsTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.settingsTable.Size = new System.Drawing.Size(219, 219);
this.settingsTable.TabIndex = 1;
//
// rightPanel
//
this.rightPanel.Controls.Add(this.settingsApply);
this.rightPanel.Controls.Add(this.groupBox1);
this.rightPanel.Location = new System.Drawing.Point(289, 1);
this.rightPanel.Margin = new System.Windows.Forms.Padding(2, 2, 12, 2);
this.rightPanel.Name = "rightPanel";
this.rightPanel.Size = new System.Drawing.Size(231, 273);
this.rightPanel.TabIndex = 11;
this.rightPanel.Visible = false;
//
// settingsApply
//
this.settingsApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.settingsApply.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.settingsApply.Location = new System.Drawing.Point(165, 252);
this.settingsApply.Margin = new System.Windows.Forms.Padding(2);
this.settingsApply.Name = "settingsApply";
this.settingsApply.Size = new System.Drawing.Size(61, 21);
this.settingsApply.TabIndex = 10;
this.settingsApply.Text = "Apply";
this.settingsApply.UseVisualStyleBackColor = true;
this.settingsApply.Click += new System.EventHandler(this.settingsApply_Click);
//
// AutoCalibrate
//
this.AutoCalibrate.Location = new System.Drawing.Point(203, 112);
this.AutoCalibrate.Name = "AutoCalibrate";
this.AutoCalibrate.Size = new System.Drawing.Size(71, 20);
this.AutoCalibrate.TabIndex = 8;
this.AutoCalibrate.Text = "Calibrate";
this.AutoCalibrate.UseVisualStyleBackColor = true;
this.AutoCalibrate.Click += new System.EventHandler(this.StartCalibrate);
//
// btn_reassign_open
//
this.btn_reassign_open.Location = new System.Drawing.Point(107, 112);
this.btn_reassign_open.Name = "btn_reassign_open";
this.btn_reassign_open.Size = new System.Drawing.Size(75, 20);
this.btn_reassign_open.TabIndex = 13;
this.btn_reassign_open.Text = "Map Buttons";
this.btn_reassign_open.UseVisualStyleBackColor = true;
this.btn_reassign_open.Click += new System.EventHandler(this.btn_reassign_open_Click);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Controls.Add(this.btn_reassign_open);
this.Controls.Add(this.foldLbl);
this.Controls.Add(this.rightPanel);
this.Controls.Add(this.AutoCalibrate);
this.Controls.Add(this.btn_open3rdP);
this.Controls.Add(this.startInTrayBox);
this.Controls.Add(this.conCntrls);
this.Controls.Add(this.donationLink);
this.Controls.Add(this.passiveScanBox);
this.Controls.Add(this.version_lbl);
this.Controls.Add(this.console_lbl);
this.Controls.Add(this.console);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "MainForm";
this.Text = "BetterJoy";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
this.Load += new System.EventHandler(this.MainForm_Load);
this.Resize += new System.EventHandler(this.MainForm_Resize);
this.contextMenu.ResumeLayout(false);
this.conCntrls.ResumeLayout(false);
this.groupBox1.ResumeLayout(false);
this.rightPanel.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
}
#endregion
#endregion
public System.Windows.Forms.TextBox console;
public System.Windows.Forms.NotifyIcon notifyIcon;
private System.Windows.Forms.Label version_lbl;
private System.Windows.Forms.ContextMenuStrip contextMenu;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
public System.Windows.Forms.TextBox console;
private System.Windows.Forms.Label console_lbl;
private System.Windows.Forms.NotifyIcon notifyIcon;
private System.Windows.Forms.Label version_lbl;
private System.Windows.Forms.ContextMenuStrip contextMenu;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
private System.Windows.Forms.CheckBox passiveScanBox;
private System.Windows.Forms.LinkLabel donationLink;
private System.Windows.Forms.GroupBox conCntrls;
@ -396,6 +408,6 @@
private System.Windows.Forms.Button settingsApply;
private System.Windows.Forms.Label foldLbl;
private System.Windows.Forms.Button AutoCalibrate;
private System.Windows.Forms.Button btn_reassign_open;
}
}
private System.Windows.Forms.Button btn_reassign_open;
}
}

View file

@ -14,421 +14,412 @@ using System.Windows.Forms;
using System.Xml.Linq;
namespace BetterJoyForCemu {
public partial class MainForm : Form {
public bool allowCalibration = Boolean.Parse(ConfigurationManager.AppSettings["AllowCalibration"]);
public List<Button> con, loc;
public bool calibrate;
public List<KeyValuePair<string, float[]>> caliData;
private Timer countDown;
private int count;
public List<int> xG, yG, zG, xA, yA, zA;
public bool shakeInputEnabled = Boolean.Parse(ConfigurationManager.AppSettings["EnableShakeInput"]);
public float shakeSesitivity = float.Parse(ConfigurationManager.AppSettings["ShakeInputSensitivity"]);
public float shakeDelay = float.Parse(ConfigurationManager.AppSettings["ShakeInputDelay"]);
public partial class MainForm : Form {
public bool nonOriginal = Boolean.Parse(ConfigurationManager.AppSettings["NonOriginalController"]);
public List<Button> con, loc;
public bool calibrate;
public List<KeyValuePair<string, float[]>> caliData;
private Timer countDown;
private int count;
public List<int> xG, yG, zG, xA, yA, zA;
public enum NonOriginalController : int {
Disabled = 0,
DefaultCalibration = 1,
ControllerCalibration = 2,
}
public MainForm() {
xG = new List<int>(); yG = new List<int>(); zG = new List<int>();
xA = new List<int>(); yA = new List<int>(); zA = new List<int>();
caliData = new List<KeyValuePair<string, float[]>> {
new KeyValuePair<string, float[]>("0", new float[6] {0,0,0,-710,0,0})
};
public MainForm() {
xG = new List<int>(); yG = new List<int>(); zG = new List<int>();
xA = new List<int>(); yA = new List<int>(); zA = new List<int>();
caliData = new List<KeyValuePair<string, float[]>> {
new KeyValuePair<string, float[]>("0", new float[6] {0,0,0,-710,0,0})
};
InitializeComponent();
InitializeComponent();
if (!nonOriginal)
AutoCalibrate.Hide();
if (!allowCalibration)
AutoCalibrate.Hide();
// Feature not yet implemented - hide
btn_open3rdP.Hide();
con = new List<Button> { con1, con2, con3, con4 };
loc = new List<Button> { loc1, loc2, loc3, loc4 };
con = new List<Button> { con1, con2, con3, con4 };
loc = new List<Button> { loc1, loc2, loc3, loc4 };
//list all options
string[] myConfigs = ConfigurationManager.AppSettings.AllKeys;
Size childSize = new Size(150, 20);
for (int i = 0; i != myConfigs.Length; i++) {
settingsTable.RowCount++;
settingsTable.Controls.Add(new Label() { Text = myConfigs[i], TextAlign = ContentAlignment.BottomLeft, AutoEllipsis = true, Size = childSize }, 0, i);
//list all options
string[] myConfigs = ConfigurationManager.AppSettings.AllKeys;
Size childSize = new Size(87, 20);
for (int i = 0; i != myConfigs.Length; i++) {
settingsTable.RowCount++;
settingsTable.Controls.Add(new Label() { Text = myConfigs[i], TextAlign = ContentAlignment.BottomLeft, AutoEllipsis = true, Size = childSize }, 0, i);
var value = ConfigurationManager.AppSettings[myConfigs[i]];
Control childControl;
if (value == "true" || value == "false") {
childControl = new CheckBox() { Checked = Boolean.Parse(value), Size = childSize };
} else {
childControl = new TextBox() { Text = value, Size = childSize };
}
var value = ConfigurationManager.AppSettings[myConfigs[i]];
Control childControl;
if (value == "true" || value == "false") {
childControl = new CheckBox() { Checked = Boolean.Parse(value), Size = childSize };
} else {
childControl = new TextBox() { Text = value, Size = childSize };
}
childControl.MouseClick += cbBox_Changed;
settingsTable.Controls.Add(childControl, 1, i);
}
}
childControl.MouseClick += cbBox_Changed;
settingsTable.Controls.Add(childControl, 1, i);
}
}
private void HideToTray() {
this.WindowState = FormWindowState.Minimized;
notifyIcon.Visible = true;
notifyIcon.BalloonTipText = "Double click the tray icon to maximise!";
notifyIcon.ShowBalloonTip(0);
this.ShowInTaskbar = false;
this.Hide();
}
private void HideToTray() {
this.WindowState = FormWindowState.Minimized;
notifyIcon.Visible = true;
notifyIcon.ShowBalloonTip(1);
this.ShowInTaskbar = false;
this.Hide();
}
private void ShowFromTray() {
this.Show();
this.WindowState = FormWindowState.Normal;
this.ShowInTaskbar = true;
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.Icon = Properties.Resources.betterjoyforcemu_icon;
notifyIcon.Visible = false;
}
private void ShowFromTray() {
this.Show();
this.WindowState = FormWindowState.Normal;
this.ShowInTaskbar = true;
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.Icon = Properties.Resources.betterjoyforcemu_icon;
notifyIcon.Visible = false;
}
private void MainForm_Resize(object sender, EventArgs e) {
if (this.WindowState == FormWindowState.Minimized) {
HideToTray();
}
}
private void MainForm_Resize(object sender, EventArgs e) {
if (this.WindowState == FormWindowState.Minimized) {
HideToTray();
}
}
private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) {
ShowFromTray();
}
private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) {
ShowFromTray();
}
private void MainForm_Load(object sender, EventArgs e) {
Config.Init(caliData);
private void MainForm_Load(object sender, EventArgs e) {
Config.Init(caliData);
Program.Start();
Program.Start();
passiveScanBox.Checked = Config.IntValue("ProgressiveScan") == 1;
startInTrayBox.Checked = Config.IntValue("StartInTray") == 1;
passiveScanBox.Checked = Config.IntValue("ProgressiveScan") == 1;
startInTrayBox.Checked = Config.IntValue("StartInTray") == 1;
if (Config.IntValue("StartInTray") == 1) {
HideToTray();
} else {
ShowFromTray();
}
}
if (Config.IntValue("StartInTray") == 1) {
HideToTray();
} else {
ShowFromTray();
}
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) {
try {
Program.Stop();
Environment.Exit(0);
} catch { }
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) {
try {
Program.Stop();
Environment.Exit(0);
} catch { }
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e) { // this does not work, for some reason. Fix before release
try {
Program.Stop();
Close();
Environment.Exit(0);
} catch { }
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e) { // this does not work, for some reason. Fix before release
try {
Program.Stop();
Close();
Environment.Exit(0);
} catch { }
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
donationLink.LinkVisited = true;
System.Diagnostics.Process.Start("http://paypal.me/DavidKhachaturov/5");
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
donationLink.LinkVisited = true;
System.Diagnostics.Process.Start("http://paypal.me/DavidKhachaturov/5");
}
private void passiveScanBox_CheckedChanged(object sender, EventArgs e) {
Config.SetValue("ProgressiveScan", passiveScanBox.Checked ? "1" : "0");
Config.Save();
}
private void passiveScanBox_CheckedChanged(object sender, EventArgs e) {
Config.SetValue("ProgressiveScan", passiveScanBox.Checked ? "1" : "0");
Config.Save();
}
public void AppendTextBox(string value) { // https://stackoverflow.com/questions/519233/writing-to-a-textbox-from-another-thread
if (InvokeRequired) {
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
console.AppendText(value);
}
public void AppendTextBox(string value) { // https://stackoverflow.com/questions/519233/writing-to-a-textbox-from-another-thread
if (InvokeRequired) {
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
console.AppendText(value);
}
bool toRumble = Boolean.Parse(ConfigurationManager.AppSettings["EnableRumble"]);
bool showAsXInput = Boolean.Parse(ConfigurationManager.AppSettings["ShowAsXInput"]);
bool showAsDS4 = Boolean.Parse(ConfigurationManager.AppSettings["ShowAsDS4"]);
bool toRumble = Boolean.Parse(ConfigurationManager.AppSettings["EnableRumble"]);
bool showAsXInput = Boolean.Parse(ConfigurationManager.AppSettings["ShowAsXInput"]);
public async void locBtnClickAsync(object sender, EventArgs e) {
Button bb = sender as Button;
public void locBtnClick(object sender, EventArgs e) {
Button bb = sender as Button;
if (bb.Tag.GetType() == typeof(Button)) {
Button button = bb.Tag as Button;
if (bb.Tag.GetType() == typeof(Button)) {
Button button = bb.Tag as Button;
if (button.Tag.GetType() == typeof(Joycon)) {
Joycon v = (Joycon)button.Tag;
v.SetRumble(160.0f, 320.0f, 1.0f);
await Task.Delay(300);
v.SetRumble(160.0f, 320.0f, 0);
}
}
}
if (button.Tag.GetType() == typeof(Joycon)) {
Joycon v = (Joycon)button.Tag;
v.SetRumble(20.0f, 400.0f, 1.0f, 300);
}
}
}
bool doNotRejoin = Boolean.Parse(ConfigurationManager.AppSettings["DoNotRejoinJoycons"]);
public void conBtnClick(object sender, EventArgs e) {
Button button = sender as Button;
public void conBtnClick(object sender, EventArgs e) {
Button button = sender as Button;
if (button.Tag.GetType() == typeof(Joycon)) {
Joycon v = (Joycon)button.Tag;
if (button.Tag.GetType() == typeof(Joycon)) {
Joycon v = (Joycon)button.Tag;
if (v.other == null && !v.isPro) { // needs connecting to other joycon (so messy omg)
bool succ = false;
if (v.other == null && !v.isPro) { // needs connecting to other joycon (so messy omg)
bool succ = false;
if (Program.mgr.j.Count == 1) { // when want to have a single joycon in vertical mode
v.other = v; // hacky; implement check in Joycon.cs to account for this
succ = true;
} else {
foreach (Joycon jc in Program.mgr.j) {
if (!jc.isPro && jc.isLeft != v.isLeft && jc != v && jc.other == null) {
v.other = jc;
jc.other = v;
if (Program.mgr.j.Count == 1 || doNotRejoin) { // when want to have a single joycon in vertical mode
v.other = v; // hacky; implement check in Joycon.cs to account for this
succ = true;
} else {
foreach (Joycon jc in Program.mgr.j) {
if (!jc.isPro && jc.isLeft != v.isLeft && jc != v && jc.other == null) {
v.other = jc;
jc.other = v;
//Set both Joycon LEDs to the one with the lowest ID
byte led = jc.LED <= v.LED ? jc.LED : v.LED;
jc.LED = led;
v.LED = led;
jc.SetPlayerLED(led);
v.SetPlayerLED(led);
if (v.out_xbox != null) {
v.out_xbox.Disconnect();
v.out_xbox = null;
}
v.xin.Disconnect();
v.xin = null;
if (v.out_ds4 != null) {
v.out_ds4.Disconnect();
v.out_ds4 = null;
}
// setting the other joycon's button image
foreach (Button b in con)
if (b.Tag == jc)
b.BackgroundImage = jc.isLeft ? Properties.Resources.jc_left : Properties.Resources.jc_right;
// setting the other joycon's button image
foreach (Button b in con)
if (b.Tag == jc)
b.BackgroundImage = jc.isLeft ? Properties.Resources.jc_left : Properties.Resources.jc_right;
succ = true;
break;
}
}
}
succ = true;
break;
}
}
}
if (succ)
foreach (Button b in con)
if (b.Tag == v)
b.BackgroundImage = v.isLeft ? Properties.Resources.jc_left : Properties.Resources.jc_right;
} else if (v.other != null && !v.isPro) { // needs disconnecting from other joycon
if (v.xin == null) {
ReenableXinput(v);
v.xin.Connect();
}
if (succ)
foreach (Button b in con)
if (b.Tag == v)
b.BackgroundImage = v.isLeft ? Properties.Resources.jc_left : Properties.Resources.jc_right;
} else if (v.other != null && !v.isPro) { // needs disconnecting from other joycon
ReenableViGEm(v);
ReenableViGEm(v.other);
if (v.other.xin == null) {
ReenableXinput(v.other);
v.other.xin.Connect();
}
button.BackgroundImage = v.isLeft ? Properties.Resources.jc_left_s : Properties.Resources.jc_right_s;
button.BackgroundImage = v.isLeft ? Properties.Resources.jc_left_s : Properties.Resources.jc_right_s;
foreach (Button b in con)
if (b.Tag == v.other)
b.BackgroundImage = v.other.isLeft ? Properties.Resources.jc_left_s : Properties.Resources.jc_right_s;
foreach (Button b in con)
if (b.Tag == v.other)
b.BackgroundImage = v.other.isLeft ? Properties.Resources.jc_left_s : Properties.Resources.jc_right_s;
v.other.other = null;
v.other = null;
}
}
}
//Set original Joycon LEDs
v.other.LED = (byte)(0x1 << v.other.PadId);
v.LED = (byte)(0x1 << v.PadId);
v.other.SetPlayerLED(v.other.LED);
v.SetPlayerLED(v.LED);
private void startInTrayBox_CheckedChanged(object sender, EventArgs e) {
Config.SetValue("StartInTray", startInTrayBox.Checked ? "1" : "0");
Config.Save();
}
v.other.other = null;
v.other = null;
}
}
}
private void btn_open3rdP_Click(object sender, EventArgs e) {
_3rdPartyControllers partyForm = new _3rdPartyControllers();
partyForm.ShowDialog();
}
private void startInTrayBox_CheckedChanged(object sender, EventArgs e) {
Config.SetValue("StartInTray", startInTrayBox.Checked ? "1" : "0");
Config.Save();
}
private void settingsApply_Click(object sender, EventArgs e) {
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = configFile.AppSettings.Settings;
private void btn_open3rdP_Click(object sender, EventArgs e) {
_3rdPartyControllers partyForm = new _3rdPartyControllers();
partyForm.ShowDialog();
}
for (int row = 0; row < ConfigurationManager.AppSettings.AllKeys.Length; row++) {
var valCtl = settingsTable.GetControlFromPosition(1, row);
var KeyCtl = settingsTable.GetControlFromPosition(0, row).Text;
private void settingsApply_Click(object sender, EventArgs e) {
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = configFile.AppSettings.Settings;
if (valCtl.GetType() == typeof(CheckBox) && settings[KeyCtl] != null) {
settings[KeyCtl].Value = ((CheckBox)valCtl).Checked.ToString().ToLower();
} else if (valCtl.GetType() == typeof(TextBox) && settings[KeyCtl] != null) {
settings[KeyCtl].Value = ((TextBox)valCtl).Text.ToLower();
}
}
for (int row = 0; row < ConfigurationManager.AppSettings.AllKeys.Length; row++) {
var valCtl = settingsTable.GetControlFromPosition(1, row);
var KeyCtl = settingsTable.GetControlFromPosition(0, row).Text;
try {
configFile.Save(ConfigurationSaveMode.Modified);
} catch (ConfigurationErrorsException) {
AppendTextBox("Error writing app settings.\r\n");
}
if (valCtl.GetType() == typeof(CheckBox) && settings[KeyCtl] != null) {
settings[KeyCtl].Value = ((CheckBox)valCtl).Checked.ToString().ToLower();
} else if (valCtl.GetType() == typeof(TextBox) && settings[KeyCtl] != null) {
settings[KeyCtl].Value = ((TextBox)valCtl).Text.ToLower();
}
}
ConfigurationManager.AppSettings["AutoPowerOff"] = "false"; // Prevent joycons poweroff when applying settings
Application.Restart();
Environment.Exit(0);
}
try {
configFile.Save(ConfigurationSaveMode.Modified);
} catch (ConfigurationErrorsException) {
AppendTextBox("Error writing app settings.\r\n");
}
void ReenableViGEm(Joycon v) {
if (showAsXInput && v.out_xbox == null) {
v.out_xbox = new Controller.OutputControllerXbox360();
Application.Restart();
Environment.Exit(0);
}
if (toRumble)
v.out_xbox.FeedbackReceived += v.ReceiveRumble;
v.out_xbox.Connect();
}
void ReenableXinput(Joycon v) {
if (showAsXInput) {
v.xin = Program.emClient.CreateXbox360Controller();
if (showAsDS4 && v.out_ds4 == null) {
v.out_ds4 = new Controller.OutputControllerDualShock4();
if (toRumble)
v.xin.FeedbackReceived += v.ReceiveRumble;
}
}
if (toRumble)
v.out_ds4.FeedbackReceived += v.Ds4_FeedbackReceived;
v.out_ds4.Connect();
}
}
private void foldLbl_Click(object sender, EventArgs e) {
rightPanel.Visible = !rightPanel.Visible;
foldLbl.Text = rightPanel.Visible ? "<" : ">";
}
private void foldLbl_Click(object sender, EventArgs e) {
rightPanel.Visible = !rightPanel.Visible;
foldLbl.Text = rightPanel.Visible ? "<" : ">";
}
private void cbBox_Changed(object sender, EventArgs e) {
var coord = settingsTable.GetPositionFromControl(sender as Control);
private void cbBox_Changed(object sender, EventArgs e) {
var coord = settingsTable.GetPositionFromControl(sender as Control);
var valCtl = settingsTable.GetControlFromPosition(coord.Column, coord.Row);
var KeyCtl = settingsTable.GetControlFromPosition(coord.Column - 1, coord.Row).Text;
var valCtl = settingsTable.GetControlFromPosition(coord.Column, coord.Row);
var KeyCtl = settingsTable.GetControlFromPosition(coord.Column - 1, coord.Row).Text;
try {
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = configFile.AppSettings.Settings;
if (valCtl.GetType() == typeof(CheckBox) && settings[KeyCtl] != null) {
settings[KeyCtl].Value = ((CheckBox)valCtl).Checked.ToString().ToLower();
} else if (valCtl.GetType() == typeof(TextBox) && settings[KeyCtl] != null) {
settings[KeyCtl].Value = ((TextBox)valCtl).Text.ToLower();
}
try {
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = configFile.AppSettings.Settings;
if (valCtl.GetType() == typeof(CheckBox) && settings[KeyCtl] != null) {
settings[KeyCtl].Value = ((CheckBox)valCtl).Checked.ToString().ToLower();
} else if (valCtl.GetType() == typeof(TextBox) && settings[KeyCtl] != null) {
settings[KeyCtl].Value = ((TextBox)valCtl).Text.ToLower();
}
if (KeyCtl == "HomeLEDOn") {
bool on = settings[KeyCtl].Value.ToLower() == "true";
foreach (Joycon j in Program.mgr.j) {
j.SetHomeLight(on);
}
}
if (KeyCtl == "HomeLEDOn") {
bool on = settings[KeyCtl].Value.ToLower() == "true";
foreach (Joycon j in Program.mgr.j) {
j.SetHomeLight(on);
}
}
configFile.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
} catch (ConfigurationErrorsException) {
AppendTextBox("Error writing app settings\r\n");
Trace.WriteLine(String.Format("rw {0}, column {1}, {2}, {3}", coord.Row, coord.Column, sender.GetType(), KeyCtl));
}
}
private void StartCalibrate(object sender, EventArgs e) {
if (Program.mgr.j.Count == 0) {
this.console.Text = "Please connect a single pro controller.";
return;
}
if (Program.mgr.j.Count > 1) {
this.console.Text = "Please calibrate one controller at a time (disconnect others).";
return;
}
this.AutoCalibrate.Enabled = false;
countDown = new Timer();
this.count = 4;
this.CountDown(null, null);
countDown.Tick += new EventHandler(CountDown);
countDown.Interval = 1000;
countDown.Enabled = true;
}
configFile.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
} catch (ConfigurationErrorsException) {
AppendTextBox("Error writing app settings\r\n");
Trace.WriteLine(String.Format("rw {0}, column {1}, {2}, {3}", coord.Row, coord.Column, sender.GetType(), KeyCtl));
}
}
private void StartCalibrate(object sender, EventArgs e) {
if (Program.mgr.j.Count == 0) {
this.console.Text = "Please connect a single pro controller.";
return;
}
if (Program.mgr.j.Count > 1) {
this.console.Text = "Please calibrate one controller at a time (disconnect others).";
return;
}
this.AutoCalibrate.Enabled = false;
countDown = new Timer();
this.count = 4;
this.CountDown(null, null);
countDown.Tick += new EventHandler(CountDown);
countDown.Interval = 1000;
countDown.Enabled = true;
}
private void StartGetData() {
this.xG.Clear(); this.yG.Clear(); this.zG.Clear();
this.xA.Clear(); this.yA.Clear(); this.zA.Clear();
countDown = new Timer();
this.count = 3;
this.calibrate = true;
countDown.Tick += new EventHandler(CalcData);
countDown.Interval = 1000;
countDown.Enabled = true;
}
private void StartGetData() {
this.xG.Clear(); this.yG.Clear(); this.zG.Clear();
this.xA.Clear(); this.yA.Clear(); this.zA.Clear();
countDown = new Timer();
this.count = 3;
this.calibrate = true;
countDown.Tick += new EventHandler(CalcData);
countDown.Interval = 1000;
countDown.Enabled = true;
}
private void btn_reassign_open_Click(object sender, EventArgs e) {
Reassign mapForm = new Reassign();
mapForm.ShowDialog();
}
private void btn_reassign_open_Click(object sender, EventArgs e) {
Reassign mapForm = new Reassign();
mapForm.ShowDialog();
}
private void CountDown(object sender, EventArgs e) {
if (this.count == 0) {
this.console.Text = "Calibrating...";
countDown.Stop();
this.StartGetData();
} else {
this.console.Text = "Plese keep the controller flat." + "\r\n";
this.console.Text += "Calibration will start in " + this.count + " seconds.";
this.count--;
}
}
private void CalcData(object sender, EventArgs e) {
if (this.count == 0) {
countDown.Stop();
this.calibrate = false;
string serNum = Program.mgr.j.First().serial_number;
int serIndex = this.findSer(serNum);
float[] Arr = new float[6] { 0, 0, 0, 0, 0, 0 };
if (serIndex == -1) {
this.caliData.Add(new KeyValuePair<string, float[]>(
serNum,
Arr
));
} else {
Arr = this.caliData[serIndex].Value;
}
Random rnd = new Random();
Arr[0] = (float)quickselect_median(this.xG, rnd.Next);
Arr[1] = (float)quickselect_median(this.yG, rnd.Next);
Arr[2] = (float)quickselect_median(this.zG, rnd.Next);
Arr[3] = (float)quickselect_median(this.xA, rnd.Next);
Arr[4] = (float)quickselect_median(this.yA, rnd.Next);
Arr[5] = (float)quickselect_median(this.zA, rnd.Next) - 4010; //Joycon.cs acc_sen 16384
this.console.Text += "Calibration completed!!!" + "\r\n";
Config.SaveCaliData(this.caliData);
Program.mgr.j.First().getActiveData();
this.AutoCalibrate.Enabled = true;
} else {
this.count--;
}
private void CountDown(object sender, EventArgs e) {
if (this.count == 0) {
this.console.Text = "Calibrating...";
countDown.Stop();
this.StartGetData();
} else {
this.console.Text = "Plese keep the controller flat." + "\r\n";
this.console.Text += "Calibration will start in " + this.count + " seconds.";
this.count--;
}
}
private void CalcData(object sender, EventArgs e) {
if (this.count == 0) {
countDown.Stop();
this.calibrate = false;
string serNum = Program.mgr.j.First().serial_number;
int serIndex = this.findSer(serNum);
float[] Arr = new float[6] { 0, 0, 0, 0, 0, 0 };
if (serIndex == -1) {
this.caliData.Add(new KeyValuePair<string, float[]>(
serNum,
Arr
));
} else {
Arr = this.caliData[serIndex].Value;
}
Random rnd = new Random();
Arr[0] = (float)quickselect_median(this.xG, rnd.Next);
Arr[1] = (float)quickselect_median(this.yG, rnd.Next);
Arr[2] = (float)quickselect_median(this.zG, rnd.Next);
Arr[3] = (float)quickselect_median(this.xA, rnd.Next);
Arr[4] = (float)quickselect_median(this.yA, rnd.Next);
Arr[5] = (float)quickselect_median(this.zA, rnd.Next) - 4010; //Joycon.cs acc_sen 16384
this.console.Text += "Calibration completed!!!" + "\r\n";
Config.SaveCaliData(this.caliData);
Program.mgr.j.First().getActiveData();
this.AutoCalibrate.Enabled = true;
} else {
this.count--;
}
}
private double quickselect_median(List<int> l, Func<int, int> pivot_fn) {
int ll = l.Count;
if (ll % 2 == 1) {
return this.quickselect(l, ll / 2, pivot_fn);
} else {
return 0.5 * (quickselect(l, ll / 2 - 1, pivot_fn) + quickselect(l, ll / 2, pivot_fn));
}
}
}
private double quickselect_median(List<int> l, Func<int, int> pivot_fn) {
int ll = l.Count;
if (ll % 2 == 1) {
return this.quickselect(l, ll / 2, pivot_fn);
} else {
return 0.5 * (quickselect(l, ll / 2 - 1, pivot_fn) + quickselect(l, ll / 2, pivot_fn));
}
}
private int quickselect(List<int> l, int k, Func<int, int> pivot_fn) {
if (l.Count == 1 && k == 0) {
return l[0];
}
int pivot = l[pivot_fn(l.Count)];
List<int> lows = l.Where(x => x < pivot).ToList();
List<int> highs = l.Where(x => x > pivot).ToList();
List<int> pivots = l.Where(x => x == pivot).ToList();
if (k < lows.Count) {
return quickselect(lows, k, pivot_fn);
} else if (k < (lows.Count + pivots.Count)) {
return pivots[0];
} else {
return quickselect(highs, k - lows.Count - pivots.Count, pivot_fn);
}
}
private int quickselect(List<int> l, int k, Func<int, int> pivot_fn) {
if (l.Count == 1 && k == 0) {
return l[0];
}
int pivot = l[pivot_fn(l.Count)];
List<int> lows = l.Where(x => x < pivot).ToList();
List<int> highs = l.Where(x => x > pivot).ToList();
List<int> pivots = l.Where(x => x == pivot).ToList();
if (k < lows.Count) {
return quickselect(lows, k, pivot_fn);
} else if (k < (lows.Count + pivots.Count)) {
return pivots[0];
} else {
return quickselect(highs, k - lows.Count - pivots.Count, pivot_fn);
}
}
public float[] activeCaliData(string serNum) {
for (int i = 0; i < this.caliData.Count; i++) {
if (this.caliData[i].Key == serNum) {
return this.caliData[i].Value;
}
}
return this.caliData[0].Value;
}
public float[] activeCaliData(string serNum) {
for (int i = 0; i < this.caliData.Count; i++) {
if (this.caliData[i].Key == serNum) {
return this.caliData[i].Value;
}
}
return this.caliData[0].Value;
}
private int findSer(string serNum) {
for (int i = 0; i < this.caliData.Count; i++) {
if (this.caliData[i].Key == serNum) {
return i;
}
}
return -1;
}
}
private int findSer(string serNum) {
for (int i = 0; i < this.caliData.Count; i++) {
if (this.caliData[i].Key == serNum) {
return i;
}
}
return -1;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BetterJoy")]
[assembly: AssemblyTitle("BetterJoyForCemu")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BetterJoy")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyProduct("BetterJoyForCemu")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View file

@ -9,145 +9,135 @@
//------------------------------------------------------------------------------
namespace BetterJoyForCemu.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// 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", "16.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() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[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("BetterJoyForCemu.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon betterjoyforcemu_icon {
get {
object obj = ResourceManager.GetObject("betterjoyforcemu_icon", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap cross {
get {
object obj = ResourceManager.GetObject("cross", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap jc_left {
get {
object obj = ResourceManager.GetObject("jc_left", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap jc_left_s {
get {
object obj = ResourceManager.GetObject("jc_left_s", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap jc_right {
get {
object obj = ResourceManager.GetObject("jc_right", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap jc_right_s {
get {
object obj = ResourceManager.GetObject("jc_right_s", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap pro {
get {
object obj = ResourceManager.GetObject("pro", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap snes {
get {
object obj = ResourceManager.GetObject("snes", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// 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", "16.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() {
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ultra {
get {
object obj = ResourceManager.GetObject("ultra", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[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("BetterJoyForCemu.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon betterjoyforcemu_icon {
get {
object obj = ResourceManager.GetObject("betterjoyforcemu_icon", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap cross {
get {
object obj = ResourceManager.GetObject("cross", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap jc_left {
get {
object obj = ResourceManager.GetObject("jc_left", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap jc_left_s {
get {
object obj = ResourceManager.GetObject("jc_left_s", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap jc_right {
get {
object obj = ResourceManager.GetObject("jc_right", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap jc_right_s {
get {
object obj = ResourceManager.GetObject("jc_right_s", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap pro {
get {
object obj = ResourceManager.GetObject("pro", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap snes {
get {
object obj = ResourceManager.GetObject("snes", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View file

@ -121,9 +121,6 @@
<data name="snes" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Icons\snes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ultra" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Icons\ultra.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="pro" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Icons\pro.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>

View file

@ -79,248 +79,226 @@ namespace BetterJoyForCemu {
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Reassign));
this.btn_capture = new BetterJoyForCemu.SplitButton();
this.lbl_capture = new System.Windows.Forms.Label();
this.lbl_home = new System.Windows.Forms.Label();
this.btn_home = new BetterJoyForCemu.SplitButton();
this.lbl_sl_l = new System.Windows.Forms.Label();
this.btn_sl_l = new BetterJoyForCemu.SplitButton();
this.lbl_sr_l = new System.Windows.Forms.Label();
this.btn_sr_l = new BetterJoyForCemu.SplitButton();
this.lbl_sl_r = new System.Windows.Forms.Label();
this.btn_sl_r = new BetterJoyForCemu.SplitButton();
this.lbl_sr_r = new System.Windows.Forms.Label();
this.btn_sr_r = new BetterJoyForCemu.SplitButton();
this.btn_close = new System.Windows.Forms.Button();
this.btn_apply = new System.Windows.Forms.Button();
this.tip_reassign = new System.Windows.Forms.ToolTip(this.components);
this.lbl_reset_mouse = new System.Windows.Forms.Label();
this.btn_reset_mouse = new BetterJoyForCemu.SplitButton();
this.lbl_activate_gyro = new System.Windows.Forms.Label();
this.btn_active_gyro = new BetterJoyForCemu.SplitButton();
this.lbl_shake = new System.Windows.Forms.Label();
this.btn_shake = new BetterJoyForCemu.SplitButton();
this.SuspendLayout();
//
// btn_capture
//
this.btn_capture.Location = new System.Drawing.Point(105, 12);
this.btn_capture.Name = "btn_capture";
this.btn_capture.Size = new System.Drawing.Size(75, 23);
this.btn_capture.TabIndex = 0;
this.btn_capture.UseVisualStyleBackColor = true;
//
// lbl_capture
//
this.lbl_capture.AutoSize = true;
this.lbl_capture.Location = new System.Drawing.Point(15, 17);
this.lbl_capture.Name = "lbl_capture";
this.lbl_capture.Size = new System.Drawing.Size(44, 13);
this.lbl_capture.TabIndex = 2;
this.lbl_capture.Text = "Capture";
this.lbl_capture.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// lbl_home
//
this.lbl_home.AutoSize = true;
this.lbl_home.Location = new System.Drawing.Point(15, 46);
this.lbl_home.Name = "lbl_home";
this.lbl_home.Size = new System.Drawing.Size(35, 13);
this.lbl_home.TabIndex = 4;
this.lbl_home.Text = "Home";
this.lbl_home.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_home
//
this.btn_home.Location = new System.Drawing.Point(105, 41);
this.btn_home.Name = "btn_home";
this.btn_home.Size = new System.Drawing.Size(75, 23);
this.btn_home.TabIndex = 3;
this.btn_home.UseVisualStyleBackColor = true;
//
// lbl_sl_l
//
this.lbl_sl_l.AutoSize = true;
this.lbl_sl_l.Location = new System.Drawing.Point(15, 75);
this.lbl_sl_l.Name = "lbl_sl_l";
this.lbl_sl_l.Size = new System.Drawing.Size(78, 13);
this.lbl_sl_l.TabIndex = 6;
this.lbl_sl_l.Text = "SL Left Joycon";
this.lbl_sl_l.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_sl_l
//
this.btn_sl_l.Location = new System.Drawing.Point(105, 70);
this.btn_sl_l.Name = "btn_sl_l";
this.btn_sl_l.Size = new System.Drawing.Size(75, 23);
this.btn_sl_l.TabIndex = 5;
this.btn_sl_l.UseVisualStyleBackColor = true;
//
// lbl_sr_l
//
this.lbl_sr_l.AutoSize = true;
this.lbl_sr_l.Location = new System.Drawing.Point(15, 104);
this.lbl_sr_l.Name = "lbl_sr_l";
this.lbl_sr_l.Size = new System.Drawing.Size(80, 13);
this.lbl_sr_l.TabIndex = 8;
this.lbl_sr_l.Text = "SR Left Joycon";
this.lbl_sr_l.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_sr_l
//
this.btn_sr_l.Location = new System.Drawing.Point(105, 99);
this.btn_sr_l.Name = "btn_sr_l";
this.btn_sr_l.Size = new System.Drawing.Size(75, 23);
this.btn_sr_l.TabIndex = 7;
this.btn_sr_l.UseVisualStyleBackColor = true;
//
// lbl_sl_r
//
this.lbl_sl_r.AutoSize = true;
this.lbl_sl_r.Location = new System.Drawing.Point(15, 133);
this.lbl_sl_r.Name = "lbl_sl_r";
this.lbl_sl_r.Size = new System.Drawing.Size(85, 13);
this.lbl_sl_r.TabIndex = 10;
this.lbl_sl_r.Text = "SL Right Joycon";
this.lbl_sl_r.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_sl_r
//
this.btn_sl_r.Location = new System.Drawing.Point(105, 128);
this.btn_sl_r.Name = "btn_sl_r";
this.btn_sl_r.Size = new System.Drawing.Size(75, 23);
this.btn_sl_r.TabIndex = 9;
this.btn_sl_r.UseVisualStyleBackColor = true;
//
// lbl_sr_r
//
this.lbl_sr_r.AutoSize = true;
this.lbl_sr_r.Location = new System.Drawing.Point(15, 162);
this.lbl_sr_r.Name = "lbl_sr_r";
this.lbl_sr_r.Size = new System.Drawing.Size(87, 13);
this.lbl_sr_r.TabIndex = 12;
this.lbl_sr_r.Text = "SR Right Joycon";
this.lbl_sr_r.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_sr_r
//
this.btn_sr_r.Location = new System.Drawing.Point(105, 157);
this.btn_sr_r.Name = "btn_sr_r";
this.btn_sr_r.Size = new System.Drawing.Size(75, 23);
this.btn_sr_r.TabIndex = 11;
this.btn_sr_r.UseVisualStyleBackColor = true;
//
// btn_close
//
this.btn_close.Location = new System.Drawing.Point(15, 289);
this.btn_close.Name = "btn_close";
this.btn_close.Size = new System.Drawing.Size(75, 23);
this.btn_close.TabIndex = 13;
this.btn_close.Text = "Okay";
this.btn_close.UseVisualStyleBackColor = true;
this.btn_close.Click += new System.EventHandler(this.btn_close_Click);
//
// btn_apply
//
this.btn_apply.Location = new System.Drawing.Point(105, 289);
this.btn_apply.Name = "btn_apply";
this.btn_apply.Size = new System.Drawing.Size(75, 23);
this.btn_apply.TabIndex = 14;
this.btn_apply.Text = "Apply";
this.btn_apply.UseVisualStyleBackColor = true;
this.btn_apply.Click += new System.EventHandler(this.btn_apply_Click);
//
// lbl_reset_mouse
//
this.lbl_reset_mouse.AutoSize = true;
this.lbl_reset_mouse.Location = new System.Drawing.Point(15, 223);
this.lbl_reset_mouse.Name = "lbl_reset_mouse";
this.lbl_reset_mouse.Size = new System.Drawing.Size(80, 13);
this.lbl_reset_mouse.TabIndex = 16;
this.lbl_reset_mouse.Text = "Re-Centre Gyro";
this.lbl_reset_mouse.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_reset_mouse
//
this.btn_reset_mouse.Location = new System.Drawing.Point(105, 218);
this.btn_reset_mouse.Name = "btn_reset_mouse";
this.btn_reset_mouse.Size = new System.Drawing.Size(75, 23);
this.btn_reset_mouse.TabIndex = 15;
this.btn_reset_mouse.UseVisualStyleBackColor = true;
//
// lbl_activate_gyro
//
this.lbl_activate_gyro.AutoSize = true;
this.lbl_activate_gyro.Location = new System.Drawing.Point(14, 252);
this.lbl_activate_gyro.Name = "lbl_activate_gyro";
this.lbl_activate_gyro.Size = new System.Drawing.Size(71, 13);
this.lbl_activate_gyro.TabIndex = 17;
this.lbl_activate_gyro.Text = "Activate Gyro";
this.lbl_activate_gyro.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_active_gyro
//
this.btn_active_gyro.Location = new System.Drawing.Point(105, 247);
this.btn_active_gyro.Name = "btn_active_gyro";
this.btn_active_gyro.Size = new System.Drawing.Size(75, 23);
this.btn_active_gyro.TabIndex = 18;
this.btn_active_gyro.UseVisualStyleBackColor = true;
//
// label1
//
this.lbl_shake.AutoSize = true;
this.lbl_shake.Location = new System.Drawing.Point(15, 191);
this.lbl_shake.Name = "lbl_shake";
this.lbl_shake.Size = new System.Drawing.Size(87, 13);
this.lbl_shake.TabIndex = 20;
this.lbl_shake.Text = "Shake Input";
this.lbl_shake.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// splitButton1
//
this.btn_shake.Location = new System.Drawing.Point(105, 186);
this.btn_shake.Name = "btn_shake";
this.btn_shake.Size = new System.Drawing.Size(75, 23);
this.btn_shake.TabIndex = 19;
this.btn_shake.UseVisualStyleBackColor = true;
//
// Reassign
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(192, 338);
this.Controls.Add(this.lbl_shake);
this.Controls.Add(this.btn_shake);
this.Controls.Add(this.btn_active_gyro);
this.Controls.Add(this.lbl_activate_gyro);
this.Controls.Add(this.lbl_reset_mouse);
this.Controls.Add(this.btn_reset_mouse);
this.Controls.Add(this.btn_apply);
this.Controls.Add(this.btn_close);
this.Controls.Add(this.lbl_sr_r);
this.Controls.Add(this.btn_sr_r);
this.Controls.Add(this.lbl_sl_r);
this.Controls.Add(this.btn_sl_r);
this.Controls.Add(this.lbl_sr_l);
this.Controls.Add(this.btn_sr_l);
this.Controls.Add(this.lbl_sl_l);
this.Controls.Add(this.btn_sl_l);
this.Controls.Add(this.lbl_home);
this.Controls.Add(this.btn_home);
this.Controls.Add(this.lbl_capture);
this.Controls.Add(this.btn_capture);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Reassign";
this.Text = "Map Special Buttons";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Reassign_FormClosing);
this.Load += new System.EventHandler(this.Reassign_Load);
this.ResumeLayout(false);
this.PerformLayout();
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Reassign));
this.btn_capture = new BetterJoyForCemu.SplitButton();
this.lbl_capture = new System.Windows.Forms.Label();
this.lbl_home = new System.Windows.Forms.Label();
this.btn_home = new BetterJoyForCemu.SplitButton();
this.lbl_sl_l = new System.Windows.Forms.Label();
this.btn_sl_l = new BetterJoyForCemu.SplitButton();
this.lbl_sr_l = new System.Windows.Forms.Label();
this.btn_sr_l = new BetterJoyForCemu.SplitButton();
this.lbl_sl_r = new System.Windows.Forms.Label();
this.btn_sl_r = new BetterJoyForCemu.SplitButton();
this.lbl_sr_r = new System.Windows.Forms.Label();
this.btn_sr_r = new BetterJoyForCemu.SplitButton();
this.btn_close = new Button();
this.btn_apply = new Button();
this.tip_reassign = new System.Windows.Forms.ToolTip(this.components);
this.lbl_reset_mouse = new System.Windows.Forms.Label();
this.btn_reset_mouse = new BetterJoyForCemu.SplitButton();
this.lbl_activate_gyro = new System.Windows.Forms.Label();
this.btn_active_gyro = new SplitButton();
this.SuspendLayout();
//
// btn_capture
//
this.btn_capture.Location = new System.Drawing.Point(105, 12);
this.btn_capture.Name = "btn_capture";
this.btn_capture.Size = new System.Drawing.Size(75, 23);
this.btn_capture.TabIndex = 0;
this.btn_capture.UseVisualStyleBackColor = true;
//
// lbl_capture
//
this.lbl_capture.AutoSize = true;
this.lbl_capture.Location = new System.Drawing.Point(15, 17);
this.lbl_capture.Name = "lbl_capture";
this.lbl_capture.Size = new System.Drawing.Size(44, 13);
this.lbl_capture.TabIndex = 2;
this.lbl_capture.Text = "Capture";
this.lbl_capture.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// lbl_home
//
this.lbl_home.AutoSize = true;
this.lbl_home.Location = new System.Drawing.Point(15, 46);
this.lbl_home.Name = "lbl_home";
this.lbl_home.Size = new System.Drawing.Size(35, 13);
this.lbl_home.TabIndex = 4;
this.lbl_home.Text = "Home";
this.lbl_home.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_home
//
this.btn_home.Location = new System.Drawing.Point(105, 41);
this.btn_home.Name = "btn_home";
this.btn_home.Size = new System.Drawing.Size(75, 23);
this.btn_home.TabIndex = 3;
this.btn_home.UseVisualStyleBackColor = true;
//
// lbl_sl_l
//
this.lbl_sl_l.AutoSize = true;
this.lbl_sl_l.Location = new System.Drawing.Point(15, 75);
this.lbl_sl_l.Name = "lbl_sl_l";
this.lbl_sl_l.Size = new System.Drawing.Size(78, 13);
this.lbl_sl_l.TabIndex = 6;
this.lbl_sl_l.Text = "SL Left Joycon";
this.lbl_sl_l.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_sl_l
//
this.btn_sl_l.Location = new System.Drawing.Point(105, 70);
this.btn_sl_l.Name = "btn_sl_l";
this.btn_sl_l.Size = new System.Drawing.Size(75, 23);
this.btn_sl_l.TabIndex = 5;
this.btn_sl_l.UseVisualStyleBackColor = true;
//
// lbl_sr_l
//
this.lbl_sr_l.AutoSize = true;
this.lbl_sr_l.Location = new System.Drawing.Point(15, 104);
this.lbl_sr_l.Name = "lbl_sr_l";
this.lbl_sr_l.Size = new System.Drawing.Size(80, 13);
this.lbl_sr_l.TabIndex = 8;
this.lbl_sr_l.Text = "SR Left Joycon";
this.lbl_sr_l.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_sr_l
//
this.btn_sr_l.Location = new System.Drawing.Point(105, 99);
this.btn_sr_l.Name = "btn_sr_l";
this.btn_sr_l.Size = new System.Drawing.Size(75, 23);
this.btn_sr_l.TabIndex = 7;
this.btn_sr_l.UseVisualStyleBackColor = true;
//
// lbl_sl_r
//
this.lbl_sl_r.AutoSize = true;
this.lbl_sl_r.Location = new System.Drawing.Point(15, 133);
this.lbl_sl_r.Name = "lbl_sl_r";
this.lbl_sl_r.Size = new System.Drawing.Size(85, 13);
this.lbl_sl_r.TabIndex = 10;
this.lbl_sl_r.Text = "SL Right Joycon";
this.lbl_sl_r.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_sl_r
//
this.btn_sl_r.Location = new System.Drawing.Point(105, 128);
this.btn_sl_r.Name = "btn_sl_r";
this.btn_sl_r.Size = new System.Drawing.Size(75, 23);
this.btn_sl_r.TabIndex = 9;
this.btn_sl_r.UseVisualStyleBackColor = true;
//
// lbl_sr_r
//
this.lbl_sr_r.AutoSize = true;
this.lbl_sr_r.Location = new System.Drawing.Point(15, 162);
this.lbl_sr_r.Name = "lbl_sr_r";
this.lbl_sr_r.Size = new System.Drawing.Size(87, 13);
this.lbl_sr_r.TabIndex = 12;
this.lbl_sr_r.Text = "SR Right Joycon";
this.lbl_sr_r.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_sr_r
//
this.btn_sr_r.Location = new System.Drawing.Point(105, 157);
this.btn_sr_r.Name = "btn_sr_r";
this.btn_sr_r.Size = new System.Drawing.Size(75, 23);
this.btn_sr_r.TabIndex = 11;
this.btn_sr_r.UseVisualStyleBackColor = true;
//
// btn_close
//
this.btn_close.Location = new System.Drawing.Point(15, 257);
this.btn_close.Name = "btn_close";
this.btn_close.Size = new System.Drawing.Size(75, 23);
this.btn_close.TabIndex = 13;
this.btn_close.Text = "Okay";
this.btn_close.UseVisualStyleBackColor = true;
this.btn_close.Click += new System.EventHandler(this.btn_close_Click);
//
// btn_apply
//
this.btn_apply.Location = new System.Drawing.Point(105, 257);
this.btn_apply.Name = "btn_apply";
this.btn_apply.Size = new System.Drawing.Size(75, 23);
this.btn_apply.TabIndex = 14;
this.btn_apply.Text = "Apply";
this.btn_apply.UseVisualStyleBackColor = true;
this.btn_apply.Click += new System.EventHandler(this.btn_apply_Click);
//
// lbl_reset_mouse
//
this.lbl_reset_mouse.AutoSize = true;
this.lbl_reset_mouse.Location = new System.Drawing.Point(15, 191);
this.lbl_reset_mouse.Name = "lbl_reset_mouse";
this.lbl_reset_mouse.Size = new System.Drawing.Size(80, 13);
this.lbl_reset_mouse.TabIndex = 16;
this.lbl_reset_mouse.Text = "Re-Centre Gyro";
this.lbl_reset_mouse.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_reset_mouse
//
this.btn_reset_mouse.Location = new System.Drawing.Point(105, 186);
this.btn_reset_mouse.Name = "btn_reset_mouse";
this.btn_reset_mouse.Size = new System.Drawing.Size(75, 23);
this.btn_reset_mouse.TabIndex = 15;
this.btn_reset_mouse.UseVisualStyleBackColor = true;
//
// lbl_activate_gyro
//
this.lbl_activate_gyro.AutoSize = true;
this.lbl_activate_gyro.Location = new System.Drawing.Point(14, 220);
this.lbl_activate_gyro.Name = "lbl_activate_gyro";
this.lbl_activate_gyro.Size = new System.Drawing.Size(71, 13);
this.lbl_activate_gyro.TabIndex = 17;
this.lbl_activate_gyro.Text = "Activate Gyro";
this.lbl_activate_gyro.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// btn_active_gyro
//
this.btn_active_gyro.Location = new System.Drawing.Point(105, 215);
this.btn_active_gyro.Name = "btn_active_gyro";
this.btn_active_gyro.Size = new System.Drawing.Size(75, 23);
this.btn_active_gyro.TabIndex = 18;
this.btn_active_gyro.UseVisualStyleBackColor = true;
//
// Reassign
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(192, 292);
this.Controls.Add(this.btn_active_gyro);
this.Controls.Add(this.lbl_activate_gyro);
this.Controls.Add(this.lbl_reset_mouse);
this.Controls.Add(this.btn_reset_mouse);
this.Controls.Add(this.btn_apply);
this.Controls.Add(this.btn_close);
this.Controls.Add(this.lbl_sr_r);
this.Controls.Add(this.btn_sr_r);
this.Controls.Add(this.lbl_sl_r);
this.Controls.Add(this.btn_sl_r);
this.Controls.Add(this.lbl_sr_l);
this.Controls.Add(this.btn_sr_l);
this.Controls.Add(this.lbl_sl_l);
this.Controls.Add(this.btn_sl_l);
this.Controls.Add(this.lbl_home);
this.Controls.Add(this.btn_home);
this.Controls.Add(this.lbl_capture);
this.Controls.Add(this.btn_capture);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Reassign";
this.Text = "Map Special Buttons";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Reassign_FormClosing);
this.Load += new System.EventHandler(this.Reassign_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
@ -345,7 +323,5 @@ namespace BetterJoyForCemu {
private SplitButton btn_reset_mouse;
private Label lbl_activate_gyro;
private SplitButton btn_active_gyro;
private Label lbl_shake;
private SplitButton btn_shake;
}
}
}
}

View file

@ -10,123 +10,123 @@ using System.Threading.Tasks;
using System.Windows.Forms;
namespace BetterJoyForCemu {
public partial class Reassign : Form {
private WindowsInput.Events.Sources.IKeyboardEventSource keyboard;
private WindowsInput.Events.Sources.IMouseEventSource mouse;
public partial class Reassign : Form {
private WindowsInput.Events.Sources.IKeyboardEventSource keyboard;
private WindowsInput.Events.Sources.IMouseEventSource mouse;
ContextMenuStrip menu_joy_buttons = new ContextMenuStrip();
ContextMenuStrip menu_joy_buttons = new ContextMenuStrip();
private Control curAssignment;
private Control curAssignment;
public Reassign() {
InitializeComponent();
public Reassign() {
InitializeComponent();
foreach (int i in Enum.GetValues(typeof(Joycon.Button))) {
ToolStripMenuItem temp = new ToolStripMenuItem(Enum.GetName(typeof(Joycon.Button), i));
temp.Tag = i;
menu_joy_buttons.Items.Add(temp);
}
foreach (int i in Enum.GetValues(typeof(Joycon.Button))) {
ToolStripMenuItem temp = new ToolStripMenuItem(Enum.GetName(typeof(Joycon.Button), i));
temp.Tag = i;
menu_joy_buttons.Items.Add(temp);
}
menu_joy_buttons.ItemClicked += Menu_joy_buttons_ItemClicked;
menu_joy_buttons.ItemClicked += Menu_joy_buttons_ItemClicked;
foreach (SplitButton c in new SplitButton[] { btn_capture, btn_home, btn_sl_l, btn_sl_r, btn_sr_l, btn_sr_r, btn_shake, btn_reset_mouse, btn_active_gyro }) {
c.Tag = c.Name.Substring(4);
GetPrettyName(c);
foreach (SplitButton c in new SplitButton[] { btn_capture, btn_home, btn_sl_l, btn_sl_r, btn_sr_l, btn_sr_r, btn_reset_mouse , btn_active_gyro}) {
c.Tag = c.Name.Substring(4);
GetPrettyName(c);
tip_reassign.SetToolTip(c, "Left-click to detect input.\r\nMiddle-click to clear to default.\r\nRight-click to see more options.");
c.MouseDown += Remap;
c.Menu = menu_joy_buttons;
c.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
}
}
tip_reassign.SetToolTip(c, "Left-click to detect input.\r\nMiddle-click to clear to default.\r\nRight-click to see more options.");
c.MouseDown += Remap;
c.Menu = menu_joy_buttons;
c.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
}
}
private void Menu_joy_buttons_ItemClicked(object sender, ToolStripItemClickedEventArgs e) {
Control c = sender as Control;
private void Menu_joy_buttons_ItemClicked(object sender, ToolStripItemClickedEventArgs e) {
Control c = sender as Control;
ToolStripItem clickedItem = e.ClickedItem;
ToolStripItem clickedItem = e.ClickedItem;
SplitButton caller = (SplitButton)c.Tag;
Config.SetValue((string)caller.Tag, "joy_" + (clickedItem.Tag));
GetPrettyName(caller);
}
SplitButton caller = (SplitButton)c.Tag;
Config.SetValue((string)caller.Tag, "joy_" + (clickedItem.Tag));
GetPrettyName(caller);
}
private void Remap(object sender, MouseEventArgs e) {
SplitButton c = sender as SplitButton;
switch (e.Button) {
case MouseButtons.Left:
c.Text = "...";
curAssignment = c;
break;
case MouseButtons.Middle:
Config.SetValue((string)c.Tag, Config.GetDefaultValue((string)c.Tag));
GetPrettyName(c);
break;
case MouseButtons.Right:
break;
}
}
private void Remap(object sender, MouseEventArgs e) {
SplitButton c = sender as SplitButton;
switch (e.Button) {
case MouseButtons.Left:
c.Text = "...";
curAssignment = c;
break;
case MouseButtons.Middle:
Config.SetValue((string) c.Tag, Config.GetDefaultValue((string) c.Tag));
GetPrettyName(c);
break;
case MouseButtons.Right:
break;
}
}
private void Reassign_Load(object sender, EventArgs e) {
keyboard = WindowsInput.Capture.Global.KeyboardAsync();
keyboard.KeyEvent += Keyboard_KeyEvent;
mouse = WindowsInput.Capture.Global.MouseAsync();
mouse.MouseEvent += Mouse_MouseEvent;
}
private void Reassign_Load(object sender, EventArgs e) {
keyboard = WindowsInput.Capture.Global.KeyboardAsync();
keyboard.KeyEvent += Keyboard_KeyEvent;
mouse = WindowsInput.Capture.Global.MouseAsync();
mouse.MouseEvent += Mouse_MouseEvent;
}
private void Mouse_MouseEvent(object sender, WindowsInput.Events.Sources.EventSourceEventArgs<WindowsInput.Events.Sources.MouseEvent> e) {
if (curAssignment != null && e.Data.ButtonDown != null) {
Config.SetValue((string)curAssignment.Tag, "mse_" + ((int)e.Data.ButtonDown.Button));
AsyncPrettyName(curAssignment);
curAssignment = null;
e.Next_Hook_Enabled = false;
}
}
private void Mouse_MouseEvent(object sender, WindowsInput.Events.Sources.EventSourceEventArgs<WindowsInput.Events.Sources.MouseEvent> e) {
if (curAssignment != null && e.Data.ButtonDown != null) {
Config.SetValue((string)curAssignment.Tag, "mse_" + ((int)e.Data.ButtonDown.Button));
AsyncPrettyName(curAssignment);
curAssignment = null;
e.Next_Hook_Enabled = false;
}
}
private void Keyboard_KeyEvent(object sender, WindowsInput.Events.Sources.EventSourceEventArgs<WindowsInput.Events.Sources.KeyboardEvent> e) {
if (curAssignment != null && e.Data.KeyDown != null) {
Config.SetValue((string)curAssignment.Tag, "key_" + ((int)e.Data.KeyDown.Key));
AsyncPrettyName(curAssignment);
curAssignment = null;
e.Next_Hook_Enabled = false;
}
}
private void Keyboard_KeyEvent(object sender, WindowsInput.Events.Sources.EventSourceEventArgs<WindowsInput.Events.Sources.KeyboardEvent> e) {
if (curAssignment != null && e.Data.KeyDown != null) {
Config.SetValue((string)curAssignment.Tag, "key_" + ((int)e.Data.KeyDown.Key));
AsyncPrettyName(curAssignment);
curAssignment = null;
e.Next_Hook_Enabled = false;
}
}
private void Reassign_FormClosing(object sender, FormClosingEventArgs e) {
keyboard.Dispose();
mouse.Dispose();
}
private void Reassign_FormClosing(object sender, FormClosingEventArgs e) {
keyboard.Dispose();
mouse.Dispose();
}
private void AsyncPrettyName(Control c) {
if (InvokeRequired) {
this.Invoke(new Action<Control>(AsyncPrettyName), new object[] { c });
return;
}
GetPrettyName(c);
}
private void AsyncPrettyName(Control c) {
if (InvokeRequired) {
this.Invoke(new Action<Control>(AsyncPrettyName), new object[] { c });
return;
}
GetPrettyName(c);
}
private void GetPrettyName(Control c) {
string val;
switch (val = Config.Value((string)c.Tag)) {
case "0":
if (c == btn_home)
c.Text = "Guide";
else
c.Text = "";
break;
default:
Type t = val.StartsWith("joy_") ? typeof(Joycon.Button) : (val.StartsWith("key_") ? typeof(WindowsInput.Events.KeyCode) : typeof(WindowsInput.Events.ButtonCode));
c.Text = Enum.GetName(t, Int32.Parse(val.Substring(4)));
break;
}
}
private void GetPrettyName(Control c) {
string val;
switch (val = Config.Value((string)c.Tag)) {
case "0":
if (c == btn_home)
c.Text = "Guide";
else
c.Text = "";
break;
default:
Type t = val.StartsWith("joy_") ? typeof(Joycon.Button) : (val.StartsWith("key_") ? typeof(WindowsInput.Events.KeyCode) : typeof(WindowsInput.Events.ButtonCode));
c.Text = Enum.GetName(t, Int32.Parse(val.Substring(4)));
break;
}
}
private void btn_apply_Click(object sender, EventArgs e) {
Config.Save();
}
private void btn_apply_Click(object sender, EventArgs e) {
Config.Save();
}
private void btn_close_Click(object sender, EventArgs e) {
btn_apply_Click(sender, e);
Close();
}
}
private void btn_close_Click(object sender, EventArgs e) {
btn_apply_Click(sender, e);
Close();
}
}
}

File diff suppressed because it is too large Load diff

BIN
BetterJoyForCemu/hidapi.dll Normal file

Binary file not shown.

View file

@ -2,6 +2,6 @@
<packages>
<package id="Crc32.NET" version="1.2.0" targetFramework="net461" />
<package id="JetBrains.Annotations" version="2020.1.0" targetFramework="net461" />
<package id="Nefarius.ViGEm.Client" version="1.17.178" targetFramework="net461" />
<package id="WindowsInput" version="6.3.0" targetFramework="net461" />
<package id="Nefarius.ViGEm.Client" version="1.0.0" targetFramework="net461" />
<package id="WindowsInput" version="6.1.1" targetFramework="net461" />
</packages>

Binary file not shown.

Binary file not shown.

109
README.md
View file

@ -1,107 +1,4 @@
<p align="center">
<img src="title.png">
</p>
# BetterJoy v6.1 - DS4 Gyro
This is an experimental branch of BetterJoy that uses a custom build of ViGEm to allow the use of DS4 gyro/accel controls. For more info, please see [the following wiki page](https://github.com/Davidobot/BetterJoy/wiki/DS4-Gyro).
# BetterJoy v7.0
Allows the Nintendo Switch Pro Controller, Joycons, and Switch SNES controller to be used with [Cemu](http://cemu.info/) using [Cemuhook](https://sshnuke.net/cemuhook/), [Citra](https://citra-emu.org/), [Dolphin](https://dolphin-emu.org/), [Yuzu](https://yuzu-emu.org/), and system-wide with generic XInput support.
It also allows using the gyro to control your mouse and remap the special buttons (SL, SR, Capture) to key bindings of your choice.
If anyone would like to donate (for whatever reason), [you can do so here](https://www.paypal.me/DavidKhachaturov/5).
#### Personal note
Thank you for using my software and all the constructive feedback I've been getting about it. I started writing this project a while back and have since then learnt a lot more about programming and software development in general. I don't have too much time to work on this project, but I will try to fix bugs when and if they arise. Thank you for your patience in that regard too!
It's been quite a wild ride, with nearly **590k** (!!) official download on GitHub and probably many more through the nightlies. I think this project was responsible for both software jobs I landed so far, so I am quite proud of it.
### Screenshot
![Example](https://user-images.githubusercontent.com/16619943/67919451-bf8e5680-fb76-11e9-995e-7193b87548e1.png)
# Downloads
Go to the [Releases tab](https://github.com/Davidobot/BetterJoy/releases/)!
# How to use
1. Install drivers
1. Read the READMEs (they're there for a reason!)
1. Run *Drivers/ViGEmBus_Setup_1.16.116.exe*
1. Restart your computer
2. Run *BetterJoyForCemu.exe*
1. Run as Administrator if your keyboard/mouse button mappings don't work
3. Connect your controllers.
4. Start Cemu and ensure CemuHook has the controller selected.
1. If using Joycons, CemuHook will detect two controllers - each will give all buttons, but choosing one over the other just chooses preference for which hand to use for gyro controls.
5. Go into *Input Settings*, choose XInput as a source and assign buttons normally.
1. If you don't want to do this for some reason, just have one input profile set up with *Wii U Gamepad* as the controller and enable "Also use for buttons/axes" under *GamePad motion source*. **This is no longer required as of version 3**
2. Turn rumble up to 70-80% if you want rumble.
* As of version 3, you can use the pro controller and Joycons as normal xbox controllers on your PC - try it with Steam!
# More Info
Check out the [wiki](https://github.com/Davidobot/BetterJoy/wiki)! There, you'll find all sorts of goodness such as the changelog, description of app settings, the FAQ and Problems page, and info on how to make BetterJoy work with Steam *better*.
# Connecting and Disconnecting the Controller
## Bluetooth Mode
* Hold down the small button (sync) on the top of the controller for 5 seconds - this puts the controller into broadcasting mode.
* Search for it in your bluetooth settings and pair normally.
* To disconnect the controller - hold the home button (or capture button) down for 2 seconds (or press the sync button). To reconnect - press any button on your controller.
## USB Mode
* Plug the controller into your computer.
## Disconnecting \[Windows 10]
1. Go into "Bluetooth and other devices settings"
1. Under the first category "Mouse, keyboard, & pen", there should be the pro controller.
1. Click on it and a "Remove" button will be revealed.
1. Press the "Remove" button
# Building
## Visual Studio (IDE)
1. If you didn't already, install **Visual Studio Community 2019** via
[the official guide](https://docs.microsoft.com/en-us/visualstudio/install/install-visual-studio?view=vs-2019).
When asked about the workloads, select **.NET Desktop Development**.
2. Get the code project via Git or by using the *Download ZIP* button.
3. Open Visual Studio Community and open the solution file (*BetterJoy.sln*).
4. Open the NuGet manager via *Tools > NuGet Package Manager > Package Manager Settings*.
5. You should have a warning mentioning *restoring your packages*. Click on the **Restore** button.
6. You can now run and build BetterJoy.
## Visual Studio Build Tools (CLI)
1. Download **Visual Studio Build Tools** via
[the official link](https://visualstudio.microsoft.com/it/downloads/#build-tools-for-visual-studio-2019).
2. Install **NuGet** by following
[the official guide](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools#nugetexe-cli).
You should follow the section for ***nuget.exe***.
Verify that you can run `nuget` from your favourite terminal.
3. Get the code project via Git or by using the *Download ZIP* button.
4. Open a terminal (*cmd*, *PowerShell*, ...) and enter the folder with the source code.
5. Restore the NuGet dependencies by running: `nuget restore`
6. Now build the app with MSBuild:
```
msbuild .\BetterJoy.sln -p:Configuration=CONFIGURATION -p:Platform=PLATFORM -t:Rebuild
```
The available values for **CONFIGURATION** are *Release* and *Debug*.
The available values for **PLATFORM** are *x86* and *x64* (you want the latter 99.99% of the time).
7. You have now built the app. See the next section for locating the binaries.
## Binaries location
The built binaries are located under
*BetterJoyForCemu\bin\PLATFORM\CONFIGURATION*
where `PLATFORM` and `CONFIGURATION` are the one provided at build time.
# Acknowledgements
A massive thanks goes out to [rajkosto](https://github.com/rajkosto/) for putting up with 17 emails and replying very quickly to my silly queries. The UDP server is also mostly taken from his [ScpToolkit](https://github.com/rajkosto/ScpToolkit) repo.
Also I am very grateful to [mfosse](https://github.com/mfosse/JoyCon-Driver) for pointing me in the right direction and to [Looking-Glass](https://github.com/Looking-Glass/JoyconLib) without whom I would not be able to figure anything out. (being honest here - the joycon code is his)
Many thanks to [nefarius](https://github.com/ViGEm/ViGEmBus) for his ViGEm project! Apologies and appreciation go out to [epigramx](https://github.com/epigramx), creator of *WiimoteHook*, for giving me the driver idea and for letting me keep using his installation batch script even though I took it without permission. Thanks go out to [MTCKC](https://github.com/MTCKC/ProconXInput) for inspiration and batch files.
A last thanks goes out to [dekuNukem](https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering) for his documentation, especially on the SPI calibration data and the IMU sensor notes!
Massive *thank you* to **all** code contributors!
Icons (modified): "[Switch Pro Controller](https://thenounproject.com/term/nintendo-switch/930119/)", "[
Switch Detachable Controller Left](https://thenounproject.com/remsing/uploads/?i=930115)", "[Switch Detachable Controller Right](https://thenounproject.com/remsing/uploads/?i=930121)" icons by Chad Remsing from [the Noun Project](http://thenounproject.com/). [Super Nintendo Controller](https://thenounproject.com/themizarkshow/collection/vectogram/?i=193592) icon by Mark Davis from the [the Noun Project](http://thenounproject.com/); icon modified by [Amy Alexander](https://www.linkedin.com/in/-amy-alexander/). [Nintendo 64 Controller](https://thenounproject.com/icon/game-controller-193588/) icon by Mark Davis from the [the Noun Project](http://thenounproject.com/); icon modified by [Gino Moena](https://www.github.com/GinoMoena).
I will merge this branch into master once ViGEm updates to include the gyro API (we're working on it)