Remapping joystick buttons and axes on Linux

Saturday, July 4, 2009

I have many joypads / joysticks with many different button layouts, and by using this simple utility I can reconfigure the button layout by running a simple script, intead of reconfiguring every game and emulator everytime I want to use a different joystick.

DOWNLOAD it here:
http://www.mediafire.com/?msitbdej0ad
http://ubuntuforums.org/attachment.php?attachmentid=66632&d=1208782381

It's a patched version of the jscal utility from the joystick package. It will allow the remapping of buttons and axes directly into the driver.

It's compiled for Ubuntu 7.10 AMD64, but it will work with any later version. Also, you can recompile it to any version by doing a "make clean;make"

I have been looking for something like this for ages. Found it here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=444142

Quoting the patch author:


Quote:
Package: joystick
Version: 20051019-1
Severity: wishlist
Tags: patch

Motivation

I found no simple tool that would remap the joystick axes
and buttons on the device driver level (joydev module), while the driver
clearly provides the interface for this. My patch extends to
capabilities of jscal in order to remap axes and buttons. While
remapping in the X configuration file is possible, that mapping does not
seem to help in all games.


Detail

I bought a Trust GM-2550 Predator joystick the other day, and I noticed
that the axes were mapped incorrectly: the throttle in place of the
rudder, and the pinky button's axes were shifted up 1 slot in the axis
map. I found no tool to re-map the axes on the device driver (joydev)
level. While remapping is possible in the X config, this did not solve
the problem for - for example - SearchAndRescue.

Also I found no way to remap joystick buttons on the device driver
level. This is quite necessary for example for tuxkart, because some of
the buttons the game uses are unfortunately unreachable while holding
the joystick comfortably (some buttons are too far on the stick).

I found that the joydev kernel module does provide the API for axes and
button remapping. I added two command line options to jscal and two
corresponding functions that utilize the API and remap buttons and axes.
I have tested the axes and button remapping, and it works as intended. I
can swap buttons and axes as I wish.


Implementation

Please find the diff of jscal.c in joystick attached (joystick.diff).

The modified jscal.c adds two command line arguments:

-q --print-mappings Print the current axis and button
mappings as a jscal command line

and

-u n_of_buttons,btnmap1,btnmap2,
...> --set-mappings Sets axis and button mappings to the
specified values

An example output of -q looks like this (./jscal -q /dev/input/js0):

jscal -u
10,0,1,2,5,6,16,17,40,41,42,13,288,289,290,291,292 ,293,294,295,296,297,298,299,300
/dev/input/js0

The joystick has 10 axes and 13 buttons. If now one is to switch axes 2
and 5 (to get the rudder and the throttle right), one has to execute:

jscal -u
10,0,1,5,2,6,16,17,40,41,42,13,288,289,290,291,292 ,293,294,295,296,297,298,299,300
/dev/input/js0

changing 2,5 to 5,2 on the line.

Remapping buttons is done the same way.


Then, there is a very good way to load the joystick layout configuration automatically when you plug the device, with udev.

First you must create a udev rule. This is mine:

##/etc/udev/rules.d/85-joy-config.rules

##digiusb 0e8f:0013
BUS=="usb",ACTION=="add",ATTRS{idVendor}=="0e8f",ATTRS{idProduct}=="0013",RUN+="/usr/bin/joy-config-digiusb.sh"

##genesis6b 0f00:0008
BUS=="usb",ACTION=="add",ATTRS{idVendor}=="0f00",ATTRS{idProduct}=="0008",RUN+="/usr/bin/joy-config-genesis6b.sh"


As you can see the rule will execute the specified script as soon as the device with given idVendor and idProduct is plugged.

This is how I did the scripts:

"/usr/bin/joy-config-digiusb.sh"
#!/bin/bash
#digiusb 0e8f:0013
#/usr/bin/joy-config-digiusb.sh
sleep 1
jscal -u 4,0,1,16,17,10,289,290,291,293,294,295,296,297,288,292 /dev/input/js0
jscal -u 4,0,1,16,17,10,289,290,291,293,294,295,296,297,288,292 /dev/input/js1
jscal -u 4,0,1,16,17,10,289,290,291,293,294,295,296,297,288,292 /dev/input/js2
jscal -u 4,0,1,16,17,10,289,290,291,293,294,295,296,297,288,292 /dev/input/js3


"/usr/bin/joy-config-genesis6b.sh"
#!/bin/bash
#genesis6b 0f00:0008
#/usr/bin/joy-config-genesis6b.sh
sleep 1
jscal -u 2,0,1,16,309,310,311,312,313,314,308,316,317,318,319,315,304,305,306,307 /dev/input/js0
jscal -u 2,0,1,16,309,310,311,312,313,314,308,316,317,318,319,315,304,305,306,307 /dev/input/js1
jscal -u 2,0,1,16,309,310,311,312,313,314,308,316,317,318,319,315,304,305,306,307 /dev/input/js2
jscal -u 2,0,1,16,309,310,311,312,313,314,308,316,317,318,319,315,304,305,306,307 /dev/input/js3


I have added a "sleep 1" just in case the driver doesn't get ready on time.

Important: don't miss the "#!/bin/bash" or it will silently fail.

Also, my scripts will attempt to apply the layout to js0-3, as it will only succeed if the device matches the button/axis layout. I couldn't figure out a more elegant solution, but this one works for me.

Hope you find it useful.

Have fun.

0 comentários:

Post a Comment

Easy-Share


template by Ourblogtemplates.com
©Copyright 2009, Cleber de Mattos Casali. All rights reserved.