Le mode 13h |
Avant toute chose, je tiens à signaler ceci : J'ai découvert la programmation graphique il y a seulement quelques mois. Cette rubrique n'est donc pas un magnifique cours sur la programmation graphique, mais plutôt le fruit de mes recherches personnelles (waaah...). Inutile donc d'espérer apprendre l'élaboration d'objets 3D avec modulation de texture, filtrage trilinéaire et Z-buffering le tout utilisant les derniers drivers OpenGL pour 3DFX Voodoo3 !!! Je m'arrêterai donc là où s'arrêtent mes connaissances (c à d pas très loin...)
A) Introduction Le mode 13h est le mode graphique qui présente le meilleur rapport performances / simplicité. Sa résolution de 320 x 200 en 256 couleurs, sa mémoire linéaire, sa vitesse appréciable et sa simplicité en font un mode graphique intéressant pour débuter la programmation graphique.
B) Détecter une carte VGA Je crois que le mode 13h est disponible sur toutes les cartes video VGA. De nos jours toutes les cartes video supportent le VGA (waah... trop cool !!) mais il est tout de même plus raisonnable de vérifier la présence d'une carte VGA avant d'initialiser un mode graphique. Cela se fait grâce à la fonction 1Ah de l'interruption 10h (entrées/sorties video). Cette fonction nécessite la valeur 1Ah dans AH et 0 dans AL (1A00h dans AX quoi !). Elle renvoie 1Ah dans AL si une carte supportant le VGA est présente. Ce qui donne en ASM : mov AX, 1A00h ou en C : int detect_VGA ()
C) Initialiser le mode 13h Une fois la carte détectée, on peut passer à l'initialisation. Pour cela, on utilise la fonction 0 de l'interruption 10h avec la valeur 13h dans AL. Ce qui donne en ASM (préférable) : mov AX, 0013h ou en C : void init_13h ()
D) Fermer le mode 13h Avant la fin de votre programme, la fermeture du mode graphique est indispensable. Cette opération est similaire à l'initialisation, sauf qu'au lieu de spécifier 13h dans AL, on place 03 dans AL car 03 est le mode texte standard.
E) Afficher un point à l'écran Avant toute chose, il est indispensable de connaître la disposition de la mémoire video en mode 13h. Elle débute à l'adresse A000:0000 et prend fin en A000:FA00. Un bref calcul mental vous indique qu'elle s'étend donc sur 64000 bytes. Chaque pixel de l'écran est sauvegardé en mémoire video dans 1 byte (256 couleurs). Avec une résolution de 320x200, il est donc logique d'avoir une mémoire de 64000 bytes !! Cette mémoire est dite linéaire, c à d : si on la représente comme un vecteur (ce qu'elle est !!), toutes les lignes de l'écran sont disposées séquentiellement, en partant de la première et en finissant par la 200eme. Mais alors, tout s'éclaircit !! Le calcul de l'offset d'un pixel dont les coordonnées sont X,Y se fait via la formule : offset = 320 * Y + X (Quoi !! Encore une formule à étudier !! Moi qui pensait pouvoir m'amuser...) Entre-nous, elle n'est pas mortelle... Bref, pour afficher un point à l'écran en C (exemple : point rouge en X=10, Y=50) unsigned offset; Remarque : La fonction pokeb place un byte à une
adresse logique précise. Sa syntaxe est pokeb(unsigned segment, unsigned offset, char
byte); Encore une remarque : Vous avez compris que l'utilisation d'un entier non signé est ici préférable. En effet, un entier signé (int) n'utilise que 15 bits, à cause du bit signe, ce qui implique une limite maximum de 32767. C'est un peu juste pour placer des nombres qui peuvent atteindre 64000... Moralité : utilisez votre bit (signe) intelligemment... L'affichage du même point en ASM donne : ;------- initialisation du segment de
mémoire video dans ES Cet algorithme nécessite tout de même une petite
explication. Pour ne pas utiliser une multiplication (mul) TOUJOURS TROP gourmande en
ressources (plus de 100 cycles machines !), j'ai préféré utiliser 2 shifts (décalages
de bits). Un shift de 8 bits vers la gauche correspond à une multiplication par 2^8 soit
256. L'addition avec un deuxième shift de 6 bits vers la gauche (2^6 = 64) permet
d'obtenir une multiplication par 320, pour un coût avoisinant les 75 cycles machines.
F) Un petit exercice Il est désormais temps de mettre vos connaissances en pratique. Attardons-nous à la mise au point d'un petit programme en C qui afficherait un objet se déplaçant le long de l'écran. Ma version est disponible ici. L'objet en question serait déclaré en mémoire sous forme d'une bit-map (zone de points) de la manière suivante : char
alien[9][14]={{0,0,0,0,0,4,4,4,4,0,0,0,0,0}, concrètement, ça ressemble à ça :
<EOK> * * (End Of Knowledges)
|
| Si vous éprouvez
une difficulté quelconque, si vous avez repéré une erreur dans un programme, si vous
avez une idée à proposer ou une suggestion à faire, n'hésitez pas à me contacter !!!
(ici : <SpiX>)
|
© Copyright Benjamin Fonzé 1999/2000