joaorb64 / joycond-cemuhook

Support for cemuhook's UDP protocol for joycond devices
MIT License
139 stars 19 forks source link

wiimote support #54

Open cipitaua opened 2 years ago

cipitaua commented 2 years ago

It would be great to add support for wiimote, since the only existing project - linuxmotehook - seems stuck with a bug that makes it totally unusable.

Presently the default kernel driver provides the following input devices for each connected wiimote:

$ cat /proc/bus/input/devices | grep Wii
N: Name="Nintendo Wii Remote Accelerometer"
N: Name="Nintendo Wii Remote IR"
N: Name="Nintendo Wii Remote"
N: Name="Nintendo Wii Remote Nunchuk"

Do you think it would be possible to add wiimote support in joycond-cemuhook?

v1993 commented 2 years ago

FYI - wiimote driver uses very different (non-standard too) reporting mechanism than modern drivers (e.g. hid-nintendo) do, making using it trickier than it should be. Maybe I should "just" rewrite linuxmotehook in C++ to avoid said bug.

cipitaua commented 2 years ago

that would be awesome, anything that makes it usable would surely help

also python seems a good choice: joycond-cemuhook is in python (a single python file!) and it works perfectly

thank you

v1993 commented 2 years ago

I have already written https://github.com/v1993/evdevhook, so C++ is a fine option as well (besides, it ensures that there are far less bridges needed which means less places for issues to arise). Strictly speaking, "the right thing" would be to write a new kernel driver for WiiMote that would expose features in standardized way, but I'm not ready to take on that.

cipitaua commented 2 years ago

great, I'm available for testing and coding (although I'm more close to C than C++)

joaorb64 commented 2 years ago

It may take a while for me to have my wiimote in hands, but I'd be down for exploring this! From what @v1993 said it doesn't seem that easy and we're patching old kernel drivers' features together, that could definitely be standardized by default.

joaorb64 commented 2 years ago

I now have a wiimote here with me, so I might start working on something similar to joycond for xwiimote devices. So it would deal with LEDs, etc but also output cemuhook data. It will take some time until I have anything because I'm taking a lot of different projects at once, though.

cipitaua commented 2 years ago

great news, thank you

joaorb64 commented 2 years ago

To be honest, I'd like to discuss a bit about this implementation. My idea is that it should be a program that uses libxwiimote similarly to what joycond does, assigning evdev devices and handling player leds and whatnot. What should be the default mapping for Wiimote+Nunchuck? Maybe there could be different modes that you could switch using button combinations? And then, obviously, it should expose cemuhook devices.

cipitaua commented 2 years ago

@joaorb64

What should be the default mapping for Wiimote+Nunchuck?

I think it would be useful to comply with MoltenGamepad layout mimicking xbox, which is recognized correctly in most of the games and it's very smartly chosen.

Maybe there could be different modes that you could switch using button combinations?

that could be useful, for example with home+plus and home+minus, but also profile selection from command line parameters would be fine

joaorb64 commented 2 years ago

I copied over the code from joycond-cemuhook and have something functional here (and I desperately need to cleanup the code). I had to manually install xwiimote and xwiimote-bindings, which I think should be automated/made easier eventually. In a hardcoded way, I'm getting the first connected Wiimote and covering 2 cases (with hotplug/unplug support):

1- Wiimote: works sideways using mapping from a json file. Motion is assigned for sideways usage. 2- Wiimote+Nunchuk: At the moment I'm only using motion from the Wiimote. Also has its own mapping.

I'll try to upload it in a new repo even if the code isn't very pretty, because it's already a start and works really well!

Update: https://github.com/joaorb64/xwiimote-cemuhook :D

joaorb64 commented 2 years ago

Update: With some spaghetti code, I was able to also make it so connecting a Nunchuk to the Wiimote exposes a secondary device with its own motion. Again, this goes to enforce a design where each controller uses its own cemuhook server.

Please let me know you're able to make it work on your end! I'm really hyped for this, even though very few games on Switch actually use motion controls. Nunchuk motion, even being only accelerometer, works perfectly with Mario Kart 8. I wonder if that's also the case for ARMS...

cipitaua commented 2 years ago

wow... impressive. I'll test it asap! Btw, I guess the wiimote requires "motion plus"?

joaorb64 commented 2 years ago

It depends on the game. Mario Kart 8 uses accelerometer only, but I'm certain Splatoon 2 uses the gyroscope for aiming. This is a game-based requirement.

cipitaua commented 2 years ago

ah ok, then cemuhook exposes what it finds, just accelerometers (wiimote) or all coordinates (wiimote + motionplus)?

