XBoxDrv: a Fedora systemctl service

Two years ago, I discovered a user-space XBox 360 controller driver as replacement to the lackluster (then) kernel driver, xpad.  After rebuilding my new workstation and installing Fedora 20 on it, I took notice that its repository includes the xboxdrv package.  😎

It includes a replete set of sample configurations and the standard man page.  I can imagine all of the optimal configurations needed for the endless sea of emulators and games under my possession, but I don’t quite have that kind of time to be tinkering with such things.  Instead, I looked to its stock systemctl service and decided it only needed a little modification for my needs in there.  First, I validated my controllers visibility on USB:

$ xboxdrv -L
 id | wid | idVendor | idProduct | Name
----+-----+----------+-----------+--------------------------------------
  0 |   0 |   0x24c6 |    0x5303 | Xbox Airflo wired controller
  1 |   0 |   0x24c6 |    0x5303 | Xbox Airflo wired controller

Next, I modified the /usr/lib/systemd/system/xboxdrv.service file to reflect the changes in bold below:

ExecStart=/bin/xboxdrv --daemon --detach --detach-kernel-driver --pid-file /var/run/xboxdrv.pid --dbus disabled --silent --deadzone 4000 --deadzone-trigger 10% --dpad-as-button --led 2 --next-controller --dpad-as-button --led 3

It is not enough to just use the detach kernel driver option, as the man page suggests, the kernel xpad module needs to be blacklisted, as it gets in my way of joystick enumeration.  And I prefer to use the 4/8-way directional pad as buttons, for easy mapping, compatibility, and playable as a classic Atari joystick to emulators.  Since I have two controllers plugged in all the time, I want them to light up with their LED to signal as #1 and #2 and hopefully have their devices fixed as /dev/input/js0 and /dev/input/js1 respectively.

To activate that 1-line edit without any need to re-boot:

$ sudo systemctl daemon-reload
$ sudo systemctl restart xboxdrv

Some simple default mappings for MAME inputs to allow for ESCAPE – COIN – START functions as Back – Xbox – Start buttons, LEFT – RIGHT – UP – DOWN functions as dpad buttons, Fire 1 – 6 functions as A – B – X – Y – LTrigger – RTrigger buttons.  The Left and Right Hat controllers are also default assigned, so games like Battle Zone and Karate Champ will operate naturally using those inputs.  Only the 1st controller mappings are shown below, but it can be copy/pasted for any 2nd, 3rd, 4th, etc. controller:

$ cat ~/.mame/cfg/default.cfg
<?xml version="1.0"?>
<!-- This file is autogenerated; comments and unknown tags will be stripped -->
<mameconfig version="10">
    <system name="default">
        <input>
            <port type="P1_JOYSTICK_UP">
                <newseq type="standard">
                    KEYCODE_UP OR JOYCODE_1_BUTTON1
                </newseq>
            </port>
            <port type="P1_JOYSTICK_DOWN">
                <newseq type="standard">
                    KEYCODE_DOWN OR JOYCODE_1_BUTTON2
                </newseq>
            </port>
            <port type="P1_JOYSTICK_LEFT">
                <newseq type="standard">
                    KEYCODE_LEFT OR JOYCODE_1_BUTTON3
                </newseq>
            </port>
            <port type="P1_JOYSTICK_RIGHT">
                <newseq type="standard">
                    KEYCODE_RIGHT OR JOYCODE_1_BUTTON4
                </newseq>
            </port>
            <port type="P1_JOYSTICKRIGHT_UP">
                <newseq type="standard">
                    KEYCODE_I OR JOYCODE_1_RXAXIS_NEG_SWITCH
                </newseq>
            </port>
            <port type="P1_JOYSTICKRIGHT_DOWN">
                <newseq type="standard">
                    KEYCODE_K OR JOYCODE_1_RXAXIS_POS_SWITCH
                </newseq>
            </port>
            <port type="P1_JOYSTICKRIGHT_LEFT">
                <newseq type="standard">
                    KEYCODE_J OR JOYCODE_1_ZAXIS_NEG_SWITCH
                </newseq>
            </port>
            <port type="P1_JOYSTICKRIGHT_RIGHT">
                <newseq type="standard">
                    KEYCODE_L OR JOYCODE_1_ZAXIS_POS_SWITCH
                </newseq>
            </port>
            <port type="P1_BUTTON1">
                <newseq type="standard">
                    KEYCODE_LCONTROL OR JOYCODE_1_BUTTON5 OR MOUSECODE_1_BUTTON1
                </newseq>
            </port>
            <port type="P1_BUTTON2">
                <newseq type="standard">
                    KEYCODE_LALT OR JOYCODE_1_BUTTON6 OR MOUSECODE_1_BUTTON3
                </newseq>
            </port>
            <port type="P1_BUTTON3">
                <newseq type="standard">
                    KEYCODE_SPACE OR JOYCODE_1_BUTTON7 OR MOUSECODE_1_BUTTON2
                </newseq>
            </port>
            <port type="P1_BUTTON4">
                <newseq type="standard">
                    KEYCODE_LSHIFT OR JOYCODE_1_BUTTON8
                </newseq>
            </port>
            <port type="P1_BUTTON5">
                <newseq type="standard">
                    KEYCODE_Z OR JOYCODE_1_BUTTON9
                </newseq>
            </port>
            <port type="P1_BUTTON6">
                <newseq type="standard">
                    KEYCODE_X OR JOYCODE_1_BUTTON10
                </newseq>
            </port>
            <port type="START1">
                <newseq type="standard">
                    KEYCODE_1 OR JOYCODE_1_BUTTON12
                </newseq>
            </port>
            <port type="COIN1">
                <newseq type="standard">
                    KEYCODE_5 OR JOYCODE_1_BUTTON13
                </newseq>
            </port>
            <port type="UI_SELECT">
                <newseq type="standard">
                    KEYCODE_ENTER OR JOYCODE_1_BUTTON5
                </newseq>
            </port>
            <port type="UI_CANCEL">
                <newseq type="standard">
                    KEYCODE_ESC OR JOYCODE_1_BUTTON11
                </newseq>
            </port>
        </input>
    </system>
</mameconfig>

🙂