Steam for Linux

Steam for Linux

Sunr' ever Feb 20, 2014 @ 3:36pm
Play with any USB controller on Linux using xboxdrv to emulate a XBOX controller
EDIT: This tutorial works for games you play from Steam Client and for games you play outside of the Steam Client. If you're willing to play only Steam Games, try this Steam Big Picture tutorial first. If it doesn't work, then xboxdrv is guaranteed to put your controller to work.

---------------------------------------

Some games are meant to be played using a XBOX controller by default. If you have one, excelent, but if you don't, some controllers won't work 100% out of the box. For example, there are games where a PS2 controller + USB adapter will missplace some buttons: A is where Y should be, X is where A should be etc. You can correct this by remapping all your buttons/axis to the right place. On Windows you would use a program called x360ce and on Linux you'll use xboxdrv. I'll explaing how to set xboxdrv for your USB controller on Linux.


1. Installing xboxdrv

If your distro already has xboxdrv packed, install it from the repositories. If it doesn't, download the source code from their website (http://pingus.seul.org/~grumbel/xboxdrv/) and compile it. Since this step is distro specific, I won't cover it. If you're not sure how to do it, ask for help in your distro's forum.


2. Avoiding xpad conflict

Check if your distro loads xpad module to handle XBOX controller events:

# lsmod | grep xpad

If it returns a blank line, you're fine, go straight to the next section. If it returns something else, you must unload xpad module before loading xboxdrv by executing this command:

# rmmod xpad


3. Finding the proper input event

List all your available input events:

# ls /dev/input/ | grep event*

It will probably range from event0 to event20. You'll have to test each one of them until you find out which one is the event associated with your USB controller. To do so, enter the following command and press your controller buttons (press CTRL+C to exit after checking):

# evtest /dev/input/event11

If you got the wrong event, nothing will happen when you press buttons. When you get the right event, you'll notice because as soon as you press a button there will be a corresponding terminal output. Keep testing your available events until you find out which one is correct. In my case, /dev/input/event11 is associated with my PS2 controller.


4. Mapping your USB controller