I'll try to find some time tonight to test it better, so far I got a ModuleNotFoundError: No module named '_xwiimote'

joaorb64 commented 2 years ago

Yes, it exposes what it finds. That's the case for the Nunchuk, which only registers accelerometers.

Seems like this error is related to swig and _xwiimote.cpython-39-x86_64-linux-gnu.so. Looks like we'd have to include a build for each Python version (3.9, 3.8, ...) or include the build process somewhere. You'll have to build xwiimote-bindings for your Python version.

cipitaua commented 2 years ago

Looks like we'd have to include a build for each Python version (3.9, 3.8, ...)

I have 3.8 and 3.9 installed

You'll have to build xwiimote-bindings for your Python version.

I see two occurrencies on github: https://github.com/dvdhrm/xwiimote-bindings and https://github.com/BrainTech/xwiimote-bindings

joaorb64 commented 2 years ago

I used https://github.com/dvdhrm/xwiimote-bindings!

cipitaua commented 2 years ago

I had to manually compile xwiimote, due to this issue (I'm on ubuntu devel), and I get errors while compiling xwiimote-bindings (see attched log)

log.make.txt

joaorb64 commented 2 years ago

Try purging any wiimote related packages (xwiimote, libxwiimote2, etc) from your system and try again. I'm also on Ubuntu (21.10), and from my terminal history I had to do this. Maybe it will even make it so the code from my repo just works in your end.

cipitaua commented 2 years ago

ok, I've managed to compile xwiimote-bindings, and I've overwritten xwiimote.py with the new one, but sadly it still gives the same error: ModuleNotFoundError: No module named '_xwiimote'

joaorb64 commented 2 years ago

Try also copying the .so generated by xwiimote-bindings in /build/lib.linux-x86_64-3.9/...? Are you able to run the examples?

cipitaua commented 2 years ago

yes, the problem is that I've installed xwiimote, xwiimote-bindings, and xwiimote-cemuhook in ~/Apps/ , thus I likely have to set LD_LIBRARY_PATH or something similar

by setting LD_LIBRARY_PATH=. ./xwiimote-cemuhook.py I get

=== Nintendo Wii Remote === mon fd 3 ooops, [Errno 22] Invalid argument

but I haven't connected the wiimote yet (I have it at home), now I'm in office

joaorb64 commented 2 years ago

You got it! This error is because there's no wiimote connected :)

cipitaua commented 2 years ago

looking forward to test it then :)

thank you!

joaorb64 commented 2 years ago

Uploading videos for visibility and to show how well it works for me at the moment:

https://user-images.githubusercontent.com/7636440/139880241-848577c0-9634-43b2-966c-7062a4680a4c.mp4

https://user-images.githubusercontent.com/7636440/139880267-dd33a465-7773-4628-b5c6-aa1f21acaad3.mp4

cipitaua commented 2 years ago

it mostly works, but I cannot make the nunchuck work. Do I have to enable it somehow?

Also, I get several [Errno 11] Resource temporarily unavailable in output

dmesg output:

[1082424.704111] wiimote 0005:057E:0306.0018: hidraw0: BLUETOOTH HID v6.00 Gamepad [Nintendo RVL-CNT-01] on d8:f2:ca:b8:f6:95
[1082424.704146] wiimote 0005:057E:0306.0018: New device registered
[1082424.815126] wiimote 0005:057E:0306.0018: detected device: Nintendo Wii Remote (Gen 1)
[1082424.815676] input: Nintendo Wii Remote Accelerometer as /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0018/input/input121
[1082424.815944] input: Nintendo Wii Remote IR as /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0018/input/input122
[1082424.816154] input: Nintendo Wii Remote as /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0018/input/input120
[1082424.988840] wiimote 0005:057E:0306.0018: detected extension: Nintendo Wii Motion Plus
[1082424.988912] input: Nintendo Wii Remote Motion Plus as /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0018/input/input123
[1082447.741888] input: xwiimote controller 1 as /devices/virtual/input/input124
[1082448.090376] wiimote 0005:057E:0306.0018: detected extension: Nintendo Wii Nunchuk
[1082448.090501] input: Nintendo Wii Remote Nunchuk as /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0018/input/input125
[1084529.262199] input: xwiimote controller 1 as /devices/virtual/input/input126
joaorb64 commented 2 years ago

I also get this resource busy message, so I don't think that's the reason why it's not working. Does the program itself detect that the nunchuck is attached? It should show "wiimote + nunchuk" and load the nunchuk.json mappings. Also, I could not make the input from cemuhook work in Yuzu, but the virtual evdev device works for me (also shows correctly in jstest-gtk)

