Programmation graphiques
La génération de graphiques d'ordinateur est l'une des applications de programmation les plus impressionnantes et les plus importantes. Le QuickPascal fournit une excellente prise en charge graphique avec plus de 80 sous-programmes qui vous permettent de peindre l'écran presque comme vous le souhaitez. Les limitations, le cas échéant, sont presque toujours dues à des contraintes du matériel plutôt que du paquet QuickPascal lui-même.
Adaptateurs graphiques
Bien que l'écran texte soit souvent la porte d'entrée pour afficher des messages et des caractères à l'écran avec 40 ou 80 colonnes à 25 lignes, le QuickPascal offre beaucoup plus de possibilité que cela. Si vous examinez l'un de ces caractères, vous découvrirez que l'image est en fait formée d'un motif rectangulaire de l'image est en fait formée d'un motif rectangulaire de points au lieu de lignes lisses. Chacun de ces points est appelé élément d'image ou, plus simplement, pixel. Chaque caractère ASCII s'affiche sur votre écran sous la forme d'un bloc de 126 pixels, disposés de 8 ou 9 pixels sur 8, 14 ou 16 pixels de haut.
En mode texte, vous n'avez qu'à spécifier un caractère et ses attributs; l'affichage physique du caractère à l'écran est la tâche d'un matériel spécial à l'intérieur d'un compatible IBM PC. Cependant, en mode graphique, vous devez contrôler chaque pixel individuellement. Même si vous n'avez qu'un écran monochrome, vous avez maintenant besoin d'un seul bit pour spécifier le réglage (activé ou désactivé) de chaque pixel. Si vous avez une carte CGA avec quatre couleurs, vous avez besoin de 2 bits pour chaque pixel. De même, si votre compatible IBM PC possède une carte vidéo VGA avec 256 couleurs, chaque pixel est contrôlé par 8 bits.
La résolution d'un écran est une mesure du nombre de pixels qu'il contient. Comme les photos de fils de journaux, les images graphiques sur votre moniteur sont composées de points. Vous pouvez augmenter la clarté d'une image en augmentant le nombre de points qu'elle contient ; cependant, ce faisant, vous augmentez vos besoins en mémoire. Souvent, vous devez choisir entre augmenter la résolution ou augmenter le nombre de couleurs disponibles. Si vous doublez le nombre de bits référençant un seul pixel, vous doublez le nombre de couleurs que le bit peut afficher mais vous diminuez également la résolution de l'écran de moitié.
Chaque compatible IBM PC repose sur un équipement spécial, appelé adaptateur graphique, pour entreposer les images graphiques sous forme de bits, puis afficher ces images à l'écran. Voici les adaptateurs graphiques pris en charge par QuickPascal, ainsi que les constantes prédéfinies définies pour eux dans l'unité MSGraph :
Constante prédéfinie | Valeur | Adaptateur |
---|---|---|
_MDPA | $01 | Monochrome Display Printer Adapter |
_CGA | $02 | Color Graphics Adapter |
_EGA | $04 | Enhanced Graphics Adapter |
_VGA | $08 | Video Graphics Array |
_MCGA | $10 | MultiColor Graphics Array |
_HGC | $20 | Hercules Graphics Card |
_OCGA | $42 | Olivetti Color Graphiccs Adapter |
_OEGA | $44 | Olivetti Enhanced Graphics Adapter |
_OVGA | $48 | Olivetti Video Graphics Array |
L'adaptateur graphique couleur (CGA) est la série de cartes adaptatrices la plus couramment utilisée. Il offre une excellente résolution mais est limité dans le nombre de couleurs qu'il peut afficher. La série Enhanced Graphics Adapter (EGA) offre toutes les capacités de la série CGA, ainsi qu'une résolution plus élevée et quatre fois le nombre de couleurs. La série Video Graphics Array (VGA) prend en charge toutes les options des cartes CGA et EGA, ajoute une résolution encore plus élevée et augmente le nombre de couleurs disponibles par un autre facteur de quatre.
Le QuickPascal identifiera automatiquement quelle carte adaptatrice est installée sur votre compatible IBM PC et chargera tous les logiciels nécessaires pour la prendre en charge. La seule exception se produit si votre compatiable IBM PC est équipé de l'adaptateur graphique Hercules. Dans ce cas, vous devrez exécuter le pilote de périphérique MSHERC.COM avant de commencer tout programme graphique QuickPascal. Étant donné que MSHERC.COM est résident en mémoire, vous souhaiterez peut-être simplifier les choses en l'ajoutant à votre fichier AUTOEXEC.BAT.
Réglage du mode graphique
Il ne suffit pas d'inclure l'unité MSGraph dans votre programme pour commencer une session graphique. Le QuickPascal suppose toujours que le mode par défaut est le texte, pas les graphiques. Vous devrez sélectionner et entrer un mode graphique approprié avant de pouvoir appeler des routines graphiques.
Dans l'unité CRT, on utilise la procédure TextMode pour changer le mode actuel, dans les programmes graphiques, vous sélectionnez un mode graphique en appelant la fonction _SetVideoMode. Le mode d'une carte graphique spécifie la résolution de l'écran et le nombre de couleurs qu'il peut afficher.
La fonction _SetVideoMode garde une trace du mode vidéo d'origine, ce qui signifie que vous pouvez utiliser le paramètre _DefaultMode pour restaurer ce mode. De même, _SetVideoMode peut déterminer automatiquement les paramètres optimaux pour le nombre maximum de pixels ou pour le nombre maximum de couleurs.
La fonction _SetVideoMode a également une valeur de retour. S'il réussit à définir le mode demandé, il renvoie le nombre de lignes de texte. Si la fonction échoue, elle renvoie un 0. Voici les paramètres que vous pouvez utiliser avec _SetVideoMode lorsque vous souhaitez que QuickPascal détermine la configuration de votre compatible IBM PC et identifie un mode approprié :
Constante prédéfinie | Description |
---|---|
_MaxResMode | Définit la résolution la plus élevée en mode graphique. |
_MaxColorMode | Définit le mode graphique avec le plus de couleurs. |
_DefaultMode | Restaure l'écran à son mode d'origine. |
Si vous avez un adaptateur CGA installé sur votre compatible IBM PC, vous pouvez éventuellement demander l'un de ces modes :
Constante prédéfinie | Résolution | Couleurs |
---|---|---|
_MRes4Color | 320x200 pixels | 4 couleurs |
_MResNoColor | 320x200 pixels | 4 nuance de gris |
_HResBW | 640x200 pixels | 2 couleurs (Noir et blanc) |
Si votre système est configuré avec un adaptateur EGA, vous pouvez utiliser n'importe quel mode pouvant être géré par un CGA, ou l'un des modes suivants :
Constante prédéfinie | Résolution | Couleurs |
---|---|---|
_MRes16Color | 320x200 pixels | 16 couleurs |
_HRes16Color | 640x200 pixels | 16 couleurs |
_EResColor | 640x350 pixels | 4 ou 16 couleurs |
_EResNoColor | 640x350 pixels | 2 couleurs (Noir et blanc) |
Le nombre réel de couleurs disponibles en mode _EResColor dépend de la quantité de mémoire de votre carte vidéo EGA. Un système VGA prend en charge tous les modes CGA et EGA, ainsi que l'un des suivants :
Constante prédéfinie | Résolution | Couleurs |
---|---|---|
_MRes256Color | 320x200 pixels | 256 couleurs |
_VRes16Color | 640x480 pixels | 16 couleurs |
_VRes2Color | 640x480 pixels | 2 couleurs |
Enfin, vous pouvez utiliser les constantes suivantes si votre compatible IBM PC est configuré avec une carte Hercules, ou si votre compatible IBM PC a été fabriqué par Olivetti ou AT&T :
Constante prédéfinie | Résolution | Couleurs | Adaptateur |
---|---|---|---|
_HercMono | 720x348 pixels | 2 couleurs | Hercules |
_OResColor | 640x400 pixels | 1 de 16 | Olivetti/AT&T |
Les adaptateurs graphiques Olivetti (_OCGA, _OEGA ou _OVGA) sont en fait compatibles avec les adaptateurs _CGA, _EGA ou _VGA correspondants; cependant, ils prennent en charge le mode haute résolution supplémentaire _OResColor.
Initiation et terminaison des graphiques
Chaque programme graphique que vous écrivez devra passer en mode graphique pour accomplir ses tâches, puis revenir au mode texte par défaut une fois terminé. Parce que vous effectuerez ces actions si souvent, cela simplifiera considérablement les choses pour développer des routines d'initialisation et de terminaison graphiques distinctes.
Le programme GrSetup suivant montre comment procéder. Le programme est conçu pour afficher un motif de trois ellipses, mais ses deux sous-programmes sont ce qui nous intéresse. Les procédures InitGraphics contiennent tout le code nécessaire pour saisir des graphiques en mode de résolution maximale. De même, la procédure DoneGraphics vous ramène en mode texte. Les deux routines arrêtent automatiquement le programme en cas d'erreur.
- Program GrSetup;
-
- Uses MSGraph;
-
- Procedure InitGraphics;Begin
- If _SetVideoMOde(_MaxResMode)=0 Then Begin
- WriteLn('Requête de mode non disponible.');
- WriteLn('Presse la touche Enter pour continuer.');
- ReadLn;
- Halt(1); { Une valeur différente de zéro indique une erreur fatal }
- End;
- End;
-
- PRocedure DoneGraphics;Begin
- _SetTextPosition(25,1);
- _SetTextColor(7);
- If _SetVideoMode(_DefaultMode) = 0Then Begin
- WriteLn('Mode texte n''est pas actuellement votre mode par défaut');
- WriteLn('Programme terminé');
- Halt; { Terminaison normal }
- End;
- ENd;
-
- BEGIN
- InitGraphics;
- _Ellipse(_GFillInterior,0,10,200,190);
- _Ellipse(_GBorder,200,10,400,190);
- _Ellipse(_GFillInterior,400,10,600,190);
- DoneGraphics;
- END.
Détection du matériel graphique
Lorsque vous lancez des graphiques avec _MaxResMode ou _MaxColorMode, vous ne pouvez pas toujours être sûr de l'adaptateur détecté ou du mode sélectionné. Heureusement, le QuickPascal fournit une solution. En appelant la procédure _GetVideoConfig avec un enregistrement de type prédéfini _VideoConfig, vous pouvez accéder à diverses informations sur la configuration d'un compatible IBM PC et le mode actuel.
Vous pouvez obtenir les informations suivantes :
- _VideoConfig=Record
- NumXPixels:Integer; { Pixels horizontales }
- NumYPixels:Integer; { Pixels verticales }
- NumTextCols:Integer; { Colonnes texte disponible }
- NumTextRows:Integer; { Lignes texte disponible }
- NumColors:Integer; { Nombre de couleurs disponibles }
- BitsPerPixels:Integer; { Bits de mémoire par pixel }
- NumVideoPages:Integer; { Nombre de page vidéo disponible }
- Mode:Integer; { Mode vidéo courant }
- Adapter:Integer; { Adaptateur installé sur le compatible PC }
- Monitor:Integer; { Moniteur en utilisation }
- Memory:Integer; { Mémoire vidéo en Kilooctets }
- End;
Le programme SHOWGRAF suivant montre comment accéder à ces informations et les intercepter. Le programme saisit les graphiques en deux modes (_MaxResMode et _MaxColorModed) et rend compte de leurs paramètres de configuration. Remarquez comment SHOWGRAF incorpore bon nombre des constantes prédéfinies de l'unité MSGraph afin d'expliquer ses résultats.
- Program ShowGraf;
-
- Uses MSGraph;
-
- Procedure RevealGraphicsInfo(DesiredMode:Integer);
- Var
- vc:_VideoConfig;
- TextRows:Integer;
- Begin
- TextRows:=_SetVideoMode(DesiredMode);
- _GetVideoConfig(vc);
- TextRows:=_SetVideoMode(_DefaultMode);
- With vc do Begin
- WriteLn('Résolution horizontale : ',NumXPixels);
- WriteLn('Résolution verticale : ',NumYPixels);
- WriteLn('Colonnes textes disponible : ',NumTextCols);
- WriteLn('Lignes textes disponible : ',NumTextRows);
- WriteLn('Nombre de couleurs disponible : ',NumColors);
- WriteLn('Bits par pixels :',BitsPerPixel);
- WriteLn('Pages vidéo disponible :',NumVideoPages);
- WriteLn('Mémoire vidéo en Kilooctets',Memory);
- ENd;
- Write('Mode vidéo courant : ');
- Case vc.Mode of
- _MaxResMode:WriteLn('La plus haute résolution des modes graphiques');
- _MaxColorMode:WriteLn('Mode graphique avec le plus de couleurs');
- _DefaultMode:WriteLn('Restaure l''écran vers le mode originale');
- _TextBW40:WriteLn('40 colonnes de texte, 16 teintes de gris');
- _TextC40:WriteLn('40 colonnes de texte, 16 ou 8 couleurs');
- _TextBW80:WriteLn('80 colonnes de texte, 16 teintes de gris');
- _TextC80:WriteLn('80 colonnes de texte, 16 ou 8 couleurs');
- _MRes4Color:WriteLn('320 x 200 pixels en 4 couleurs');
- _MResNoColor:WriteLn('320 x 200 pixels en 4 teintes de gris');
- _HResBW:WriteLn('640 x 200 pixels en noir et blanc');
- _TextMono:WriteLn('80 colonnes de texte, noir et blanc');
- _HercMono:WriteLn('720 x 348 pixels en noir et blanc pour HGC');
- _MRes16Color:WriteLn('320 x 200 pixels en 16 couleurs');
- _HRes16Color:WriteLn('640 x 200 pixels en 16 couleurs');
- _EResNoColor:WriteLn('640 x 350 pixels en noir et blanc');
- _EResColor:WriteLn('640 x 350 pixels en 4 ou 16 couleurs');
- _VRes2Color:WriteLn('640 x 480 pixels en noir et blanc');
- _VRes16Color:WriteLn('640 x 480 pixels en 16 couleurs');
- _MRes256Color:WriteLn('320 x 200 pixels en 256 couleurs');
- _OResColor:WriteLn('640 x 400 pixels en 1 de 16 couleurs (Olivetti)');
- End;
- Write('Adaptateur actif : ');
- Case vc.Adapter of
- _MDPA:WriteLn('Monochrome Display Printer Adapter');
- _CGA:WriteLn('Color Graphics Adapter');
- _EGA:WriteLn('Enhanced Graphics Adapter');
- _VGA:WriteLn('Video Graphics Array');
- _MCGA:WriteLn('MultiColor Graphics Array');
- _HGC:WriteLn('Hercules Graphics Card');
- _OCGA:WriteLn('Olivetti Color Graphics Adapter');
- _OEGA:WriteLn('Olivetti Enhanced Graphics Adapter');
- _OVGA:WriteLn('Olivetti Video Graphics Array');
- End;
- Write('Moniteur actif : ');
- Case vc.Monitor of
- _Mono:WriteLn('Monochrome');
- _Color:WriteLn('Couleur ou émulation couleur étendue');
- _EnhColor:WriteLn('Couleur étendue (Enhanced Color)');
- _AnalogMono:WriteLn('Monochrome analogique seulement');
- _AnalogColor:WriteLn('Couleur analogique seulement');
- _Analog:WriteLn('Modes monochrome ou couleur analogique');
- End;
- End;
-
- BEGIN
- RevealGraphicsInfo(_MaxResMode);
- ReadLn;
- RevealGraphicsInfo(_MaxColorMode);
- END.
Si vous exécutez SHOWGRAF sur une DOSBox, il révèle les résultats suivants pour _MaxResMode :
Résolution horizontale : 640Résolution verticale : 480
Colonnes textes disponible : 80
Lignes textes disponible : 30
Nombre de couleurs disponible : 16
Bits par pixels : 4
Pages vidéo disponible : 1
Mémoire vidéo en KMiloctet : 256
Mode vidéo courant : 640 x 480 pixels en 16 couleurs
Adaptateur actif : Video Graphics Array
Moniteur actif : Modes monochrome ou couleur analogique
De même, les informations suivantes sont produites pour _MaxColorMode :
Résolution horizontale : 320Résolution verticale : 200
Colonnes textes disponible : 40
Lignes textes disponible : 25
Nombre de couleurs disponible : 256
Bits par pixels : 8
Pages vidéo disponible : 1
Mémoire vidéo en KMiloctet : 256
Mode vidéo courant : 320 x 200 pixels en 256 couleurs
Adaptateur actif : Video Graphics Array
Moniteur actif : Modes monochrome ou couleur analogique
À moins que vous ne sachiez que votre programme s'exécutera toujours sur votre propre compatible IBM PC ou sur un autre étant configuré de manière similaire, vous devez utiliser _GetVideoConfig pour écrire votre code dans la forme la plus générale possible. Par exemple, connaître la résolution de l'écran est particulièrement important lorsque vous devez positionner des images. Avec _GetVideoConfig, vous savez immédiatement que, en coordonnées (x,y), le centre de l'écran est toujours situé à :
Basculement entre les modes texte et graphique
Les programmes doivent souvent basculer entre les modes texte et graphique. Par exemple, vous pouvez utiliser le mode texte pour collecter et modifier des informations, puis passer en mode graphique pour afficher les résultats préliminaires sous la forme, par exemple, d'un graphique à barres ou à secteurs.
Vous pouvez basculer entre les modes en appelant simplement le _SetVideoMode une seconde fois. Le QuickPascal effacera l'écran et vous amènera directement dans le nouveau mode.
Utilisation des coordonnées graphiques
Bien que leur nombre exact dépende de l'adaptateur graphique et du mode particuliers, les pixels sont toujours disposés selon un motif rectangulaire. Tout comme vous pouvez utiliser une coordonnée (x,y) pour identifier un point sur un graphique, le système de coordonnées physiques identifie un pixel particulier sur l'écran.
Le système de coordonnées physiques définit le coin supérieur gauche comme (0,0). Ce point est appelé l'origine, car il sert de point de départ pour toutes les positions d'écran. Le numéro de colonne, ou valeur x, est écrit en premier et le numéro de ligne, ou valeur y, est écrit en second. Le numéro de colonne augmente vers la droite, mais contrairement à un graphique ordinaire, le numéro de ligne augmente vers le bas.
Le schéma suivante montre un écran avec une résolution de 320x200 pixels. Les coordonnées x vont de 0 à 319 et les coordonnées y vont de 0 à 199. Par conséquent, la coordonnée physique du coin inférieur droit est (319,199). Le schéma suivante identifie également les coordonnées du pixel (200, 100).
Vous pouvez rendre visible ce pixel en utilisant la procédure _SetPixel. La routine prend comme ses deux paramètres dans les coordonnées (x,y) d'un pixel, puis définit ce pixel sur la couleur de dessin actuelle.
- _SetPixel(200,100) { Coordonnée physique }
Tout comme vous pouvez restreindre la sortie de texte à une fenêtre, vous pouvez restreindre la sortie graphique à une fenêtre. La plupart des routines de dessin QuickPascal - y compris _SetPixel - utilisent les coordonnées de la fenêtre (viewport). Par défaut, la fenêtre d'affichage comprend l'intégralité de l'écran ; par conséquent, jusqu'à ce que vous définissiez une nouvelle fenêtre, vous pouvez référencer des pixels dans la fenêtre avec des coordonnées physiques.
Quand vous le souhaitez, vous pouvez utiliser la procédure _SetViewport pour définir une nouvelle fenêtre couvrant tout ou partie de l'écran physique. Cette routine prend quatre paramètres, constitués des coordonnées physiques des coins supérieur gauche et inférieur droit de la fenêtre. Voici comment créer une fenêtre entre les coordonnées physiques (160,50) et (240,150) :
- _SetViewport(160,50,240,150);
Le schéma suivant montre l'emplacement de la fenêtre sur l'écran physique :
Vous pouvez identifier n'importe quel pixel à l'intérieur d'une fenêtre soit par sa coordonnée physique, soit par sa coordonnée de fenêtre. Le système de coordonnées de la fenêtre utilise le coin supérieur gauche de la fenêtre comme origine, et - tout comme avec le système de coordonnées physique - les coordonnées x augmentent vers la droite et les coordonnées y augmentent vers le bas.
N'oubliez pas que la plupart des routines de dessin QuickPascal utilisent les coordonnées de la fenêtre. Par conséquent, dans le but d'afficher des graphiques, le pixel à la coordonnée physique (200,100) doit maintenant être référencé avec sa coordonnée de fenêtre équivalente (40,50).
- _SetPixel(40,50); { Coordonnée dans la vue de la fenêtre }
Bien sûr, il peut être fastidieux d'utiliser un système de coordonnées dont l'origine se trouve dans le coin supérieur gauche. Après tout, tout, des graphiques à barres à l'algèbre ordinaire, suppose que l'origine se trouve dans le coin inférieur gauche. De plus, si votre application nécessite des proportions ou si elle utilise des données composées de nombres réels, vous devrez effectuer un processus de conversion assez complexe pour identifier les coordonnées entières appropriées.
Le QuickPascal résout ce problème en vous permettant de définir une fenêtre avec la procédure _SetWindow :
- Procedure _SetWindow(FInvert:Boolean;SmallestX,SmallestY,LargestX,LargestY:Double);
Dans les graphiques, une fenêtre n'est rien de plus qu'un système de coordonnées recouvrant la fenêtre courante. Si vous définissez FInvert sur TRUE, les coordonnées de la fenêtre utilisent le coin inférieur gauche de la fenêtre comme origine et les coordonnées y augmentent vers le haut. (Si FInvert est FALSE), l'origine reste dans le coin supérieur gauche et les coordonnées y augmentent vers le bas.)
Les coordonnées de la fenêtre utilisent des valeurs à virgule flottante étant automatiquement mises à l'échelle pour s'adapter précisément à la fenêtre courante. Par conséquent, si FInvert est TRUE, la coordonnée de fenêtre du coin inférieur gauche est (SmallestX, SmallestY) et la coordonnée de fenêtre du coin supérieur droit est (LargestX, LargestY). Pour toute coordonnée de fenêtre que vous spécifiez, le QuickPascal détermine automatiquement le pixel le plus proche.
Pour chaque routine de dessin QuickPascal utilisant les coordonnées de la fenêtre, vous en trouverez une autre utilisant les coordonnées de la fenêtre. Ces sous-programmes basés sur des fenêtres sont faciles à identifier car leurs noms se terminent par un trait de soulignement (_) et un w. Par exemple, _SetPixel utilise les coordonnées de la fenêtre mais _SetPixel_w utilise les coordonnées de la fenêtre.
Un exemple simple clarifiera la distinction. Supposons que vous souhaitiez développer un graphique affichant 12 mois de données, où chaque mois a une valeur comprise entre 200 et 300. Tout d'abord, établissez une fenêtre comme suit :
- _SetWindow(True,0,200,13,300);
Désormais, lorsque vous utilisez une routine de dessin basée sur une fenêtre, le QuickPascal déterminera automatiquement le pixel approprié pour chaque élément de données que vous souhaitez afficher. Si la valeur de mars est de 172,3, éclairer ce point du graphique est aussi simple que d'exécuter la commande :
- _SetPixel_w(3.0,173.3);
Le schéma suivant montre comment les trois systèmes de coordonnées se chevauchent. Remarquez comment le pixel à la coordonnée physique (200,100) peut être référencé soit en tant que coordonnée de la fenêtre (40,50) soit en tant que coordonnée de la fenêtre (6.5,250.0) :
Le programme COORDOS suivant montre comment ces systèmes de coordonnées coïncident. Tout d'abord, le programme entre en mode graphique. (Cet exemple suppose que _MaxColorMode produit une résolution de 320x200 pixels.) Ensuite, le pixel à la coordonnée physique (200, 100) est allumé. L'instruction Readln fait attendre le programme jusqu'à ce que vous appuyiez sur la touche Enter.
- Program Coordos;
-
- Uses MSGraph;
-
- Var
- Status:Integer;
-
- BEGIN
- Status:=_SetVideoMode(_MaxColorMode);
- _SetPixel(200,100);
- ReadLn;
- _SetViewport(160,50,240,150);
- _ClearScreen(_GViewport);
- _SetPixel(40,50);
- ReadLn;
- _SetWindow(True,0,200,13,300);
- _ClearScreen(_GViewport);
- _SetPixel_w(6.5,250.0);
- ReadLn;
- Status:=_SetVideoMode(_DefaultMode);
- END.
Le programme crée ensuite une fenêtre avec un coin supérieur gauche de (160,50) et un coin inférieur droit de (240,150). Puisque la procédure _ClearScreen efface l'écran, le pixel doit être rallumé - cette fois en utilisant les coordonnées de la fenêtre (40,50). Encore une fois, un ReadLn suspend le programme jusqu'à ce que vous appuyiez sur Enter.
Ensuite, le programme définit une fenêtre recouvrant la fenêtre. Encore une fois, _ClearScreen efface le contenu de la fenêtre courante, ce qui revient à effacer la fenêtre courante. Le pixel cible est ensuite rallumé avec la routine _SetPixel_w en utilisant une coordonnée de fenêtre de (6,5,250,0). Lorsque vous exécutez le programme, vous verrez que les trois systèmes de coordonnées font référence au même pixel.
Conversion entre les coordonnées
Parfois, vous devrez déterminer votre position actuelle à l'écran, puis convertir une coordonnée d'un système à un autre. Heureusement, le QuickPascal fournit les routines suivantes pour gérer ces tâches automatiquement pour vous. Physique à la fenêtre :
- PROCEDURE _GetViewCoord(x,y:Integer;Var xy:_XYCoord);
Fenêtre vers vue de fenêtre :
- Procedure _GetViewCoord_w(Var x,y:Double;Var xy:_XYCoord);
Fenêtre vers vue de fenêtre :
- Procedure _GetViewCoord_wxy(Var wxy:_WXYCoord;Var xy:_XYCoord);
Vue de fenêtre vers physique :
- Procedure _GetPhysCoord(x,y:Integer;Var xy:_XYCoord);
Vue de fenêtre vers fenêtre :
- Procedure _GetWindowCoord(x,y:Integer;Var wxy:_WXYCoord);
Retourne la coordonnée d'une vue de fenêtre :
- Procedure _GetCurrentPosition(Var xy:_XYCoord);
Retourne la coordonnée d'une fenêtre :
- Procedure _GetCurrentPosition_wxy(Var wxy:_WXYCoord);
Ces procédures prennent des paramètres sous la forme d'enregistrements _WXYCoord et _XYCoord, étant prédéfinis dans l'unité MSGraph comme suit :
Quelques routines de dessin telles que _Rectangle_wxy, _Ellipse_wxy, _Arc_wxy et _Pie_wxy) utilisent également des coordonnées au format _WXYCoord.
Utiliser des couleurs
Dans les programmes graphiques, la couleur de chaque pixel est contrôlée individuellement. Chaque pixel est entreposé en mémoire sous forme de nombre binaire. L'adaptateur d'affichage utilise ce numéro comme index dans une table pour déterminer la couleur particulière que vous souhaitez que le pixel présente.
Ainsi, il existe deux manières de modifier les couleurs de votre écran. Tout d'abord, vous pouvez modifier la couleur du dessin actuel. Bien entendu, cette méthode ne modifie que les futures images d'écran. Deuxièmement, vous pouvez modifier la table de couleurs, appelée palette, utilisée par la carte graphique. Par exemple, tous les pixels affichant du vert pourraient être changés en cyan, tous les pixels affichant du rouge pourraient être changés en magenta, et ainsi de suite. Évidemment, changer une palette a un effet immédiat et dramatique sur l'image sur tout l'écran.
Changer les couleurs CGA
Plus tôt, vous avez vu que l'adaptateur CGA a deux modes de couleur : _MRes4Color et _MResNoColor. Ces deux modes affichent 3 couleurs de premier plan sur un arrière-plan de l'une des 16 couleurs prises en charge par l'adaptateur. Vous pouvez sélectionner l'une des couleurs de fond suivantes avec la procédure _SetBkColor :
Index | Couleur |
---|---|
0 | Noir |
1 | Bleu |
2 | Vert |
3 | Cyan |
4 | Rouge |
5 | Magenta |
6 | Brun |
7 | Blanc |
8 | Gris foncé |
9 | Bleu clair |
10 | Vert clair |
11 | Cyan clair |
12 | Rouge clair |
13 | Magenta clair |
14 | Jaune |
15 | Blanc clair |
Malheureusement, vous n'avez pas le choix quand il s'agit de sélectionner les 3 couleurs de dessin. Les deux modes vous limitent à un nombre prédéfini de palettes avec une combinaison prédéfinie de couleurs.
En mode _MRes4Color, vous pouvez utiliser ces 4 palettes :
Numéro de palette | Index de couleur | ||
---|---|---|---|
1 | 2 | 3 | |
0 | Vert | Rouge | Brun |
1 | Cyan | Magenta | Gris clair |
2 | Vert clair | Rouge clair | Jaune |
3 | Cyan claire | Magenta claire | Blanc |
En mode _MResNoColor, vous disposez de ces deux palettes :
Numéro de palette | Index de couleur | ||
---|---|---|---|
1 | 2 | 3 | |
0 | Bleu | Rouge | Gris claire |
1 | Cyan claire | Rouge claire | Blanc |
Vous pouvez utiliser la fonction _SelectPalette pour sélectionner l'une des palettes autorisées et vous pouvez sélectionner une couleur de dessin particulière avec la procédure _SetColor. Par conséquent, en mode _MRes4Color, les commandes suivantes sélectionneront le bleu comme couleur d'arrière-plan, la palette 2 comme palette active, et dessineront l'image suivante en jaune :
- _SetColor(1); { Bleu }
- PriorPalette:=_SelectPalette(2); { Vert claire/rouge clair/jaune }
- _SetColor(3); { La troisième palette de couleur }
Changer les couleurs EGA
Si votre compatible IBM PC est équipé d'une carte EGA, vous disposez d'un total de 64 couleurs pour vos écrans. Cependant, le nombre de couleurs que vous pouvez utiliser à tout moment est toujours limité par le mode actuel.
Les moniteurs couleur n'utilisent en réalité que trois cartouche de couleur pour produire un pixel : rouge, vert et bleu. (D'où l'expression moniteur RVB en français ou RGB en anglais.) La couleur réelle apparaissant à l'écran est un mélange de ces trois couleurs primaires.
Une carte EGA vous permet de créer votre propre palette contenant vos propres mélanges de couleurs. Chacune des trois couleurs primaires est disponible en quatre intensités différentes, les valeurs 0 à 3 correspondant à des niveaux de faible à élevé. Vous combinez ces niveaux pour produire une valeur de couleur personnalisée avec la formule suivante :
- CouleurUtilisateur := IntensiteRouge * 16 + { $000010 }
- IntensiteBleu * 4096 + { $001000 }
- IntensiteVert * 1048576; { $100000 }
Le QuickPascal a prédéfini pour vous certaines valeurs de couleur dans l'unité MSGraph. Ce sont les valeurs entreposées dans la palette par défaut.
Couleur | Valeurs de couleurs |
---|---|
_Black | $000000 |
_Blue | $2A0000 |
_Green | $002A00 |
_Cyan | $2A2A00 |
_Red | $00002A |
_Magenta | $2A002A |
_Brown | $00152A |
_White | $2A2A2A |
_Gray | $151515 |
_LightBlue | $3F1515 |
_LightGreen | $153F15 |
_LightCyan | $3F3F15 |
_LightRed | $15153F |
_LightMagenta | $3F153F |
_Yellow | $153F3F |
_BrightWhite | $3F3F3F |
Si vous souhaitez remplacer l'une de ces valeurs par une couleur de votre propre conception, vous pouvez utiliser la fonction _RemapPalette :
- Function _RemapPalette(ColorIndex:Integer;CustomColor:LongInt):LongInt;
Le paramètre ColorIndex est l'entrée dans la palette, de 0 à 15. Un ColorIndex de 0 indique la couleur d'arrière-plan. Le CouleurUtilisateur, comme son nom l'indique, est la nouvelle valeur de couleur calculée à partir des niveaux d'intensité individuels. Si l'appel réussit, _RemapPalette renvoie la valeur de couleur actuelle à ColorIndex. Si la fonction échoue, un -1 est renvoyé.
Changer les couleurs VGA
Une carte vidéo EGA a quatre niveaux d'intensité pour ses couleurs primaires, produisant jusqu'à 4 x 4 x 4 ou 64 couleurs au total. Une carte vidéo VGA fournit 64 niveaux d'intensité individuels pour un total de 64 x 64 x 64 ou 262 144 couleurs.
Comme une carte vidéo EGA, une carte vidéo VGA vous permet de mélanger vos propres couleurs et de les insérer dans la palette avec _RemapPalette. Chaque couleur primaire se décline en 64 intensités différentes, les valeurs de 0 à 63 correspondant aux niveaux de faible à élevé. Vous combinez ces niveaux pour produire une valeur de couleur avec la formule suivante :
- CouleurUtilisateur := IntensiteRouge +
- IntensiteBleu * 256 + { $00100 }
- IntensiteVert * 65536; { $10000 }
Si vous expérimentez les mathématiques, vous découvrirez que chaque couleur valide sur une carte vidéo EGA est également disponible sur la carte vidéo VGA. Ainsi, le tableau des valeurs de couleur dans la dernière section d'action s'applique également au carte vidéo VGA.
Dessiner des lignes
Les affichages graphiques ont une position de curseur entreposant l'emplacement actuel sur l'écran. Vous pouvez sélectionner une position de curseur spécifique avec les procédures _MoveTo et _MoveTo_w.
Les procédures _LineTo et _LineTo_w tracent une ligne droite de la position actuelle à une coordonnée spécifiée. Par conséquent, pour tracer une ligne droite de (x1,y1) à (x2,y2), vous devez exécuter les instructions suivantes :
ou
En exécutant une séquence de routines de dessin au trait, vous pouvez créer n'importe quelle forme géométrique que vous aimez. Par exemple, voici une façon simple de produire un triangle :
Dessiner des rectangles
Bien sûr, vous pouvez dessiner un rectangle avec quatre lignes individuelles. Cependant, le QuickPascal simplifie cette tâche en fournissant ces procédures. Voici la procédure avec les coordonnées de la vue de fenêtre :
- Procedure _Rectangle(control,x1,y1,x2,y2:Integer);
Voici la procédure avec les coordonnées de fenêtre :
- Procedure _Rectangle_w(control:Integer;wx1,wy1,wx2,wy2:Double);
Voici la procédure avec les coordonnées de fenêtre :
- Procedure _Rectangle_wxy(control:Integer;Var wxy1,wxy2:_WXYCoord);
À l'exception de la façon dont elles acceptent les coordonnées, toutes ces routines fonctionnent de la même manière. Chaque procédure est appelée avec les coordonnées des coins supérieur gauche et inférieur droit. Le premier paramètre, control, spécifie le contenu du rectangle. Lorsque vous définissez control sur _GFillInterior, le QuickPascal remplit le rectangle à l'aide du masque de remplissage actuel. (Le masque de remplissage sera discuté sous peu.) Si vous n'avez pas sélectionné votre propre masque de remplissage, le rectangle est solidement rempli avec la couleur de dessin actuelle. Si vous ne voulez pas que le contenu du rectangle change, définissez simplement control sur _GBorder et QuickPascal ne dessinera que son contour.
Choisir le style de la ligne
Normalement, les routines _LineTo et _Rectangle produisent des lignes pleines. Cependant, vous pouvez sélectionner votre propre motif ou style de ligne en appelant la procédure _SetLineStyle.
La routine _SetLineStyle prend un seul paramètre consistant en un masque de 16 bits, où chaque bit représente un pixel dans la ligne. Si un bit est défini sur 1, le pixel correspondant est allumé avec la couleur de dessin actuelle. La couleur du pixel est inchangée si son bit est à 0. Bien que le motif ne fasse que 16 bits, il se répète sur toute la longueur de la ligne. La valeur du motif par défaut - une ligne continue - est $FFFF.
Voici comment vous pouvez passer à un style de ligne composé d'un tiret suivi de deux points :
- _SetLineStyle($FCCC);
L'image suivante montre comment le paramètre $FCCC a été choisi :
Dessiner des ellipses, des cercles et des arcs
Il est naturel de penser à spécifier un cercle sur l'écran comme vous le dessineriez avec une boussole sur un morceau de papier. Vous vous attendez probablement à sélectionner le point central et le rayon. Dessiner un cercle partiel - un arc - nécessiterait normalement également que vous spécifiiez un angle de départ et d'arrêt. Une ellipse est similaire à un cercle, sauf que vous devez spécifier à la fois un axe majeur et un axe mineur au lieu d'un seul rayon.
Maintenant, réfléchissez à la façon dont vous utilisez normalement les cercles, les arcs et les ellipses. Vous savez presque toujours où vous souhaitez positionner les limites de la forme et vous utilisez les coordonnées des limites pour calculer le point central.
Le QuickPascal simplifie grandement ce processus en vous permettant de définir directement les limites rectangulaires d'un arc ou d'une ellipse. Le point central est calculé automatiquement. Voici les trois routines que vous pouvez utiliser pour dessiner des ellipses et des cercles. Voici la procédure avec les coordonnées de la vue de fenêtre :
Voici la procédure avec les coordonnées de la fenêtre :
- Procedure _Ellipse_w(control:Integer;wx1,wy1,wx2,wy2:Double);
Voici la procédure avec les coordonnées de la fenêtre :
- Procedure _Ellipse_wxy(control:Integer;Var wxy1,wxy2:_WXYCoord);
Toutes ces procédures acceptent les coordonnées d'un rectangle et dessinent la plus grande ellipse correspondant à la limite de ce rectangle. Le paramètre control a le même but ici que dans les routines _Rectangle. À savoir, lorsque control est défini sur _GFillInterior, l'ellipse est remplie avec le style de remplissage et la couleur de dessin actuels. Lorsque control est défini sur _GBorder, seul le contour de l'ellipse est dessiné.
Rappelez-vous qu'un cercle est une ellipse avec des axes majeurs et mineurs égaux. Par conséquent, pour dessiner un cercle, appelez simplement l'une de ces routines avec des coordonnées rectangulaires définissant un carré. Dans QuickPascal, un arc est considéré comme une ellipse partielle. Vous devez spécifier le rectangle de délimitation de l'arc ainsi que ses deux extrémités. Voici la procédure avec les coordonnées de la vue de fenêtre :
Voici la procédure avec les coordonnées de la fenêtre :
Comme il est très peu probable que vous puissiez calculer le pixel le plus proche pour chaque point de terminaison, le QuickPascal vous permet de spécifier indirectement les positions des points de terminaison. Les extrémités sont définies comme l'intersection d'une ligne passant par le centre du rectangle et la troisième et quatrième coordonnée que vous passez à la routine _Arc. Si vous en avez besoin, vous pouvez obtenir les coordonnées réelles (x,y) de l'extrémité en appelant la fonction _GetArcInfo. Vous aurez une meilleure idée de la façon dont un arc est défini à partir du schéma suivant :
Couper une pointe de tarte
Les pointes de tartes sont souvent utilisés pour illustrer comment un certain nombre (par exemple, les dépenses totales) est composé de valeurs individuelles (telles qu'une nourriture, un loyer et des services publics). Vous pouvez dessiner un secteur en définissant d'abord un arc, en obtenant ses extrémités au centre du rectangle. Vous pouvez également obtenir le même résultat avec l'une des procédures suivantes. Voici la procédure avec les coordonnées de la fenêtre :
Ces deux routines dessinent et éventuellement remplissent un coin en forme de tarte. Les coordonnées spécifient la limite rectangulaire du secteur ; le centre de la tarte est le centre du rectangle. Le paramètre control détermine la façon dont le coin est dessiné, selon que vous le définissez sur _GBorder ou _GFillInterior.
Choisir un motif de remplissage
Le motif de remplissage est le dessin remplissant une région délimitée. Par défaut, le QuickPascal utilise des couleurs unies. Cependant, vous pouvez choisir votre propre design avec la procédure _SetFillMask :
- Procedure _SetFillMask(mask:_FillMask);
Le motif de remplissage est un réseau de pixels 8x8, répété sur toute la région. Lorsque vous avez spécifié un style de ligne personnalisé comme indiquer plus tôt, vous avez contrôlé chaque pixel avec le réglage d'un seul bit. Vous pouvez contrôler les 64 bits du motif de remplissage de la même manière.
Le champ masque est un tableau de 8 octets ; chaque octet correspond à une seule ligne de 8 pixels, de haut en bas. Lorsqu'un bit est défini sur 1, le pixel correspondant est allumé dans la couleur de dessin actuelle. Si le bit est à 0, le pixel reste inchangé. La schéma suivant illustre comment vous pouvez développer un masque pour un motif de lignes inclinées du coin inférieur gauche au coin supérieur droit :
Le programme FillPatt suivant utilise le masque pour produire une paire de rectangles. Le premier rectangle a le motif plein par défaut tandis que le deuxième rectangle apparaît avec le motif de ligne :
- Program FillPatt;
-
- Uses MSGraph;
- Var
- Status:Integer;
- vc:_VideoConfig;
- x,y:Integer;
- Fill:_FillMask;
-
- BEGIN
- Status:=_SetVideoMode(_MaxResMode);
- _GetVideoConfig(vc);
- x:=vc.NumXPixels shr 1;
- y:=vc.NumYPixels shr 1;
- _Rectangle(_GFillInterior,0,0,X,Y);
- Fill[0]:=$01; { 00000001 }
- Fill[1]:=$02; { 00000010 }
- Fill[2]:=$04; { 00000100 }
- Fill[3]:=$08; { 00001000 }
- Fill[4]:=$10; { 00010000 }
- Fill[5]:=$20; { 00100000 }
- Fill[6]:=$40; { 01000000 }
- Fill[7]:=$80; { 10000000 }
- _SetFillMask(Fill);
- _Rectangle(_GFillInterior,X,Y,2*X,2*Y);
- ReadLn;
- Status:=_SetVideoMode(_DefaultMode);
- END.
Remplissage d'une région délimitée
Vous pouvez facilement remplir des rectangles, des ellipses et des secteurs en définissant leurs paramètres control sur _GFillInterior. Cependant, afin de remplir d'autres formes - y compris le triangle que vous avez créé en appelant à plusieurs reprises les routines _LineTo - vous devrez utiliser _FloodFill ou _FloodFill_w. Voici la procédure avec la coordonnées de la vue de fenêtre :
- Procedure _FloodFill(x,y,boundary:Integer);
Voici la procédure avec la coordonnées de la fenêtre :
- Procedure _FloodFill_w(wx,wy:Double;boundary:Integer);
Chacune de ces routines remplit une figure fermée avec le motif de remplissage et la couleur actuels. La zone affectée est la plus petite région délimitée qui contient la coordonnée spécifiée. Le QuickPascal commence à cet endroit, le rayonnement vers l'extérieur jusqu'à ce qu'il rencontre des pixels de la couleur boundary. Si la boundary se compose de lignes pleines ou d'arcs, l'intérieur de la région est rempli. Si la limite a des ouvertures, la couleur fuira à l'extérieur de la figure et remplira l'arrière-plan.
Affichage du texte à l'écran
Tous les modes graphiques de toutes les cartes graphiques prennent en charge la sortie de texte, même si les caractères peuvent ne pas avoir la même forme ou la même clarté que ceux produits en mode texte monochrome. Vous pouvez utiliser la procédure _GetVideoConfig pour déterminer le nombre de lignes et de colonnes de texte disponibles. Les résultats du programme SHOWGRAF ont montré comment la disposition du texte change entre _MaxColorMode et _MaxResMode. En _MaxResMode, la densité de pixels autorisait 25 lignes de 80 caractères. En revanche, _MaxColorMode ne prenait en charge que 25 lignes de 40 colonnes.
Dans un programme non graphique, vous positionnez le curseur avec GotoXY et affichez les données avec Write ou WriteLn. Dans un programme graphique, vous utilisez _SetTextPosition pour positionner le curseur de texte et _OutText pour afficher une chaîne de caractères. N'oubliez pas que les coordonnées du texte font référence au coin supérieur gauche de l'écran en tant que position (1,1) - et non en (0,0).
Vous devez vous souvenir de certaines choses lorsque vous travaillez avec ces routines. Premièrement, les paramètres Row et Column dans _SetTextPosition sont dans l'ordre inverse de leurs paramètres correspondants dans GotoXY. Deuxièmement, _OutText ne peut gérer qu'un paramètre de chaîne de caractères; par conséquent, toutes les valeurs numériques doivent être converties avant de pouvoir être affichées. Enfin, comme pour la procédure Write, lorsque _OutText se termine, le curseur se trouve à un espace à droite du dernier caractère affiché. Le curseur n'est pas remis à la première position de la ligne suivante.
Utiliser des polices de caractères de texte
Précédamment, il a été expliqué comment utiliser l'ensemble de caractères de texte conçu dans le matériel d'une carte d'adaptateur graphique. Le QuickPascal prend également en charge un deuxième type de sortie de texte, appelé police, entièrement contrôlé par un logiciel. Chaque police de caractères a sa propre police de caractères et son propre ensemble de tailles de caractères. De plus, vous pouvez placer des caractères générés par la police de caractères n'importe où sur l'écran ; ils ne sont pas limités à un petit nombre de lignes ou de colonnes de texte. Par conséquent, l'utilisation d'une police de caractères appropriée ajoute souvent considérablement à l'impact d'un affichage graphique.
La première étape de l'utilisation d'une police de caractères consiste à la charger pour la charger en mémoire avec la fonction _RegisterFonts :
- Function _RegisterFonts(FontPath:CString):Integer;
Le QuickPascal entrepose chaque police de caractères dans son propre fichier disque ; tous ces fichiers ont l'extension .FON. Lorsque vous appelez la routine _RegisterFonts, vous utilisez la chaîne de caractères FontPath pour contenir le nom des fichiers de polices de caractères que vous souhaitez charger. Vous devez inclure un nom de chemin complet (c'est-à-dire une spécification d'unité de disque et de répertoire) si les fichiers ne se trouvent pas dans le répertoire actuel. Si vous souhaitez charger toutes les polices de caractères disponibles, spécifiez *.FON comme masque.
Par exemple, pour charger toutes les polices de caractères du répertoire C:\LANGAGE\QP, vous pouvez exécuter les commandes suivantes :
- NumberLoaded:=_RegisterFonts('C:\LANGAGE\QP\*.FON');
- If NumberLoaded <= 0 Then Begin
- WriteLn('Aucune police de caractères n''a été chargé. SVP corrigé.');
- End;
La fonction _RegisterFonts renvoie le nombre de polices qu'elle charge avec succès ; par conséquent, une valeur de retour de 0 indique une erreur. Après avoir chargé les polices de caractères souhaitées en mémoire, vous devrez utiliser la fonction _SetFont pour indiquer à QuickPascal le nom de la police de caractères que vous souhaitez utiliser ensuite :
La chaîne de caractères FontOptions contient les caractéristiques de la police de caractères souhaitée. La fonction renverra un numéro d'index positif si elle trouve une correspondance, et votre programme utilisera cette police de caractères pour la sortie de texte. Si aucune police correspondante n'est trouvée, _SetFont renvoie une valeur négative.
Si vous n'avez chargé qu'une seule police de caractères, ou si vous connaissez l'ordre dans lequel les polices de caractères ont été chargées, les paramètres FontOptions peuvent contenir le numéro d'index précédé de la lettre n, comme suit :
Plus généralement, vous voudrez spécifier une police de caractères particulière en utilisant la lettre t comme préfixe. Vous pouvez également spécifier la taille souhaitée en incluant la hauteur et la largeur en pixels. Voici comment vous demanderiez la police de caractères Tms Rmn, en supposant que vous voulez que chaque caractère fasse 40 pixels de haut et 25 pixels de large :
La lettre b à la fin du spécificateur de taille demande à QuickPascal de trouver une approximation "la mieux adaptée". Voici les six polices de caractères parmi lesquelles vous pouvez choisir :
- Courier
- Helv
- Tms Rmn
- Script
- Modern
- Roman
Maintenant que vous avez identifié la police de caractères que vous souhaitez utiliser, déplacez-vous vers l'emplacement d'écran souhaité avec _MoveTo et affichez votre texte avec la procédure _OutGText. (Notez que la police de caractères, la taille et la position du curseur à la prochaine chaîne affichée par la procédure _OutText resteront inchangées).
Si vous le souhaitez, vous pouvez utiliser la fonction _GetFontInfo pour obtenir des informations sur la police de caractères sélectionnée. La routine _GetFontInfo renvoie un enregistrement du type prédéfini _FontInfo, comme suit :
- Type
- { Structure pour _GetFontInfo }
- _FontInfo = Record
- FontType : Integer; { Bit 0 fixé=vecteur, effacé=bit map }
- Ascent : Integer; { Pixels de haut en bas }
- PixWidth : Integer; { Largeur en pixels, 0 = proportionnel }
- PixHeight : Integer; { Hauteur des caractères en pixels }
- AvgWidth : Integer; { Largeur moyenne des caractères en pixels }
- FileName : CSTRING[80];{ Nom de fichier incluant le chemin }
- FaceName : CSTRING[31];{ Nom de la police de caractères }
- End;
Sélection d'une couleur de texte
Par défaut, le QuickPascal affiche tous les caractères du texte graphique en blanc. Bien que _SetColor détermine la couleur de toutes les images graphiques, vous devez utiliser la procédure _SetTextColor pour modifier la couleur de votre sortie de texte.
Pour effectuer votre sélection, appelez _SetTextColor avec un paramètre compris entre 0 et 31. Les couleurs correspondant aux nombres 0 à 15 sont les mêmes que celles utilisées par la routine _SetBkColor décrite plus haut dans la page. Les paramètres de 16 à 31 correspondent également à ces couleurs, sauf qu'ils font clignoter la sortie de texte.