public void conBtnClick(object sender, EventArgs e) { Button button = sender as Button; 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 (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; //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); v.xin.Dispose(); v.xin = 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; } } 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 (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; 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; } } //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); v.other.other = null; v.other = null; } } }
public void CheckForNewControllers() { CleanUp(); // 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 top_ptr = ptr; hid_device_info enumerate; // Add device to list bool foundNew = false; while (ptr != IntPtr.Zero) { enumerate = (hid_device_info)Marshal.PtrToStructure(ptr, typeof(hid_device_info)); if (enumerate.serial_number == null) { ptr = enumerate.next; // can't believe it took me this long to figure out why USB connections used up so much CPU. // it was getting stuck in an inf loop here! continue; } if (form.nonOriginal) { enumerate.product_id = product_pro; } bool validController = (enumerate.product_id == product_l || enumerate.product_id == product_r || enumerate.product_id == product_pro || enumerate.product_id == product_snes); if (validController && !ControllerAlreadyAdded(enumerate.path)) { switch (enumerate.product_id) { case product_l: isLeft = true; form.AppendTextBox("Left Joy-Con connected.\r\n"); break; case product_r: isLeft = false; form.AppendTextBox("Right Joy-Con connected.\r\n"); break; case product_pro: isLeft = true; form.AppendTextBox("Pro controller connected.\r\n"); break; case product_snes: isLeft = true; form.AppendTextBox("SNES controller connected.\r\n"); break; default: form.AppendTextBox("Non Joy-Con Nintendo input device skipped.\r\n"); break; } // Add controller to block-list for HidGuardian if (Program.useHIDG) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"http://*****:*****@"hwids=HID\" + enumerate.path.Split('#')[1].ToUpper(); var data = Encoding.UTF8.GetBytes(postData); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"; request.ContentLength = data.Length; using (var stream = request.GetRequestStream()) stream.Write(data, 0, data.Length); try { var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); } catch { form.AppendTextBox("Unable to add controller to block-list.\r\n"); } } // -------------------- // IntPtr handle = HIDapi.hid_open_path(enumerate.path); try { HIDapi.hid_set_nonblocking(handle, 1); } catch { form.AppendTextBox("Unable to open path to device - are you using the correct (64 vs 32-bit) version for your PC?\r\n"); break; } bool isPro = enumerate.product_id == product_pro; bool isSnes = enumerate.product_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; j.Last().form = form; if (j.Count < 5) { int ii = -1; foreach (Button v in form.con) { ii++; if (!v.Enabled) { System.Drawing.Bitmap temp; switch (enumerate.product_id) { case (product_l): temp = Properties.Resources.jc_left_s; break; case (product_r): temp = Properties.Resources.jc_right_s; break; case (product_pro): temp = Properties.Resources.pro; break; case (product_snes): temp = Properties.Resources.snes; break; default: temp = Properties.Resources.cross; break; } v.Invoke(new MethodInvoker(delegate { v.Tag = j.Last(); // assign controller to button v.Enabled = true; v.Click += new EventHandler(form.conBtnClick); v.BackgroundImage = temp; })); form.loc[ii].Invoke(new MethodInvoker(delegate { form.loc[ii].Tag = v; form.loc[ii].Click += new EventHandler(form.locBtnClick); })); break; } } } byte[] mac = new byte[6]; for (int n = 0; n < 6; n++) { mac[n] = byte.Parse(enumerate.serial_number.Substring(n * 2, 2), System.Globalization.NumberStyles.HexNumber); } j[j.Count - 1].PadMacAddress = new PhysicalAddress(mac); } ptr = enumerate.next; } if (foundNew) // attempt to auto join-up joycons on connection { Joycon temp = null; foreach (Joycon v in j) { if (!v.isPro) { if (temp == null) { temp = v; } else if (temp.isLeft != v.isLeft && v.other == null) { temp.other = v; v.other = temp; //Set both Joycon LEDs to the one with the lowest ID byte led = temp.LED <= v.LED ? temp.LED : v.LED; temp.LED = led; v.LED = led; temp.SetPlayerLED(led); v.SetPlayerLED(led); temp.xin.Dispose(); temp.xin = null; foreach (Button b in form.con) { if (b.Tag == v || b.Tag == temp) { Joycon tt = (b.Tag == v) ? v : (b.Tag == temp) ? temp : v; b.BackgroundImage = tt.isLeft ? Properties.Resources.jc_left : Properties.Resources.jc_right; } } temp = null; // repeat } } } } HIDapi.hid_free_enumeration(top_ptr); foreach (Joycon jc in j) // Connect device straight away { if (jc.state == Joycon.state_.NOT_ATTACHED) { if (jc.xin != null) { jc.xin.Connect(); } jc.Attach(leds_: jc.LED); bool on = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).AppSettings.Settings["HomeLEDOn"].Value.ToLower() == "true"; foreach (Joycon j in Program.mgr.j) { j.SetHomeLight(on); } jc.Begin(); if (form.nonOriginal) { jc.getActiveData(); } } } }
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(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) { * ptr = enumerate.next; // can't believe it took me this long to figure out why USB connections used up so much CPU. * // it was getting stuck in an inf loop here! * continue; * }*/ if (form.nonOriginal) { enumerate.product_id = product_pro; } bool validController = (enumerate.product_id == product_l || enumerate.product_id == product_r || 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 (prod_id) { case product_l: isLeft = true; form.AppendTextBox("左Joy-Con手柄已连接。\r\n"); break; case product_r: isLeft = false; form.AppendTextBox("右Joy-Con手柄已连接。\r\n"); break; case product_pro: isLeft = true; form.AppendTextBox("Switch Pro手柄已连接。\r\n"); break; case product_snes: isLeft = true; form.AppendTextBox("SNES手柄已连接。\r\n"); break; default: form.AppendTextBox("非任天堂Joy-Con输入设备,已跳过。\r\n"); break; } // Add controller to block-list for HidGuardian if (Program.useHIDG) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"http://*****:*****@"hwids=HID\" + enumerate.path.Split('#')[1].ToUpper(); var data = Encoding.UTF8.GetBytes(postData); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"; request.ContentLength = data.Length; using (var stream = request.GetRequestStream()) stream.Write(data, 0, data.Length); try { var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); } catch { form.AppendTextBox("无法此将控制器添加到阻止列表。\r\n"); } } // -------------------- // IntPtr handle = HIDapi.hid_open_path(enumerate.path); try { HIDapi.hid_set_nonblocking(handle, 1); } catch { form.AppendTextBox("无法打开设备路径!请确认操作系统的版本(64位与32位),并检查是否打开了对应的版本。\r\n"); break; } 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, thirdParty != null)); foundNew = true; j.Last().form = form; if (j.Count < 5) { int ii = -1; foreach (Button v in form.con) { ii++; if (!v.Enabled) { System.Drawing.Bitmap temp; switch (prod_id) { case (product_l): temp = Properties.Resources.jc_left_s; break; case (product_r): temp = Properties.Resources.jc_right_s; break; case (product_pro): temp = Properties.Resources.pro; break; case (product_snes): temp = Properties.Resources.snes; break; default: temp = Properties.Resources.cross; break; } v.Invoke(new MethodInvoker(delegate { v.Tag = j.Last(); // assign controller to button v.Enabled = true; v.Click += new EventHandler(form.conBtnClick); v.BackgroundImage = temp; })); form.loc[ii].Invoke(new MethodInvoker(delegate { form.loc[ii].Tag = v; form.loc[ii].Click += new EventHandler(form.locBtnClick); })); break; } } } 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); } ptr = enumerate.next; } if (foundNew) // attempt to auto join-up joycons on connection { Joycon temp = null; foreach (Joycon v in j) { if (!v.isPro) { if (temp == null) { temp = v; } else if (temp.isLeft != v.isLeft && v.other == null) { temp.other = v; v.other = temp; //Set both Joycon LEDs to the one with the lowest ID byte led = Math.Min(temp.LED, v.LED); temp.LED = led; v.LED = led; temp.SetPlayerLED(led); v.SetPlayerLED(led); if (temp.out_xbox != null) { try { temp.out_xbox.Disconnect(); } catch (Exception e) { // it wasn't connected in the first place, go figure } } if (temp.out_ds4 != null) { try { temp.out_ds4.Disconnect(); } catch (Exception e) { // it wasn't connected in the first place, go figure } } temp.out_xbox = null; temp.out_ds4 = null; foreach (Button b in form.con) { if (b.Tag == v || b.Tag == temp) { Joycon tt = (b.Tag == v) ? v : (b.Tag == temp) ? temp : v; b.BackgroundImage = tt.isLeft ? Properties.Resources.jc_left : Properties.Resources.jc_right; } } temp = null; // repeat } } } } HIDapi.hid_free_enumeration(top_ptr); foreach (Joycon jc in j) // Connect device straight away { if (jc.state == Joycon.state_.NOT_ATTACHED) { if (jc.out_xbox != null) { jc.out_xbox.Connect(); } if (jc.out_ds4 != null) { jc.out_ds4.Connect(); } try { jc.Attach(leds_: jc.LED); } catch (Exception e) { jc.state = Joycon.state_.DROPPED; continue; } bool on = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).AppSettings.Settings["HomeLEDOn"].Value.ToLower() == "true"; foreach (Joycon j in Program.mgr.j) { j.SetHomeLight(on); } jc.Begin(); if (form.nonOriginal) { jc.getActiveData(); } } } }