[LINUX] HOW-TO enhance your emulation experience with Wii Classic Controllers

  Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
MooseTracks Offline
Junior Member
Posts: 6
Joined: Oct 2011
Reputation: 0
Star  [LINUX] HOW-TO enhance your emulation experience with Wii Classic Controllers
Post: #1
Long time lurker, first time poster. I've pulled a lot of great information from this forum and since I haven't seen anything on emulation using a wii controller specifically, I thought maybe I could give back to the community. If a guide has already been written and I missed it, my apologies.

The specific system that I know this guide will work on is:
XBMC 10.1 (Dharma stable)
Ubuntu Lucid

I won't get into specific emulation setup, but I had relied heavily on this guide by Izod517.

Additionally, I'm set up with Angelscry's Advanced Launcher.

This setup will use wminput to convert controller button presses into key presses, which can then be used to trigger actions within the emulator as if that is how your emulator control input is laid out.

I'm not sure what (if any) complications will arise with the wii in standby mode. I made sure to turn mine off before pairing any wiimotes.

1. Acquire a Bluetooth dongle
Ok, first off, you're going to need bluetooth. Fortunately, it can be had for cheap. I'm using an ASUS USB-BT211 Mini USB Bluetooth V2.1 and there haven't been any problems. If you need one, go purchase one. Otherwise, we will get to it shortly, so you can set it aside for now.

2. Setup the uinput module
We need to use the uinput module, but my understanding is that recent linux distributions should have it already, it just might not be active (as was the case in Lucid for me). You can use modprobe to check to see if you have it available, and lsmod to see if it's active.

Code:
$ modprobe -l | grep uinput
kernel/drivers/input/misc/uinput.ko

If modprobe returns the kernel location for you, check to see if it's loaded.

Code:
$ lsmod | grep uinput
uinput                  6312  0

If it's loaded already, skip ahead to step 3. For me, it was available but not loading.

To get uinput to load automatically, we're going to add it to the "/etc/modules" file.

Code:
$ sudo nano /etc/modules

/etc/modules will look something like this:
Code:
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

loop
lp

Add "uinput" to the end. Save and close.

3. Create a udev rule for the uinput device
In order to connect to the Wiimote as a regular user though, you need to add a new udev rule to extend permissions to the uinput device. You can create a new group for this or you can use a pre-existing one. The group plugdev should hopefully exist with your default xbmc user already attached, so that helps simplify things.

Just to make sure the group exists:
Code:
$ more /etc/group | grep plugdev
plugdev:x:46:xbmc

If you see "plugdev" with "xbmc" (or whatever your default group is called) at the end of the line you're in good shape.

Create the new udev file:
Code:
$ sudo touch /etc/udev/rules.d/95-uinput.rules

Edit that file and add the following line:
Code:
KERNEL=="uinput", GROUP="plugdev"

At this point you may need to reboot to make sure uinput is loaded and that it's using the new udev rules. Alternatively, I *think* running modprobe on uinput and reloading udev will accomplish what we need. I can't say for certain because I had a couple reboots in there before I eventually moved onto the next step.

Code:
$ modprobe uinput
$ sudo reload udev

4. Install wminput
Now it's time to install wminput.

Code:
$ sudo apt-get update
$ sudo apt-get install wminput

5. Setup Bluetooth
Plug in your dongle and install bluez and some python.

Code:
$ sudo apt-get install bluez python-gobject python-dbus

At this point your bluetooth should be working. Double check with hcitool dev.

Code:
$ hcitool dev
Devices:
     hci0    00:11:95:00:1A:CF

If all is good, you'll see "hciX" followed by the address of the dongle.

For more confirmation that everything is working, we can now find the address of the wiimote. Run hcitool scan and then press buttons 1+2 on the wiimote to put it into discoverable mode:

Code:
$ hcitool scan
Scanning ...
     E0:E7:51:A0:A9:94       Nintendo RVL-CNT-01

At this point you should be able to connect your wiimote and use it as a mouse. Test that by running wminput.

Code:
$ sudo wminput
Put Wiimote in discoverable mode now (press 1+2)...
Ready.

Now, if you're like me, you're pretty giddy because tilting the wiimote is causing the mouse pointer to move across the screen. Take a deep breath and relax, because it only gets better from here.