If you have a PS3 controller, you can skip this section and go stragth to section 5. If you have any other controller, you must map it. To do so, while using evtest with the event associated to your controller (for example, # evtest /dev/input/event11), each time you press a button you'll receive a terminal output like this:

Event: time 1380985017.964843, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
Event: time 1380985017.964843, type 1 (EV_KEY), code 290 (BTN_THUMB2), value 1


In this case, I pressed the button corresponding to where the A button is on the XBOX controller, and this button is mapped as BTN_THUMB2. Then I pressed the button corresponding to where the B button is on the XBOX controller, and the output was this:

Event: time 1380985018.460841, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90002
Event: time 1380985018.460841, type 1 (EV_KEY), code 289 (BTN_THUMB), value 1


This output tells me that this button is mapped with the name BTN_THUMB. Take note of all these names. Do this for all your buttons and all your axis. You must take note of their names to be able to map them properly later. In the end, you'll have a list with all names and the corresponding XBOX buttons. You must map these buttons to valid XBOX buttons symbols:

Buttons: A, B, X, Y, RB (frontal upper right), RT (posterior upper right), LB (frontal upper left), LT (posterior upper left), START, BACK

Directionals: DPAD_X (horizontal D-pad), DPAD_Y (vertical D-pad), X1 (left analog horizontal), Y1 (left analog vertical), X2 (right analog horizontal), Y2 (right analog vertical)

Analog clicks: TL (left analog click), TR (right analog click)

I made an image to illustrate these valid XBOX buttons symbols[lh4.googleusercontent.com] you'll use to map your controller events. For a PS2 + USB adapter, this is how the final mapping list will look:

BTN_THUMB2=a
BTN_THUMB=b
BTN_BASE3=back
BTN_BASE4=start
BTN_BASE=lb
BTN_BASE2=rb
BTN_TOP2=lt
BTN_PINKIE=rt
BTN_BASE5=tl
BTN_BASE6=tr
ABS_X=x1
BTN_TOP=x
BTN_TRIGGER=y
ABS_Y=y1
ABS_RZ=x2
ABS_Z=y2
ABS_HAT0X=dpad_x
ABS_HAT0Y=dpad_y
-Y1=Y1
-Y2=Y2

Note that if you have a PS2 controller too, you won't have to map all your buttons again, since I already did this (just copy this list for further use). To see what each XBOX button is named after, you can use the built in xboxsrv help to see the valid names:

$ xboxsrv --help-button
$ xboxsrv --help-axis
$ xboxsrv --help-abs



5. Initializing xboxdrv

If you have a PS3 controller, you don't have to map your controller nor nothing. Just initialize xboxdrv like this and everything will be working:

# xboxdrv --silent --detach-kernel-driver

If you have any other controller, now that you have all your buttons and axis mapped, you must initialize xboxdrv properly. To do so, you'll have to initialize it like this:

# xboxdrv --evdev [EVENT] --evdev-absmap [ABS MAP] --axismap [AXIS MAP] --evdev-keymap [BUTTONS MAP] --mimic-xpad --silent &

[EVENT] is the event associated with your controller (section 3 of this post) and [ABS MAP], [AXIS MAP] and [BUTTONS MAP] are your controller mapping (section 4 of this post). In my case, my PS2 controller + USB adapter is associated with /dev/input/event11 and has the above mapping, so I initialize xboxdrv like this:

# xboxdrv --evdev /dev/input/event11 --evdev-absmap ABS_X=x1,ABS_Y=y1,ABS_RZ=x2,ABS_Z=y2,ABS_HAT0X=dpad_x,ABS_HAT0Y=dpad_y --axismap -Y1=Y1,-Y2=Y2 --evdev-keymap BTN_TOP=x,BTN_TRIGGER=y,BTN_THUMB2=a,BTN_THUMB=b,BTN_BASE3=back,BTN_BASE4=start,BTN_BASE=lb,BTN_BASE2=rb,BTN_TOP2=lt,BTN_PINKIE=rt,BTN_BASE5=tl,BTN_BASE6=tr --mimic-xpad --silent &

Note that if you have a PS2 controller too, you will initialize xboxdrv exactly the same way I do, except for the event, which might be another one.


6. Initializing xboxdrv during system startup

Everytime you restart your computer, you must unload xpad module (section 2) if it's loaded in your distro and properly initialize xboxdrv (section 5). To do these things automatically, you can put them on /etc/rc.local or whatever your distro calls it. It's distro specific, so go to your distro's forum and ask them where is your /etc/rc.local if you can't find it. In my case, I use OpenSUSE 13.1 and this file is located at /etc/rc.d/boot.local


7. Final words

I hope this helps you. With these steps I was able to set my USB controller to be remaped and emulated as a XBOX controller. I would appreciate if some moderator fixed this topic, so other users could easily find it.
Last edited by Sunr' ever; Apr 28, 2014 @ 8:10am
< >
Showing 31-45 of 89 comments
whitefox7 Jan 9, 2015 @ 2:50pm 
Never mind guys, I found a solution by myself, but I would like to hear your opinion: after loading xboxdrv, I noticed that the actual file Bastion use for gamepad settings is the new event file (in my case event16), so I renamed it using

mv /dev/input/event16 /dev/input/event13

and there it is, it works with all my games under Linux! But... what do you think? Renaming files so randomly is quite disturbing form me, expecially inside root tree, but let me know what do you think.
Sunr' ever Jan 9, 2015 @ 4:53pm 
This is probably a game specific issue with Bastion. A harmless solution could be to terminate xboxdrv and restart it using event16 when you wanted to play Bastion.
Gfurst Jan 9, 2015 @ 6:18pm 
Let me see if I got this right... your original event file for the gamepad ( the first one that appears) is the event13? xboxdrv creates a new event** and js** files, which are mapped as a xbox 360 controller... is this new file the event16?

If thats the case then Bastion should be using the correct one.

But actually, games should use the js# file interface and not the raw event# files, there may be an conflict if your system creates a js0 for the original joystick and xboxdrv creates an js1 for the emulated one, as this is my case.

It usually works well, but shows up two different joystick options for me, normally games will pick the xbox one so it works ok, but still shows up the two different options. That may be the case with your game, and just removing the js0 file before starting xboxdrv should fix around the conflict.

As it is in my case, both js# appears and are options in some games, but the original one won't work since xboxdrv locks up the original event so it won't send any input. If in doubt check the man page about xboxdrv where some of these things are explained.

http://pingus.seul.org/~grumbel/xboxdrv/xboxdrv.html
Gfurst Jan 9, 2015 @ 6:21pm 
Just some explanation taken from the man page about event devices:

--evdev DEVICE

Allows you to read input data from a regular event device. This allows you to use xboxdrv on regular PC joysticks. The data that is read from the event device is converted internally into a XboxMsg object and then passed through the same configuration pipeline as it would be for a regular Xbox360 controller. This allows you to make use of all the regular configurability, but limits you to the number of axis and buttons that an Xbox360 controller provides.

As a regular PC joystick will most likely already create a /dev/input/jsX device by itself, you might need to get rid of that so that a game will properly detect the joystick device created by xboxdrv. The easiest way to accomplish that is to simply delete the old joystick and rename the device that xboxdrv created to /dev/input/js0. When you use udev, this operation should be harmless and automatically reverse itself when you remove the controller and plug it back in or when you reboot the computer.
whitefox7 Jan 11, 2015 @ 2:27am 
It is exactly as you said Gfurst, I tried every possible combination and the only one that allows the gamepad to be regognized in the right way (with the new xbox mapping/configuration) is to rename the new event file (the xbox one) as the old event file.

I also noticed that the new js* file (created by xboxdrv) and the old one (js0, it appears every time you plugged in the gamepad), they both seems to receive inputs from the gamepad, while the old event file (after xboxdrv execution) seems to be (correctly) busy, so no fear in this case.

Now, when I said that I tried every possible combination, I mean that renaming the new js* file as the old one didn't work, but only with Bastion: it's strange, because in that way Bastion is stucked trying to get a valid input signal from a gamepad that is recognized by the game, but it is sending no input, so my conclusion is that Bastion uses the event13 file instead the js* file, while the other games use the correct one.
Jarno + Jarno Jan 19, 2015 @ 8:57am 
Xboxdrv is great tool.
You can also make atleast 2 different modes how your pad act.
On my case, when I start xbox360 controller first time after boot, it works as gamepad and by pressing that big X-button (guide) I can toggle my controller between gamepad and mouse/keyboard.
This is very useful for me since I dont have wireless mouse and like to watch e.g. youtube while laying on bed etc.
My default xboxdrv config: http://pastebin.com/Ncn3rZPR
Bash script what runs on-connect: http://pastebin.com/FzFri9eN

If using that --mouse, it uses xboxdrvs "default" commands to send mouse commands, like left stick is mouse cursor etc, but you can also overwrite those defaults like in row 8 in my startXboxdrv.sh.
xXTrinity5000Xx Mar 4, 2015 @ 6:50am 
I am having problems with my axis mapping when I enter it into the terminal this is what happens


trinity@TrinityCraft:~$ xboxdrv --evdev event7 --evdev-absmap ABS_Y=y1,ABS_Z=y2,AB,ABS_X=x1,ABS_R2=x2,ABS_HATOX=dpad_x,ABS_HATOY=dpad_y --axismap -Y1=Y1,-Y2=Y2 --evdev-keymap BTN_TL2=START,BTN_TR2=BACK,BTN_A=X,BTN_B=A,BTN_C=B,BTN_X=Y,BTN_TL=LT,BTN_TR=RT,BTN_Y=LB,BTN_Z=RB --mimic-xpad --silent &
[1] 27348
trinity@TrinityCraft:~$
-- [] ------------------------------------------------------
string2axis(): couldn't convert string "" to XboxAxis


Someone please help >.<
xXTrinity5000Xx Mar 4, 2015 @ 6:51am 
string2axis I don't know why it put the hearts
Sunr' ever Mar 4, 2015 @ 1:07pm 
This error says you used a double quotation mark (") and your terminal can't interpret it. Try using single quotation marks instead. If you didn't use it, your xboxdrv version used it somewhere in some script. Either try to use another terminal, change your locales to en_US or try using another version of xboxdrv.
xXTrinity5000Xx Mar 5, 2015 @ 2:49pm 
ok thanks :)
BLASTER♡Linux Mar 31, 2015 @ 10:56am 
I have paired a WiiU pro controller with bluetooth and im geting this events when i press the DPAD:
Event: time 1427824497.136844, type 1 (EV_KEY), code 544 (?), value 0
Event: time 1427824497.136844, -------------- SYN_REPORT ------------
Event: time 1427824497.486779, type 1 (EV_KEY), code 545 (?), value 1
Event: time 1427824497.486779, -------------- SYN_REPORT ------------
Event: time 1427824497.516772, type 1 (EV_KEY), code 545 (?), value 0
Event: time 1427824497.516772, -------------- SYN_REPORT ------------
Event: time 1427824497.796719, type 1 (EV_KEY), code 546 (?), value 1
Event: time 1427824497.796719, -------------- SYN_REPORT ------------
Event: time 1427824497.881702, type 1 (EV_KEY), code 546 (?), value 0
Event: time 1427824497.881702, -------------- SYN_REPORT ------------
Event: time 1427824498.046807, type 1 (EV_KEY), code 547 (?), value 1
Event: time 1427824498.046807, -------------- SYN_REPORT ------------
Event: time 1427824498.096801, type 1 (EV_KEY), code 547 (?), value 0
Event: time 1427824498.096801, -------------- SYN_REPORT ------------
Event: time 1427824506.111696, type 3 (EV_ABS), code 4 (ABS_RY), value -3


How im is upposed to map that? it only happens with the dpad.
Last edited by BLASTER♡Linux; Mar 31, 2015 @ 10:56am
Sunr' ever Apr 7, 2015 @ 8:43am 
@Blaster-PR, your linux kernel can't handle these inputs as events yet, you need to perform a previous step by defining events to each code in input.h file. The procedure is distro specific and it's a bit complicated. I suggest you to ask for help on your distro's official forums.
Null Apr 28, 2015 @ 6:03am 
I have a pretty annoying issue, I've identified that the event is event14, but I've found out that there seems to be a really bad deadzone issue, for example when I watch the event of the controller, it is non-stop hitting the axis buttons, spamming controls in the console when i'm not even touching the controller

The same behavior happens when I try to set custom controls in mupen64, I would try to set a control and immediately it would activate an axis + or - as if the deadzone is all over the place. Anyone else experience similar? I've tried 3 different controllers, so its definitely the driver
theManeShaneZulah Jun 11, 2015 @ 10:21am 
To whom it may concern,
I am late to the party, but I am attempting to run my Xbox360 controller on Ubuntu Kylin.

I have tried several times over, all the steps listed, in an effort to get my controller mapped for Risk of Rain - which will allow me to move thru menus, but not play the game itself (even when options list otherwise).

When I try to map out my buttons, via the event commands listed here, my command prompt comes back:

Testing ... (interrupt to exit)
***********************************************
This device is grabbed by another process.
No events are available to evtest while the
other grab is active.
In most cases, this is caused by an X driver,
try VT-switching and re-run evtest again.
***********************************************

Any help is appreciated. I am rather new to Ubuntu - but I won't let it stop me from playing games.
L:

Respectfully,
Artifex
Sunr' ever Jun 11, 2015 @ 6:23pm 
@Artifex, there is another program using your joypad. Can you find out what could it be?
< >
Showing 31-45 of 89 comments
Per page: 15 30 50

Date Posted: Feb 20, 2014 @ 3:36pm
Posts: 90