Closed AcideA7X closed 3 years ago
You might be able to jank this into working by running multiple instances of XJoy, but I have never tested this.
The code isn't too complicated and is all contained within one file, so I definitely recommend trying to modify the project to suit your needs if you have any C++ experience or are willing to teach yourself a bit.
If you do get it working the way you want, feel free to submit a pull request!
Good luck!!
Not sure if you still need this, but for anyone else who stumbles upon this in the future, I just replaced a few lines to get this working.
In the file XJoy.cpp, replace this:
void initialize_left_joycon() {
struct hid_device_info *left_joycon_info = hid_enumerate(NINTENDO, JOYCON_L);
if(left_joycon_info != NULL) std::cout << " => found left Joy-Con" << std::endl;
else {
std::cout << " => could not find left Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
std::cout << "press [ENTER] to exit" << std::endl;
getchar();
exit(1);
}
left_joycon = hid_open(NINTENDO, JOYCON_L, left_joycon_info->serial_number);
if(left_joycon != NULL) std::cout << " => successfully connected to left Joy-Con" << std::endl;
else {
std::cout << " => could not connect to left Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
std::cout << "press [ENTER] to exit" << std::endl;
getchar();
exit(1);
}
setup_joycon(left_joycon, 0x1, 1);
}
void initialize_right_joycon() {
struct hid_device_info *right_joycon_info = hid_enumerate(NINTENDO, JOYCON_R);
if(right_joycon_info != NULL) std::cout << " => found right Joy-Con" << std::endl;
else {
std::cout << " => could not find right Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
std::cout << "press [ENTER] to exit" << std::endl;
getchar();
exit(1);
}
right_joycon = hid_open(NINTENDO, JOYCON_R, right_joycon_info->serial_number);
if(right_joycon != NULL) std::cout << " => successfully connected to right Joy-Con" << std::endl;
else {
std::cout << " => could not connect to right Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
std::cout << "press [ENTER] to exit" << std::endl;
getchar();
exit(1);
}
setup_joycon(right_joycon, 0x1, 0);
}
with this:
void initialize_left_joycon() {
struct hid_device_info *left_joycon_info = hid_enumerate(NINTENDO, JOYCON_L);
if (left_joycon_info == NULL) {
std::cout << " => could not find left Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
std::cout << "press [ENTER] to exit" << std::endl;
getchar();
exit(1);
}
while (left_joycon_info->next != NULL) {
left_joycon_info = left_joycon_info->next;
}
std::cout << " => found left Joy-Con" << std::endl;
left_joycon = hid_open(NINTENDO, JOYCON_L, left_joycon_info->serial_number);
if(left_joycon != NULL) std::cout << " => successfully connected to left Joy-Con" << std::endl;
else {
std::cout << " => could not connect to left Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
std::cout << "press [ENTER] to exit" << std::endl;
getchar();
exit(1);
}
setup_joycon(left_joycon, 0x1, 1);
}
void initialize_right_joycon() {
struct hid_device_info *right_joycon_info = hid_enumerate(NINTENDO, JOYCON_R);
if (right_joycon_info == NULL) {
std::cout << " => could not find right Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
std::cout << "press [ENTER] to exit" << std::endl;
getchar();
exit(1);
}
while (right_joycon_info->next != NULL) {
right_joycon_info = right_joycon_info->next;
}
std::cout << " => found right Joy-Con" << std::endl;
right_joycon = hid_open(NINTENDO, JOYCON_R, right_joycon_info->serial_number);
if(right_joycon != NULL) std::cout << " => successfully connected to right Joy-Con" << std::endl;
else {
std::cout << " => could not connect to right Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
std::cout << "press [ENTER] to exit" << std::endl;
getchar();
exit(1);
}
setup_joycon(right_joycon, 0x1, 0);
}
At the beginning of the function, our left_joycon_info variable is actually a linked list of all connected left JoyCons. The original code just takes the first one, so connecting another one and launching another XJoy will just reconnect it to the first pair. This replaced snippet makes it so that it pairs with the last pair of connected JoyCons instead - a rough fix (and I'm not going to make a pull request), but it works. Just connect your first pair, launch XJoy, then connect your second pair and launch XJoy again. Repeat for however many pairs of JoyCons you have.
Yes, hid_enumerate returns a list, so you can iterate on them.
I will do a proper PR for this, and try to relay on serial number so you can put it on config and pair same joycons at any time
reformatting as a patch:
--- Xjoy.cpp
+++ Xjoy.cpp
@@ -1,7 +1,7 @@
void initialize_left_joycon() {
struct hid_device_info *left_joycon_info = hid_enumerate(NINTENDO, JOYCON_L);
- if(left_joycon_info != NULL) std::cout << " => found left Joy-Con" << std::endl;
- else {
+
+ if(left_joycon_info == NULL) {
std::cout << " => could not find left Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
@@ -9,6 +9,12 @@
getchar();
exit(1);
}
+
+ while (left_joycon_info->next != NULL) {
+ left_joycon_info = left_joycon_info->next;
+ }
+
+ std::cout << " => found left Joy-Con" << std::endl;
left_joycon = hid_open(NINTENDO, JOYCON_L, left_joycon_info->serial_number);
if(left_joycon != NULL) std::cout << " => successfully connected to left Joy-Con" << std::endl;
else {
@@ -25,8 +31,8 @@
void initialize_right_joycon() {
struct hid_device_info *right_joycon_info = hid_enumerate(NINTENDO, JOYCON_R);
- if(right_joycon_info != NULL) std::cout << " => found right Joy-Con" << std::endl;
- else {
+
+ if(right_joycon_info == NULL) {
std::cout << " => could not find right Joy-Con" << std::endl;
hid_exit();
vigem_free(client);
@@ -34,6 +40,12 @@
getchar();
exit(1);
}
+
+ while (right_joycon_info->next != NULL) {
+ right_joycon_info = right_joycon_info->next;
+ }
+
+ std::cout << " => found right Joy-Con" << std::endl;
right_joycon = hid_open(NINTENDO, JOYCON_R, right_joycon_info->serial_number);
if(right_joycon != NULL) std::cout << " => successfully connected to right Joy-Con" << std::endl;
else {
@@ -45,7 +57,4 @@
exit(1);
}
setup_joycon(right_joycon, 0x1, 0);
}
Awesome guys will happily merge a PR please do be careful about testing that everything still works
@sam0x17 To me the trick of running two times didn't work. I'm checking if listening to existing joycons, you can detect two pressing L+R to pair them.
The idea is discard input from paired joycons, using serial number.
Not sure if hidapi serial number is unique and the same all the time, so I tried to read the serial number from joycon, but didn't work (not sure why, I'm using same code as JC toolkit, that works indeed https://github.com/CTCaer/jc_toolkit/blob/master/jctool/jctool.cpp#L149)
When that is ready, is turn XJoy as service an option? and add motion parameters?
Gotcha, this is some good insight.
I don't work directly on this project anymore but happy to accept pull requests adding those features @albfan
Ok, solved: The https://github.com/CTCaer/jc_toolkit/blob/master/jctool/jctool.h#L20 the alignment for data read is important
#pragma pack(push, 1)
...
#pragma pack(pop)
That allows to read serial if other serial is not unique.
Allow me some time to put all in order. Trying to pair with "L+R" right now
Hello! I tried to use 4 joycons to play with a friends and it turns out Xjoy only recognize one pair of Joycons Do have any solution for us? Or is connecting 4 joycons juts impossible for now?
Thank you for your help!