Introduction
Aujourd'hui, un article qui risque d'être assez long (et très probablement assez mal écrit) pour revenir sur mon activité de ces derniers jours.Avant de commencer, le contexte : la plateforme RaspberryPi est équivalente à un téléphone portable et permet de faire de l'émulation de consoles grâce à des distributions comme RetroPie (utilisant RetroArch, un des seul émulateur pi basé sur Pico capable de faire tourner certains jeux de Megadrive, comme Sonic Spinball, et EmulsationStation pour proposer une interface de lancement des jeux). Il existe aussi Chameleon et PiMAME, mais malheureusement l'émulateur Megadrive qui y est intégré ne fonctionne pas avec tout les jeux.
J'ai pu valider cette partie, et tester avec une manette bas de gamme (moyennant quelques configurations à la main pour EmulationStation et RetroArch).
Maintenant il peut être intéressant de pouvoir jouer à 2, et donc connecter 2 manettes, mais :
- les fils, c'est chiants
- la Pi n'aime pas trop se faire tirer du courant, ça la fait planter
D'où cette idée : acheter un dongle bluetooth et utiliser des manettes sans fil. J'en ai commandé 2 sur Amazon :
Cette première n'est absolument pas Bluetooth contrairement à ce qu'indique son nom .. Il faut utiliser leur gros dongle .. Amazon va la récupérer.
L'autre manette est celle ci :
Qui n'est pas une manette WiiU Pro contrairement à ce qu'indique son nom, mais une Wii Classic Controller Pro (qui fait aussi Wiimote simple).
Elle fonctionne en bluetooth comme les manettes Wii, on peut donc en associer plusieurs sur un simple dongle bluetooth.
Première approche
Ma première approche a été d'utiliser les tutos disponibles sur internet, tel que :- http://blog.petrockblock.com/forums/topic/tutorial-to-get-wiimotes-with-classic-controllers-to-work-with-retropie/
- https://github.com/petrockblog/RetroPie-Setup/wiki/Wiimotes-with-classic-controllers
- http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/robot/wiimote/
Ils se basent sur cwiid couplé avec wminput pour gérer les boutons. Seulement .. avec cette manette, ça ne fonctionne pas, il y a des messages d'erreur ("Received unexpected write report") et la partie Classic (il y a un switch sur la manette) fait comme si aucune touche n'était pressée. J'ai tenté de compiler la derniere version de cwiid, qui m'a permit de jouer avec les leds, mais pas plus.
J'ai fait d'autres recherche et suis tombé sur quelques liens :
Il a fallu compiler wiiuse (je passe les détails, c'est expliqué), mais je n'ai pas eu beaucoup plus de succès.
J'ai songé à un moment à parser les messages de la manette à la main, en prenant la méthode suitante : http://smus.com/prototyping-wii-remote-python/ mais quand un rapide test montre que la manette balance des 0xFF en continu, c'est qu'il faut lui envoyer les bonnes données avant, et bon .. flemme.
L'approche xwiimote / hid-wiimote
C'est en faisant des recherche sur la WiiU Pro Controller que j'ai vu qu'il existait une manette pour WiiU, qui n'est donc pas la même, et qu'il existe des logiciels pour l'utiliser (mais la mienne n'est pas celle-ci, même si je l'ai cru à un moment, le nom de la manette prêtant à confusion) :
- http://www.destructoid.com/wii-u-pro-controller-can-now-be-used-on-a-pc-mac-245781.phtml
- http://gbatemp.net/threads/wii-u-pro-controller-to-pc-program-release.343159/
Et la un message intéressant donne le nom d'un driver sympa, xwiimote.
XWiimote is an open-source linux device driver for Nintendo Wii / Wii U Remotes and compatible devices. It is a relatively new driver that tries to supercede cwiid, wiiuse and others by integrating the driver into existing linux infrastructure. The project consists of an official linux kernel driver, which is part of the kernel since linux-3.1, an extension to bluez, the official linux bluetooth stack, an X11 input driver, some user-space helpers and test applications.
Surprise donc ! Il existe un module kernel, qui se prétend mieux que cwiid et wiiuse, et qui se trouve être présent dans RetroPie (kernel 3.6.11+). Il y a même un super programme qui affiche les touches de la Wiimote et ses extensions en ASCII (xwiishow) !
(tiré de http://leftbraintinkering.blogspot.fr/2014/01/wii-remote-plus-and-linux.html) |
Mais après compilation de xwiishow, malheureusement même constat, le Classic controller ne fonctionne pas :(. Je commence à penser que la manette est défectueuse.
A noter qu'il faut utiliser hidd pour associer la Wiimote, bluez demandant un PIN.
Hack de hid-wiimote
Ayant jeté un œil aux sources du module hid-wiimote, et n'ayant plus rien à perdre (a part renvoyer la manette, mais elle me plait vraiment avec sa forme à la SuperNES), je me lance dans la modification de ce module.
Il faut pour ça pouvoir compiler, sur une Pi contrairement aux petits logiciels d'avant, c'est impensable, il faut donc passer par de la cross-compilation. l'avantage avec la Pi c'est qu'il existe plein de docs/tutos, on trouve donc des instructions pour cela : http://elinux.org/RPi_Kernel_Compilation.
Une VM Ubuntu x64, les libs pour exécuter des programmes x86, puis il suffit de suivre les instructions :
A noter qu'il faut compiler le kernel (make) avant de compiler les modules (make modules), sinon :
Mais le stick gauche ne fonctionne pas en vertical et les triggers font 2 actions au lieu d'une.Il faut pour ça pouvoir compiler, sur une Pi contrairement aux petits logiciels d'avant, c'est impensable, il faut donc passer par de la cross-compilation. l'avantage avec la Pi c'est qu'il existe plein de docs/tutos, on trouve donc des instructions pour cela : http://elinux.org/RPi_Kernel_Compilation.
Une VM Ubuntu x64, les libs pour exécuter des programmes x86, puis il suffit de suivre les instructions :
KERNEL_SRC=/home/user/raspbian-kernel/linux-rpi-3.6.y/
CCPREFIX=/home/user/raspbian-kernel/tools-master/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-
make mrproper
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
make ARCH=arm CROSS_COMPILE=${CCPREFIX}
make ARCH=arm CROSS_COMPILE=${CCPREFIX} modules
A noter qu'il faut compiler le kernel (make) avant de compiler les modules (make modules), sinon :
ERROR: could not insert 'hid_wiimote': Exec format error
Reconnaissance du Classic Controller
Le principal problème étant que l'extensions Classic n'est pas reconnu, alors qu'a priori présente, je décide de la forcer : wmem = 0x55;
wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem));
wmem = 0x0;
wiimote_cmd_write(ext->wdata, 0xa400fb, &wmem, sizeof(wmem));
return WIIEXT_CLASSIC;
Et la, même si rien n'est reconnu ou fonctionnel dans xwiishow, evtest affiche bien des boutons en mode Classic !Debug des controles
Pour voir ce qu'envoi la manette, j'essaye un débogage (comme je peux, le debugging de kernel je connais pas), c'est sale (mais fonctionnel) :#define BYTETOBINARYPATTERN "%d%d%d%d%d%d%d%d"
#define BYTETOBINARY(byte) \
(byte & 0x80 ? 1 : 0), \
(byte & 0x40 ? 1 : 0), \
(byte & 0x20 ? 1 : 0), \
(byte & 0x10 ? 1 : 0), \
(byte & 0x08 ? 1 : 0), \
(byte & 0x04 ? 1 : 0), \
(byte & 0x02 ? 1 : 0), \
(byte & 0x01 ? 1 : 0)
printk(KERN_INFO "Byte %d "BYTETOBINARYPATTERN"", 0, BYTETOBINARY(payload[0]));
printk(KERN_INFO "Byte %d "BYTETOBINARYPATTERN"", 1, BYTETOBINARY(payload[1]));
printk(KERN_INFO "Byte %d "BYTETOBINARYPATTERN"", 2, BYTETOBINARY(payload[2]));
printk(KERN_INFO "Byte %d "BYTETOBINARYPATTERN"", 3, BYTETOBINARY(payload[3]));
printk(KERN_INFO "Byte %d "BYTETOBINARYPATTERN"", 4, BYTETOBINARY(payload[4]));
printk(KERN_INFO "Byte %d "BYTETOBINARYPATTERN"", 5, BYTETOBINARY(payload[5]));
Et ça donne pleiiiiin de lignes dans les logs :Jan 17 17:16:52 raspberrypi kernel: [65820.154165] Byte 1 00100000Byte 2 00010000
Jan 17 17:16:52 raspberrypi kernel: [65820.154198] Byte 3 00000000Byte 4 11111111
Jan 17 17:16:52 raspberrypi kernel: [65820.154221] Byte 5 11111111Byte 0 10100000
Jan 17 17:16:52 raspberrypi kernel: [65820.161071] Byte 1 00100000Byte 2 00010000
Jan 17 17:16:52 raspberrypi kernel: [65820.161100] Byte 3 00000000Byte 4 11111111
Jan 17 17:16:52 raspberrypi kernel: [65820.161121] Byte 5 11111111Byte 0 10100000
Comme je disais, c'est sale, mais ça fonctionne et permet de repérer doucement les touches, je me suis alors construit une carte :Byte 0 10100000
^^-------RX(12)
^^^^^^-LX
Byte 1 00100000
^^-------RX(34)
^^^^^^-LY
Byte 2 00010000
^--------RX(5)
^^------TL
^^^^^-RY
Byte 3 00000000
^^^------TL
^^^^^-TR
Byte 4 11111111
^--------RIGHT
^-------DOWN
^------BTL
^-----MINUS
^----HOME
^---PLUS
^--BTR
^-1
Byte 5 11111111
^--------TL2
^-------B = ZL
^------Y
^-----A
^----X = ZR
^---TR2
^--LEFT
^-UP
Corrections
Il s'avère que cela correspond aux indications dans les sources de hid-wiimote .. C'est donc ailleurs que se situe le problème. Entre temps je tombe sur les sources du module pour le kernel 3.11, qui sont corrigées lx = payload[0] & 0x3e;
ly = payload[0] & 0x3e;
lx = ly ? Oui, il y a comme un problème.Il y a aussi une double négation sur les touches qui fait qu'elle apparaissent comme pressées en permanence, c'est corrigé aussi.
J'en profite aussi pour modifier les touches du D-Pad pour mapper des boutons au lieu des touches UP/DOWN/LEFT/RIGHT, qui ne sont pas reconnues par retroarch-joyconfig.
Enfin il y a un dernier bug qui est apparu quand j'ai voulu tester l'utilisation avec 2 wiimotes (voir si les leds sont gérées .. la réponse est non), qui nécessite de supprimer l'intégration du report des informations batterie dans le kernel, sinon il tente de créer 2 fois le même périphérique, et alors :
[178790.876742] ------------[ cut here ]------------
[178790.876794] WARNING: at fs/sysfs/dir.c:536 sysfs_add_one+0x88/0xc0()
[178790.876810] sysfs: cannot create duplicate filename '/class/power_supply/wiimote_battery'
[...]
[178790.883777] ---[ end trace 66509376675ee1a0 ]---
[178791.878245] power_supply wiimote_battery: driver failed to report `capacity' property: 4294967291
[178791.878349] wiimote 0005:057E:0306.0015: Cannot register battery device
[178792.882087] wiimote: probe of 0005:057E:0306.0015 failed with error -17
Bref, l'ensemble des modification est visible ici :
https://github.com/Alex131089/raspberrypi-linux/compare/raspberrypi:rpi-3.6.y...rpi-3.6.y-hid-wiimote
Conclusion
Bien que je ne soit pas entré dans le détail, j'ai une petite vue du fonctionnement des Wiimote, et de la gestion au niveau du kernel. Première expérience de cross-compilation aussi, merci au projet RaspberryPi qui a préparé les outils.Ma manette est donc fonctionnelle, il reste à tester en condition réelle, mais les contrôles semblent tous reconnus cette fois. Il reste à créer un script qui pourra scanner une liste de commande (hidd --connect) ou toute commande (hidd --search) pour s'y connecter, qui scannera en permanence, et qui affectera les bonnes leds (p1, p2) aux commandes, à coup de recherche dans /sys/class ^^
Je joins aussi mon fichier de "travail" qui contient moulte liens sur lesquels je suis tombé pendant mes recherches.
2 commentaires:
TL;Dr
In conclusion, you can see all types of cost strategies in a web-based casino. Players could make lightning-fast transactions to and from their on-line casino accounts with cryptocurrency. The anonymity is a bonus as prospects now need to maintain delicate data safe from prying eyes. Sure, Red Dogis the overall most suitable option|best option}, with all 카지노 of their bonus codes and RTG video games, but there’s no sense in lacking out… Why not join two and even three? Sadly, Bitstarz’s banking choices can’t evaluate to the large choice of crypto SuperSlots accepts, but they do fairly properly for themselves regardless.
Enregistrer un commentaire