A Weird Imagination

Emulating Xbox controllers using GameCube controllers

The problem

I previously wrote about making different controllers act like Xbox 360 controllers. While it's a useful general-purpose solution, it's can be a bit clunky to have to explicitly set the mappings for each controller. More importantly, the remapping leaves the original controller entries in /dev/input/, although they don't do anything, and some games1 assume that the four players are controlled by the first four controllers. This is no longer true if js0 is the real first controller and js1 is the copy made by xboxdrv to look like an Xbox 360 controller. Or, worse, if js0-js3 are the four real controllers and js4-js7 are the ones we want the game to actually use.

The specific reason I'm remapping the controllers, is that the gamepads I'm actually using are GameCube controllers connected via the Nintendo GameCube controller Adapter for Wii U, which connects up to four GameCube controllers to a USB port. wii-u-gc-adapter makes them usable as controllers, but they appear different enough from Xbox 360 controllers that remapping them is necessary for most games.

The solution

Just build and use the version of wii-u-gc-adapter in my feature/mimic-xpad branch and your GameCube controllers will show up as Xbox controllers.

The details

As Nintendo GameCube controller Adapter for Wii U does not actually make the controllers act like normal USB HID devices, wii-u-gc-adapter acts a user-space drive, using uinput to generate /dev/input/js* devices, similar to how xboxdrv works. As it's a fairly small C program, it was straightforward for me to modify it to generate a device that acts like an Xbox 360 controller generated by xboxdrv with the --mimic-xpad option.

My goal was to make the controllers look identical according to jstest, so I ran the various Xbox 360 controller drivers and wii-u-gc-adapter and took notes on what the output looked like and which controllers on the physical controller corresponded to the output from jstest. Then I just fiddled around with the button and axis map definitions in the source of wii-u-gc-adapter until the output looked identical and the button correspondences were correct (e.g., the d-pad button mapping looks weird, but it works).

Getting the original mappings back

I could have made a --mimic-xpad mode of wii-u-gc-adapter like xboxdrv has... but that seemed like a lot of additional work for what is currently a simple hacky solution. Instead I just built the feature/mimic-xpad branch and renamed that binary to wii-u-gc-adapter.xpad to distinguish it from the normal wii-u-gc-adapter.

  1. The specific game I was trying to play was No Heroes Here, which does not have official Linux support, but is playable on Linux through Proton


Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.

There are no comments yet.