xpad freezing oddworldI bought Oddworld: New 'n' Tasty a few weeks ago only to find there is a show stopping bug that causes the game to freeze on startup when the xbox 360 wireless receiver is plugged in. Its been reported that the game works fine with the wired controller so it seemed obvious there was something going on with the wireless driver.

Since then I've slowly learnt more about the xbox controller drivers on Linux and eventually I couldn't help myself any longer, so I dove in to see if I could find a solution.

After it was confirmed to me that Oddworld still freezes on the an updated driver from Valve that is used with SteamOS and fixes other bugs such as always reporting that there are 4 controllers when the wireless adapter is plugged in and fixing the constantly blinking light issue, I turned to giving the alternative xpad360wr kernel driver a go [1].

Once I figured out how to unload the xpad driver and load the xpad360wr driver I tried to use my controller with the new xpad360wr driver on a game that didn't previously freeze with the xpad driver, but now my controller wasn't detected by the game at all.

I recalled seeing a list of id's in the xpad drivers source code for identifying usb devices so I decided to make sure the xpad360wr wasn't just missing an id.

It turns out xpad lists two id's for the wireless receiver:

{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },

{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },

Where as the xpad360wr driver only listed the ids 0x045e, 0x0719 so I simply changed the id and rebuild the driver.

Unfortunately now when I tried to connect the controller my laptop locked up and required a reboot, it seemed like a slight win because at least it seemed to be detecting the controller now. The kernel was reporting some null dereferencing errors with the driver and I was about to contact the xpad360wr developer about this when I thought I'd better make sure that I was using the correct id first.

My plan was simple, build the Steam OS xpad driver and with the 0x045e, 0x0291 ids commented out and if the driver doesn't work with a known working game then that's the correct id and there is a bug in xpad360wr.

However something strange now happened, my controller now worked with Oddworld the freezing issue was gone. I can't explain why its now just working, maybe it's something to do with my receiver being a cheap ebay knock off rather than an official receiver. My knowledge in this area of the operating system is pretty much non existent but I intend to follow this up with the xpad and xpad360wr dev's to see if they can hopefully explain the issue and help solve it properly once and for all for everyone. I may even get to contribute my first kernel patch 🙂

For now here is how to build and install your own kernel module to work around the issue.

1. Blacklist the default xpad driver so its no longer loaded.

On Fedora I created the file:

/etc/modprobe.d/blacklist-xpad.conf

And added the following line to permanently disable the driver from being loaded:

blacklist xpad

Then reboot.

2. Download and extract the source for the Steam OS xpad driver:

http://ppa.launchpad.net/mdeslaur/steamos/ubuntu/pool/main/s/steamos-xpad-dkms/steamos-xpad-dkms_0.3.orig.tar.gz

3. Open the xpad.c source file and comment out or delete the following line:

{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },

4. Build the Steam OS xpad driver

In a terminal just type “make” in the directory where you have extracted it.

5. Load the driver you just built by typing the following into the terminal:

sudo insmod xpad.ko

6. Play Oddworld

Note: One thing I did find is the controls are mapped badly but I've read this is an issue with the wired controller also so I'm not sure if this is related to this hack or not. Also I believe you will need to reload the driver each time you reboot, I haven't worked out how to load this automatically yet.

It would be great to know if this worked for you. Feel free to leave a comment below.

Update: I finally worked out why commenting out that line of code caused the controller to work. It causes the driver to use some fall-back code to try and work out what type of device it is. The important thing is it ends up giving the device the name “Generic X-Box pad” rather than “Xbox 360 Wireless Receiver (XBOX)”. So what's happening is the game is checking if the device name contains “Xbox 360” then doing something (I'm not sure what) that's causing the game to break.
This means for those with the other type of wireless receiver you just need to change the name on the other line of code and the work around should work for you too.

Update 2: Using the remapping settings here the game now works perfectly with the patched xpad driver. http://steamcommunity.com/app/314660/discussions/0/611702631211590678/

[1] https://github.com/computerquip/xpad360wr