Xpad et manette Xbox360 sur Debian
Pour le jour où beaucoup de jeux seront disponibles sous linux ^^
Dans un instant de folie, j'ai acheté une manette de XBox 360 cet hiver. Oui vous avez bien lu : XBox ! Aka la manette de chez Microtruc ...
Mon but n'est certainement pas d'en vanter les mérites en écrivant cet article. Quand j'étais dans le rayon, j'ai fortement hésité pendant environ 1/2 heures, le moment de folie fut agrémenté d'un dilemme cornélien et d'une impression incroyable de trahison -les clients m'entourant ont du m'entendre gémir- puis j'ai craqué et ais déboursé beaucoup d'argent pour la chose. Pour ma défense, c'était ça ou une manette en carton avec des loupiotes.
Le but de cet achat était uniquement de pouvoir jouer à un jeu de voiture, une fois lassé de ce jeu, je l'ai remisé dans un placard sous l'évier d'où elle n'aurait jamais du sortir :p
Recentrons le propos ! En ouvrant le placard récemment, j'ai eu des remords, non pas pour la manette mais pour mon portefeuille et en bon linuxien je me suis dit : "Cette chose peut elle fonctionner sur Debian ??" ...
Me voilà donc à tester ça. Après quelques recherche, j'ai appris qu'un projet de portage d'une distribution GNU/Linux sur console XBox existait et qu'ils avaient donc écrit un certain nombre de pilotes pour gérer les périphériques; dont la fameuse manette.
Plus loin, j'ai vu que la distribution d'Ubuntu Hardy Heron gère nativement la manette. Ce qui n'est pas encore le cas sur Debian. D'où cet article qui ré-utilise très largement les explications du site ubuntu-fr.org pour installer la manette mais ici transposé sur une Debian Lenny .
En fait on va devoir modifier le module1 xpad pour lui permettre d'accepter les manettes xbox. C'est plus simple qu'il n'y parait.
Préparation du module :
Télécharger les sources :
$ mkdir xbox360 $ cd xbox360 $ wget http://xbox-linux.cvs.sourceforge.net/*checkout*/xbox-linux/kernel-2.6/drivers/usb/input/xpad.c [...] $ wget http://xbox-linux.cvs.sourceforge.net/*checkout*/xbox-linux/kernel-2.6/drivers/usb/input/xpad.h [...]
Les sources sont présentes ici et ici aussi au cas où !
Créer le Makefile :
$ vi Makefile KERNEL_DIR?=/usr/src/linux obj-m:= xpad.o KDIR := /lib/modules/$(shell uname -r)/build EXTRA_CFLAGS=-I$(shell pwd) all: $(MAKE) modules -C $(KDIR) SUBDIRS=$(shell pwd)
(attention ce sont des tabulations devant la dernière lignes)
Je vous le donne directement. L'objectif, ici, n'est pas d'apprendre à faire un Makefile
Compilation du module :
Normalement sur une distribution normale, cela suffit mais si nous lançons le make sur une Debian, celui-ci va nous insulter :
$ make ake modules -C /lib/modules/2.6.26-2-686/build SUBDIRS=/home/kevin/xpad360 make[1]: entrant dans le répertoire « /usr/src/linux-headers-2.6.26-2-686 » CC [M] /home/kevin/xpad360/xpad.o /home/kevin/xpad360/xpad.c: In function ‘xpad_open’: /home/kevin/xpad360/xpad.c:382: error: ‘struct input_dev’ has no member named ‘private’ /home/kevin/xpad360/xpad.c: In function ‘xpad_close’: /home/kevin/xpad360/xpad.c:408: error: ‘struct input_dev’ has no member named ‘private’ /home/kevin/xpad360/xpad.c: In function ‘xpad_probe’: /home/kevin/xpad360/xpad.c:496: error: ‘struct input_dev’ has no member named ‘cdev’ /home/kevin/xpad360/xpad.c:497: error: ‘struct input_dev’ has no member named ‘private’ /home/kevin/xpad360/xpad.c:564: warning: ignoring return value of ‘input_register_device’, declared with attribute warn_unused_result make[2]: *** [/home/kevin/xpad360/xpad.o] Erreur 1 make[1]: *** [_module_/home/kevin/xpad360] Erreur 2 make[1]: quittant le répertoire « /usr/src/linux-headers-2.6.26-2-686 » make: *** [all] Erreur 2
Ceci est normal, le pilote n'est pas adapté à Debian. Il va falloir modifier les sources et du coup nous allons apprendre à patcher. Don't panic ! c'est vraiment simple : la commande diff permet de créer le patch et la commande patch de l'appliquer à un fichier.
Sauvegarder la source de xpad.c
$ cp xpad.c xpad.c.1
Ci-dessous le patch issu du diff avec la source originale que l'on devra mettre dans un fichier xpad.c.patch .
87d86 < { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", GAMEPAD_XBOX }, 382c381 < struct usb_xpad *xpad = dev->private; --- > struct usb_xpad *xpad = input_get_drvdata(dev); 408c407 < struct usb_xpad *xpad = dev->private; --- > struct usb_xpad *xpad = input_get_drvdata(dev); 496,497c495,498 < input_dev->cdev.dev = &intf->dev; < input_dev->private = xpad; --- > //input_dev->cdev.dev = &intf->dev; > input_dev->dev.parent = &intf->dev; > //input_dev->private = xpad; > input_set_drvdata(input_dev, xpad); 529c530 < -32768, 32767, 16, 128); --- > -32768, 32767, 16, 12000);
Il suffit ensuite d'utiliser patch :
$ patch xpad.c xpad.c.patch patching file xpad.c
Comme je le disais, le patch est issu d'un diff, faisons le test :
$ diff xpad.c xpad.c.1
Pour créer le fichier, une simple redirection > suffit
NB : En pratique, on utilise généralement diff avec l'option -u
$ diff -u xpad.c xpad.c.1 > xpad.c.patch.1
Ce qui permet de créer un contexte d'application de patch et le patch sera plus propre, il connaitra même le fichier à modifier. La commande patch s'utilise alors comme ceci :
$ patch -p0 < xpad.c.patch.1 patching file xpad.c
Pour comparer voici le fichier issu de diff -u : xpad.c.patch2
Maintenant que la source est corrigée, on peut faire le make :
$ make make modules -C /lib/modules/2.6.26-2-686/build SUBDIRS=/home/torus/xpad360.2 make[1]: entrant dans le répertoire « /usr/src/linux-headers-2.6.26-2-686 » CC [M] /home/torus/xpad360.2/xpad.o /home/torus/xpad360.2/xpad.c: In function ‘xpad_probe’: /home/torus/xpad360.2/xpad.c:565: warning: ignoring return value of ‘input_register_device’, declared with attribute warn_unused_result Building modules, stage 2. MODPOST 1 modules CC /home/torus/xpad360.2/xpad.mod.o LD [M] /home/torus/xpad360.2/xpad.ko make[1]: quittant le répertoire « /usr/src/linux-headers-2.6.26-2-686 »
Ce n'est pas encore parfait mais ça aura le mérite de marcher. Si quelqu'un veut bien corriger, je me porte acquéreur
Installation du module :
En root il vous faudra aller ici :
# cd /lib/modules/2.6.26-2-686/kernel/drivers/input/joystick
décharger les modules actuels du noyau qui servent à contrôler les joysticks
# modprobe -r xpad joydev usbhid
sauvegarder le module xpad.ko
# mv xpad.ko xpad.ko.bak
copier celui que l'on vient de compiler dans le répertoire /lib/modules/2.6.26-2-686/kernel/drivers/input/joystick
# cp ~kevin/xbox360/xpad.ko .
recréer la liste des dépendances entre modules (on ne sait jamais)
# depmod -a
puis charger les modules
# modprobe xpad joydev usbhid
Au besoin, ajouter dans /etc/modules ces lignes pour que les modules soit chargés au démarrage du pc :
usbhid joydev xpad
It's done ! il ne reste plus qu'à connecter la manette et de voir si la LED s'allume puis à calibrer le tout avec jscalibrator 2
On peut maintenant jouer à Super Mario Bros avec zsnes et une manette de XBox le tout sur une Debian ! Si ça c'est pas la classe américaine ?! euh non japonaise ... ah ben non finalement c'est juste Linuxien
Annexe :
Les manettes de XBox 360 sans fil ont un problème connu et qui m'est arrivé : l'émetteur/récepteur peut ne plus être détecté, la LED ne s'allumant plus même avec les pilotes officiels installés sur une bécane Microtruc. En fait cela vient d'un fusible en CMS qui a tendance à claquer un peut trop facilement.
La correction est simple mais demandera un fer à souder et de la précision.
Attention ! La garantie ne sera plus valable !
Ouvrez votre émetteur en introduisant un tournevis du côté du câble et faites levier. Le couvercle est un peu collé mais pas trop.
Puis shunter avec un fil le fusible en rouge ci-dessous :
Normalement la manette devrait remarcher.
^_^
PS : merci à la personne qui a mis ces photos en ligne sur imageshack.
- module : le pilote pour ceux qui ne serait pas familier
- jscalibrator ou l'utilitaire de KDE qui est conseillé si vous êtes sous KDE.