public Config3rdPartyForm(Joycon j) { InitializeComponent(); this.j = j; selector = new Selector3rdPartyType(); GetColor(); init(); }
public void Start() { for (int i = 0; i < j.Count; ++i) { Joycon jc = j[i]; byte LEDs = 0x0; LEDs |= (byte)(0x1 << i); jc.Attach(leds_: LEDs); jc.Begin(); } }
void ReenableXinput(Joycon v) { if (showAsXInput) { v.xin = Program.emClient.CreateXbox360Controller(); if (toRumble) { v.xin.FeedbackReceived += v.ReceiveRumble; } } }
void ReenableXinput(Joycon v) { if (showAsXInput) { v.xin = new Xbox360Controller(Program.emClient); if (toRumble) { v.xin.FeedbackReceived += v.ReceiveRumble; } v.report = new Xbox360Report(); } }
private void buttonSensorsCalibrate_Click(object sender, EventArgs e) { Joycon v = this.joycon; DialogResult result = MessageBox.Show("Place the controller with the stick facing upward on a flat, stable surface and click OK.", "Calibarte Motion Controls", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); if (result == DialogResult.OK) { Cursor tmp = this.Cursor; this.Cursor = Cursors.WaitCursor; v.CalibarteMotionControls(); this.Cursor = tmp; MessageBox.Show("Calibartion finished", "Calibarte Motion Controls"); } }
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 (button.Tag.GetType() == typeof(Joycon)) { Joycon v = (Joycon)button.Tag; v.SetRumble(20.0f, 400.0f, 1.0f, 300); } } }
private void checkBoxForceGyroSen_CheckedChanged(object sender, EventArgs e) { if (checkBoxForceGyroSen.Checked) { Joycon v = this.joycon; Config.SaveGyroSensitivity(v.PadMacAddress.ToString(), new Int16[3] { 13371, 13371, 13371 }); } else { Joycon v = this.joycon; Config.SaveGyroSensitivity(v.PadMacAddress.ToString(), new Int16[3] { 0, 0, 0 }); } }
public void Start() { for (int i = 0; i < j.Count; ++i) { Joycon jc = j[i]; if (jc.xin != null) { jc.xin.Connect(); } byte LEDs = 0x0; LEDs |= (byte)(0x1 << i); jc.Attach(leds_: LEDs); jc.Begin(); } }
public async void locBtnClickAsync(object sender, EventArgs e) { Button bb = sender 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); } } }
void CleanUp() // removes dropped controllers from list { List <Joycon> rem = new List <Joycon>(); for (int i = 0; i < j.Count; i++) { Joycon v = j[i]; if (v.state == Joycon.state_.DROPPED) { v.Detach(); rem.Add(v); form.AppendTextBox("Removed dropped controller to list. Can be reconnected.\r\n"); } } foreach (Joycon v in rem) { j.Remove(v); } }
private void StickCalibrate_Click(bool isSecondStick) { Joycon v = this.joycon; DialogResult result = MessageBox.Show("Leave the stick centered, then click OK to continue.", "Calibarte Stick", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); if (result == DialogResult.OK) { v.BeginCalibrateStick(isSecondStick, Joycon.CalibratingStickPhase.CENTER); //result = MessageBox.Show("Leave the stick centered, then click OK.", "Calibarte Stick", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); System.Threading.Thread.Sleep(1000); v.FinishCalibrateStick(Joycon.CalibratingStickPhase.CENTER); MessageBox.Show("Center calibartion finished, click OK to continue", "Calibarte Stick"); v.BeginCalibrateStick(isSecondStick, Joycon.CalibratingStickPhase.ROUND); result = MessageBox.Show("Move the stick all axises through its complete range, then click OK.", "Calibarte Stick", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); v.FinishCalibrateStick(Joycon.CalibratingStickPhase.ROUND); MessageBox.Show("Analog stick calibartion finished", "Calibarte Stick"); } }
void CleanUp() // removes dropped controllers from list { List <Joycon> rem = new List <Joycon>(); for (int i = 0; i < j.Count; i++) { Joycon v = j[i]; if (v.state == Joycon.state_.DROPPED) { if (v.other != null) { v.other.other = null; // The other of the other is the joycon itself } v.Detach(); rem.Add(v); foreach (Button b in form.con) { if (b.Enabled & b.Tag == v) { b.Invoke(new MethodInvoker(delegate { b.BackColor = System.Drawing.Color.FromArgb(0x00, System.Drawing.SystemColors.Control); b.Enabled = false; b.BackgroundImage = Properties.Resources.cross; })); break; } } form.AppendTextBox("Removed dropped controller to list. Can be reconnected.\r\n"); } } foreach (Joycon v in rem) { j.Remove(v); } }
public async void locBtnClickAsync(object sender, EventArgs e) { Button bb = sender 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; /* Switch Pro适合的振动测试数据(就是点击"验证测试"按钮时手柄振动强度) * v.SetRumble(20.0f, 110.0f, 1.0f); * await Task.Delay(200); * v.SetRumble(20.0f, 110.0f, 0); */ v.SetRumble(160.0f, 320.0f, 1.0f); await Task.Delay(300); v.SetRumble(160.0f, 320.0f, 0); } } }
void ReenableViGEm(Joycon v) { if (showAsXInput && v.out_xbox == null) { v.out_xbox = new Controller.OutputControllerXbox360(); if (toRumble) { v.out_xbox.FeedbackReceived += v.ReceiveRumble; } v.out_xbox.Connect(); } if (showAsDS4 && v.out_ds4 == null) { v.out_ds4 = new Controller.OutputControllerDualShock4(); if (toRumble) { v.out_ds4.FeedbackReceived += v.Ds4_FeedbackReceived; } v.out_ds4.Connect(); } }
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.product_id == product_l || enumerate.product_id == product_r || enumerate.product_id == product_pro) && !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; default: form.AppendTextBox("Non Joy-Con Nintendo input device skipped.\r\n"); break; } // Add controller to block-list for HidGuardian if (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"); } } else // Remove affected devices from list { try { HttpWebResponse r1 = (HttpWebResponse)WebRequest.Create(@"http://localhost:26762/api/v1/hidguardian/affected/purge/").GetResponse(); } catch { } } // -------------------- // 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; } j.Add(new Joycon(handle, EnableIMU, EnableLocalize & EnableIMU, 0.05f, isLeft, enumerate.path, j.Count, enumerate.product_id == product_pro, enumerate.serial_number == "000000000001")); 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; 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; } int found = 0; int minPadID = 10; foreach (Joycon v in j) // current system is designed for a maximum of two joycons connected to the PC { if (!v.isPro) { found++; minPadID = Math.Min(v.PadId, minPadID); } v.LED = (byte)(0x1 << v.PadId); } if (found == 2 && foundNew) { form.AppendTextBox("Both joycons successfully found.\r\n"); Joycon temp = null; foreach (Joycon v in j) { if (!v.isPro) { v.LED = (byte)(0x1 << minPadID); if (temp == null) { temp = v; } else { temp.other = v; v.other = temp; temp.xin.Dispose(); temp.xin = null; } foreach (Button b in form.con) { if (b.Tag == v) { if (v.isLeft) { b.BackgroundImage = Properties.Resources.jc_left; } else { b.BackgroundImage = Properties.Resources.jc_right; } } } } } // Join up the two joycons } 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); jc.Begin(); } } }
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 NewReportIncoming(Joycon hidReport) { if (!running) { return; } var clientsList = new List <IPEndPoint>(); var now = DateTime.UtcNow; lock (clients) { var clientsToDelete = new List <IPEndPoint>(); foreach (var cl in clients) { const double TimeoutLimit = 5; if ((now - cl.Value.AllPadsTime).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else if ((hidReport.PadId >= 0 && hidReport.PadId <= 3) && (now - cl.Value.PadIdsTime[(byte)hidReport.PadId]).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else if (cl.Value.PadMacsTime.ContainsKey(hidReport.PadMacAddress) && (now - cl.Value.PadMacsTime[hidReport.PadMacAddress]).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else //check if this client is totally dead, and remove it if so { bool clientOk = false; for (int i = 0; i < cl.Value.PadIdsTime.Length; i++) { var dur = (now - cl.Value.PadIdsTime[i]).TotalSeconds; if (dur < TimeoutLimit) { clientOk = true; break; } } if (!clientOk) { foreach (var dict in cl.Value.PadMacsTime) { var dur = (now - dict.Value).TotalSeconds; if (dur < TimeoutLimit) { clientOk = true; break; } } if (!clientOk) { clientsToDelete.Add(cl.Key); } } } } foreach (var delCl in clientsToDelete) { clients.Remove(delCl); } clientsToDelete.Clear(); clientsToDelete = null; } if (clientsList.Count <= 0) { return; } byte[] outputData = new byte[100]; int outIdx = BeginPacket(outputData, 1001); Array.Copy(BitConverter.GetBytes((uint)MessageType.DSUS_PadDataRsp), 0, outputData, outIdx, 4); outIdx += 4; outputData[outIdx++] = (byte)hidReport.PadId; outputData[outIdx++] = (byte)hidReport.constate; outputData[outIdx++] = (byte)hidReport.model; outputData[outIdx++] = (byte)hidReport.connection; { byte[] padMac = hidReport.PadMacAddress.GetAddressBytes(); outputData[outIdx++] = padMac[0]; outputData[outIdx++] = padMac[1]; outputData[outIdx++] = padMac[2]; outputData[outIdx++] = padMac[3]; outputData[outIdx++] = padMac[4]; outputData[outIdx++] = padMac[5]; } outputData[outIdx++] = (byte)hidReport.battery; outputData[outIdx++] = 1; Array.Copy(BitConverter.GetBytes(hidReport.packetCounter), 0, outputData, outIdx, 4); outIdx += 4; if (!ReportToBuffer(hidReport, outputData, ref outIdx)) { return; } else { FinishPacket(outputData); } foreach (var cl in clientsList) { try { udpSock.SendTo(outputData, cl); } catch (SocketException ex) { } } clientsList.Clear(); clientsList = null; }
private bool ReportToBuffer(Joycon hidReport, byte[] outputData, ref int outIdx) { outputData[outIdx] = 0; bool isLeft = hidReport.isLeft; if (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_LEFT : Joycon.Button.Y)) { outputData[outIdx] |= 0x80; } if (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_DOWN : Joycon.Button.B)) { outputData[outIdx] |= 0x40; } if (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_RIGHT : Joycon.Button.A)) { outputData[outIdx] |= 0x20; } if (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_UP : Joycon.Button.X)) { outputData[outIdx] |= 0x10; } if (hidReport.GetButton(Joycon.Button.PLUS)) { outputData[outIdx] |= 0x08; } if (hidReport.GetButton(isLeft ? Joycon.Button.STICK2 : Joycon.Button.STICK)) { outputData[outIdx] |= 0x04; } if (hidReport.GetButton(isLeft ? Joycon.Button.STICK : Joycon.Button.STICK2)) { outputData[outIdx] |= 0x02; } if (hidReport.GetButton(Joycon.Button.MINUS)) { outputData[outIdx] |= 0x01; } outputData[++outIdx] = 0; if (hidReport.GetButton(!swapXY ? (isLeft ? Joycon.Button.Y : Joycon.Button.DPAD_LEFT) : (isLeft ? Joycon.Button.X : Joycon.Button.DPAD_UP))) { outputData[outIdx] |= 0x80; } if (hidReport.GetButton(!swapAB ? (isLeft ? Joycon.Button.B : Joycon.Button.DPAD_DOWN) : (isLeft ? Joycon.Button.A : Joycon.Button.DPAD_RIGHT))) { outputData[outIdx] |= 0x40; } if (hidReport.GetButton(!swapAB ? (isLeft ? Joycon.Button.A : Joycon.Button.DPAD_RIGHT) : (isLeft ? Joycon.Button.B : Joycon.Button.DPAD_DOWN))) { outputData[outIdx] |= 0x20; } if (hidReport.GetButton(!swapXY ? (isLeft ? Joycon.Button.X : Joycon.Button.DPAD_UP) : (isLeft ? Joycon.Button.Y : Joycon.Button.DPAD_LEFT))) { outputData[outIdx] |= 0x10; } if (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER2_1 : Joycon.Button.SHOULDER_1)) { outputData[outIdx] |= 0x08; } if (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER_1 : Joycon.Button.SHOULDER2_1)) { outputData[outIdx] |= 0x04; } if (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER2_2 : Joycon.Button.SHOULDER_2)) { outputData[outIdx] |= 0x02; } if (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER_2 : Joycon.Button.SHOULDER2_2)) { outputData[outIdx] |= 0x01; } outputData[++outIdx] = (hidReport.GetButton(Joycon.Button.HOME)) ? (byte)1 : (byte)0; outputData[++outIdx] = 0; // no touch pad float[] leftStick = hidReport.GetStick(); // 127 is 0 outputData[++outIdx] = (byte)(Math.Max(0, Math.Min(255, 127 + leftStick[0] * 127))); outputData[++outIdx] = (byte)(Math.Max(0, Math.Min(255, 127 + leftStick[1] * 127))); float[] rightStick = hidReport.GetStick2(); // 127 is 0 outputData[++outIdx] = (byte)(Math.Max(0, Math.Min(255, 127 + rightStick[0] * 127))); outputData[++outIdx] = (byte)(Math.Max(0, Math.Min(255, 127 + rightStick[1] * 127))); //we don't have analog buttons so just use the Button enums (which give either 0 or 0xFF) outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_LEFT : Joycon.Button.Y)) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_DOWN : Joycon.Button.B)) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_RIGHT : Joycon.Button.A)) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_UP : Joycon.Button.X)) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(!swapXY ? (isLeft ? Joycon.Button.Y : Joycon.Button.DPAD_LEFT) : (isLeft ? Joycon.Button.X : Joycon.Button.DPAD_UP))) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(!swapAB ? (isLeft ? Joycon.Button.B : Joycon.Button.DPAD_DOWN) : (isLeft ? Joycon.Button.A : Joycon.Button.DPAD_RIGHT))) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(!swapAB ? (isLeft ? Joycon.Button.A : Joycon.Button.DPAD_RIGHT) : (isLeft ? Joycon.Button.B : Joycon.Button.DPAD_DOWN))) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(!swapXY ? (isLeft ? Joycon.Button.X : Joycon.Button.DPAD_UP) : (isLeft ? Joycon.Button.Y : Joycon.Button.DPAD_LEFT))) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER2_1 : Joycon.Button.SHOULDER_1)) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER_1 : Joycon.Button.SHOULDER2_1)) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER2_2 : Joycon.Button.SHOULDER_2)) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER_2 : Joycon.Button.SHOULDER2_2)) ? (byte)0xFF : (byte)0; outIdx++; //DS4 only: touchpad points for (int i = 0; i < 2; i++) { outIdx += 6; } //motion timestamp Array.Copy(BitConverter.GetBytes(hidReport.Timestamp), 0, outputData, outIdx, 8); outIdx += 8; //accelerometer { var accel = hidReport.GetAccel(); if (accel != null) { Array.Copy(BitConverter.GetBytes(accel.Y), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes(-accel.Z), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes(accel.X), 0, outputData, outIdx, 4); outIdx += 4; } else { outIdx += 12; Console.WriteLine("No accelerometer reported."); } } //gyroscope { var gyro = hidReport.GetGyro(); if (gyro != null) { Array.Copy(BitConverter.GetBytes(gyro.Y), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes(gyro.Z), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes(gyro.X), 0, outputData, outIdx, 4); outIdx += 4; } else { outIdx += 12; Console.WriteLine("No gyroscope reported."); } } return(true); }
public void Awake() { instance = this; int i = 0; j = new List <Joycon>(); bool isLeft = false; HIDapi.hid_init(); IntPtr ptr = HIDapi.hid_enumerate(vendor_id, 0x0); IntPtr top_ptr = ptr; if (ptr == IntPtr.Zero) { ptr = HIDapi.hid_enumerate(vendor_id_, 0x0); if (ptr == IntPtr.Zero) { HIDapi.hid_free_enumeration(ptr); Console.WriteLine("No Joy-Cons found!"); } } hid_device_info enumerate; while (ptr != IntPtr.Zero) { enumerate = (hid_device_info)Marshal.PtrToStructure(ptr, typeof(hid_device_info)); if (enumerate.product_id == product_l || enumerate.product_id == product_r || enumerate.product_id == product_pro) { if (enumerate.product_id == product_l) { isLeft = true; Console.WriteLine("Left Joy-Con connected."); } else if (enumerate.product_id == product_r) { isLeft = false; Console.WriteLine("Right Joy-Con connected."); } else if (enumerate.product_id == product_pro) { isLeft = true; Console.WriteLine("Pro controller connected."); } else { Console.WriteLine("Non Joy-Con input device skipped."); } IntPtr handle = HIDapi.hid_open_path(enumerate.path); try { HIDapi.hid_set_nonblocking(handle, 1); } catch (Exception e) { Console.WriteLine("Unable to open path to device - are you using the correct (64 vs 32-bit) version for your PC?"); break; } j.Add(new Joycon(handle, EnableIMU, EnableLocalize & EnableIMU, 0.05f, isLeft, j.Count, enumerate.product_id == product_pro, enumerate.serial_number == "000000000001")); 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); ++i; } ptr = enumerate.next; } int found = 0; foreach (Joycon v in j) { if (v.isLeft && !v.isPro) { found++; } if (!v.isLeft && !v.isPro) { found++; } } if (found == 2) { Console.WriteLine("Both joycons successfully found."); Joycon temp = null; foreach (Joycon v in j) { if (v.isLeft && !v.isPro) { if (temp == null) { temp = v; } else { temp.other = v; v.other = temp; } } if (!v.isLeft && !v.isPro) { if (temp == null) { temp = v; } else { temp.other = v; v.other = temp; } } } // Join up the two joycons } else if (found != 0) { Console.WriteLine("Only one joycon found. Please connect both and then restart the program."); } HIDapi.hid_free_enumeration(top_ptr); }
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) { int found = 0; int minPadID = 10; foreach (Joycon jc in Program.mgr.j) // current system is designed for a maximum of two joycons connected to the PC { if (!jc.isPro) { found++; minPadID = Math.Min(jc.PadId, minPadID); } jc.LED = (byte)(0x1 << jc.PadId); } if (found == 2) { AppendTextBox("Both joycons successfully found.\r\n"); Joycon temp = null; foreach (Joycon jc in Program.mgr.j) { if (!jc.isPro) { jc.LED = (byte)(0x1 << minPadID); if (temp == null) { temp = jc; } else { temp.other = jc; jc.other = temp; temp.xin.Dispose(); temp.xin = null; } foreach (Button b in con) { if (b.Tag == jc) { if (jc.isLeft) { b.BackgroundImage = Properties.Resources.jc_left; } else { b.BackgroundImage = Properties.Resources.jc_right; } } } } } // Join up the two joycons } } 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(); } if (v.isLeft) { button.BackgroundImage = Properties.Resources.jc_left_s; } else { button.BackgroundImage = Properties.Resources.jc_right_s; } foreach (Button b in con) { if (b.Tag == v.other) { if (v.other.isLeft) { b.BackgroundImage = Properties.Resources.jc_left_s; } else { b.BackgroundImage = Properties.Resources.jc_right_s; } } } v.other.other = null; v.other = null; } } }
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; 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; v.xin.Dispose(); v.xin = null; 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; } } v.other.other = null; v.other = null; } } }
public FormCalibration(Joycon joycon) { this.joycon = joycon; InitializeComponent(); }
private bool ReportToBuffer(Joycon hidReport, byte[] outputData, ref int outIdx) { var ds4 = Joycon.MapToDualShock4Input(hidReport); outputData[outIdx] = 0; if (ds4.dPad == Controller.DpadDirection.West || ds4.dPad == Controller.DpadDirection.Northwest || ds4.dPad == Controller.DpadDirection.Southwest) { outputData[outIdx] |= 0x80; } if (ds4.dPad == Controller.DpadDirection.South || ds4.dPad == Controller.DpadDirection.Southwest || ds4.dPad == Controller.DpadDirection.Southeast) { outputData[outIdx] |= 0x40; } if (ds4.dPad == Controller.DpadDirection.East || ds4.dPad == Controller.DpadDirection.Northeast || ds4.dPad == Controller.DpadDirection.Southeast) { outputData[outIdx] |= 0x20; } if (ds4.dPad == Controller.DpadDirection.North || ds4.dPad == Controller.DpadDirection.Northwest || ds4.dPad == Controller.DpadDirection.Northeast) { outputData[outIdx] |= 0x10; } if (ds4.options) { outputData[outIdx] |= 0x08; } if (ds4.thumb_right) { outputData[outIdx] |= 0x04; } if (ds4.thumb_left) { outputData[outIdx] |= 0x02; } if (ds4.share) { outputData[outIdx] |= 0x01; } outputData[++outIdx] = 0; if (ds4.square) { outputData[outIdx] |= 0x80; } if (ds4.cross) { outputData[outIdx] |= 0x40; } if (ds4.circle) { outputData[outIdx] |= 0x20; } if (ds4.triangle) { outputData[outIdx] |= 0x10; } if (ds4.shoulder_right) { outputData[outIdx] |= 0x08; } if (ds4.shoulder_left) { outputData[outIdx] |= 0x04; } if (ds4.trigger_right_value == Byte.MaxValue) { outputData[outIdx] |= 0x02; } if (ds4.trigger_left_value == Byte.MaxValue) { outputData[outIdx] |= 0x01; } outputData[++outIdx] = ds4.ps ? (byte)1 : (byte)0; outputData[++outIdx] = ds4.touchpad ? (byte)1 : (byte)0; outputData[++outIdx] = ds4.thumb_left_x; outputData[++outIdx] = ds4.thumb_left_y; outputData[++outIdx] = ds4.thumb_right_x; outputData[++outIdx] = ds4.thumb_right_y; //we don't have analog buttons so just use the Button enums (which give either 0 or 0xFF) outputData[++outIdx] = (ds4.dPad == Controller.DpadDirection.West || ds4.dPad == Controller.DpadDirection.Northwest || ds4.dPad == Controller.DpadDirection.Southwest) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (ds4.dPad == Controller.DpadDirection.South || ds4.dPad == Controller.DpadDirection.Southwest || ds4.dPad == Controller.DpadDirection.Southeast) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (ds4.dPad == Controller.DpadDirection.East || ds4.dPad == Controller.DpadDirection.Northeast || ds4.dPad == Controller.DpadDirection.Southeast) ? (byte)0xFF : (byte)0; outputData[++outIdx] = (ds4.dPad == Controller.DpadDirection.North || ds4.dPad == Controller.DpadDirection.Northwest || ds4.dPad == Controller.DpadDirection.Northeast) ? (byte)0xFF : (byte)0;; outputData[++outIdx] = ds4.square ? (byte)0xFF : (byte)0; outputData[++outIdx] = ds4.cross ? (byte)0xFF : (byte)0; outputData[++outIdx] = ds4.circle ? (byte)0xFF : (byte)0; outputData[++outIdx] = ds4.triangle ? (byte)0xFF : (byte)0; outputData[++outIdx] = ds4.shoulder_right ? (byte)0xFF : (byte)0; outputData[++outIdx] = ds4.shoulder_left ? (byte)0xFF : (byte)0; outputData[++outIdx] = ds4.trigger_right_value; outputData[++outIdx] = ds4.trigger_left_value; outIdx++; //DS4 only: touchpad points for (int i = 0; i < 2; i++) { outIdx += 6; } //motion timestamp Array.Copy(BitConverter.GetBytes(hidReport.Timestamp), 0, outputData, outIdx, 8); outIdx += 8; //accelerometer { var accel = hidReport.GetAccel(); if (accel != null) { Array.Copy(BitConverter.GetBytes(accel.Y), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes(-accel.Z), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes(accel.X), 0, outputData, outIdx, 4); outIdx += 4; } else { outIdx += 12; Console.WriteLine("No accelerometer reported."); } } //gyroscope { var gyro = hidReport.GetGyro(); if (gyro != null) { Array.Copy(BitConverter.GetBytes(gyro.Y), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes(gyro.Z), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes(gyro.X), 0, outputData, outIdx, 4); outIdx += 4; } else { outIdx += 12; Console.WriteLine("No gyroscope reported."); } } return(true); }
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; if (v.out_xbox != null) { v.out_xbox.Disconnect(); v.out_xbox = 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; } } 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 { ReenableViGEm(v); ReenableViGEm(v.other); 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; } } v.other.other = null; v.other = null; } } }
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() { // 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; } 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 && enumerate.serial_number == v.serial_number) { validController = true; thirdParty = v; break; } } ushort prod_id = thirdParty == null ? enumerate.product_id : TypeToProdId(thirdParty.type); if (prod_id == 0) { ptr = enumerate.next; // controller was not assigned a type, but advance ptr anyway continue; } if (validController && !ControllerAlreadyAdded(enumerate.path)) { switch (prod_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 = 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.locBtnClickAsync); })); 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) { // Do not attach two controllers if they are either: // - Not a Joycon // - Already attached to another Joycon (that isn't itself) if (v.isPro || (v.other != null && v.other != v)) { continue; } // Otherwise, iterate through and find the Joycon with the lowest // id that has not been attached already (Does not include self) if (temp == null) { temp = v; } else if (temp.isLeft != v.isLeft && v.other == null) { temp.other = v; v.other = temp; 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); bool on = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).AppSettings.Settings["HomeLEDOn"].Value.ToLower() == "true"; 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(); } catch (Exception e) { jc.state = Joycon.state_.DROPPED; continue; } jc.SetHomeLight(on); jc.Begin(); if (form.allowCalibration) { jc.getActiveData(); } } } }
public void Awake() { instance = this; int i = 0; j = new List <Joycon>(); bool isLeft = false; HIDapi.hid_init(); IntPtr ptr = HIDapi.hid_enumerate(vendor_id, 0x0); IntPtr top_ptr = ptr; if (ptr == IntPtr.Zero) { ptr = HIDapi.hid_enumerate(vendor_id_, 0x0); if (ptr == IntPtr.Zero) { HIDapi.hid_free_enumeration(ptr); form.console.Text += "No Joy-Cons found!\r\n"; } } hid_device_info enumerate; while (ptr != IntPtr.Zero) { enumerate = (hid_device_info)Marshal.PtrToStructure(ptr, typeof(hid_device_info)); if (enumerate.product_id == product_l || enumerate.product_id == product_r || enumerate.product_id == product_pro) { if (enumerate.product_id == product_l) { isLeft = true; form.console.Text += "Left Joy-Con connected.\r\n"; } else if (enumerate.product_id == product_r) { isLeft = false; form.console.Text += "Right Joy-Con connected.\r\n"; } else if (enumerate.product_id == product_pro) { isLeft = true; form.console.Text += "Pro controller connected.\r\n"; } else { form.console.Text += "Non Joy-Con input device skipped.\r\n"; } // Add controller to block-list for HidGuardian 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 (Exception e) { form.console.Text += "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 (Exception e) { form.console.Text += "Unable to open path to device - are you using the correct (64 vs 32-bit) version for your PC?\r\n"; break; } j.Add(new Joycon(handle, EnableIMU, EnableLocalize & EnableIMU, 0.05f, isLeft, j.Count, enumerate.product_id == product_pro, enumerate.serial_number == "000000000001")); j.Last().form = form; 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); ++i; } ptr = enumerate.next; } int found = 0; foreach (Joycon v in j) { if (v.isLeft && !v.isPro) { found++; } if (!v.isLeft && !v.isPro) { found++; } } if (found == 2) { form.console.Text += "Both joycons successfully found.\r\n"; Joycon temp = null; foreach (Joycon v in j) { if (v.isLeft && !v.isPro) { if (temp == null) { temp = v; } else { temp.other = v; v.other = temp; } } if (!v.isLeft && !v.isPro) { if (temp == null) { temp = v; } else { temp.other = v; v.other = temp; } } } // Join up the two joycons } else if (found != 0) { form.console.Text += "Only one joycon found. Please connect both and then restart the program.\r\n"; } HIDapi.hid_free_enumeration(top_ptr); }