6. Install lswm
Running "lswm" while the wiimote is in discoverable mode will return the wiimote's address, similar to "hcitool scan". The difference is that "lswm" will only return the address and not "Nintendo RVL...". This will be useful for our launch script.

Code:
$ sudo apt-get install lswm

7. Update /etc/sudoers so that wminput can be run without entering a password
wminput needs to be run as root, which is fine if you plan on connecting your wiimotes from a terminal every time. Once we get around having to enter a password to run wminput we can make a simple "connect wiimote" script that can be initiated from within XBMC via Advanced Launcher. To do this, we have to edit the "/etc/sudoers" file.

Code:
$ sudo visudo

Scroll down to the end and add the following line. Replace "xbmc" with your user name (if you didn't set it up as xbmc).

Code:
%xbmc ALL=NOPASSWD: /usr/bin/wminput

8. Create wminput configure files
Make a directory structure in your home directory for ".cwiid/wminput". And within that "wminput" directory, you'll make a configuration file for player1 and player2.

Code:
$ mkdir -p ~/.cwiid/wminput
$ touch ~/.cwiid/wminput/buttons-player1
$ touch ~/.cwiid/wminput/buttons-player2

The "buttons-player1" and "buttons-player2" files will contain the key mappings for your wiimote and classic controller and should look something like this:

buttons-player1
Code:
Plugin.led.Led1 = 1

Wiimote.A      = KEY_ENTER
Wiimote.B      = KEY_BACKSPACE
Wiimote.Up      = KEY_UP
Wiimote.Down    = KEY_DOWN
Wiimote.Left    = KEY_LEFT
Wiimote.Right   = KEY_RIGHT
Wiimote.Minus   = KEY_BACKSPACE
Wiimote.Plus    = KEY_ENTER
#Wiimote.Home
#Wiimote.1
#Wiimote.2

Classic.Up      = KEY_A
Classic.Down    = KEY_B
Classic.Left    = KEY_C
Classic.Right   = KEY_D
Classic.Minus   = KEY_E
Classic.Plus    = KEY_F
Classic.Home    = KEY_ESC
Classic.A       = KEY_G
Classic.B       = KEY_H
Classic.X       = KEY_I
Classic.Y       = KEY_J
Classic.L       = KEY_K
Classic.R       = KEY_L
Classic.ZL      = KEY_M
Classic.ZR      = KEY_N

buttons-player2
Code:
Plugin.led.Led2 = 1

Wiimote.A      = KEY_ENTER
Wiimote.B      = KEY_BACKSPACE
Wiimote.Up      = KEY_UP
Wiimote.Down    = KEY_DOWN
Wiimote.Left    = KEY_LEFT
Wiimote.Right   = KEY_RIGHT
Wiimote.Minus   = KEY_BACKSPACE
Wiimote.Plus    = KEY_ENTER
#Wiimote.Home
#Wiimote.1
#Wiimote.2

Classic.Up      = KEY_O
Classic.Down    = KEY_P
Classic.Left    = KEY_Q
Classic.Right   = KEY_R
Classic.Minus   = KEY_S
Classic.Plus    = KEY_T
Classic.Home    = KEY_ESC
Classic.A       = KEY_U
Classic.B       = KEY_V
Classic.X       = KEY_W
Classic.Y       = KEY_X
Classic.L       = KEY_Y
Classic.R       = KEY_Z
Classic.ZL      = KEY_9
Classic.ZR      = KEY_0

What I chose to do here was rather than map out the d-pad as wsad and the buttons as something like buttonB=o buttonA=p, I simply mapped player1's buttons to letters A-N and player2's buttons to O-Z (plus 9 and 0). This just makes it easier to keep track of which ones have been used.

Also, the wiimote itself will be used to navigate within XBMC and the classic controller 'home' button is mapped to the escape key for the added bonus of exiting the emulator.

8. Update the emulator configure files with the new keyboard input layout

For mednafen it'll be found in ~/.mednafen/mednafen.cfg

For zsnes it's in ~/zsnes/zinput.cfg

9. Create script(s) to connect the wiimote(s)
You can make this step a little more complex if you like and write a script that takes arguments which you can pass into a launcher so that one script will connect multiple wiimotes. Or you can make a shell script for each wiimote and be done with it. (remember to make it executable)

Something like this:
Code:
#!/bin/bash
sudo /usr/bin/wminput -w -c ~/.cwiid/wminput/buttons-player1 $(lswm) &

Here we capture the output from "lswm" which returns the address for the current wiimote in discoverable mode which is then associated with the buttons-player1 config file.



And there you have it. A wiimote to navigate XBMC and a classic controller to control your emulators. When you're done, you can power off the wiimote to close wminput.


References
wminput docs
wminput.list (doc link is broken)
How-to on wiimote install/config for linux
How-to wiimote in ubuntu
Ubuntu bluetooth installation
(This post was last modified: 2011-10-24 05:47 by MooseTracks.)
find quote
MooseTracks Offline
Junior Member
Posts: 6
Joined: Oct 2011
Reputation: 0
Post: #2
Emulator .cfg files
.mednafen.cfg
[Image: wiiclassiccontrollermap.jpg]
The d-pad and select (minus) / start (plus) are positioned as they are on the controller, but I moved B-A to Y-B because I prefer that layout. Also, due to the extra buttons I was able to add a little more functionality to the mednafen mapping to control saved states, but I restricted it to player 1. If you set it up yourself, I think by default "t" brings up the net play terminal so be sure check for overlapping keys on player 2's controller.

.zinput.cfg
Nothing really to add since it's essentially an SNES controller. ZL and ZR could have some added functionality but at this point I haven't added anything.


Check Battery Life
If you add the following line to your buttons-player1 file:

Code:
Plugin.led.Battery = 1

You can check the battery life by pressing wiimote buttons A+B simultaneously. The wiimote LEDs will light up based on the current battery state. Supposedly you can change the button(s) to trigger the battery check but I can't figure out / find documentation on how exactly to set "Plugin.led.Button". This is only a problem if you have those buttons defined, such as how I currently have them to navigate menu selections. Within the emulators themselves there shouldn't be a problem as long as those keys aren't used in the .cfg files.
(This post was last modified: 2011-10-24 06:31 by MooseTracks.)
find quote
Vietomatic Offline
Junior Member
Posts: 9
Joined: Oct 2011
Reputation: 0
Post: #3
Thank you for the detailed instructions.

Would you mind posting your mednafen.cfg and zsnes.cfg file? I would like to load up the emulator without having to set the controls every time.
find quote
MooseTracks Offline
Junior Member
Posts: 6
Joined: Oct 2011
Reputation: 0
Post: #4
Not a problem, I'm glad the guide was helpful! I've uploaded my mednafen.cfg and zinput.cfg files to pastebin, feel free to use them as they are or make modifications as needed.
find quote
Vietomatic Offline
Junior Member
Posts: 9
Joined: Oct 2011
Reputation: 0
Post: #5
Thanks again, MooseTracks, you are most helpful! I'm glad that you put the escape function as the home key.

I can get it working on my Ubuntu XBMC Live setup. However, I have to open up a telnet window and manually enter the following to make sure my controllers connect:

sudo /usr/bin/wminput -w -c ~/.cwiid/wminput/buttons-player1 $(lswm) &
sudo /usr/bin/wminput -w -c ~/.cwiid/wminput/buttons-player2 $(lswm) &

I tried adding those lines to my startup script (/etc/rc.local) but it does not connect automatically (or at all).

Please forgive my limited Ubuntu/Linux knowledge, but where can I add those lines to make it run on XBMC startup? Thanks.
find quote
MooseTracks Offline
Junior Member
Posts: 6
Joined: Oct 2011
Reputation: 0
Post: #6
Someone else on the forums with more Linux experience might be of more help on this, but I'll share what I know to this point until I have time to experiment a bit.

I'm not sure of how to "pair" the wiimote to the bluetooth device. I think bluez uses a PIN on the paired hardware (about 1/3 of the way down):
Quote:
Code:
sudo bluez-simple-agent hci0 XX:XX:XX:XX:XX:XX

XX:XX:XX:XX:XX:XX is the MAC or BT ADD or BlueTooth Address of the bt device. Press the reset or pair button on your keyboard, simple-agent will ask to specify a pin like 1111, then type that pin on the bt keyboard and your bt keyboard is paired.
Code:
sudo bluez-test-device trusted XX:XX:XX:XX:XX:XX yes

To set the device as trusted


As far as I've found, the wiimote doesn't have a PIN, so I'm not sure how to go about creating that automatic connection on startup.

Now, when you mention "connect automatically (or at all)" does one of the two wiimotes connect after you've put it in discoverable mode? And then one doesn't connect at all?

At one point we were messing with rc.local trying to get instances of wminput running on start up and it seemed like there was a problem with starting a second instance before connecting the first wiimote. I might be incorrect on that, but I think that was the conclusion we came to.

Which is why I ended up making launcher scripts and placing them as favorites in my "Games" menu item. I agree that it's not as ideal as pressing any button on the wiimote to activate it like you do with the Wii itself, but so far that's the best solution I've come up.
find quote
Vietomatic Offline
Junior Member
Posts: 9
Joined: Oct 2011
Reputation: 0
Post: #7
Before, I used the other tutorial on how to use the WiiMote as an XBMC remote (menu navigation only, not active for games). Using that method, the WiiMote is automatically detected upon startup, but you still had to activate the connection by pressing 1+2 on the Wiimote. The rc.local file had the startup line for this method.

Now, since I want to use the WiiMote as a remote AND game controller, I cannot use that script anymore, but to use your method. It works fine, but I was wondering what I could do to make it automatic, as I described above.

I now manually run those two lines of code to connect my controllers, one at a time.

For now, I will use the favorites to run the scripts. Thanks for all of your help and prompt reply...I'd buy you a beer!
find quote
MooseTracks Offline
Junior Member
Posts: 6
Joined: Oct 2011
Reputation: 0
Post: #8
Do you have a link for the Wiimote guide you used previously? I'd like to take a look and see if it's possible to improve my setup without losing any functionality.

I'll hopefully have some time to tinker tomorrow afternoon, or maybe on the weekend.

And I'll take the offer for a beer as a response that I've put up a useful guide, which is much appreciated!

Cheers! :beer:
find quote
Vietomatic Offline
Junior Member
Posts: 9
Joined: Oct 2011
Reputation: 0
Post: #9
This is the XBCM API that allows the Wiimote to serve as a navigation tool:
http://wiki.xbmc.org/?title=EventServer#WiiRemote

This is the tutorial (there are similar tutorials out there): http://forum.xbmc.org/showthread.php?tid=60621

I've showed off my XBMC/Home Theater/Emulator setup to my buddy, and he wants one now. Cheers!
find quote
Vietomatic Offline
Junior Member
Posts: 9
Joined: Oct 2011
Reputation: 0
Post: #10
Oh, I found a small typo/bug in your mednafen.cfg:

;nes, Port 2, Gamepad: A
nes.input.port2.gamepad.a keyboard 114

Should be keycode 118 instead of 114.
find quote
MooseTracks Offline
Junior Member
Posts: 6
Joined: Oct 2011
Reputation: 0
Post: #11
Typo? No, you just found my "accidentally on purpose" handicap for when I have friends over.

"Dude...why does my character move right when I push A?"

"I don't know, but it isn't helping your score in the slightest."

(good catch, my friends will thank you)


Also, after looking at those links, have you tried getting only one to pair on start up through rc.local? Change the -w flag to -d for daemon mode so it can reconnect after a disconnect.

Code:
sudo /usr/bin/wminput -d -c ~/.cwiid/wminput/buttons-player1 $(lswm) &


If you don't have time tonight, I'll give it a shot tomorrow. That would work well actually, then there would only have to be a launcher to connect player 2.
(This post was last modified: 2011-10-28 03:47 by MooseTracks.)
find quote
Vietomatic Offline
Junior Member
Posts: 9
Joined: Oct 2011
Reputation: 0
Post: #12
Haha, someone should write a button-randomizer script...part of the game will be to figure out what button does what!

So I've tried every iteration of the code you provided in my rc.local script, but it won't detect or connect to my wiimote. Running the code separately on the command line will work. I believe it may be merely a syntax issue, or perhaps "sudo" commands cannot be included in rc.local?

It would be great to have one wiimote connect automatically, how else could I navigate to the launcher script to connect player 2's wiimote (besides using another input device)? Kinda like one hand clapping, sorta (bad analogy, haha). Thanks again.
find quote