cipitaua commented 2 years ago

Does the program itself detect that the nunchuck is attached?

I'm not sure, this is the output:


=== Nintendo Wii Remote ===
mon fd 3
Found device: /sys/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0018
mp 0 0 0 0
/dev/input/event17 Nintendo Wii Remote  
/dev/input/event16 Nintendo Wii Remote IR  
/dev/input/event14 Nintendo Wii Remote Accelerometer  
/dev/input/event15 Integrated Camera: Integrated C usb-0000:00:14.0-8/button 
/dev/input/event13 HDA Intel PCH HDMI/DP,pcm=10 ALSA 
/dev/input/event12 HDA Intel PCH HDMI/DP,pcm=9 ALSA 
/dev/input/event11 HDA Intel PCH HDMI/DP,pcm=8 ALSA 
/dev/input/event10 HDA Intel PCH HDMI/DP,pcm=7 ALSA 
/dev/input/event9 HDA Intel PCH HDMI/DP,pcm=3 ALSA 
/dev/input/event8 HDA Intel PCH Headphone ALSA 
/dev/input/event7 HDA Intel PCH Mic ALSA 
/dev/input/event6 Synaptics TM3288-011 rmi4-00/input0 
/dev/input/event5 ThinkPad Extra Buttons thinkpad_acpi/input0 
/dev/input/event4 Video Bus LNXVIDEO/video/input0 
/dev/input/event3 AT Translated Set 2 keyboard isa0060/serio0/input0 
/dev/input/event2 Power Button LNXPWRBN/button/input0 
/dev/input/event1 Lid Switch PNP0C0D/button/input0 
/dev/input/event0 Sleep Button PNP0C0E/button/input0 
Debug: Started UDP server with ip 127.0.0.1, port 26760
<xwiimote.iface; proxy of <Swig Object of type 'xwii_iface *' at 0x7fd519a362d0> >
fd: 4
opened mask: 0
opened mask: 7
Input events task started
[Errno 11] Resource temporarily unavailable
Debug: Battery level reading thread started
Debug: Battery level changed
================= ('127.0.0.1', 26760) ================
Device                     LED status   Battery Lv   MAC Addr    
1 wiimote                  ■ □ □ □      34 ▃         00:1f:c5:35:96:db
2 ❎ 
3 ❎ 
4 ❎ 
=======================================================
joaorb64 commented 2 years ago

Weird... Can you run xwiimote-bindings examples or xwiishow and see the string it shows as extension? It should be exactly "nunchuk". Seems like your system recognized it but somehow my code didn't.

cipitaua commented 2 years ago

xwiishow does not see the nunchuck extension, this is weird because I've used the wiimote+nunchuck many times, the last was a few weeks ago and I've never had problems. Now it does not work, I've even tried to reinstall xwiimote from distro packages.

cipitaua commented 2 years ago

ok, it seems a problem related to the wiimotion plus: without the wiimotion plus the nunchuck does work

cipitaua commented 2 years ago

however, I've checked with a second wiimote which has integrated motion plus and it has the same problem: nunchuck is not usable in combination with motion plus. So it does not seem a hardware problem.

joaorb64 commented 2 years ago

Weird, in the videos you can see I'm using a wm+ and it works. Is everything Nintendo-branded? Maybe a xwiimote bug? Might be even possible that this is fixed in some fork, let's see if we can find a solution

joaorb64 commented 2 years ago

Seems like this is the issue @v1993 mentioned before. In the main repo you can also see he has an open issue regarding this. Then why does it work for me? I guess I hit the hardware lottery, and xwiimote needs some love.

cipitaua commented 2 years ago

Is everything Nintendo-branded?

yes, and I used them with a real wii

joaorb64 commented 2 years ago

I also imagine that you don't have this issue using dolphin's internal wiimote drivers, right?

cipitaua commented 2 years ago

Seems like this is the issue @v1993 mentioned before. In the main repo you can also see he has an open issue regarding this. Then why does it work for me? I guess I hit the hardware lottery, and xwiimote needs some love.

he said that the code on github does work, and it's what I'm using

cipitaua commented 2 years ago

I also imagine that you don't have this issue using dolphin's internal wiimote drivers, right?

I've tried, but no "real" wiimote is seen by dolphin :(

cipitaua commented 2 years ago

I've opened a new issue in xwiimote

v1993 commented 2 years ago

FWIW - I'm looking into rewriting linuxmotehook in another language (either C++ or Vala) to bypass original problem in bindings. There's no conflict of interest with xwiimote-cemuhook either, since I prefer to avoid more invasive changes to system (changing access rights and creating new evdev devices), opting to only expose UDP interface.