Born to be wired
749729 visites
Uptime 105 days

Articles taggés avec ‘SVGA’

 Le pixel infernal

 17 novembre 2009  Bricolage, Projet Arcade  3 commentaires
Mince, figlet me dit que je devrais aller me coucher !

Dans l’article précédent, je détaillais mes premières étapes de la transformation d’un vieil ordinateur portable en horloge Pong, à savoir l’installation d’un Damn Small Linux sur le système.

L’étape suivante n’est pas de tout repos, puisqu’il faut maintenant afficher à l’écran les graphismes de mon choix. En l’occurrence, un terrain, deux raquettes carrées, une balle carrée, et un score qui évolue en fonction de l’heure. Mais ne plaçons pas la charrue avant les bœufs, autant commencer doucement, et tenter d’afficher dans un premier temps un modeste pixel.

Car à ce stade, DSL démarre en mode console.

Elle est belle, ma console, elle est belle !

Elle est belle, ma console, elle est belle !

Après un peu de nettoyage dans les scripts de démarrage de DSL, j’obtiens beaucoup moins d’erreurs lors du boot. À terme, mon but est d’avoir un affichage le moins verbeux possible pendant le boot, histoire de donner à la future horloge un petit côté appliance. Comprenez par là que les messages affichés pendant la phase de démarrage sont totalement inutiles aux yeux des non-informaticiens, il sera donc intéressant d’en diminuer le nombre, tout en gardant la possibilité de les afficher moyennant la manipulation appropriée (un paramètre passé au noyau, par exemple). Mais ceci est purement cosmétique et ne constitue pas la priorité n°1.

Nous sommes donc en mode console. Le mode console, c’est une division de l’écran en 80 colonnes et 25 lignes, chaque case située à leur intersection pouvant afficher exactement un caractère, ni plus ni moins. C’est donc fait pour afficher du texte, de manière (quasi) exclusive.

Alors, grâce à des bidouilles comme figlet, déjà utilisé sur mon minitel, il est possible de dessiner avec les caractères de la console, mais on est très loin de maîtriser ce qui sera affiché au pixel près.

Mince, figlet me dit que je devrais aller me coucher !

Mince, figlet me dit que je devrais aller me coucher !

Alors, comment diable afficher un simple pixel sur l’écran ? Linux utilise généralement un serveur X11 pour tout ce qui touche au mode graphique. C’est sur X11 que vient se greffer le gestionnaire de fenêtres qui affiche à l’utilisateur un bureau ergonomique et coloré. Bien que le gestionnaire de fenêtres sur DSL soit extrêmement léger, le pauvre portable avec ses 8 Mo de RAM n’a pas les ressources suffisantes pour en profiter. J’ai quand même fait le test pour rigoler, je peux afficher un bureau (640×480, 16 couleurs) en moins de 3 minutes, le tout étant suivi par une interminable période de swap, pendant laquelle il est inutile d’espérer lancer la moindre commande. En définitive, on abandonne complètement l’idée.

Le bureau, c'est possible, à condition d'avoir le temps...

Le bureau, c’est possible, à condition d’avoir l’éternité devant soi…

Dans mon cas, le salut ne sera pas apporté par X11. Il me faut quelque chose de plus léger pour afficher mon pixel. Quelque chose qui me permette de programmer des applications graphiques sans passer par X11. Quelque chose comme SVGAlib.

Caution - Geek content

Attention, à partir d’ici, ça devient un poil plus technique. Le passage qui va suivre est susceptible de déclencher des nausées, voire des vomissements, chez les non-informaticiens. Je décline toute responsabilité.

SVGAlib est une bibliothèque graphique de bas niveau pour Linux. Tout à fait dans l’esprit de ce dont j’ai besoin. En plus, le site fourmille d’exemples. Je recopie le code permettant d’afficher un simple pixel à l’écran et le compile dans la foulée.

#include <stdlib.h>
#include <vga.h>

int main(void)
{
	vga_init();
	vga_setmode(G320x200x256); // Passe l'écran en résolution 320x200, 256 couleurs
	vga_setcolor(4); // On sélectionne la couleur rouge
	vga_drawpixel(10, 10); // On dessine le fameux pixel

	sleep(5); // On attend 5 secondes...
	vga_setmode(TEXT); // On repasse en mode console

	return EXIT_SUCCESS; // Et on sort fièrement dans la bonne humeur
}

À ce stade, transférer le programme compilé pour le tester sur le portable est une activité relativement chronophage. Rappelez-vous : pas de lecteur CD, pas de carte réseau.

Je décide donc d’installer une copie de DSL dans une machine virtuelle (qui elle est équipée d’une carte réseau virtuelle) et sur laquelle je peux transférer mes versions compilées à grands coups de netcat.

Bien que la compilation (en environnement Debian) se passe sans trop de problèmes bloquants, la première exécution du programme dans la machine virtuelle ne se termine pas par un franc succès. Les libs SVGA sont absentes par défaut dans DSL. Qui pourrait en faire un reproche, s’agissant d’une distrib allégée ?

À tout hasard, je choisis de copier les libs de ma Debian dans DSL. Cette solution barbare fait lamentablement planter le programme avec pour toute sortie la célèbre Segmentation Fault. Je ne saurais pas expliquer exactement pourquoi, il existe de nombreuses raisons pour que cette opération ne fonctionne pas. Les libs ne sont pas optimisées pour 486, elles ne sont pas compilées pour fonctionner sur un noyau 2.4, elles sont compilées avec des options propres à Debian, etc… Un coup dans l’eau.

À cet instant, je suis confronté au moment d’angoisse que tout développeur a connu, quand il sait que toutes les solutions simples n’ont pas fonctionné, et qu’il va falloir sortir l’artillerie lourde sans savoir dans quelle direction tirer. J’en profite pour remercier tipeon, qui a toujours de bonnes idées lorsque je lance des appels à l’aide à la cantonade sur les forums ;)

Je commence à envisager de cross-compiler ces libs moi-même, quand, au détour d’une recherche sur le net, entre deux sites pornographiques, je découvre sur cette page un visualiseur d’images utilisant SVGAlib et porté sur DSL : ZGV. Les libs étant comprises dans l’archive, je les déploie sur ma machine virtuelle, relance mon programme, et constate avec le plus grand bonheur un écran vierge, à l’exception d’un petit pixel rouge en haut à gauche de l’écran. Bingo ! :)

C’est un petit pixel pour le geek, mais un bitmap géant pour la communauté.

À partir de ce moment, le concept est démontré, il est donc possible d’utiliser SVGAlib pour afficher de manière instantanée à peu près n’importe quel graphisme sur commande à partir de la console. La preuve avec ce second exemple qui sera plus parlant qu’un bête pixel rouge :

Un joli dégradé de bleu, merci SVGAlib !

Un joli dégradé de bleu, merci SVGAlib !

Voila qui termine la partie qui à mon sens pouvait poser le plus de difficultés. Le reste, bien que pas forcément évident au premier abord, pourra se résumer à un peu de programmation et un peu de bon sens. Mais je ne manquerai pas de le détailler.

À bientôt pour la suite des aventures du laptop qui ne voulait pas mourir ;)