Using joysticks & gamepads in FreeBSD
=====================================

FreeBSD is not really the first thing that comes to mind when talking about 
playing video games. In fact, it's probably the last thing that comes to mind.
Either most people play games on Windows at best, or Linux if they're truly 
adventurous. Why use FreeBSD for gaming at all? Maybe it's because I like having 
FreeBSD as my operating system and I don't want to switch to Linux or Windows to 
fire up my emulator of choice!

It is possible to use joysticks in FreeBSD, but since there was no documentation 
to the average user on how to do this (or anywhere in the handbook), I figured 
that I'd take a swing at writing something like this out (since it took me long
enough to figure out by myself).

For this howto, I'll assume that you have a USB joystick or joypad, because I 
don't have an old-skool PCI-style joystick to test. Besides, most joysticks
these days are USB. However, the driver we'll use has support for these older 
PCI card types, but I've never tried it.

FreeBSD recognises USB joysticks through the "uhid" module. By default, this 
module is compiled into the GENERIC kernal already (It is in FreeBSD 6.2), so
you don't need to recompile the kernal to get it. All you need to do first is to 
plug in your USB joystick and then check /var/log/messages or "dmesg" to see 
that your joystick was identified as a uhid device. You should see something 
like the following in the logs:-

uhid0: CHEAP PLASTIC CO. USB Gamepad, rev 1.10/1.00, addr 2, iclass 3/0

You will notice that a /dev/uhid0 device appears in the dev filesystem to 
represent this device.

We're not done yet though. The UHID module in the kernal is for "USB Human Input 
Devices". This description is incredibly broad, and that's because this module
exists for input devices that don't have their own driver. In other words, 
FreeBSD has detected that there is SOMETHING plugged into the USB port on your 
PC, and it knows that it is used as an input device.... it just has no idea that 
this input device is actually a digital joystick.

You can play around with UHID devices with the "usbhidctl" command, and see how 
it responds. You'll notice that, as it stands, the uhid module can detect things 
like X&Y axes, as well as how many buttons your joystick has. The displayed 
values and classes are all things that pretty much all input devices have in 
common however, whether we are talking about mice, trackballs, graphics tablets, 
or digital/analog joysticks.

In order to use a joystick in an emulator (such as xmame for example), we need 
to install the linux joystick driver module. FreeBSD has a port of the linux 
joystick driver, and this seems a more logical solution since Linux is the 
target system that most emulators and GPL games aim for.

The driver module can be done by going to /usr/ports/devel/linux-js and 
installing the port:-

 # cd /usr/ports/devel/linux-js
 # make install

Or you can simply add it as a package (if the port is broken, which is the 
case at time of writing):-

 # pkg_add -r linux-js

The linux-js package produces the linux-js kernal module. It has to be loaded in 
order for the joystick to be detected as a joystick, and for emulators and other 
games to interact with it.

You need to add the following lines to your /boot/loader.conf file in order to 
load this module at boot time. You don't have to do this part if uhid is already
compiled into your kernel (FreeBSD 6.2 will autoload the module when it detects 
a joystick), but doing so makes sure that the module gets loaded
before the kernal starts up in earnest.

     joy_load="YES"          (if PC joystick support is desired)
     uhid_load="YES"         (if USB joystick support is desired)

Next you have to enable the joystick module for use with uhid devices by adding 
the following line into your /etc/rc.conf

     linux_js_enable="YES"

To load the module on-the-fly without having to restart your machine, simply 
load the module with kldload:-

 # kldload linux_js

Note that either the "joy" or "uhid" modules must be operational for this module 
to work. (although we should have already established this by now)

The linux_js module then detects your uhid0 device as a joystick, and creates a 
new device node for it at /dev/input/js0. More than one joystick connected to 
the PC will result in more device nodes becoming available (such as js1, js2, 
js3 etc.). You can check now to see that the linux-joystick module properly 
detects your device as a joystick. You should now see someting like this in dmesg:-

linux_js: /dev/uhid0 (CHEAP PLASTIC CO. USB Gamepad) attached to /dev/input/js0

From here we can test the joystick's operation with the jstest command:-

 # jstest /dev/input/js0

With jstest, you'll see your joystick axes and buttons status. Good to use in
case you think your joystick/joypad is a bit broken (tends to happen to cheap 
plastic). You'll see something like this:-

Joystick (CHEAP PLASTIC CO. USB Gamepad) has 3 axes and 8 buttons. Driver version is 2.1.0.
Testing ... (interrupt to exit)
Axes:  0:     0  1:     0  2:-32767 Buttons:  0:off  1:on   2:off  3:off  4:off  5:off  6:off  7:off

You can calibrate an analog joystick with the jscal command. Since I don't 
have an analog joystick, I don't know how this works. You don't need it if you 
simply have a digital joystick.

 # jscal -c /dev/input/js0

Calibration details can be saved at shutdown and re-enabled at boot by adding 
the following line to /etc/rc.conf

     jscal_enable="YES"

Now for the real world test, and the fun part. Compiling in all your games/
emulators!

You should ALWAYS make sure that the linux_js package is installed BEFORE 
compiling in any games or emulators from ports. This is because a lot of games 
and emulators detect the availability of linux joystick libraries (libusbhid in 
particular) before even bothering to compile joystick code in. If you don't have 
the joystick libraries installed and you compile your favourite game/emulator, 
you may find that it won't detect your joystick, or even have options available 
to you to set up joysticks - even if you install the linux-joystick module later 
on. (The Commdore VICE emulator is a prime example of this issue. Snes9x is 
another.) If this occurs, you'll need to "make distclean" and recompile in the 
program again.

What programs in FreeBSD actually work with joysticks? Well, I've had great 
success with ZSNES and XMAME, because they just needed to be told 
where to find the joystick device (at /dev/input/js0). VICE recently had joystick support added, so the whole world of Commodore 64 gaming is open to you, FreeBSD, and your joypad.

Other times, you'll find that some programs just won't accept your joystick.
GENS seems to have issues receiving data from the joystick for example, 
making it impossible to configure the joystick to the controls. I think that 
getting this to work will require some hacking. (I believe there is a
joystick driver for Xorg out there - and would it help?).

Also, some of the emulator front-ends don't seem to work well with linux-js,
and this is perhaps also due in part to the fact that they expect certain
command-line options to exist when, over time, emulator command line options 
tend to change and evolve. Unfortunately this can mean that the option to set 
the joystick device fails when the emulator is run. Snes9express suffers from 
this, as does gxmame at the moment. Kmamerun seems to be ok, as long as you 
choose the "X11 joystick driver" from the menu. (which it really isn't. It 
actually starts linux joystick driver instead, thanks to the fact that kmamerun 
has its command line options all mixed up.)

Until various game related ports start adding in options or patches for the 
linux-joystick, there is no nice solution to work around these issues.




Hosted by www.Geocities.ws

1