Skip to content

Commit 37aba95

Browse files
committed
Added ability to toggle for single/double joycon mode.
Reworked UI further. Final commit for v5.
1 parent be3c73b commit 37aba95

9 files changed

Lines changed: 215 additions & 22 deletions

File tree

BetterJoyForCemu/BetterJoyForCemu.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@
125125
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
126126
</Content>
127127
<Content Include="Icons\cross.png" />
128+
<Content Include="Icons\jc_left_s.png" />
129+
<Content Include="Icons\jc_right_s.png" />
128130
<Resource Include="Icons\jc_left.png" />
129131
<Resource Include="Icons\jc_right.png" />
130132
<Resource Include="Icons\pro.png" />
18.6 KB
Loading
19.1 KB
Loading

BetterJoyForCemu/Joycon.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public byte[] GetData() {
205205
public int packetCounter = 0;
206206

207207
public Xbox360Controller xin;
208-
Xbox360Report report;
208+
public Xbox360Report report;
209209

210210
int rumblePeriod = Int32.Parse(ConfigurationManager.AppSettings["RumblePeriod"]);
211211
int lowFreq = Int32.Parse(ConfigurationManager.AppSettings["LowFreqRumble"]);
@@ -420,7 +420,7 @@ private int ReceiveRaw() {
420420
return ret;
421421
}
422422

423-
private Thread PollThreadObj;
423+
private Thread PollThreadObj; // pro times out over time randomly if it was USB and then bluetooth??
424424
private void Poll() {
425425
int attempts = 0;
426426
while (!stop_polling & state > state_.NO_JOYCONS) {

BetterJoyForCemu/MainForm.Designer.cs

Lines changed: 53 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

BetterJoyForCemu/MainForm.cs

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System;
1+
using Nefarius.ViGEm.Client.Targets;
2+
using Nefarius.ViGEm.Client.Targets.Xbox360;
3+
using System;
24
using System.Collections.Generic;
35
using System.ComponentModel;
46
using System.Configuration;
@@ -12,12 +14,13 @@
1214

1315
namespace BetterJoyForCemu {
1416
public partial class MainForm : Form {
15-
public List<Button> con;
17+
public List<Button> con, loc;
1618

1719
public MainForm() {
1820
InitializeComponent();
1921

2022
con = new List<Button> { con1, con2, con3, con4 };
23+
loc = new List<Button> { loc1, loc2, loc3, loc4 };
2124
}
2225

2326
private void MainForm_Resize(object sender, EventArgs e) {
@@ -52,7 +55,7 @@ private void MainForm_FormClosing(object sender, FormClosingEventArgs e) {
5255
} catch { }
5356
}
5457

55-
private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
58+
private void exitToolStripMenuItem_Click(object sender, EventArgs e) { // this does not work, for some reason. Fix before release
5659
try {
5760
Program.Stop();
5861
Close();
@@ -77,16 +80,107 @@ public void AppendTextBox(string value) { // https://stackoverflow.com/questions
7780
console.AppendText(value);
7881
}
7982

80-
public void conBtnClick(object sender, EventArgs e) {
81-
Button button = sender as Button;
83+
bool toRumble = Boolean.Parse(ConfigurationManager.AppSettings["EnableRumble"]);
84+
bool showAsXInput = Boolean.Parse(ConfigurationManager.AppSettings["ShowAsXInput"]);
8285

83-
if (button.ClientRectangle.Contains(PointToClient(Control.MousePosition))) { // hacky but allows both l&r clicks
84-
if (button.Tag.GetType() == typeof(Joycon)) {
85-
Joycon v = (Joycon)button.Tag;
86+
public void locBtnClick(object sender, EventArgs e) {
87+
Button bb = sender as Button;
88+
89+
if (bb.Tag.GetType() == typeof(Button)) {
90+
Button button = bb.Tag as Button;
8691

92+
if (button.Tag.GetType() == typeof(Joycon)) {
93+
Joycon v = (Joycon) button.Tag;
8794
v.SetRumble(20.0f, 400.0f, 1.0f, 300);
8895
}
8996
}
9097
}
98+
99+
public void conBtnClick(object sender, EventArgs e) {
100+
Button button = sender as Button;
101+
102+
if (button.Tag.GetType() == typeof(Joycon)) {
103+
Joycon v = (Joycon)button.Tag;
104+
105+
if (v.other == null && !v.isPro) { // needs connecting to other joycon (so messy omg)
106+
107+
int found = 0;
108+
int minPadID = 10;
109+
foreach (Joycon jc in Program.mgr.j) { // current system is designed for a maximum of two joycons connected to the PC
110+
if (!jc.isPro) {
111+
found++;
112+
minPadID = Math.Min(jc.PadId, minPadID);
113+
}
114+
jc.LED = (byte)(0x1 << jc.PadId);
115+
}
116+
117+
if (found == 2) {
118+
AppendTextBox("Both joycons successfully found.\r\n");
119+
Joycon temp = null;
120+
foreach (Joycon jc in Program.mgr.j) {
121+
if (!jc.isPro) {
122+
jc.LED = (byte)(0x1 << minPadID);
123+
124+
if (temp == null)
125+
temp = jc;
126+
else {
127+
temp.other = jc;
128+
jc.other = temp;
129+
130+
temp.xin.Dispose();
131+
temp.xin = null;
132+
}
133+
134+
foreach (Button b in con) {
135+
if (b.Tag == jc) {
136+
if (jc.isLeft)
137+
b.BackgroundImage = Properties.Resources.jc_left;
138+
else
139+
b.BackgroundImage = Properties.Resources.jc_right;
140+
}
141+
}
142+
}
143+
} // Join up the two joycons
144+
}
145+
} else if (v.other != null && !v.isPro) { // needs disconnecting from other joycon
146+
if (v.xin == null) {
147+
ReenableXinput(v);
148+
v.xin.Connect();
149+
}
150+
151+
if (v.other.xin == null) {
152+
ReenableXinput(v.other);
153+
v.other.xin.Connect();
154+
}
155+
156+
if (v.isLeft)
157+
button.BackgroundImage = Properties.Resources.jc_left_s;
158+
else
159+
button.BackgroundImage = Properties.Resources.jc_right_s;
160+
161+
foreach (Button b in con) {
162+
if (b.Tag == v.other) {
163+
if (v.other.isLeft)
164+
b.BackgroundImage = Properties.Resources.jc_left_s;
165+
else
166+
b.BackgroundImage = Properties.Resources.jc_right_s;
167+
}
168+
}
169+
170+
v.other.other = null;
171+
v.other = null;
172+
}
173+
}
174+
}
175+
176+
void ReenableXinput(Joycon v) {
177+
if (showAsXInput) {
178+
v.xin = new Xbox360Controller(Program.emClient);
179+
180+
if (toRumble)
181+
v.xin.FeedbackReceived += v.ReceiveRumble;
182+
v.report = new Xbox360Report();
183+
}
184+
}
91185
}
92186
}

BetterJoyForCemu/Program.cs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,16 @@ void CleanUp() { // removes dropped controllers from list
7171
for (int i = 0; i < j.Count; i++) {
7272
Joycon v = j[i];
7373
if (v.state == Joycon.state_.DROPPED) {
74+
if (v.other != null)
75+
v.other.other = null; // The other of the other is the joycon itself
76+
7477
v.Detach(); rem.Add(v);
7578

7679
foreach (Button b in form.con) {
7780
if (b.Enabled & b.Tag == v) {
7881
b.Invoke(new MethodInvoker(delegate {
7982
b.Enabled = false;
83+
b.BackgroundImage = Properties.Resources.cross;
8084
}));
8185
break;
8286
}
@@ -105,6 +109,7 @@ public void CheckForNewControllers() {
105109
IntPtr top_ptr = ptr;
106110

107111
hid_device_info enumerate; // Add device to list
112+
bool foundNew = false;
108113
while (ptr != IntPtr.Zero) {
109114
enumerate = (hid_device_info)Marshal.PtrToStructure(ptr, typeof(hid_device_info));
110115

@@ -159,17 +164,20 @@ public void CheckForNewControllers() {
159164

160165
j.Add(new Joycon(handle, EnableIMU, EnableLocalize & EnableIMU, 0.05f, isLeft, enumerate.path, j.Count, enumerate.product_id == product_pro, enumerate.serial_number == "000000000001"));
161166

167+
foundNew = true;
162168
j.Last().form = form;
163169

164170
if (j.Count < 5) {
171+
int ii = -1;
165172
foreach (Button v in form.con) {
173+
ii++;
166174
if (!v.Enabled) {
167175
System.Drawing.Bitmap temp;
168176
switch (enumerate.product_id) {
169177
case (product_l):
170-
temp = Properties.Resources.jc_left; break;
178+
temp = Properties.Resources.jc_left_s; break;
171179
case (product_r):
172-
temp = Properties.Resources.jc_right; break;
180+
temp = Properties.Resources.jc_right_s; break;
173181
case (product_pro):
174182
temp = Properties.Resources.pro; break;
175183
default:
@@ -182,6 +190,12 @@ public void CheckForNewControllers() {
182190
v.Click += new EventHandler(form.conBtnClick);
183191
v.BackgroundImage = temp;
184192
}));
193+
194+
form.loc[ii].Invoke(new MethodInvoker(delegate {
195+
form.loc[ii].Tag = v;
196+
form.loc[ii].Click += new EventHandler(form.locBtnClick);
197+
}));
198+
185199
break;
186200
}
187201
}
@@ -202,12 +216,11 @@ public void CheckForNewControllers() {
202216
if (!v.isPro) {
203217
found++;
204218
minPadID = Math.Min(v.PadId, minPadID);
205-
} else {
206-
v.LED = (byte)(0x1 << v.PadId);
207219
}
220+
v.LED = (byte)(0x1 << v.PadId);
208221
}
209222

210-
if (found == 2) {
223+
if (found == 2 && foundNew) {
211224
form.AppendTextBox("Both joycons successfully found.\r\n");
212225
Joycon temp = null;
213226
foreach (Joycon v in j) {
@@ -223,6 +236,15 @@ public void CheckForNewControllers() {
223236
temp.xin.Dispose();
224237
temp.xin = null;
225238
}
239+
240+
foreach (Button b in form.con) {
241+
if (b.Tag == v) {
242+
if (v.isLeft)
243+
b.BackgroundImage = Properties.Resources.jc_left;
244+
else
245+
b.BackgroundImage = Properties.Resources.jc_right;
246+
}
247+
}
226248
}
227249
} // Join up the two joycons
228250
}
@@ -308,7 +330,7 @@ class Program {
308330

309331
private static readonly HttpClient client = new HttpClient();
310332

311-
static JoyconManager mgr;
333+
public static JoyconManager mgr;
312334
static HighResTimer timer;
313335
static string pid;
314336

0 commit comments

Comments
 (0)