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.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)