Setting up the Xbox 360 controller - mdeguzis/RetroRig GitHub Wiki

Table of Contents

About xboxdrv

Xboxdrv is a Xbox/Xbox360 gamepad driver for Linux that works in userspace. It is an alternative to the xpad kernel driver and has support for Xbox1 gamepads, Xbox360 USB gamepads and Xbox360 wireless gamepads.

<a name="install"

Installing

RetroRig includes xboxdrv as part of its base install, but if you should need to add it manually for whatever reason, you can install it as so:

sudo apt-get install xboxdrv

What follows below are the implementation methods you can use.

Implementation Methods

RetroRig, by default, makes use of an init script designed for Debian based systems (up until systemd becomes standard across all variants like Ubuntu).The init.d script uses the daemon "-D" Option to handle adding new controllers with correct indicator IDs. Using the daemon method is preferred over launching several different instances, where controllers may hook into the controller hub at the wrong time.

Using an init script (default)

Save the follwing content to /etc/init.d/xboxdrv:

#! /bin/bash
### BEGIN INIT INFO
# Provides:          xbox-controller
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start XBOX Controller Service
# Description:       Start the xboxdrv daemon with several options
#                    support up to 4 Controllers
### END INIT INFO

# Author: MasteRehm

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="XBOX Controller Service"
NAME=xboxdrv
DAEMON=/usr/bin/$NAME
DAEMON_ARGS="-D -d --deadzone 4000 --dbus disabled --detach"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

do_start()
{
        if [ $CONTROLLER_NUM -gt 4 ]; then
                echo -e "\n$CONTROLLER"; exit 1;
        fi
        start-stop-daemon -S -q -x $DAEMON -- $DAEMON_ARGS $CONTROLLER
        # Workaround: xboxdrv daemon creates /dev/input/js[4-7] device files, if /dev/input/js[0-3] created on startup.
        if [ -x /usr/bin/rename ]; then
                sleep 1
                if [ `ls /dev/input/js*` =~ /dev/input/js[4-7] ](/mdeguzis/RetroRig/wiki/-`ls-/dev/input/js*`-=~-/dev/input/js[4-7]-); then rename 's/js4/js0/;s/js5/js1/;s/js6/js2/;s/js7/js3/' /dev/input/js*; fi
        fi
}


do_stop()
{
    start-stop-daemon -K -o -q -x $DAEMON
    sleep 1
}

case "$1" in
  start)
    log_daemon_msg "Starting $DESC" "$NAME"
    do_start
     status=$?
    log_end_msg $status
    ;;
  stop)
    log_daemon_msg "Stopping $DESC" "$NAME"
    do_stop
     status=$?
    log_end_msg $status
    ;;
  status)
    status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
    ;;
  restart)
    log_daemon_msg "Restarting $DESC" "$NAME"
    do_stop
    case "$?" in
      0|1)
        do_start
        case "$?" in
            0) log_end_msg 0 ;;
            1) log_end_msg 1 ;; # Old process is still running
            *) log_end_msg 1 ;; # Failed to start
        esac
        ;;
      *)
        # Failed to stop
        log_end_msg 1
        ;;
    esac
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
    exit 3
    ;;
esac

sudo chmod +x /etc/init.d/xboxdrv
sudo update-rc.d xboxdrv start
You will also need a default configuration file. Save the following content to /etc/default/xboxdrv:

# How many Controllers? (support up to 4 Controllers)
CONTROLLER_NUM=2

case $CONTROLLER_NUM in
    1) CONTROLLER="-w 0 -l 2 --trigger-as-button --dpad-as-button"
    ;;
    2) CONTROLLER="-w 0 -l 2 --trigger-as-button --dpad-as-button --next-controller -w 1 -l 3 --trigger-as-button --dpad-as-button"
    ;;
    3) CONTROLLER="-w 0 -l 2 --trigger-as-button --dpad-as-button --next-controller -w 1 -l 3 --trigger-as-button --dpad-as-button --next-controller -w 2 -l 4 --trigger-as-button --dpad-as-button"
    ;;
    4) CONTROLLER="-w 0 -l 2 --trigger-as-button --dpad-as-button --next-controller -w 1 -l 3 --trigger-as-button --dpad-as-button --next-controller -w 2 -l 4 --trigger-as-button --dpad-as-button --next-controller -w 3 -l 5 --trigger-as-button --dpad-as-button"
    ;;
    *) CONTROLLER="incorrect amount of controller specified"
    ;;
esac

To specifiy the amount of controller, edit the variable CONTROLLER_NUM.

It is generally advisable to use the daemon mode, 'cause it uses less CPU and RAM instead of several xboxdrv processes for each controller.

<a name="multiple>

Multiples instances of xboxdrv

You have to launch multiple instances of xboxdrv (one for each controller). I have found this method to be sub-optimal in some cases, where controllers are disconnected at different times. Resycning a wireless receiver (if wireless is used) helps to some degree.

For example we can edit the file /etc/rc.local to start instances of xboxdrv during boot

Here is an example of what to insert in /etc/rc.local for 4 wireless pads (put this just before exit 0):

xboxdrv --trigger-as-button --wid 0 --led 2 --deadzone 4000 --silent &
sleep 1
xboxdrv --trigger-as-button --wid 1 --led 3 --deadzone 4000 --silent &
sleep 1
xboxdrv --trigger-as-button --wid 2 --led 4 --deadzone 4000 --silent &
sleep 1
xboxdrv --trigger-as-button --wid 3 --led 5 --deadzone 4000 --silent &

(replace the --wid by --id if you use wired controllers) You must swich-on your pads before booting the raspberry.

Notice the sleep 1 between each instance: this prevents the RPi from setting random controllers with random led status; adjust timing if necessary.

Using the command line

Another way is to specify this single command :

xboxdrv -D i 0 --next-controller -i 1 --next-controller -i 2 --next-controller -i 3 --deadzone 4000 --dbus disabled &

Credit: PetrockBlog