Une Borne d'Arcade maison -40-
Par makoto doushite le mardi, 18 juin 2013, 21:30 - Arcade - Lien permanent
Suite de l'étude précédente :
Édit du 1 Mars 2020 : Méthode mise à jour ici
AdvanceMame en vrai 15 kHz !
Ce billet s'annonce long et d'apparence complexe à décrypter, mais n'ayez crainte, je vais m'efforcer d'être le plus clair possible.
Il vient en complément du précédent, afin de peaufiner les réglages de la borne, pour un affichage « Pixels Perfect » !
- Il y a quelques temps, suite à la découverte du projet GroovyMame, je me suis re-penché sur le fonctionnement de l'émulateur en 15 kHz.
Après beaucoup de nouvelles expérimentations et de temps à comprendre le fonctionnement des choses, j'ai enfin compris pourquoi je ne parvenais pas à faire fonctionner correctement le mode Frame Buffer d'Advancemame et pourquoi les faibles résolutions ne passaient pas sur l'écran TV.
Je vais donc revenir sur mes précédents articles afin de pointer les bêtises que j'y ai dites et d'y apporter des explications et solutions concrètes.
Pour info, le fichier advmame.rc distribubé dans le TUTO informatique était réglé sur
device_video_output auto device_video_overlaysize auto
Mais je me suis rendu compte qu'en guise « d'auto mode », Advancemame utilisait en fait le mode overlay à la taille du seul modelines disponible :
device_video_output overlay device_video_overlaysize 768
L'image est malgré tout très agréable et se révèle être un simple compromis pour celui qui n'a pas envie de se palucher tous les modelines, sauf que la spécificité d'Advancemame perd tout son sens…
J'écrirais donc peut-être un nouveau Pack d'installation facile plus tard.
État des lieux :
En effet, dans le billet Une Borne d'Arcade maison -4-, je concluais comme ceci :
on se rends compte que le TV ne supporte pas des valeurs de pclock basses […] le TV n'est capable de fonctionner que dans sa résolution native, avec un pixel clock élevé (15 à 17MHz)-- […] à moins d'avoir un téléviseur qui accepte un faible pclock (testé 2 télé, résultats idem), je ne vois pas comment exploiter correctement le mode Frame Buffer d'AdvanceMame sur un TV !!
FAUX, un téléviseur sait très bien exploiter un signal de faible pclock, par exemple, puisqu'une Super Nintendo a toujours su afficher une image de faible résolution.
- Tout ça en fait est la faute aux pilotes libres ATI et nVidia qui ont vu leurs capacités à fournir des petites résolutions supprimées de linux, ce afin de protéger les écrans informatiques actuels d'une mauvaise manipulation d'un administrateur peu averti.
Comment faire alors ?
Une première piste :
- Sans la voir, j'avais une partie de l'explication sous les yeux, dans la documentation d'installation indiquant la disponibilité de patchs frame buffer dans les fichiers sources d'Advancemame ( dossier contrib/mame/fb).
Ces patchs de pilotes vidéo servent en fait à faire sauter cette « sécurité », autorisant alors l'utilisation de faible pclock !
Super ! bah voilà, yaka patcher >_<;
Oui mais quoi ? Pas vraiment expliqué, on découvre qu'il s'agit de patch pour linux…
Okééé, ça veut dire compilation de noyaux… chouette… Y'a pas un module dispo dés fois ? Arf, bah non -_-.
Bon, alors allons-y, patchons !
- Sauf que les patchs proposés sont valables pour des vielles versions de linux, et après avoir ressortit un vieux noyaux chez kernel.org (linux-2.4.22), l'avoir patché avec succès (linux-2.4.22-radeonfb-id.diff et linux-2.4.22-rivafb-0.9.4c.diff) la compilation n'a pas aboutit, sans doute due à une mauvaise configuration dans la phase menuconfig que je ne maîtrise pas suffisamment.
Une seconde piste :
- Amèrement, je laissais cette défaite derrière moi en re-découvrant, la possibilité d'utiliser SVGAlib pour faire à peu de choses près la même chose qu'avec frame buffer; Ici pas besoin de compiler linux, juste installer SVGAlib et de me souvenir que déjà à l'époque, je n'étais pas parvenu à compiler SVGAlib dans la version 1.9.14 recommandée.
En effet la compilation plante lamentablement.
J'ai alors essayé les autres versions, en les patchant à chaque fois (patch dispo dans les fichiers sources, contrib/mame/svgalib), mais sans succès, compilation impossible.
Des pistes de recherches me firent entrevoir que vu la vétusté du truc, les compilateurs actuels n'étaient peut-être par capable de le compiler.
Et donc de me mettre en quête d'installer un OS avec une vieille version de GCC, mais toujours sans résultat T_T.
- Il fallait que je me fasse une raison, tous ces softs et les patchs disponibles sont trop vieux pour être exploités.
L'ultime solution envisageable restant alors de me fabriquer ma propre distribution grâce à Linux From Scratch… Projet très intéressant, mais… STOP ! Ça va trop loin là, au départ je voulais juste une fonction toute simple ;
La troisième, c'est la bonne !
- Et c'est là qu'intervient le projet GroovyMame !
Celui-ci propose une distribution iso contenant un linux déjà patché 15kHz et le logiciel GroovyMame, qui sans que les modelines de chaque résolutions n'aient besoins d'être listées dans xorg, bascule dans la résolution de chaque jeux :
1 - Lancement du jeu.
2 - Détection de la résolution du jeu par Switchres.
3 - Génération/sélection du modelines par Switchres, envoyée à Xrandr, (le plus proche possible de l'original, mais dés fois bien à l'ouest)
4 - Xrandr sélectionne cette résolution et y bascule l'affichage de Xorg.
- La solution était là, c'est ce noyaux qu'il me fallait.…
Sauf que le site du projet à déménagé 3 fois depuis un sourceforge vers un google code, puis vers un homonyme sans tiret dans l'url, que le dépot GIT ne fonctionne pas… Grrrrr !! Maiiis Heu!!!
Bref, j'ai tout de même réussit à récupérer une vieille version des sources et à tester aussi le binaire de GroovyMame, mais rien pour patcher le noyaux…
Ce n'est qu'en fouillant le forum Arcade Control que j'ai fini par trouver un développeur du projet qui en a posté quelques versions !
Compilation de Linux patché @15kHz :[1]
- Je vais donc décrire comment j'ai généré ce noyau, mais avant d'aller plus loin, je pense à ceux que la compilation de noyau rebute, ou pour qui le tuto se passerait mal (interruption inexpliquée de la compilation…) et propose de télécharger le linux patché 15kHz que j'ai compilé, prêt à être installé en quelques secondes sur « toutes distributions » de la grande famille Debian (Ubuntu, Mint, etc)… Je n'en ai testé que deux ( Debian Wheezy et sur Ubuntu 10.04LTS), mais ça devrait passer ailleurs…
linux-image-3.2.32-patched15khz_i386.deb
linux-image-3.9.6-patched15khz_i386.deb
Pour l'installer, suffit d'utiliser dpkg avec les droits root ou via un sudo :
dpkg -i linux-image-3.2.32-patched15khz_i386.deb
Bien ! Passons aux choses sérieuses !
- Préambule, rappel des faits :
Il est en fait, nous l'avions vu, déjà possible d'afficher une image en 15 kHz sur un téléviseur grâce à Xorg configuré à l'ancienne avec le fichier xorg.conf, avec xrandr, ou maintenant avec KMS.
Il suffit pour cela de passer un modeline au pilote libre ATI (radeon) ou nVidia (nouveau).
Voici un exemple de fichier xorg.conf qui fonctionne à tous les coups :
Section "Device" Identifier "ATI" Driver "radeon" EndSection Section "Monitor" Identifier "TV" HorizSync 15.0 - 20.0 VertRefresh 50.0 - 60.0 # Le modeline TV @15kHz Modeline "768x288x50.08" 15.375000 768 792 880 964 288 288 288 322 -HSync -VSync EndSection Section "Screen" Identifier "Default Screen" Device "ATI" Monitor "TV" DefaultDepth 24 SubSection "Display" Depth 24 Modes "768x288x50.08" EndSubSection EndSection
Donc avec ceci, on affiche une image progressive de 768x288 avec un PixelClock de 15.375 MHz.
Pour afficher une image plus petite, le PixelClock sera donc plus petit, de l'ordre de 6 ou 7 MHz…
Et bien comme je l'évoquais, tests à l'appui, force est de constater que les pilotes libres contenus dans Linux ne sont pas capables de gérer un faible PixelClock !
Impossible donc d'afficher une image à 320x240.
L'équipe de GroovyMame fournit des patchs pour modifier les sources de n'importe quel Linux qu'il faut ensuite compiler et installer sur sa distribution préférée.
Les voici rassemblés ici par mes soins : http://makotoworkshop.org/sources/patch15khz/
- I - Prérequis
Dans cet exemple, nous allons compiler un Linux sur Debian Wheezy, qui tourne pour le moment avec un kernel 3.2.
Notes : Contrairement à mon habitude, je vais indiquer les chemins donnés par le terminal, histoire de pouvoir bien suivre le processus, donc :
- Le caractère # signifie qu'on est logué en root où que les droits root sont nécessaires (sudo).
- Le caractère $ signifie qu'on est logué en utilisateur.
- Le caratère ~ signifie que le chemin actuel se trouve dans le dossier de l'utilisateur (/home/votre_utilisateur, ou /root).
I–1 - Installer les programmes nécessaires à la compilation :
~# apt-get install build-essential kernel-package debconf-utils dpkg-dev debhelper ncurses-dev fakeroot zlib1g-dev
I–2 - Préparation et récupération des sources :
Aller dans son répertoire personnel et créer le répertoire de travail :
~$ cd ~/ ~$ mkdir src
I–3 - Obtenir les sources à partir des dépôts :
Pour connaître les sources disponibles pour votre système :
~$ aptitude search linux-source
Renverra quelque chose du genre :
v linux-source - Linux kernel source (meta-package) p linux-source-2.6 - Linux kernel source (dummy package) p linux-source-3.2 - Linux kernel source for version 3.2 with Debian patches
Pour obtenir les sources, il suffit d'installer le paquet et de déplacer les données :
~$ su - mot de passe : ~# apt-get install linux-source-3.2 ~# cp /usr/src/linux-source-3.2.tar.bz2 /home/votre_user/src ~# chown votre_user:votre_user /home/votre_user/src/linux-source-3.2.tar.bz2
I–4 - On travaille avec un utilisateur :
Une fois les paquets installés il va falloir décompresser les sources de votre futur noyau. Il est conseillé de déléguer les tâches de configuration du noyau à un utilisateur. Pour cela, l'utilisateur doit appartenir au groupe src.
Pour ajouter par exemple l'utilisateur makoto au groupe src :
~# adduser makoto src Adding user `makoto' to group `src' ... Adding user makoto to group src Done. ~# exit
I–5 - Se placer dans votre répertoire ~/src et décompresser les sources :
~$ cd src/ ~/src$ tar xvjf linux-source-3.2.tar.bz2
I–6 - Le chemin vers les sources :
On ajoute enfin les liens symboliques linux qui pointent vers le répertoire de vos sources. Ainsi suivant la version de nos sources on sait qu'elles se trouveront toujours dans le répertoire ~/src/linux :
Remarque: Il est possible que le lien symbolique existe déjà, auquel cas il faudra l'effacer...
~/src$ su - mot de passe : ~# cd /usr/src/ /usr/src# ln -s /home/votre_user/src/linux-source-3.2 linux /usr/src# exit ~/src$ ln -s ~/src/linux-source-3.2 linux
- II - Patcher les sources
II–1 - Récupération des patchs :
Se rendre dans votre home et télécharger puis extraire le TarGz de patch correspondant à votre noyau, ici le fichier patch-3.2.tar.gz pour le noyau 3.2.
~/src$ cd ~/ ~$ wget makotoworkshop.org/sources/patch15khz/patch-3.2.tar.gz ~$ tar xvf patch-3.2.tar.gz
II–2 - Tester les patchs :
Se rendre dans le dossier linux
~$ cd src/linux
Lancer successivement ces 3 commandes pour tester chaque patchs sur les sources sans l'appliquer:
~/src/linux$ patch -p1 --dry-run < ~/patch-3.2/ati9200_pllfix-3.4.diff ~/src/linux$ patch -p1 --dry-run < ~/patch-3.2/avga3000-3.4.diff ~/src/linux$ patch -p1 --dry-run < ~/patch-3.2/linux-3.4.diff
Aucune erreur ne doit être retournée.
II–3 - Application des patchs :
Patcher les sources successivement avec ces 3 commandes :
~/src/linux$ patch -p1 < ~/patch-3.2/ati9200_pllfix-3.4.diff ~/src/linux$ patch -p1 < ~/patch-3.2/avga3000-3.4.diff ~/src/linux$ patch -p1 < ~/patch-3.2/linux-3.4.diff
- III - Configuration du noyau
Récupérer la configuration du noyau :
~/src/linux$ cp -vi /boot/config-`uname -r` .config
Mettre à jour la configuration.
~/src/linux$ make oldconfig
Puisqu'on compile la même version que le noyau actuel, la commande ne doit constater aucune différence, et donc ne poser aucune question.
- IV - La compilation
Nettoyage avant compilation :
~/src/linux$ make-kpkg clean
La commande fakeroot permet de simuler l'environnement root au programme make-kpkg pour que ce dernier puisse générer les paquets de votre futur noyau. Cela a l'avantage d'éviter de faire la compilation en tant que root.
La compilation sur une machine puissante dure à peine 30 minutes. Cela peut dépasser plusieurs heures en fonction de votre configuration.[2]
~/src/linux$ fakeroot make-kpkg \--initrd \--append-to-version "-pached15khz" kernel-image kernel-headers
La commande ci-dessus vous sortira un paquet nommé "linux-image-3.2-patched15khz3.2-patched15khz-10.00.Customi386.deb"
- V - Installation du noyau
~/src/linux$ su - mot de passe : ~# cd /home/votre_user/src/ /home/votre_user/src# dpkg -i linux-image-3.2-patched15khz_3.2-patched15khz-10.00.Custom_i386.deb
- VI - Test du noyau
Redémarrer l'ordinateur sur ce noyau fraîchement installé. Si tout va bien le démarrage se passera sans encombre, sinon en cas de Kernel Panic, voir VII…
VI–1 - Pour tester le noyau avec xorg.conf :
- Modifier ou créer le fichier :
~# nano /etc/X11/xorg.conf
Et remplacer le modeline par celui-ci, en 320x240. (testé compatible ATI Radeon 9000 et 9200 et nVdia TNT2 Model 64 et Elsa Erazor X)
Section "Device" Identifier "ATI" Driver "radeon" EndSection Section "Monitor" Identifier "TV" HorizSync 15.0 - 20.0 VertRefresh 50.0 - 60.0 # Le modeline TV @15kHz Modeline "320x240" 6.452 320 344 376 408 240 242 245 264 -HSync -VSync EndSection Section "Screen" Identifier "Default Screen" Device "ATI" Monitor "TV" DefaultDepth 24 SubSection "Display" Depth 24 Modes "320x240" EndSubSection EndSection
Pour une carte nVidia, remplacer simplement :
Driver "radeon"
par
Driver "nouveau"
- Démarrer X :
$ startx
Enjoy !!!
VI–2 - Pour tester le noyau avec Xrandr, sans fichier xorg.conf :
Oui, ce fichier n'est plus nécessaire de nos jours. Son absence n'empêchera par X de démarrer.
Démarrer X :
$ startx
- Xrandr permet de changer de la résolution d'X par une simple commande.
Elle permet aussi d'ajouter des modelines en plus; Taper :
$ xrandr
Et apparaît alors la liste des résolutions disponibles, donc en 31kHz !
Une astérisque repère la résolution en cour…
- Pour ajouter le modeline d'exemple, taper ceci :
$ xrandr --newmode "320x240" 6.452 320 344 376 408 240 242 245 264 -hsync -vsync
- Taper à nouveau xrandr permet de voir que le mode a été créé, mais il n'est pas encore utilisable en l'état !
320x240 (0x1da) 6.0MHz h: width 320 start 344 end 376 total 408 skew 0 clock 14.7KHz v: height 240 start 242 end 245 total 264 clock 55.7Hz
- En effet, il faut l'associer à une sortie de la carte graphique (selon la carte, VGA-0 ou DVI-0 avec ATI)
$ xrandr --addmode DVI-0 "320x240"
Un nouveau xrandr listera maintenant la résolution disponible.
- Reste donc à basculer dessus avec :
$ xrandr \--output DVI-0 \--mode "320x240"
L'affichage bascule en 320x240, débrancher vite l'écran VGA et connecter le téléviseur sur la carte graphique…
Enjoy !!!
- Il est bien sûr possible d'automatiser un peu cela avec un script bash, histoire de ne pas avoir à se repalucher les lignes de commande !
Genre comme ça :
#!/bin/bash xrandr --newmode "256x264" 5.356 256 272 296 328 264 265 268 278 -hsync -vsync xrandr --newmode "304x240" 6.208 304 328 360 392 240 243 246 264 -hsync -vsync xrandr --newmode "320x240" 6.452 320 344 376 408 240 242 245 264 -hsync -vsync xrandr --newmode "384x288" 7.851 384 408 448 496 288 289 292 309 -hsync -vsync xrandr --newmode "640x288" 13.125 640 680 744 832 288 289 292 309 -hsync -vsync xrandr --addmode DVI-0 "256x264" xrandr --addmode DVI-0 "304x240" xrandr --addmode DVI-0 "320x240" xrandr --addmode DVI-0 "384x288" xrandr --addmode DVI-0 "640x288"
Voilà, nous en avons terminé !
Utiliser Advancemame avec Xorg en 15kHz :
Vous êtes encore là ??
Bien, alors on en arrive au but de la manœuvre _
- Tout comme le récent Groovymame, Advancemame est capable de générer « à la volée » le modeline correspondant à la résolution d'un jeu en lisant la config dans la rom de ce jeu, puis de basculer l'affichage dans cette résolution.
Mais ça, c'eut été vrai en utilisant la méthode d'affichage en frame buffer ou SVGAlib.
Avec Xorg, on est obligé d'utiliser la méthode d'affichage SDL qui n'est pas capable de cela.
- Néanmoins, il est possible de renseigner la Section Monitor du fichier Xorg.conf avec tous les modelines dont on a besoin, et de configurer AdvanceMame afin qu'il les exploite à bon escient :
Section "Monitor" Identifier "TV" HorizSync 15.0 - 20.0 VertRefresh 50.0 - 60.0 # Les modelines TV @15kHz Modeline "256x264" 5.356 256 272 296 328 264 265 268 278 -HSync -VSync Modeline "304x240" 6.208 304 328 360 392 240 243 246 264 -HSync -VSync Modeline "320x240" 6.452 320 344 376 408 240 242 245 264 -HSync -VSync Modeline "384x288" 7.851 384 408 448 496 288 289 292 309 -HSync -VSync Modeline "640x288" 13.125 640 680 744 832 288 289 292 309 -HSync -VSync EndSection
- Pour utiliser ces modelines inscrit dans xorg.conf, le fichier ~/.advance/advmame.rc devra donc contenir les options suivantes :[3]
device_video sdl device_video_output fullscreen device_video_overlaysize auto display_resize none display_resizeeffect none
- Maintenant après avoir lancé un jeu, il suffit de faire apparaître le menu (Tab), d'aller dans la section video, d'entrer dans la sous section mode et de choisir le modeline correspondant à la résolution indiquée par le carton qui s'est affiché au lancement du jeu.
L'affichage va basculer dans ce mode…
Puis sortir de cette section et aller en bas sur Save for this game size/freq, qui aura pour effet de sauvegarder ce réglage dans le fichier advmame.rc !
- C'est fait, on utilise à présent les résolutions natives de chaque jeux _
Note importante :
Pour utiliser l'émulateur sous Debian, il faut, après avoir activé les dépots « non-free », ajouter le paquet « firmware-linux-nonfree » qui contient des bouts de drivers non libre, permettant donc d'activer le Direct Rendering, ceci pour résoudre des problèmes de cisaillement dans l'image (tearing), en plus d'un crénelage excessif.
Ce problème n'apparaît pas avec Ubuntu, car le paquet non-libre « linux-firmware » est installé par défaut…[4]
- VII - Désinstallation :
Si pour une raison ou une autre vous n'arrivez pas à démarrer sur votre nouveau noyau et que vous souhaitiez le désinstaller. Redémarrez sur le dernier noyau opérationnel, puis :
~$ su - mot de passe : ~# apt-get remove --purge linux-image-3.2-patched15khz_3.2-patched15khz-10.00.Custom_i386.deb
À suivre…
Ressources :
http://advancemame.sourceforge.net/doc.html
http://www.isalo.org/wiki.debian-fr/index.php?title=Compiler_et_patcher_son_noyau
easymamecab.mameworld.info/html/svgalib.htm
Notes
[1] - Quand je dis «Linux» je parle bien entendu du noyau (kernel) et non de la distribution GNU/Linux (debian, Ubuntu, RedHat…)
[2] Astuce : Il peut alors être utile d'utiliser VirtualBox pour compiler le noyau sur un PC puissant, puis de récupérer le paquet compilé pour aller l'installer sur sa vieille machine de récup destinée à la borne.
[3] Ces options sont décrites dans la documentation dispo avec les sources, ou en ligne : http://advancemame.sourceforge.net/doc-advdev.html#4 et http://advancemame.sourceforge.net/doc-advmame.html#8.3
[4] Pourquoi Ubuntu contient déjà ces morceaux de code ? Peut-être parce que la distribution n'est pas si libre qu'elle en à l'air, mais c'est pour faciliter la vie parait-il… En attendant ça m'a fait perdre beaucoup de temps dans ma quête de la compréhension du système -_-
Commentaires
Bonjour et merci pour cet excellent tutorial.
Je viens de patcher une install en 15khz grâce à vous.
Le seul moment où j'ai galérer et de définir le kernel par defaut au démarrage
GRUB_DEFAULT="Previous Linux versions>Ubuntu, avec Linux 3.2.76-patched15khz"