OpenBSD Journal

OpenBSD adds support for XBox360 controllers

Contributed by tbert on from the control-freak dept.

With the following commit, Jeremy Evans (jeremy@) has added OpenBSD XBox360 controller support as a uhid(4) device. As always when faced with an interesting commit message, the correct thing for any self-respecting undeadly editor to do is, well, start begging the developer for an interview...

CVSROOT:	/cvs
Module name:	src
Changes by:	jeremy@	2013/10/24 21:09:59

Modified files:
	sys/dev/usb    : uhidev.c 
Added files:
	sys/dev/usb    : uhid_rdesc.h 
Removed files:
	sys/dev/usb    : ugraphire_rdesc.h 

Log message:
Add support for Microsoft XBox 360 controller as a uhid. It doesn't use
the standard interface class and doesn't have a report descriptor, so
use a manually created one.
The controller shows up as multiple devices with different interface
numbers, so only match the first one as a uhid.  The controller shows up
as both a uhid and a ugen.

Rename ugraphire_rdesc.h to uhid_rdesc.h and add the manually created
Xbox 360 report descriptor to the file.

Add ifndef SMALL_KERNEL around the related blocks for the XBox 360
controller and Wacom Graphire, so this should actually shrink the
ramdisks.

Manual report descriptor taken from a 2005 FreeBSD commit.  Much help
from mpi@ for getting this suitable for commit to OpenBSD.

OK mpi@

Lucky for me, and you, begging works! Jeremy was kind enough to write in and give us all the glorious details:

I recently added support for XBox360 controllers to OpenBSD. This gives the background behind the commit.

I have a Logitech Dual Action controller that I bought a few years ago that works well, but it's impossible to buy new anymore. For a while, that was fine for me, but I started playing games with my 5-year old son, with him using the controller and me using the keyboard. The keyboard gaming was causing some pain in my hands, so I started looking into getting a second controller.

Here's the `usbdevs -v` output:

low speed, power 30 mA, config 1, Logitech Dual Action(0xc216), Logitech(0x046d), rev 3.00

The product name, "Logitech Dual Action," only tells you so much since many vendors keep reusing the same product name while they are continually changing the internal components of the product. Similar can be true for part numbers, but part numbers tend to get changed more often than product names. Unfortunately, the magic sticker containing the part number fell off years ago, so I only have the above vendor and product ID's. Unlike most of the supposed "Logitech Dual Action" controllers I've found for sale, the one I have has an extra "Mode" button:



Logitech also makes a widely available and not too expensive F310 controller, but I'm not sure if it is supported. I thought the best bet would be a Playstation controller via a USB adapter. The first couple USB adapters I tried from Amazon didn't work at all. When plugged in, nothing showed up.

Edd Barrett (edd@) managed to find one Playstation to USB adapter that show up correctly as a uhid(4) device and works on OpenBSD with our emulators/dgen-sdl and emulators/mednafen ports:

uhidev0 at uhub4 port 1 configuration 1 interface 0 "WiseGroup.,Ltd MP-8888 USB Joypad" rev 1.10/3.00 addr 2
uhidev0: iclass 3/0
uhid0 at uhidev0: input=7, output=3, feature=0

I remembered that the XBox360 wired controller used a plain USB connection, so I figured I'd give that a try. I hooked it up to the computer and it showed up as a ugen(4), but it wasn't recognized by libSDL, so it didn't work with any of the emulators I used.

I did some searching and found that someone had already written code to support the XBox 360 Controller in FreeBSD in 2005, and that Joe Gidi had ported that code to OpenBSD in 2010, but it wasn't merged. I looked over the diff to add support, and it appeared to be fairly simple, so I just tried applying it. Thankfully, it applied correctly. I tried building a new kernel and that was successful. On rebooting to the new kernel, the controller showed up as both a uhid(4) and ugen(4), so I was able to use it in the emulators, with some minor issues.

The email thread to add the XBox360 controller support in 2010 ended with Ted Unangst (tedu@) stating that it needed to be modified so that it didn't expand the ramdisks. I made the necessary modifications, rebuilt the kernel to make sure it still worked, and built a whole release to make sure the ramdisks still worked.

Since it appeared to work, I made a new post to tech@ with the modified diff. Martin Pieuchot (mpi@) was kind enough to review and provide feedback on my XBox controller patch. He pointed out how in addition to not expanding the ramdisks, we could actually shrink the ramdisks by removing unnecessary header for wacom graphire tablets (usbtablet(4)) since usm(4) is not included in the ramdisk kernels. Additionally, he objected to the way the diff attempted to recognize the XBox controller, since it involved some magic numbers, and recommended some additional improvements.

After some back and forth with mpi@ I was able to get a committable diff. I use the XBox controller support on a fairly regular basis, and I've found it works well with SNES games using emulators/snes9x, but there is a lot of input lag when playing NES games using emulators/mednafen. Also, since the directional pad shows up as 4 separate buttons instead of a hat, it's not usable by libSDL although it is recognized by usbhidctl(1). Playing games designed for a directional pad with an analog stick works OK in some titles, but not so well in others.

This was my first kernel commit, and hopefully I'll be able to do more kernel work in the future. I've already started working with mpi@ to do some USB cleanup, which I should start committing soon.

I'm still looking for a better controller that works similar to my existing Logitech Dual Action. If anyone has suggestions, please let me know.

Thanks Jeremy for giving us all the details of your XBox controller work. And yes, everyone knows that the only reason why you did all of this hard work was so you could gain an unfair advantage when playing games against your five year old.

(Comments are closed)


Comments
  1. By Anonymous Coward (91.154.66.65) on

    The day after this was committed, I walked to a shop and bought an Xbox 360 controller. It's a lot nicer than my ancient Gravis GamePad Pro USB. Thanks, Jeremy.

  2. By sneaker (sneaker) sneaker@noahpugsley.net on

    Psh, old news. Already saw it on bsdnow!

    Sike, thanks for the writeup!

  3. By Jeremy Evans (67.187.248.7) on

    I've found a working Playstation/Playstation 2 USB adapter on Amazon: http://www.amazon.com/Dual-Controller-Adapter-Converter-Playstation-2/dp/B001AATQ0Y/ref=sr_1_1?ie=UTF8&qid=1383883053&sr=8-1&keywords=ps+usb+adapter+hde

    This shows up as:

    uhidev0 at uhub4 port 1 configuration 1 interface 0 "vendor 0x0810 Twin USB Joystick" rev 1.00/1.06 addr 2
    uhidev0: iclass 3/0, 2 report ids
    uhid0 at uhidev0 reportid 1: input=7, output=4, feature=0
    uhid1 at uhidev0 reportid 2: input=7, output=4, feature=0

    Both ports are usable with either Playstation or Playstation 2 (Dualshock 2) controllers.

    It works well in snes9x-gtk, dgen, desmume, and mednafen in PCE mode. However, most other mednafen emulation modes suffer from severe/unplayable input lag with it (just like with the XBox360 controller), for reasons I cannot currently determine. This input lag does not occur with the Logitech Dual Action controller I have.

    Comments
    1. By jcr (jcr) on http://designtools.org

      > It works well in snes9x-gtk, dgen, desmume, and mednafen in PCE mode. However, most other mednafen emulation modes suffer from severe/unplayable input lag with it (just like with the XBox360 controller), for reasons I cannot currently determine. This input lag does not occur with the Logitech Dual Action controller I have.

      Thanks Jeremy for the update. So far I've been unsuccessful in finding another Logitech like the one you have.

Credits

Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original deadly.org with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]