Patch: more comprehensive Xbox gamepad support

David Fifield david at bamsoftware.com
Sat Jan 8 03:10:48 EST 2005


This patch adds support for Xbox gamepads using various drivers to
pydance.

There are two different Xbox gamepad drivers, the one that comes with
Linux 2.6, and the one distributed by the Xbox Linux project, and they
have different numbers of axes and buttons. I've included definitions
for both drivers.

Another complication is whether you have the evdev module loaded in
addition the joydev. The evdev driver reports some axes as hat switches
(two axes become one hat). I've modified the relevant parts of pad.py to
consider hats when counting axes. The number of buttons doesn't change,
so this shouldn't affect gameplay, only joystick detection.

There was an existing entry for an Xbox controller with 14 axes and 10
buttons. I couldn't find any combination of drivers or joydev/evdev that
produced this configuration.

The patch has been tested with a Microsoft Xbox gamepad and a Level Six
DDR Deluxe Dance Mat V.3.1 (the latter requires a kernel patch recently
added to the Xbox Linux CVS).

David Fifield
-------------- next part --------------
diff -Nru pydance-1.0.2.orig/pad.py pydance-1.0.2/pad.py
--- pydance-1.0.2.orig/pad.py	2004-01-06 21:41:20.000000000 -0700
+++ pydance-1.0.2/pad.py	2005-01-07 22:36:28.507579880 -0700
@@ -78,7 +78,26 @@
 # X-Box controller with X-Box Linux
 A14B10 = { 4: UP, 0: DOWN, 3: LEFT, 1: RIGHT,  6: START, 9: QUIT }
 
-MATS = { (6, 12): A6B12, (14, 10): A14B10, (2, 10): A2B10, (2, 8): A2B8 }
+# Xbox gamepads, Linux driver
+# With joydev module: 8 axes, 10 buttons
+# With evdev module: 6 axes, 1 hat, 10 buttons
+# B: 1, A: 0, X: 3, Y: 4, White: 5, Black: 2
+# Back: 9, Start: 6
+# Left analog stick: 7, Right analog stick: 8
+A8B10 = { 4: UP, 0: DOWN, 3: LEFT, 1: RIGHT, 6: START, 9: QUIT }
+
+# XBox gamepads, Xbox Linux driver
+# With joydev module: 14 axes, 14 buttons
+# With evdev module: 6 axes, 4 hats, 14 buttons
+# Left: 12, Up: 9, Right: 10, Down: 11
+# B: 1, A: 0, X: 3, Y: 4, White: 5, Black: 2
+# Back: 13, Start: 6
+# Left analog stick: 7, Right analog stick: 8
+A14B14 = { 13: QUIT, 9: UP, 1: UPLEFT, 12: LEFT, 4: DOWNLEFT, 11: DOWN,
+           3: DOWNRIGHT, 10: RIGHT, 0: UPRIGHT, 6: START }
+
+MATS = { (6, 12): A6B12, (14, 10): A14B10, (2, 10): A2B10, (2, 8): A2B8,
+         (8, 10): A8B10, (14, 14): A14B14 }
 
 class Pad(object):
 
@@ -104,7 +123,8 @@
     for i in range(totaljoy):
       m = pygame.joystick.Joystick(i)
       m.init()
-      args = (i, m.get_numaxes(), m.get_numbuttons())
+      # One hat is two axes.
+      args = (i, m.get_numaxes() + 2 * m.get_numhats(), m.get_numbuttons())
       print "Joystick %d initialized: %d axes, %d buttons." % args
 
       if args[2] == 32: emsusb2 = i
@@ -133,15 +153,15 @@
       print "EMSUSB2 found. Using preset EMSUSB2 config."
     elif mat != None:
       joy = pygame.joystick.Joystick(mat)
-      but, axes = joy.get_numaxes(), joy.get_numbuttons()
+      axes, but = joy.get_numaxes() + 2 * joy.get_numhats(), joy.get_numbuttons()
       print "Initializing player 1 using js%d." % mat
-      self.merge_events(0, mat, MATS[(but, axes)])
+      self.merge_events(0, mat, MATS[(axes, but)])
 
       if mat2:
         joy = pygame.joystick.Joystick(mat2)
-        but, axes = joy.get_numaxes(), joy.get_numbuttons()
+        axes, but = joy.get_numaxes() + 2 * joy.get_numhats(), joy.get_numbuttons()
         print "Initializing player 2 using js%d." % mat2
-        self.merge_events(1, mat2, MATS[(but, axes)])
+        self.merge_events(1, mat2, MATS[(axes, but)])
     elif totaljoy > 0:
       print "No known joysticks found! If you want to use yours,"
       print "you'll have to map its button manually once to use it."


More information about the pyddr-discuss mailing list