- WIP Adding support for 3rd party controllers

This commit is contained in:
David Khachaturov 2020-06-12 16:04:24 +01:00
parent a291f0daf6
commit e1f3e573fd
5 changed files with 753 additions and 669 deletions

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.chk_isLeft = new System.Windows.Forms.CheckBox();
this.chk_isPro = new System.Windows.Forms.CheckBox();
this.label2 = new System.Windows.Forms.Label();
this.chooseType = new System.Windows.Forms.ComboBox();
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.chk_isLeft);
this.group_props.Controls.Add(this.chk_isPro);
this.group_props.Controls.Add(this.label2);
this.group_props.Controls.Add(this.chooseType);
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,29 +92,23 @@
this.group_props.TabStop = false;
this.group_props.Text = "Settings";
//
// chk_isLeft
// label2
//
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);
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";
//
// chk_isPro
// chooseType
//
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);
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);
//
// btn_applyAndClose
//
@ -203,10 +197,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,6 +3,7 @@ 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;
@ -13,26 +14,82 @@ 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 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) {
this.product_id = product_id; this.vendor_id = vendor_id; this.type = type;
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);
}
}
public override int GetHashCode() {
return Tuple.Create(product_id, vendor_id).GetHashCode();
}
public override string ToString() {
return name;
}
public string Serialise() {
return String.Format("{0}|{1}|{2}|{3}", name, product_id, vendor_id, type);
}
}
const string PATH = "3rdPartyControllers";
public _3rdPartyControllers() {
InitializeComponent();
list_allControllers.DisplayMember = "Text";
/*list_allControllers.DisplayMember = "Text";
list_allControllers.ValueMember = "Value";
list_customControllers.DisplayMember = "Text";
list_customControllers.ValueMember = "Value";
list_customControllers.ValueMember = "Value";*/
list_allControllers.HorizontalScrollbar = true; list_customControllers.HorizontalScrollbar = true;
RefreshControllerList();
chooseType.Items.AddRange(new String[] { "Pro Controller", "Left Joycon", "Right Joycon" });
group_props.Controls.Add(chk_isLeft);
group_props.Controls.Add(chk_isPro);
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('|');
list_customControllers.Items.Add(new SController(split[0], ushort.Parse(split[1]), ushort.Parse(split[2]), byte.Parse(split[3])));
}
}
}
CopyCustomControllers();
RefreshControllerList();
}
public void CopyCustomControllers() {
Program.thirdPartyCons.Clear();
foreach (SController v in list_customControllers.Items) {
Program.thirdPartyCons.Add(v);
}
}
private bool ContainsText(ListBox a, String manu) {
foreach (var v in a.Items) {
dynamic d = v as dynamic;
if (d.Text == null)
foreach (SController v in a.Items) {
if (v == null)
continue;
if (d.Text.Equals(manu))
if (v.name.Equals(manu))
return true;
}
return false;
@ -41,14 +98,15 @@ namespace BetterJoyForCemu {
private void RefreshControllerList() {
list_allControllers.Items.Clear();
IntPtr ptr = HIDapi.hid_enumerate(0x0, 0x0);
IntPtr top_ptr = ptr;
hid_device_info enumerate; // Add device to list
while (ptr != IntPtr.Zero) {
enumerate = (hid_device_info)Marshal.PtrToStructure(ptr, typeof(hid_device_info));
if (!ContainsText(list_customControllers, enumerate.product_string) && !ContainsText(list_allControllers, enumerate.product_string))
list_allControllers.Items.Add(new { Text = enumerate.product_string, Value = enumerate });
if (!ContainsText(list_customControllers, enumerate.product_string) && !ContainsText(list_allControllers, enumerate.product_string)) {
list_allControllers.Items.Add(new SController(enumerate.product_string, enumerate.vendor_id, enumerate.product_id, 0));
// 0 type is undefined
}
ptr = enumerate.next;
}
@ -58,6 +116,7 @@ namespace BetterJoyForCemu {
if (list_allControllers.SelectedItem != null) {
list_customControllers.Items.Add(list_allControllers.SelectedItem);
list_allControllers.Items.Remove(list_allControllers.SelectedItem);
list_allControllers.ClearSelected();
}
}
@ -66,20 +125,18 @@ 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) {
@ -97,16 +154,22 @@ namespace BetterJoyForCemu {
private void list_allControllers_SelectedValueChanged(object sender, EventArgs e) {
if (list_allControllers.SelectedItem != null)
tip_device.Show((list_allControllers.SelectedItem as dynamic).Text, list_allControllers);
tip_device.Show((list_allControllers.SelectedItem as SController).name, list_allControllers);
}
private void list_customControllers_SelectedValueChanged(object sender, EventArgs e) {
if (list_customControllers.SelectedItem != null) {
tip_device.Show((list_customControllers.SelectedItem as dynamic).Text, list_customControllers);
SController v = (list_customControllers.SelectedItem as SController);
tip_device.Show(v.name, list_customControllers);
chooseType.SelectedIndex = v.type - 1;
group_props.Enabled = true;
} else
} else {
chooseType.SelectedIndex = -1;
group_props.Enabled = false;
}
}
private void list_customControllers_MouseDown(object sender, MouseEventArgs e) {
if (e.Y > list_customControllers.ItemHeight * list_customControllers.Items.Count)
@ -117,5 +180,12 @@ 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

@ -26,7 +26,6 @@
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();
@ -68,16 +67,6 @@
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";
@ -265,7 +254,7 @@
//
// btn_open3rdP
//
this.btn_open3rdP.Location = new System.Drawing.Point(188, 112);
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;
@ -337,7 +326,7 @@
//
// btn_reassign_open
//
this.btn_reassign_open.Location = new System.Drawing.Point(107, 112);
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;
@ -362,7 +351,6 @@
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")));
@ -384,7 +372,6 @@
#endregion
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;

View file

@ -35,9 +35,6 @@ namespace BetterJoyForCemu {
if (!nonOriginal)
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 };

View file

@ -15,6 +15,7 @@ using System.Timers;
using System.Web.Configuration;
using System.Windows.Forms;
using Nefarius.ViGEm.Client;
using static BetterJoyForCemu._3rdPartyControllers;
using static BetterJoyForCemu.HIDapi;
namespace BetterJoyForCemu {
@ -95,15 +96,28 @@ namespace BetterJoyForCemu {
}
}
private ushort TypeToProdId(byte type) {
switch (type) {
case 1:
return product_pro;
case 2:
return product_l;
case 3:
return product_r;
}
return 0;
}
public void CheckForNewControllers() {
// move all code for initializing devices here and well as the initial code from Start()
bool isLeft = false;
IntPtr ptr = HIDapi.hid_enumerate(vendor_id, 0x0);
IntPtr ptr = HIDapi.hid_enumerate(0x0, 0x0);
IntPtr top_ptr = ptr;
hid_device_info enumerate; // Add device to list
bool foundNew = false;
while (ptr != IntPtr.Zero) {
SController thirdParty = null;
enumerate = (hid_device_info)Marshal.PtrToStructure(ptr, typeof(hid_device_info));
if (enumerate.serial_number == null) {
@ -117,9 +131,21 @@ namespace BetterJoyForCemu {
}
bool validController = (enumerate.product_id == product_l || enumerate.product_id == product_r ||
enumerate.product_id == product_pro || enumerate.product_id == product_snes);
enumerate.product_id == product_pro || enumerate.product_id == product_snes) && enumerate.vendor_id == vendor_id;
// check list of custom controllers specified
foreach (SController v in Program.thirdPartyCons) {
if (enumerate.vendor_id == v.vendor_id && enumerate.product_id == v.product_id) {
validController = true;
thirdParty = v;
break;
}
}
ushort prod_id = thirdParty == null ? enumerate.product_id : TypeToProdId(thirdParty.type);
if (prod_id == 0)
continue; // controller was not assigned a type
if (validController && !ControllerAlreadyAdded(enumerate.path)) {
switch (enumerate.product_id) {
switch (prod_id) {
case product_l:
isLeft = true;
form.AppendTextBox("Left Joy-Con connected.\r\n"); break;
@ -166,8 +192,8 @@ namespace BetterJoyForCemu {
break;
}
bool isPro = enumerate.product_id == product_pro;
bool isSnes = enumerate.product_id == product_snes;
bool isPro = prod_id == product_pro;
bool isSnes = prod_id == product_snes;
j.Add(new Joycon(handle, EnableIMU, EnableLocalize & EnableIMU, 0.05f, isLeft, enumerate.path, enumerate.serial_number, j.Count, isPro, isSnes));
foundNew = true;
@ -179,7 +205,7 @@ namespace BetterJoyForCemu {
ii++;
if (!v.Enabled) {
System.Drawing.Bitmap temp;
switch (enumerate.product_id) {
switch (prod_id) {
case (product_l):
temp = Properties.Resources.jc_left_s; break;
case (product_r):
@ -210,8 +236,12 @@ namespace BetterJoyForCemu {
}
byte[] mac = new byte[6];
try {
for (int n = 0; n < 6; n++)
mac[n] = byte.Parse(enumerate.serial_number.Substring(n * 2, 2), System.Globalization.NumberStyles.HexNumber);
} catch (Exception e) {
// could not parse mac address
}
j[j.Count - 1].PadMacAddress = new PhysicalAddress(mac);
}
@ -330,6 +360,8 @@ namespace BetterJoyForCemu {
static public bool useHIDG = Boolean.Parse(ConfigurationManager.AppSettings["UseHIDG"]);
public static List<SController> thirdPartyCons = new List<SController>();
private static WindowsInput.Events.Sources.IKeyboardEventSource keyboard;
private static WindowsInput.Events.Sources.IMouseEventSource mouse;
@ -390,6 +422,10 @@ namespace BetterJoyForCemu {
}
}
// a bit hacky
_3rdPartyControllers partyForm = new _3rdPartyControllers();
partyForm.CopyCustomControllers();
mgr = new JoyconManager();
mgr.form = form;
mgr.Awake();