Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative way to match Joy-Cons devices #27

Closed
gal20 opened this issue Jan 3, 2021 · 16 comments · Fixed by #29
Closed

Alternative way to match Joy-Cons devices #27

gal20 opened this issue Jan 3, 2021 · 16 comments · Fixed by #29

Comments

@gal20
Copy link
Contributor

gal20 commented Jan 3, 2021

Continuing the discussion from #26.
I figured out another way we might be able to auto-detect the Joy-Cons in a combined device. The paired Joy-Cons have the same leds turned on, and it is unique - other Joy-Cons will have different leds turned on. If we could find the led status of each device, we could match the identical ones. I don't think joycond currently exposes this info - I tried using device.leds() for the evdev devices, but it always returns an empty list.
If joycond is able to expose the led information, we could use that to find out which devices are paired.

@joaorb64
Copy link
Owner

joaorb64 commented Jan 4, 2021

@DanielOgorchock

@joaorb64
Copy link
Owner

joaorb64 commented Jan 4, 2021

Based on https://github.com/DanielOgorchock/joycond/blob/778a7270ec403a23af02117b1da764fa0122dc23/src/phys_ctlr.cpp#L31 I noticed there are files in (Ubuntu) /sys/class/leds/0005\:057E\:2009.0002\:player1/brightness (also player2-4 and home) which mantain led status (we can check from these files)!!!
Maybe even indicate joycond-cemuhook connected devices by turning the home led on? Might be an interesting idea.
I'm not sure where does this pathname come from yet.

Edit: found a path following symlinks that goes /sys/class/input/event18/device/device/leds

@joaorb64
Copy link
Owner

joaorb64 commented Jan 4, 2021

I got as far as this:
image

Soon I'll make a commit :)

Edit: Now I get it, there's no /eventX/device/device/leds for Combined joycons...

@gal20
Copy link
Contributor Author

gal20 commented Jan 4, 2021

I think I figured out where the random-looking hex part of the path comes from.
The first part comes from combining the device info (bustype, vendor, product). you can use this line to generate this:

reduce(lambda x, y: x + format(y, "04X") + ":", device.info[:-1], "")[:-1]

where device is an evdev.InputDevice object
the last part (after the dot) seems to be an incrementing number based on the number of hid devices you have. You can look at the directory /sys/bus/hid/devices to see all these values. You can determine it with this command:

format(int(os.listdir(F"/sys/class/input/{os.path.basename(device.path)}/device/device/hidraw/")[0].replace("hidraw", "")) + 1, "04X")

since the folder in device/hidraw is named hidraw<number>, where the <number> is that index minus 1.

@joaorb64
Copy link
Owner

joaorb64 commented Jan 4, 2021

I'm looking through joycond's source code and I think we need an edit right around here: https://github.com/DanielOgorchock/joycond/blob/778a7270ec403a23af02117b1da764fa0122dc23/src/virt_ctlr_combined.cpp#L259
If I got it right, we need to add libevdev_enable_event_type for LEDs and assign each led from the Right Joycon (I'm assuming, because it's the only one with the Home led). I'll be busy for now so I'll commit my led-reading code in a new branch and stop for today.
If you're free and interested in messing up with joycond, go ahead :P

@joaorb64
Copy link
Owner

joaorb64 commented Jan 4, 2021

This is my initial go at it just for reference, open to any different approach https://github.com/joaorb64/joycond-cemuhook/tree/led-status

@joaorb64
Copy link
Owner

joaorb64 commented Jan 6, 2021

I tried multiple things but I'm unable to make joycond register either one of the controller's uniq or LED status, I'm a linux driver newbie and don't really know where to learn how to do this.

  • With one of the controller's uniq we should be able to get one of the IMU devices, read its LED status, and find the other device with matching LEDS;
  • With LED status for Combined joycons, we should be able to find its both IMU devices

@gal20
Copy link
Contributor Author

gal20 commented Jan 6, 2021

Detecting the leds is possible with pyudev (#28). However, the combined controller doesn't have leds, so we can't automatically match if there is more than one combined controller. The other virtual devices joycond creates do have leds though. If joycond could create leds for the combined device as well, we could use that to match the devices more easily

@joaorb64
Copy link
Owner

joaorb64 commented Jan 7, 2021

I just thought of another way of solving this issue.

Solution:

  • joycond-cemuhook would require root access, and it would have it anyways as a system service;
  • root doesn't lose access to left and right joycons that are part of a combined joycons device, and their LED status is accessible

Logic:

  • joycond-cemuhook keeps track of all Nintendo Switch physical devices;
  • for each device, keep a cemuhook device;
  • when reporting device events, report for all devices with same LED combination.

So if I have a Combined device, I'd have slots 1 and 2 assigned to Joycon R and Joycon L, each reporting its own motion but also reporting the same button inputs.

We'd have to check how emulators have been dealing with cemuhook, but maybe having a whole cemuhook server for each device could also mean unlimited devices, as combined joycons take 2 slots. Yuzu for example has an option to connect to multiple servers so I'm guessing it would work well with it.

@gal20
Copy link
Contributor Author

gal20 commented Jan 7, 2021

* root doesn't lose access to left and right joycons that are part of a combined joycons device, and their LED status is accessible

I'm not sure what you mean here. What information does root permission gives us that we can't get with normal user?

We can already detect the led status of the individual Joy-Cons in a combined pair.
If DanielOgorchock/joycond#49 is merged, we will be able to also detect the led status of the combined device itself. This is enough information to auto-detect all devices.

@joaorb64
Copy link
Owner

joaorb64 commented Jan 7, 2021

I meant that the evdev device is still accessible to root. Joycond hides left and right joycons when it creates a combined joycons device.

@joaorb64
Copy link
Owner

joaorb64 commented Jan 7, 2021

This is the output if run as root:

image

Notice that we have both individual controllers and something that indicates they're combined! This is what I meant. When reading inputs from the Left Joycon, we can check if there's a Right Joycon with matching LEDs and apply these inputs to that device too. So we're not directly using Combined Joycons.

@gal20
Copy link
Contributor Author

gal20 commented Jan 7, 2021

This isn't necessary, though. The IMU devices have LEDs as well, so this doesn't add any new information. With DanielOgorchock/joycond#49, we will be able to match the LEDs of the IMUs with the LEDs of the combined device. I've pushed a new branch as a proof-of-concept: auto_detection

@joaorb64
Copy link
Owner

joaorb64 commented Jan 7, 2021

I tested it and it works great!

Now the only thing that I think would be even better to close it out is to:

  1. Always have Right Joycon as first in a Combined Joycons device (I'm mostly thinking of Dolphin when proposing it to be the Right one)
  2. Register inputs to both cemuhook devices

Then if Dolphin had an option to select from which motion device the Nunchuck motion is coming from, configuration would be possible in a matter of seconds...

@gal20
Copy link
Contributor Author

gal20 commented Jan 7, 2021

1. Always have Right Joycon as first in a Combined Joycons device (I'm mostly thinking of Dolphin when proposing it to be the Right one)

This line does exactly this:
motion_devices = sorted(devices, key=lambda d: "Right" in d.name, reverse=True)
the list is sorted so the right Joy-Con always comes first

@joaorb64
Copy link
Owner

joaorb64 commented Jan 7, 2021

Sorry, the hype for testing made me overlook it, haha. Nice work! Now if my PR gets merged we're ready to have a system service as proposed in #6 !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants