Section courante

A propos

Section administrative du site

Utiliser des graphiques

Cette page explique comment appeler des routines graphiques définissant des points, dessinent des lignes, changent les couleurs et dessinent des formes telles que des rectangles et des cercles. La première section décrit la structure générale de tout programme graphique, définit les termes graphiques importants et présente un exemple de programme étape par étape, montrant comment utiliser les routines de base. Les sections suivantes expliquent les modes vidéo, les systèmes de coordonnées et l'animation.

Pour exécuter des programmes graphiques, votre ordinateur doit avoir une capacité graphique. La fonction graphique QuickPascal prend en charge les modes vidéo CGA (Color Graphics Adapter), EGA (Enhanced Graphics Adapter) et VGA (Video Graphics Adapter) disponibles sur les ordinateurs IBM PC et compatibles IBM PC. La fonction graphique prend également en charge les modes vidéo améliorés Olivetti (et AT&T) et le mode graphique monochrome Hercules.

Cette page traite des techniques d'écriture de programmes graphiques mais ne couvre pas toutes les procédures et fonctions graphiques (il en existe plus de 75). Vous pouvez explorer des rubriques supplémentaires à l'aide de QP Advisor et des exemples de programmes. Assurez-vous de vérifier le fichier README.DOC pour tout changement ou ajout de dernière minute.

Premiers pas avec les graphiques

Le sujet des graphiques et de l'affichage des couleurs sur les ordinateurs est assez complexe. Cette page et la page «Utiliser des polices de caractères», proposent une introduction aux graphiques et aux polices de caractères. Les sections suivantes couvrent les termes graphiques courants et répertorient les sources pour plus d'informations sur les graphiques.

Termes graphiques

Il y a plusieurs concepts que vous devez connaître avant de pouvoir créer des programmes graphiques. La liste suivante explique les termes les plus utiles :

Écrire votre premier programme graphique

Dans le QuickPascal, tous les programmes graphiques doivent suivre ces six étapes de base :

Un programme graphique simple, 1STGRAPH.PAS, est illustré ci-dessous. Plus loin dans la page, ce programme sera disséqué dans les six éléments requis d'un programme graphique.

  1. Program FirstGraphics;
  2.  { 1STGRAPH.PAS : Démontre la structure de base du programme graphique }
  3. Uses
  4.  MSGraph;
  5. Var
  6.  a, i:integer;
  7.  vc:_VideoConfig;
  8.  
  9. BEGIN { Début du programme principal. }
  10.  _ClearScreen(_GClearScreen);
  11.   {Définissez le mode vidéo de résolution la plus élevée et vérifiez le succès }
  12.  a:=_SetVideoMode(_MaxResMode);
  13.  If(a = 0)Then Begin
  14.   WriteLn('Aucun mode graphique valide ; appuyez sur RETURN pour continuer');
  15.   ReadLn;
  16.   a:=_SetVideoMode(_DefaultMode);
  17.   Halt(0);
  18.  End;
  19.   { Découvrez quelques caractéristiques de l'écran. }
  20.  _GetVideoConfig(vc);
  21.  Writeln('Mode: ',vc.Mode );
  22.  Writeln('Résolution horizontale : ', vc.NumXPixels);
  23.  Writeln('Résolution vertical : ', vc.NumYPixels);
  24.  Writeln('Nombre de couleurs: ', vc.NumColors);
  25.    { Dessinez un rectangle coloré et une ellipse dans le quadrant inférieur gauche. }
  26.  _SetColor(4);
  27.  _Rectangle(_GBorder,0,vc.NumYPixels-1,vc.NumXPixels DIV 4,vc.NumYPixels * 3 DIV 4);
  28.  _Ellipse(_GBorder,0,vc.NumYPixels-1,vc.NumXPixels DIV 4,vc.NumYPixels * 3 DIV 4);
  29.   { Tracez une ligne du coin du rectangle au centre de l'écran. }
  30.  _SetColor(3);
  31.  _MoveTo(vc.NumXPixels DIV 4, vc.NumYPixels DIV 4 );
  32.  _LineTo(vc.NumXPixels DIV 2, vc.NumYPixels DIV 2 );
  33.   { Attendez la touche RETURN puis restaurez le mode vidéo. }
  34.  ReadLn;
  35.  a:=_SetVideoMode(_DefaultMode);
  36. END.

Utilisation de l'unité MSGraph

La première étape de la création de 1STGRAPH.PAS consiste à utiliser l'unité MSGraph dans votre programme QuickPascal. L'unité MSGraph contient les constantes, les types de données, les procédures et les fonctions utilisées dans les programmes graphiques. Les unités QuickPascal sont expliquées dans la page Les unités. L'unité MSGraph est la bibliothèque de fonctionnalités graphiques auxquelles vous devez accéder à partir de votre programme.

La section USES de votre programme appelle MSGraph. Cette section apparaît immédiatement après la ligne de déclaration PROGRAM et ressemble à ceci :

  1. Uses
  2.  MSGraph;

Notez que certains composantes de l'unité MSGraph sont incompatibles avec certaines fonctions de l'unité Crt. Certaines des routines de l'unité Crt traitant de l'affichage (telles que HighVideo ou DirectVideo) entrent en conflit avec les fonctions graphiques.

Les routines Crt suivantes peuvent être utilisées en toute sécurité avec l'unité MSGraph :

Réglage du mode vidéo

Avant de pouvoir commencer à dessiner des images à l'écran, votre programme doit indiquer à la carte graphique de passer du mode texte au mode graphique. Appelez _SetVideoMode, en lui passant une constante prédéfinie lui indiquant le mode à afficher. Les constantes répertoriées dans le tableau suivant sont définies dans l'unité MSGraph. Les dimensions sont indiquées en colonnes pour les modes texte vidéo et en pixels pour le mode graphique :

Constante Mode vidéo Type de mode/Matériel
_DefaultMode Restaure le mode d'origine Les deux/tous
_MaxResMode Résolution la plus élevée Graphiques/Tous
_MaxColorMode Couleurs maximales Graphiques/Tous
_TextBW40 Texte de 40 colonnes, 16 gris Texte/CGA
_TextC40 Texte de 40 colonnes, couleur 16/8 Texte/CGA
_TextBW80 Texte de 80 colonnes, 16 gris Texte/CGA
_TextC80 Texte de 80 colonnes, couleur 16/8 Texte/CGA
_MRes4Color 320 x 200 pixels en 4 couleurs Graphisme/CGA
_MResNoColor 320 x 200 pixels en 4 gris Graphisme/CGA
_HResBW 640 x 200 pixels en Noir et Blanc Graphisme/CGA
_TextMono Texte de 80 colonnes en Noir et Blanc Texte/MDPA
_HercMono 720 x 348 pixels en noir et blanc pour HGC Graphiques/HGC
_MRes16Color 320 x 200 pixels en 16 couleurs Graphiques/EGA
_HRes16Color 640 x 200 pixels en 16 couleurs Graphiques/EGA
_EResNoColor 640 x 350 en noir et blanc Graphiques/EGA
_EResColor 640 x 350 pixels en 4 ou 16 couleurs Graphiques/EGA
_VRes2Color 640 x 480 en noir et blanc Graphiques/VGA/MCGA
_VResl6Color 640 x 480 en 16 couleurs Graphiques/VGA
_MRes256Color 320 x 200 pixels en 256 couleurs Graphiques/VGA/MCGA
_OResColor 640 x 400, 1 des 16 couleurs Graphiques/Olivetti

Les modes spéciaux _MaxResMode et _MaxColorMode sont utilisés lorsque vous voulez simplement que QuickPascal détermine la résolution la plus élevée ou le mode de couleur maximum disponible.

Si la fonction _SetVideoMode renvoie un 0, cela signifie que le matériel ne prend pas en charge le mode sélectionné. Vous pouvez continuer à sélectionner d'autres modes vidéo jusqu'à ce qu'une valeur différente de zéro soit renvoyée. Si la configuration matérielle ne prend en charge aucun des modes vidéo sélectionnés, quittez le programme.

Le segment de l'exemple de programme 1STGRAPH.PAS ci-dessous définit le mode vidéo pour une résolution maximale, puis vérifie le succès. Si la fonction _SetVideoMode échoue (et renvoie un 0), le programme affiche un message, restaure le mode vidéo et s'arrête.

  1.  { Définissez le mode de résolution le plus élevé et vérifiez le succès }
  2. a:=_SetVideoMode(_MaxResMode);
  3. If(a = 0)Then Begin
  4.  WriteLn('Aucun mode graphique valide ; appuyez sur RETURN pour continuer');
  5.  ReadLn;
  6.  a:=_SetVideoMode(_DefaultMode);
  7.  Halt(0);
  8. End;

Détermination des paramètres vidéo

Après être entré en mode graphique, vous pouvez vérifier la configuration vidéo actuelle. Ceci est nécessaire lorsque vous avez utilisé la constante _MaxResMode ou _MaxColorMode, puisque vous ne connaissez pas les spécificités du mode vidéo sélectionné.

La configuration vidéo nécessite une structure spéciale appelée _VideoConfig, étant définie dans l'unité MSGraph. La procédure _GetVideoConfig trouve les informations de configuration vidéo actuelles.

La structure _VideoConfig contient les éléments suivants :

  1. { Structure pour _GetVideoConfig }
  2. _VideoConfig=Record
  3.  NumXPixels:Integer; { Résolution horizontale }
  4.  NumYPixels:Integer; { Résolution verticale }
  5.  NumTextCols:Integer; { Nombre de colonnes de texte disponibles }
  6.  NumTextRows:Integer; { Nombre de lignes de texte disponibles }
  7.  NumColors:Integer; { Nombre de couleurs actuelles }
  8.  BitsPerPixel:Integer; { Nombre de bits par pixel }
  9.  NumVideoPages:Integer; { Nombre de pages vidéo disponibles }
  10.  Mode:Integer; { Mode vidéo actuel }
  11.  Adapter:Integer; { Adaptateur d'affichage actif }
  12.  Monitor:Integer; { Moniteur d'affichage actif }
  13.  Memory:Integer; { Mémoire vidéo de l'adaptateur en Kilooctets }
  14. End;

Les variables de la structure _VideoConfig sont initialisées lorsque vous appelez _GetVideoConfig. Dans l'exemple de programme suivant, le mode vidéo est défini sur _MaxResMode. Le programme appelle alors _GetVideoConfig pour déterminer les dimensions de l'écran (en pixels) et le nombre maximum de couleurs autorisées :

  1.  { Rechercher quelques caractéristiques de l'écran. }
  2. _GetVideoConfig(vc);
  3. WriteLn('Mode: ',vc.Mode);
  4. WriteLn('Résolution horizontale : ', vc.NumXPixels);
  5. WriteLn('Résolution vertical : ', vc.NumYPixels);
  6. WriteLn('Nombre de couleurs : ', vc.NumColors);

Configuration des systèmes de coordonnées

La troisième étape de l'écriture d'un programme graphique QuickPascal consiste à établir le «système de coordonnées».

Un système de coordonnées est utilisé pour identifier un emplacement de pixel par rapport à un axe horizontal et vertical. Dans un mode graphique, chaque pixel de l'écran peut être localisé au moyen d'un couple unique de coordonnées. L'unité graphique QuickPascal prend en charge les systèmes de coordonnées suivants :

Puisque cet exemple de programme graphique ne précise pas le contraire, le système de coordonnées utilisé est celui fourni par les dimensions physiques de l'écran. C'est ce qu'on appelle le «système de coordonnées physiques».

Mais combien d'écran est disponible pour travailler ? Il peut y avoir 720x348, 640x480, 640x400, 640x350 ou 640x200 pixels. Les éléments NumXPixels et NumYPixels de la structure _VideoConfig fournissent les dimensions de l'écran. Sur une carte VGA, une demande de résolution maximale mettrait l'écran en mode _VRes16Color. La résolution horizontale est de 640 pixels et la résolution verticale est de 480. La résolution horizontale peut être de 640, mais les pixels sont numérotés de 0 à 639.

Le système de coordonnées physiques place l'origine (ou la paire de coordonnées (0,0)) dans le coin supérieur gauche de l'écran. Les valeurs positives croissantes de la coordonnée x s'étendent de gauche à droite. Les valeurs positives croissantes de la coordonnée y s'étendent de haut en bas. Le système de coordonnées physiques dépend de la configuration du matériel et de l'affichage et ne peut pas être modifié. Les autres systèmes de coordonnées et les procédures utilisées pour traduire entre eux sont décrits quelques section plus loin.

Dessiner des graphiques

Les quelques lignes suivantes de cet exemple de programme dessinent un rectangle et une ellipse, puis une ligne vers le centre de l'écran. Avant de dessiner le rectangle ou la ligne, la couleur graphique est définie sur deux valeurs différentes. Le segment de programme dessinant le rectangle et l'ellipse est illustré ci-dessous :

  1. { Dessinez un rectangle coloré et une ellipse dans le quadrant inférieur gauche. }
  2. _SetColor(4);
  3. _Rectangle(_GBorder,0,vc.NumYPixels-1,vc.NumXPixels DIV 4,vc.NumYPixels * 3 DIV 4);
  4. _Ellipse(_GBorder,0,vc.NumYPixels-1,vc.NumXPixels DIV 4,vc.NumYPixels * 3 DIV 4); 

L'appel à la procédure _Rectangle a cinq paramètres. Le premier paramètre est le «drapeau de remplissage», pouvant être soit _GBorder soit _GFillInterior. L'indicateur de remplissage détermine si la figure sera dessinée avec juste la bordure ou comme une figure pleine. Choisissez _GBorder si vous voulez un rectangle de quatre lignes (une bordure uniquement, dans le style de ligne actuel). Ou vous pouvez choisir _GFillInterior si vous voulez un rectangle uni (rempli avec la couleur et le motif de remplissage actuels).

Les deuxième et troisième arguments sont les coordonnées x et y d'un coin du rectangle. Les quatrième et cinquième paramètres sont les coordonnées du coin opposé. Les coordonnées des deux coins sont définies en fonction des mesures obtenues à partir de _GetVideoConfig. Par conséquent, ce programme dessine correctement le rectangle dans n'importe quel mode graphique.

La procédure _Ellipse dessine une ellipse à l'écran. Ses paramètres ressemblent aux paramètres de _Rectangle. Les deux procédures nécessitent un indicateur de remplissage et deux coins d'un "rectangle de délimitation". "Lorsque l'ellipse est dessinée, quatre points touchent les bords du rectangle englobant. Un rectangle englobant définit l'espace dans lequel une figure arrondie est dessinée. Pour une figure arrondie, le centre du rectangle englobant définit le centre de la figure arrondie. Un rectangle englobant est défini par les coordonnées du coin supérieur gauche et du coin inférieur droit du rectangle.

Lorsque le programme entre pour la première fois en mode graphique ou définit une fenêtre d'affichage, la position de dessin est définie au centre de l'écran. Étant donné que la procédure _Rectangle prend les coins du rectangle comme paramètres, il n'est pas nécessaire de définir la position du dessin. Mais une fois les figures dessinées, le programme déplace la position de dessin actuelle (avec la procédure _MoveTo) et trace une ligne de la nouvelle position au centre de l'écran :

  1.  { Tracez une ligne du coin du rectangle au centre de l'écran. }
  2. _SetColor(3);
  3. _MoveTo(vc.NumXPixels DIV 4, vc.NumYPixels DIV 4 );
  4. _LineTo(vc.NumXPixels DIV 2, vc.NumYPixels DIV 2 ); 

Encore une fois, les coordonnées sont données en termes de NumXPixels et NumYPixels pour assurer la portabilité entre les modes vidéo.

Restauration de la configuration vidéo initiale et sortie

La dernière étape de tout programme graphique consiste à restaurer le mode vidéo par défaut. Dans l'exemple de programme, la procédure ReadLn attend la touche RETURN. La fonction _SetVideoMode restaure l'écran au mode par défaut, ce qui ramène l'écran à la normale.

  1.  { Attendez la touche RETURN puis restaurez le mode vidéo. }
  2. ReadLn;
  3. a:=_SetVideoMode(_DefaultMode); 

Utilisation des modes vidéo

L'unité MSGraph de QuickPascal prend en charge les adaptateurs vidéo et les écrans suivants :

Les sections suivant expliquent comment sélectionner un mode vidéo, puis discutent des principaux modes graphiques CGA, EGA et VGA. Une liste complète des modes vidéo QuickPascal pouvant être définis par la fonction _SetVideoMode est présentée dans le tableau plus bas dans cette page.

Remarque : Si vous utilisez une carte graphique Hercules, vous devez exécuter le programme MSHERC.COM avant de tenter d'afficher des graphiques en mode _HercMono. Si votre ordinateur dispose également d'une carte graphique couleur, vous devez exécuter MSHERC.COM avec l'option /H (/HALF) pour définir la carte graphique Hercules en mode HALF. Sinon, les résultats seront imprévisibles.

La structure _VideoConfig, étant renvoyée par _GetVideoConfig, inclut des champs indiquant le type de carte graphique et de moniteur utilisé. Le tableau suivant répertorie les constantes des adaptateurs graphiques.

Constante Valeur Description
_MDPA 0x0001 Monochrome Display Adapter
_CGA 0x0002 Color Graphics Adapter
_EGA 0x0004 Enhanced Graphics Adapter
_VGA 0x0008 Video Graphics Array
_MCGA 0x0010 MultiColor Graphics Array
_HGC 0x0020 Hercules Graphics Card
_OCGA 0x0042 Olivetti Color Graphics Adapter
_OEGA 0x0044 Olivetti Enhanced Graphics Adapter
_OVGA 0x0048 Olivetti Video Graphics Array

Liste des constantes des moniteurs reconnus :

Constante Valeur Description
_Mono 0x0001 Monochrome
_Color 0x0002 Couleur
_ENHColor 0x0004 Couleur améliorée
_AnalogMono 0x0008 Monochrome analogique uniquement
_AnalogColor 0x0010 Couleur analogique uniquement
_Analog 0x0018 Modes analogiques monochrome et couleur

Sélection d'un mode vidéo

Avant de pouvoir afficher des graphiques, vous devez mettre la carte graphique en mode graphique. Comme indiqué dans l'exemple de programme, la fonction _SetVideoMode exécute cette tâche. Avant d'appeler _SetVideoMode, vous devez décider quels modes graphiques sont acceptables pour vos besoins. Il existe plusieurs manières de sélectionner un mode graphique approprié :

Pour afficher tous les modes graphiques possibles, vous pouvez exécuter le programme d'exemple GRAPHIC.PAS, illustré ci-dessous :

  1. Program Graphic; { Affiche tous les modes graphiques }
  2.  
  3. Uses
  4.  Crt,MSGraph;
  5.  
  6. Const
  7.  modes:Array[0..11] of Integer=(
  8.   _MRes4Color,_MResNoColor,_HResBW,_HercMono,
  9.   _MRes16Color,_HRes16Color,_EResNoColor,_EResColor,
  10.   _VRes2Color,_VRes16Color,_MRes256Color,_OResColor
  11.  );
  12.  
  13. Var
  14.  vc:_VideoConfig;
  15.  ch,key:Char;
  16.  which:Char;
  17.  a:Integer;
  18.  
  19. Procedure print_menu;
  20.  { Affiche un menu à l'écran }
  21. Begin
  22.  Writeln('Veuillez choisir un mode graphique');
  23.  Writeln('Tapé "x" pour sortir');
  24.  Writeln;
  25.  Writeln('0 _MRES4C0L0R');
  26.  Writeln('1 _MRESNOCOLOR');
  27.  Writeln('2 _HRESBW' );
  28.  Writeln('3 _HERCMONO');
  29.  Writeln('4 _MRES16C0L0R');
  30.  Writeln('5 _HRES16C0L0R');
  31.  Writeln('6 _ERESNOCOLOR');
  32.  Writeln('7 _ERESCOLOR');
  33.  Writeln('8 _VRES2COLOR');
  34.  Writeln('9 _VRES16C0L0R');
  35.  Writeln('a _MRES256C0L0R');
  36.  Writeln('b _ORESCOLOR');
  37. End;
  38.  
  39. Procedure show_mode(which:Char);
  40.  { Affiche les différents modes vidéo. }
  41. Var
  42.  nc,i:Integer;
  43.  height:Integer;
  44.  width:Integer;
  45.  mode:String;
  46.  r:Real;
  47.  e,m:Integer;
  48. Begin
  49.  mode:=which;
  50.  If(mode < '0')or(mode > '9')Then
  51.   If mode = 'a' Then
  52.    mode:='10'
  53.   Else If mode = 'b' Then
  54.    mode:='11'
  55.   Else 
  56.    Halt; { Sortir la procédure }
  57.  Val(mode,r,e);
  58.  m:=Trunc(r);
  59.  a:=_SetVideoMode(modes[m]);
  60.  If(a <> 0)Then Begin
  61.   _GetVideoConfig( vc );
  62.   nc:=vc.NumColors;
  63.   width:=vc.NumXPixels DIV nc;
  64.   height:=vc.NumYPixels DIV 2;
  65.   For i:=1 to(nc-1)do Begin
  66.    _SetColor( i );
  67.    _Rectangle(_GFillInterior,i*width,0,(i + 1)*width, height);
  68.   End;
  69.  End { SI a est différent de 0 }
  70.   Else
  71.  Begin
  72.   Writeln('Mode vidéo ', which, ' n''est pas disponible.');
  73.   Writeln('Veuillez appuyer sur ENTER.' );
  74.  End;
  75.  ReadLn; { Attendez que ENTER soit pressé }
  76.  a:=_SetVideoMode( _DefaultMode );
  77.  print_menu;
  78. End;
  79.  
  80. BEGIN { Début le programme principal }
  81.  key:=' ';
  82.  _ClearScreen(_GClearScreen);
  83.  print_menu;
  84.  While(key <> 'x') do Begin
  85.   key:=ReadKey;
  86.   show_mode( key );
  87.  End;
  88. END.

On obtiendra un résultat ressemblant à ceci :

Modes graphiques couleur CGA

Les modes graphiques couleur CGA _MRes4Color et _MResNoColor affichent quatre couleurs sélectionnées dans l'une des palettes de couleurs prédéfinies. Ils affichent ces couleurs de premier plan sur une couleur d'arrière-plan pouvant être l'une des 16 couleurs disponibles. Avec le matériel CGA, la palette de couleurs de premier plan est prédéfinie et ne peut pas être modifiée. Chaque numéro de palette est un nombre entier comme indiqué dans le tableau suivant :

Palette Numéro Index des couleurs
1 2 3
0 Vert Rouge Brun
1 Cyan Magenta Gris clair
2 Vert clair Rouge clair Jaune
3 Cyan clair Magenta clair Blanc

Le mode graphique _MResNoColor produit des palettes contenant diverses nuances de gris sur des moniteurs en noir et blanc. Le mode _MResNoColor affiche les couleurs lorsqu'il est utilisé avec un écran couleur. Cependant, seules deux palettes sont disponibles avec un affichage couleur. Vous pouvez utiliser la fonction _SelectPalette pour sélectionner l'une de ces palettes prédéfinies. Le tableau suivant montre la correspondance entre les index de couleur et les palettes :

Palette Numéro Index des couleurs
1 2 3
0 Bleu Rouge Gris clair
1 Bleu clair Rouge clair Blanc

Vous pouvez utiliser la fonction _SelectPalette conjointement avec les modes graphiques _MRes4Color, _MResNoColor et _OResColor. Pour modifier les palettes dans d'autres modes graphiques, utilisez les routines _RemapPalette ou _RemapAllPalette.

En mode _OResColor, vous pouvez choisir l'une des 16 couleurs de premier plan en transmettant une valeur comprise entre 0 et 15 à la fonction _SelectPalette. La couleur de fond est toujours noire.

Le programme suivant définit le mode vidéo sur _MRes4Color, puis parcourt les couleurs d'arrière-plan et les combinaisons de palettes. Il fonctionne sur les ordinateurs équipés de cartes CGA, EGA, MCGA ou VGA. Un moniteur couleur est nécessaire.

  1. Program CGA;
  2.   { Démonstration de couleurs CGA }
  3. Uses
  4.  MSGraph;
  5.  
  6. Const
  7.  bkcolor:Array[0..7] of LongInt = (_Black, _Blue, _Green, _Cyan,_Red, _Magenta, _Brown, _White);
  8.  bkcolor_name:Array[0..7] of String=('NOIR   ','BLEU   ','VERT   ', 'CYAN   ','ROUGE  ','MAGENTA','BROWN ','BLANC  ');
  9.  
  10. Var
  11.  a,i,j,k:Integer;
  12. BEGIN { Début du programme principal }
  13.  a:=_SetVideoMode(_MRes4Color);
  14.  For i:=0 to 3 do Begin
  15.   a:=_SelectPalette(i);
  16.   For k:=0 to 7 do Begin
  17.    _SetBkColor(bkcolor[k]);
  18.    For j:=0 to 3 do Begin
  19.     _SetTextPosition(1,1);
  20.     WriteLn('Couleur d''arrière-plan : ',bkcolor_name[k]);
  21.     WriteLn('Palette : ', i);
  22.     Writeln('Nombre : ', j);
  23.     _SetColor(j);
  24.     _Rectangle(_GFillInterior,160,100,320,200);
  25.     ReadLn; { Attendez que ENTER soit pressé }
  26.    End; { for j }
  27.   End; { for k }
  28.  End; { for i }
  29.  a:=_SetVideoMode(_DefaultMode); { Restaurer la palette d'origine }
  30. END.

On obtiendra un résultat ressemblant à ceci :

Palettes EGA, MCGA et VGA

Le début de cette page mentionnait la différence entre les index de couleur et les valeurs de couleur. Une analogie pourrait rendre les choses plus claires. Imaginez un peintre possédant 64 tubes de peinture et une palette de peintre n'ayant de la place que pour 16 globes de peinture à la fois. Un tableau créé sous ces contraintes ne pouvait contenir que 16 couleurs (sélectionnées sur un total de 64). Les modes graphiques EGA (tels que EResColor) sont similaires : ils ont 16 index de couleurs choisis parmi un total de 64 valeurs de couleurs.

Les valeurs de couleur disponibles dans les palettes EGA, MCGA et VGA ne sont pas prédéterminées comme les palettes CGA. Au lieu de cela, les valeurs de couleur disponibles dans les palettes EGA , MCGA et VGA sont créées par un processus de "mélange de couleurs" d'éléments rouges, verts et bleus. Les deux sections suivantes décrivent le mélange des couleurs.

Mélange de couleurs VGA

Les cartes vidéo VGA offre la plus grande variété de valeurs de couleurs : 262 144 (256K). Selon le mode graphique, la taille de la palette VGA peut être de 2, 16 ou 256. Lorsque vous sélectionnez une valeur de couleur, vous spécifiez un niveau d'intensité compris entre 0 et 63 pour chacune des valeurs de couleur rouge, verte et bleue. L'entier long qui définit une valeur de couleur se compose de quatre octets (32 bits) :

MSB                             LSB
zzzzzzzz zzBBBBBB zzGGGGGG zzRRRRRR

L'octet le plus significatif doit contenir uniquement des zéros. Les deux bits de poids fort dans les trois octets restants doivent également être 0. Pour mélanger un rouge clair (rose), augmentez complètement le rouge et mélangez du vert et du bleu :

00000000 00100000 00100000 00111111

Pour représenter cette valeur en hexadécimal, utilisez le nombre $0020203F.

Pour le blanc, allumez tous les éléments ; pour le noir, réglez tous les éléments sur 0.

Mélange de couleurs EGA

Le mélange des couleurs dans les modes EGA est similaire au mélange décrit ci-dessus, mais il y a moins d'intensités pour les composantes rouge, vert et bleu. Dans les modes offrant 64 couleurs, les valeurs R, G et B couvrent 2 bits et peuvent aller de 0 à 3. L'entier long définissant une couleur RVB ressemble à ceci :

MSB                             LSB
zzzzzzzz zzBB???? zzGG???? zzRR????

Modes graphiques couleur EGA

Si vous disposez d'un adaptateur EGA, vous devez utiliser le mode vidéo _MResl6Color, _HResl6Color ou _EResColor pour obtenir les meilleurs résultats graphiques en couleur. Les modes CGA s'affichent également sur l'EGA, mais avec une résolution CGA inférieure et des options de couleur réduites.

La fonction _RemapPalette attribue une nouvelle valeur de couleur à un index de couleur. Par exemple, lorsque vous entrez pour la première fois dans un mode graphique EGA, l'index de couleur 1 est égal à la valeur de couleur bleu. Pour réaffecter la valeur de couleur rouge pur à l'index de couleur 1, vous pouvez utiliser cette ligne :

  1. a:=_RemapPalette(1,$000030);

Ou, utilisez la constante symbolique _Red, étant définie à l'aide de l'unité MSGraph :

  1. a:=_RemapPalette(1,_Red);

Après cet appel de fonction, tout objet actuellement dessiné dans l'index de couleur 1 passe instantanément du bleu au rouge.

La première valeur est un entier compris entre 0 et 15 et la deuxième valeur est un LongInt défini comme un mélange de rouge, de vert et de bleu (vous pouvez également utiliser des constantes symboliques telles que _Red).

La procédure _RemapAllPalette modifie simultanément tous les index de couleur. Vous lui passez un tableau de valeurs de couleur. La première valeur de couleur de la liste devient la nouvelle couleur associée à l'index de couleur 0.

Le nombre dans un appel de fonction définissant la couleur (comme _SetColor) est un index dans la palette des couleurs disponibles. Dans la palette de texte par défaut, un index de 1 fait référence au bleu, mais la palette peut être cartographiée pour remplacer l'index 1 par n'importe quelle autre couleur disponible. Par conséquent, la couleur produite par cette valeur de pixel change également. Le nombre d'index de couleurs dépend du nombre de couleurs prises en charge par le mode vidéo actuel.

Les routines _RemapPalette et _RemapAllPalette fonctionnent dans tous les modes mais uniquement avec le matériel EGA, MCGA ou VGA. Le _RemapPalette échoue, renvoyant une valeur de -1 lorsque vous tentez de cartographier une palette sans le matériel EGA, MCGA ou VGA.

Le programme suivant dessine un rectangle avec un intérieur rouge. Dans la palette EGA par défaut, l'indice de couleur 4 est le rouge. Cet index de couleur est changé en _Blue dans ce programme :

  1. Program EGA;
  2.  { Démonstration de palettes EGA/VGA }
  3. Uses
  4.  MSGraph;
  5.  
  6. Const
  7.  crlf=#13+#10;
  8.  
  9. Var
  10.  a:LongInt;
  11.  m:Integer;
  12.  
  13. BEGIN { Début le programme principal }
  14.  m:=_SetVideoMode(_MaxColorMode);
  15.  _SetColor(4);
  16.  _Rectangle(_GFillInterior,50,50,150,150);
  17.  _SetTextPosition(1,1);
  18.  _OutText('Palette normal ' + crlf);
  19.  _OutText('Presse ENTER');
  20.  ReadLn;
  21.  a:=_RemapPalette (4,_Blue);
  22.  _SetTextPosition(1,1);
  23.  _OutText('Cartographie de la palette' + crlf);
  24.  _OutText( 'Presse ENTER' );
  25.  ReadLn;
  26.  a:=_RemapPalette(4,_Red);
  27.  _SetTextPosition(1,1);
  28.  _OutText('Restaure la palette' + crlf);
  29.  _OutText('Presse ENTER pour effacer l''écran');
  30.  ReadLn;
  31.  _ClearScreen(_GClearScreen);
  32.  m:=_SetVideoMode(_DefaultMode);
  33. END.

Modes graphiques couleur VGA

La carte VGA ajoute les modes graphiques _VRes2Color, _VRes16Color et _MRes256Color à votre répertoire. Les modes EGA et CGA peuvent également être utilisés avec le matériel VGA, mais avec une résolution inférieure ou moins de choix de couleurs.

Les modes graphiques couleur VGA fonctionnent avec une gamme de 262 144 (256K) valeurs de couleur. Le mode graphique _VRes2Color affiche deux couleurs, le mode graphique _VRes16Color affiche 16 couleurs et le mode graphique _MRes256Color affiche 256 couleurs parmi les couleurs VGA disponibles.

La fonction _RemapPalette remplace un index de couleur par une valeur de couleur spécifiée. La fonction ci-dessous cartographie l'index de couleur 1 à la valeur de couleur donnée par la constante symbolique _Red (représentant le rouge). Une fois cette instruction exécutée, tout ce qui était affiché en bleu apparaît maintenant en rouge :

  1. { réattribuer l'index de couleur 1 au rouge VGA }
  2. a:=_RemapPalette(1, _Red);

Utilisez la procédure _RemapAllPalette pour recartographier simultanément tous les index de couleurs disponibles. Le paramètre de la procédure fait référence à un tableau de valeurs de couleur reflétant la recartographie. Le premier numéro de couleur de la liste devient la nouvelle couleur associée à l'index de couleur 0.

Des constantes symboliques pour les numéros de couleur par défaut sont fournies afin que la cartographie des couleurs VGA soit compatible avec la pratique EGA. Les noms de ces constantes sont explicites. Par exemple, les numéros de couleur pour le noir, le rouge et le jaune clair sont représentés par les constantes symboliques _Black, _Red et _Yellow.

Tous les modes d'affichage VGA fonctionnent avec n'importe quel moniteur vidéo VGA. Les couleurs sont affichées sous forme de nuances de gris lorsqu'un écran analogique monochrome est connecté. Le programme HORIZON.PAS suivant illustre ce qu'il est possible de faire avec la gamme de 256 couleurs si vous disposez d'une carte VGA :

  1. Program horizon; { Démonstration des graphiques VGA avec un cycle de 256 couleurs }
  2.  
  3. Uses
  4.  Crt, MSGraph;
  5.  
  6. Const
  7.  RED=$00002a;
  8.  GRN=$002a00;
  9.  BLU=$2a0000;
  10.  WHT=$2a2a2a;
  11.  step = 21;
  12.  
  13. Var
  14.  vc:_VideoConfig;
  15.  rainbow:Array[1..512] of LongInt;
  16.  i,a:Integer;
  17.  col,gray:LongInt;
  18.  rec:_XYCoord;
  19.  
  20. BEGIN { Début du programme principal }
  21.  a:=_SetVideoMode(_MRes256Color);
  22.  If(a=0)Then Begin
  23.   WriteLn('Ce programme nécessite une carte VGA ou MCGA');
  24.   Halt(0);
  25.  End;
  26.  For col:=0 to 63 do Begin
  27.   gray := col OR (col SHL 8) OR (col SHL 16);
  28.   rainbow[col] := BLU AND gray;
  29.   rainbow[col + 256] := BLU AND gray;
  30.   rainbow[col +64] := BLU OR gray;
  31.   rainbow[col + 64 + 256] := BLU OR gray;
  32.   rainbow[col + 128] := Red OR (WHT AND NOT gray);
  33.   rainbow[col + 128 + 256] := Red OR (WHT AND NOT gray);
  34.   rainbow[col + 192] := Red OR NOT gray;
  35.   rainbow[col + 192 + 256] := Red OR NOT gray;
  36.  End;
  37.  _SetViewOrg( 160, 85, rec );
  38.  For i:=0 to 254 do Begin
  39.   _SetColor(255-i);
  40.   _MoveTo(i,i-255);
  41.   _LineTo(-i,255-i);
  42.   _MoveTo(-i,i-255);
  43.   _LineTo(i,255-i);
  44.   _Ellipse(_GBorder,-i,-i div 2,i,i div 2);
  45.  End;
  46.  i:=0;
  47.  While not KeyPressed do Begin
  48.   _RemapAllPalette(rainbow[i]);
  49.    i:=i+step;
  50.    If(i >= 256)Then i:=0;
  51.  End;
  52.  a:=_SetVideoMode(_DefaultMode);
  53. END.

on obtiendra un résultat ressemblant à ceci :

Utilisation des modes vidéo texte couleur

Tous les adaptateurs vidéo prennent en charge les modes de texte vidéo (_TextC40, _TextC80, _TextBW40, _TextBW80, _TextMono). En utilisant les modes de texte vidéo, vous pouvez afficher du texte en couleur sans avoir à entrer dans un mode graphique. Sur un moniteur couleur, vous pouvez afficher du texte normal ou clignotant dans l'une des 16 couleurs de premier plan avec l'une des 8 couleurs d'arrière-plan. Sur un moniteur monochrome, vous pouvez spécifier des «couleurs» de texte exactement de la même manière, bien que les valeurs de couleur soient interprétées différemment par le matériel.

Les procédures et fonctions de texte décrites dans cette section peuvent être utilisées dans les modes vidéo texte ainsi que dans tous les modes graphiques.

Sélection des couleurs du texte

Dans un mode texte vidéo, chaque caractère affiché nécessite deux octets de mémoire vidéo. Le premier octet contient le code ASCII représentant le caractère et le second octet contient l'attribut d'affichage. Dans les modes de texte vidéo couleur CGA, l'octet d'attribut détermine la couleur et s'il clignotera. Seize couleurs sont disponibles : les index CGA et les index EGA et VGA par défaut. Étant donné que les palettes EGA et VGA peuvent être cartographiées, ces valeurs peuvent être faites pour correspondre à n'importe quel ensemble de 16 couleurs avec la cartographie de palette approprié.

Utilisation des couleurs de texte

Utilisez les fonctions _GetTextColor et _GetBkColor pour trouver les couleurs de premier plan et d'arrière-plan du texte actuel.

Les valeurs comprises entre 0 et 15 sont interprétées comme une couleur normale. Les valeurs comprises entre 16 et 31 ont les mêmes couleurs que celles comprises entre 0 et 15 mais avec un texte clignotant.

Définissez les couleurs de premier plan et d'arrière-plan dans un mode texte vidéo avec les fonctions _SetTextColor et _SetBkColor. Ces fonctions utilisent un seul paramètre spécifiant l'index à utiliser pour le texte affiché avec la procédure _OutText. Les index de couleur pour les modes texte vidéo couleur sont définis dans le tableau suivant :

Numéro Couleur Numéro Couleur
0 Noir 8 Gris
1 Bleu 9 Bleu clair
2 Vert 10 Vert clair
3 Cyan 11 Cyan clair
4 Rouge 12 Rouge clair
5 Magenta 13 Magenta clair
6 Marron 14 Jaune
7 Blanc 15 Blanc clair

Sur les écrans monochromes, vous pouvez sélectionner des attributs de texte de la même manière que pour les écrans couleur. Pour le texte souligné, utilisez Bleu ou Bleu clair. Pour le texte en surbrillance, utilisez n'importe quelle couleur du vert clair au blanc. Pour un texte clignotant, ajoutez 16 à la constante de couleur.

Affichage des couleurs de texte

La procédure _SetTextPosition déplace le curseur vers une ligne et une colonne pour afficher le texte en couleur. La procédure _OutText affiche le texte.

Le programme suivant affiche un graphique montrant toutes les combinaisons possibles de couleurs de texte et d'arrière-plan :

  1. Program coltext; { Affiche le texte en couleur }
  2.  
  3. Uses
  4.  Crt, MSGraph;
  5.  
  6. Var
  7.  message1,s,t:String;
  8.  blink,fgd,bgd:Integer;
  9.  a:Integer;
  10.  
  11. BEGIN { Début du programme principal }
  12.  _ClearScreen(_GClearScreen);
  13.  _OutText('Attributs de texte en couleur :');
  14.  For blink:=0 to 1 do For bgd:=0 to 6 do Begin
  15.   _SetBkColor(bgd);
  16.   _SetTextPosition(bgd+(blink*9)+3,1);
  17.   _SetTextColor(7);
  18.   Str(bgd,s);
  19.   message1:='Bgd: ';
  20.   _OutText(message1);
  21.   _OutText(s);
  22.   s:=s+' ';
  23.   message1:='Fgd: ';
  24.   _OutText(message1);
  25.   For fgd := 0 to 15 do Begin
  26.    _SetTextColor(fgd+(blink*16));
  27.    a:=fgd+(blink*16);
  28.    Str(a,s);
  29.    s:=s+' ';
  30.    _OutText(s);
  31.   End;
  32.  End; { Boucle FOR }
  33.  Repeat Until KeyPressed;
  34.  a:=_SetVideoMode(_DefaultMode);
  35. END.

on obtiendra un résultat ressemblant à ceci :

Comprendre les systèmes de coordonnées

Avant de pouvoir écrire un programme pour afficher un mot ou pour afficher des graphiques à l'écran, vous avez besoin d'un système décrivant exactement où imprimer ou afficher l'élément.

Le QuickPascal fournit plusieurs systèmes de coordonnées. Le système de coordonnées physiques a déjà été utilisé dans le programme 1STGRAPH.PAS. Cette section traite des quatre systèmes de coordonnées pris en charge par QuickPascal et montre comment traduire entre les systèmes.

Les systèmes de coordonnées pris en charge par QuickPascal sont :

Coordonnées du texte

Le QuickPascal divise l'écran de texte en lignes et en colonnes. Voir l'image suivante :

Deux conventions importantes à garder à l'esprit concernant le mode texte vidéo sont :

Si l'écran est en mode texte vidéo affichant 25 lignes et 80 colonnes (comme dans l'image précédente), les lignes sont numérotées de 1 à 25 et les colonnes sont numérotées de 1 à 80. Dans les routines telles que _SetTextPosition, étant appelée dans l'exemple de programme suivant, les paramètres que vous transmettez sont la ligne et la colonne (dans cet ordre). Certains moniteurs (tels que l'EGA ou le VGA) prennent en charge plus de 25 lignes de texte. Pour ces moniteurs, utilisez les fonctions _SetVideoModeRows ou _SetTextRows pour spécifier le nombre de lignes à afficher.

Coordonnées de l'écran physique

Supposons que vous écriviez un programme qui appelle _SetVideoMode et place l'écran en mode graphique _VRes16Color du VGA. Cela vous donne un écran contenant 640 pixels horizontaux et 480 pixels verticaux. Les pixels individuels sont nommés par leur emplacement par rapport à l'axe x et à l'axe y, comme le montre la figure 13.2.

Deux différences importantes entre les coordonnées textuelles et les coordonnées graphiques sont :

Le coin supérieur gauche est appelé "l'origine". Les coordonnées x et y de l'origine sont toujours (0,0). Si vous utilisez des variables pour faire référence aux emplacements des pixels, déclarez-les comme des entiers. Le port d'affichage ("viewport") est la région où les graphiques seront affichés.

Changer l'origine avec SetViewOrg

La procédure _SetViewOrg modifie l'emplacement de l'origine de la fenêtre. Vous passez deux nombres entiers, représentant les coordonnées x et y d'un emplacement d'écran physique. Par exemple, la ligne suivante déplacerait l'origine vers l'emplacement de l'écran physique (50, 100) :

  1. _SetViewOrg(50,100,xyorg);

L'effet sur l'écran est illustré dans l'image suivante :

Le nombre de pixels n'a pas changé, mais les noms donnés aux points ont changé. L'axe des x va désormais de -50 à +589 au lieu de 0 à 639. L'axe des y couvre désormais les valeurs de -100 à +379. (Si vous possédez un adaptateur autre que le VGA, les chiffres sont différents mais l'effet est le même.

Toutes les fonctions et procédures graphiques standard sont affectées par la nouvelle origine, y compris _MoveTo, _LineTo, _Rectangle, _Ellipse, _Arc et _Pie.

Par exemple, si vous appelez la procédure _Rectangle après avoir déplacé l'origine de la fenêtre et que vous lui transmettez les valeurs de coordonnées (0,0) et (40,40), le rectangle sera dessiné à 50 pixels du bord gauche de l'écran et à 100 pixels du haut. Il n'apparaîtrait pas dans le coin supérieur gauche.

Les valeurs transmises à _SetViewOrg sont toujours des emplacements d'écran physiques. Supposons que vous ayez appelé deux fois la même procédure :

  1. _SetViewOrg(50,100,xyorg);
  2. _SetViewOrg(50,100,xyorg);

L'origine de la fenêtre ne se déplacerait pas vers (100, 200). Il resterait à l'emplacement de l'écran physique (50,100).

Définition d'une zone de découpage avec _SetClipRgn

La procédure _SetClipRgn crée une zone rectangulaire invisible à l'écran appelée «zone de découpage». Les tentatives de dessin à l'intérieur de la zone de découpage sont réussies, tandis que les tentatives de dessin à l'extérieur de la région ne le sont pas.

Lorsque vous entrez pour la première fois dans un mode graphique, la zone de découpage par défaut correspond à l'intégralité de l'écran. Le QuickPascal ignore toute tentative de dessin en dehors de la zone de découpage.

La modification de la zone de découpage nécessite un appel à _SetClipRgn. Supposons que vous êtes entré dans le mode graphique _MRes4Color du CGA, ayant une résolution d'écran de 320x200 pixels. Si vous tracez une ligne diagonale du coin supérieur gauche au coin inférieur droit, l'écran ressemble à l'image suivante :

Vous pouvez créer une zone de découpage avec les éléments suivants :

  1. _SetClipRgn(10,10,309,189);

Ensuite, tracez une ligne avec la déclaration :

  1. _LineTo(0,0,319,199);

Avec la zone de découpage en vigueur, la même commande _LineTo donnée ci-dessus placerait la ligne illustrée à l'image suivante à l'écran :

Les lignes brisées n'apparaissent pas réellement à l'écran. Ils indiquent les limites extérieures de la région de découpage.

Coordonnées de la fenêtre

Les coordonnées de la fenêtre sont un autre système de coordonnées pris en charge par QuickPascal. Vous pouvez établir une nouvelle fenêtre d'affichage dans les limites de l'écran physique à l'aide de la procédure _SetViewport. Une fenêtre standard présente deux caractéristiques distinctes :

La procédure _SetViewport fait la même chose que d'appeler _SetViewOrg et _SetClipRgn ensemble.

Coordonnées réelles dans une fenêtre

Le QuickPascal prend en charge un système de coordonnées réelles à utiliser dans une fenêtre. Ce système vous permet d'utiliser des valeurs à virgule flottante dans les graphiques.

Les fonctions et procédures faisant référence à des coordonnées sur l'écran physique et dans la fenêtre d'affichage nécessitent des valeurs entières. Cependant, dans les applications graphiques réelles, vous souhaiterez peut-être utiliser des valeurs à virgule flottante : cours des actions, prix du blé, précipitations moyennes,...

Définition des coordonnées de la fenêtre

La procédure _SetWindow vous permet de redimensionner l'écran à presque n'importe quelle taille. De plus, les fonctions et procédures liées à la fenêtre prennent des valeurs à virgule flottante double précision au lieu d'entiers.

Si, par exemple, vous vouliez représenter graphiquement 12 mois de températures moyennes allant de -40 à +100, vous pourriez ajouter la ligne suivante à votre programme :

  1. _SetWindow(TRUE,1.0,-40.0,12.0,100.0);

Le premier paramètre est le drapeau d'inversion, plaçant la valeur y la plus basse dans le coin inférieur gauche. Les coordonnées cartésiennes minimum et maximum suivent (la virgule décimale les marque comme des valeurs à virgule flottante). La nouvelle organisation de l'écran est illustrée dans l'image suivante :

Cette procédure fait apparaître les températures de janvier et de décembre sur les bords gauche et droit de l'écran. Dans une application comme celle-ci, il peut être préférable de numéroter l'axe des x de 0,0 à 13,0, pour fournir un espace supplémentaire.

Si vous tracez un point avec _SetPixel_w ou tracez une ligne avec _LineTo_w, les valeurs sont automatiquement mises à l'échelle de la fenêtre établie. Vous pouvez également trouver la position du curseur graphique à tout moment avec _GetCurrentPosition_wxy.

Programmation de graphiques en coordonnées réelles

Les quatre étapes pour utiliser des graphiques en coordonnées réelles sont :

Les graphiques en coordonnées réelles peuvent vous donner beaucoup de flexibilité. Par exemple, vous pouvez ajuster l'un ou l'autre des axes dans une petite plage (telle que 151,25 à 151,45) ou dans un grand intervalle (-50 000 à +80 000), selon le type de données que vous représentez. De plus, en modifiant les coordonnées de la fenêtre, vous pouvez créer des effets de zoom avant ou de panoramique sur une figure.

Un exemple de graphiques en coordonnées réelles

Le programme ci-dessous illustre comment utiliser les routines de fenêtre de coordonnées réelles :

  1. Program REALG; { Exemple de graphiques en coordonnées réelles }
  2.  
  3. Uses
  4.  MsGraph,Crt;
  5.  
  6. Const
  7.  bananas:Array[0..20] OF Single=(
  8.    -0.3, -0.2, -0.224,   -0.1, -0.5, +0.21,+2.9,
  9.    +0.3, +0.2,    0.0, -0.885, -1.1, -0.3, -0.2,
  10.   0.001,0.005,   0.14,    0.0, -0.9, -0.13,+0.3
  11.  );
  12. Var
  13.  halfx,halfy,a:Integer;
  14.  vc:_VideoConfig;
  15.  ch:Char;
  16.  
  17. Function four_colors:Boolean;Begin
  18.  four_colors:=False;
  19.  If(_SetVideoMode(_MaxColorMode) > 0)Then Begin
  20.   _GetVideoConfig(vc);
  21.   If(vc.NumColors>=4)Then four_colors:=True;
  22.  End;
  23. End;
  24.  
  25. Procedure grid_shape;
  26. Var
  27.  i,x1,y1,x2,y2:Integer;
  28.  x,y:Real;
  29.  s:String[80];
  30. Begin
  31.  For i:=1 to vc.NumColors do Begin
  32.   _SetTextPosition(i,2);
  33.   _SetTextColor(i);
  34.   Str(i,s);
  35.   _OutText('Couleur ' + s);
  36.  End;
  37.  _SetColor(1);
  38.  _Rectangle_w(_GBorder,-1.0,-1.0,1.0,1.0);
  39.  _Rectangle_w(_GBorder,-1.02,-1.02,1.02,1.02);
  40.  x:=-0.9;
  41.  i:=0;
  42.  While x<0.9 do Begin
  43.   _SetColor(2);
  44.   _MoveTo_w(x,-1.0); _LineTo_w(x,1.0);
  45.   _MoveTo_w(-1.0,x); _LineTo_w(1.0,x);
  46.   _SetColor(3);
  47.   _MoveTo_w(x-0.1,bananas[i]);
  48.   Inc(i);
  49.   _LineTo_w(x,bananas[1]);
  50.   x:=x+0.1;
  51.  End;
  52.  _MoveTo_w(0.9,bananas[i]);
  53.  Inc(i);
  54.  _LineTo_w( 1.0, bananas[i] );
  55. End;
  56.  
  57. Procedure three_graphs;
  58. Var
  59.  upleft,botright:_WXYCoord;
  60.  xwidth,yheight,cols,rows:Integer; 
  61. Begin
  62.  _ClearScreen( _GClearScreen ) ;
  63.  xwidth:=vc.NumXPixels;
  64.  yheight:=vc.NumYPixels;
  65.  halfx:=xwidth DIV 2;
  66.  halfy:=yheight DIV 2;
  67.  cols:=vc.NumTextCols ;
  68.  rows:=vc.NumTextRows;
  69.   { Première fenêtre }
  70.  _SetViewport(0,0,halfx-1, halfy-1);
  71.  _SetTextWindow(1,1,rows DIV 2, cols DIV 2);
  72.  _SetWindow(False,-2.0,-2.0,2.0,2.0);
  73.  grid_shape;
  74.  _Rectangle(_GBorder,0,0,halfx-1,halfy-1);
  75.   { Seconde fenêtre }
  76.  _SetViewport(halfx, 0,xwidth-1,halfy-1);
  77.  _SetTextWindow(1, cols DIV 2+1, rows DIV 2, cols);
  78.  _SetWindow(False, -3.0, -3.0, 3.0, 3.0);
  79.  grid_shape;
  80.  _Rectangle_w(_GBorder, -3.0, -3.0, 3.0, 3.0);
  81.   { Troisième fenêtre }
  82.  _SetViewport(0, halfy, xwidth-1, yheight-1);
  83.  _SetTextWindow(rows DIV 2+2, 1, rows, cols);
  84.  _SetWindow(True, -3.0, -1.5, 1.5, 1.5);
  85.  grid_shape;
  86.  upleft.wx:=-3.0;
  87.  upleft.wy:=-1.5;
  88.  botright.wx:=1.5;
  89.  botright.wy:=1.5;
  90.  _Rectangle_wxy(_GBorder, upleft, botright);
  91. End;
  92.  
  93. BEGIN { Programme principal }
  94.  If four_colors Then Begin
  95.   _OutText('Ce programme nécessite une carte graphique CGA, EGA ou VGA');
  96.   three_graphs;
  97.  End;
  98.  ch:=ReadKey;
  99.  a:=_SetVideoMode(_DefaultMode);
  100. END.

Le corps principal du programme est court. Il appelle la fonction four_colors (définie ci-dessous), tentant d'entrer dans un mode graphique dans lequel au moins quatre couleurs sont disponibles. Si elle réussit, la fonction three_graphs est appelée. Cette fonction utilise les nombres du tableau des bananes pour dessiner trois graphiques. La sortie de l'écran REALG.PAS est illustrée dans la capture d'écran suivante :

Il convient de noter que les graphiques sont tous dessinés en utilisant les mêmes nombres. Cependant, le programme utilise trois fenêtres de coordonnées réelles différentes. Les deux fenêtres de la moitié supérieure ont la même taille en coordonnées physiques, mais elles ont des tailles de fenêtre différentes. Dans les trois cas, la grille a une largeur de deux unités. Dans le coin supérieur gauche, la fenêtre a une largeur de quatre unités ; en haut à droite, la fenêtre a une largeur de six unités, ce qui fait apparaître le graphique plus petit.

Dans deux des trois graphiques, l'une des lignes sort du bord, en dehors de la zone de découpage. Les lignes n'empiètent pas sur les autres fenêtres, car la définition d'une fenêtre crée une zone de découpage.

Enfin, notez que le graphique en bas de l'écran semble être à l'envers par rapport aux deux graphiques du dessus. C'est le résultat de la définition de l'indicateur d'inversion sur True.

Entrer dans un mode graphique

La première étape de tout programme graphique consiste à entrer dans un mode graphique. La fonction four_colors effectue cette étape :

  1. Function four_colors:Boolean;Begin
  2.  four_colors:=False;
  3.  If(_SetVideoMode(_MaxColorMode) > 0)Then Begin
  4.   _GetVideoConfig(vc);
  5.   If(vc.NumColors>=4)Then four_colors:=True;
  6.  End;
  7. End;

La procédure _GetVideoConfig place certaines informations dans la structure _VideoConfig appelée screen. Ensuite, vous utilisez le membre screen.adapter de la structure _VideoConfig dans une construction d'instruction CASE pour activer le mode graphique correspondant. Les constantes symboliques _CGA et le reste sont définies dans l'unité MSGraph. Les modes contenant la lettre «O» sont des modes Olivetti.

Si l'ordinateur est équipé d'une carte de couleur, cette fonction renvoie un TRUE. Si ce n'est pas le cas, il renvoie un FALSE, ce qui oblige le programme à ignorer la fonction three_graphs et à terminer le programme.

Si la fonction four_colors fonctionne correctement, le programme appelle la procédure ci-dessous, affichant les trois graphiques :

  1. Procedure three_graphs;
  2. Var
  3.  upleft,botright:_WXYCoord;
  4.  xwidth,yheight,cols,rows:Integer; 
  5. Begin
  6.  _ClearScreen( _GClearScreen ) ;
  7.  xwidth:=vc.NumXPixels;
  8.  yheight:=vc.NumYPixels;
  9.  halfx:=xwidth DIV 2;
  10.  halfy:=yheight DIV 2;
  11.  cols:=vc.NumTextCols ;
  12.  rows:=vc.NumTextRows;
  13.   { Première fenêtre }
  14.  _SetViewport(0,0,halfx-1, halfy-1);
  15.  _SetTextWindow(1,1,rows DIV 2, cols DIV 2);
  16.  _SetWindow(False,-2.0,-2.0,2.0,2.0);
  17.  grid_shape;
  18.  _Rectangle(_GBorder,0,0,halfx-1,halfy-1);
  19.   { Seconde fenêtre }
  20.  _SetViewport(halfx, 0,xwidth-1,halfy-1);
  21.  _SetTextWindow(1, cols DIV 2+1, rows DIV 2, cols);
  22.  _SetWindow(False, -3.0, -3.0, 3.0, 3.0);
  23.  grid_shape;
  24.  _Rectangle_w(_GBorder, -3.0, -3.0, 3.0, 3.0);
  25.   { Troisième fenêtre }
  26.  _SetViewport(0, halfy, xwidth-1, yheight-1);
  27.  _SetTextWindow(rows DIV 2+2, 1, rows, cols);
  28.  _SetWindow(True, -3.0, -1.5, 1.5, 1.5);
  29.  grid_shape;
  30.  upleft.wx:=-3.0;
  31.  upleft.wy:=-1.5;
  32.  botright.wx:=1.5;
  33.  botright.wy:=1.5;
  34.  _Rectangle_wxy(_GBorder, upleft, botright);
  35. End; 

Travailler avec des fenêtres

Bien que l'entrée dans un mode graphique efface automatiquement l'écran, cela ne fait pas de mal d'être sûr, donc three_graphs appelle la procédure _ClearScreen :

  1. _ClearScreen(_GClearScreen);

La constante _GClearScreen provoque l'effacement de tout l'écran physique. Les autres options incluent _GViewport et _GWindow, effaceront respectivement la fenêtre d'affichage actuelle et la fenêtre de texte actuelle. La première fenêtre après avoir attribué des valeurs à certaines variables, la procédure three_graphs crée la première fenêtre :

  1. _SetViewPort(0,0,halfx-1,halfy-1);
  2. _SetTextWindow(1,1, rows/2, cols/2);
  3. _SetWindow(False,-2.0, -2.0, 2.0, 2.0);

Tout d'abord, une fenêtre est définie pour couvrir le quart supérieur gauche de l'écran. Ensuite, une fenêtre de texte est définie dans les limites de cette bordure. (Notez que la numérotation commence à 1 et que l'emplacement de la ligne précède la colonne.) Enfin, une fenêtre est définie. La constante False force l'axe y à augmenter de haut en bas. Les coins de la fenêtre sont (-2.0, -2.0) en haut à gauche et (2.0, 2.0) en bas à droite.

Ensuite, la fonction grid_shape est appelée et une bordure est ajoutée à la fenêtre :

  1. grid_shape;
  2. _Rectangle(_GBorder,0,0,halfx-1,halfy-1);

Notez qu'il s'agit de la procédure standard _Rectangle, prenant des coordonnées relatives à la fenêtre (et non aux coordonnées de la fenêtre).

Deux autres fenêtres

Les deux autres fenêtres sont similaires à la première. Tous les trois appellent grid_shape (défini ci-dessous), dessinant une grille de l'emplacement (-1.0, -1.0) à (+1.0, +1.0). La grille apparaît dans différentes tailles car les coordonnées dans les fenêtres varient. La deuxième fenêtre va de (-3,0, -3,0) à (+3,0, +3,0), de sorte que la largeur de la grille correspond à un tiers de la largeur de la deuxième fenêtre, alors qu'elle correspond à la moitié de la largeur de la première.

Notez également que la troisième fenêtre contient True comme premier paramètre. Cela fait augmenter l'axe y de bas en haut, au lieu de haut en bas. En conséquence, ce graphique semble être à l'envers par rapport aux deux autres.

Après avoir appelé grid_shape, le programme encadre chaque fenêtre avec l'une des procédures suivantes :

  1. _Rectangle(_GBorder,0,0,halfx-1,halfy-1);
  2. _Rectangle_w(_GBorder,-3.0,-3.0,3.0,3.0);
  3. _Rectangle_wxy(_GBorder,upleft,botright);

Les trois procédures contiennent un indicateur de remplissage comme premier paramètre. La procédure _Rectangle prend des paramètres entiers faisant référence aux coordonnées de l'écran de la fenêtre. La procédure _Rectangle_w prend quatre valeurs à virgule flottante à double précision faisant référence aux coordonnées de la fenêtre : x supérieur gauche, y supérieur gauche, x inférieur droit et y inférieur droit. La procédure _Rectangle_wxy prend deux paramètres : les adresses des structures de type _WXYCoord, contenant deux types Double nommés wx et wy. La structure est définie dans l'unité MSGraph. Les valeurs sont attribuées juste avant l'appel de _Rectangle_wxy.

Dessiner des graphiques

La procédure grid_shape est illustrée ici :

  1. Procedure grid_shape;
  2. Var
  3.  i,x1,y1,x2,y2:Integer;
  4.  x,y:Real;
  5.  s:String[80];
  6. Begin
  7.  For i:=1 to vc.NumColors do Begin
  8.   _SetTextPosition(i,2);
  9.   _SetTextColor(i);
  10.   Str(i,s);
  11.   _OutText('Couleur ' + s);
  12.  End;
  13.  _SetColor(1);
  14.  _Rectangle_w(_GBorder,-1.0,-1.0,1.0,1.0);
  15.  _Rectangle_w(_GBorder,-1.02,-1.02,1.02,1.02);
  16.  x:=-0.9;
  17.  i:=0;
  18.  While x<0.9 do Begin
  19.   _SetColor(2);
  20.   _MoveTo_w(x,-1.0); _LineTo_w(x,1.0);
  21.   _MoveTo_w(-1.0,x); _LineTo_w(1.0,x);
  22.   _SetColor(3);
  23.   _MoveTo_w(x-0.1,bananas[i]);
  24.   Inc(i);
  25.   _LineTo_w(x,bananas[1]);
  26.   x:=x+0.1;
  27.  End;
  28.  _MoveTo_w(0.9,bananas[i]);
  29.  Inc(i);
  30.  _LineTo_w( 1.0, bananas[i] );
  31. End; 

Tout d'abord, le nombre d'index de couleurs disponibles est affecté à la variable numc et une boucle affiche toutes les couleurs disponibles :

  1. For 1:=1 to numc do Begin
  2.  _SetTextPosition(i,2);
  3.  _SetTextColor(i);
  4.  Str(i,s);
  5.  _OutText('Couleur '+s);
  6. End;

Les noms des procédures sont explicites. L'avantage d'utiliser _OutText en mode graphique est que vous pouvez contrôler la couleur du texte et limiter la sortie à la fenêtre de texte actuellement définie.

Les noms de procédure et de fonction se terminant par _w fonctionnent de la même manière que leurs équivalents de port d'affichage, sauf que vous transmettez des valeurs à virgule flottante à double précision au lieu d'entiers. Par exemple, vous transmettez des entiers à _LineTo mais des valeurs à virgule flottante à _LineTo_w.

Animation

L'unité MSGraph de QuickPascal fournit plusieurs fonctions pouvant être utilisées pour animer vos programmes graphiques. Ces fonctions proposent deux moyens d'animation :

"L'animation de page vidéo" tire parti du fait que les cartes vidéo EGA, VGA et Hercules ont suffisamment de mémoire pour entreposer plus d'une page d'affichage vidéo. Vous pouvez animer en basculant entre les pages. «Animation bitmap» capture des images bitmap de l'écran, puis les entrepose dans une mémoire tampon. Ces images peuvent être réaffichées à un nouvel emplacement pour effectuer une animation.

Cette section traite de ces deux techniques d'animation et montre deux exemples de programmes donnant vie à vos graphiques.

Animation de page vidéo

La plupart des adaptateurs vidéo contiennent suffisamment de mémoire pour que plusieurs pages d'affichage puissent être entreposées à la fois. L'unité MSGraph fournit plusieurs fonctions vous permettant de manipuler ces pages vidéo. Deux termes sont utilisés pour décrire ces pages : la «page active» est la page où opèrent les commandes de texte et de graphiques ; la «page visuelle» est la page que vous voyez affichée.

Le nombre de pages vidéo disponibles dans un adaptateur dépend de la quantité de mémoire vidéo sur l'adaptateur et du mode dans lequel l'adaptateur est utilisé. Par exemple, l'adaptateur CGA avec 16 Ko de mémoire vidéo prend en charge quatre pages vidéo en mode texte _TextC80. Un adaptateur EGA avec une mémoire vidéo complète de 256 Ko a de la place pour deux pages vidéo, même en mode _EResColor haute résolution. Pratiquement tous les adaptateurs fournissent plusieurs pages en mode texte ; seuls les adaptateurs EGA et VGA avec 256 Ko de mémoire vidéo prennent en charge deux pages vidéo dans les modes graphiques haute résolution. Le mode graphique Hercules (_HercMono) peut prendre en charge deux pages, mais uniquement s'il s'agit de la seule carte graphique présente et uniquement lorsque MSHERC.COM est démarré sans l'option /H.

Utilisez la procédure _GetVideoConfig pour obtenir des informations sur la configuration vidéo. Après avoir appelé _GetVideoConfig, utilisez l'élément NumVideoPages de la structure _VideoConfig pour déterminer le nombre de pages vidéo prises en charge.

Une utilisation simple des pages vidéo consiste à dessiner des graphiques hors écran (sur la page active), puis à faire de cette page active la page visuelle. De cette façon, vous ne voyez pas le processus de création des graphiques ; vous ne voyez que le résultat final. Ce processus de dessin hors écran puis de commutation peut être étendu pour fournir une animation.

La procédure _SetVisualPage modifie la page que vous voyez. La procédure _SetActivePage change la page où le dessin a lieu. La première page de tout système graphique porte le numéro 0, la seconde le numéro 1,... Un ensemble correspondant de fonctions _GetActivePage et _GetVisualPage renvoient respectivement la valeur de la page active ou visuelle actuelle.

Pour animer une séquence d'écrans à l'aide d'une animation de page vidéo, procédez comme suit :

L'exemple de programme PAGES.PAS utilise quatre pages vidéo pour animer un ensemble simple d'images de personnages en mode texte :

  1. Program page_animation;
  2.  { PAGES.PAS: Utiliser des pages vidéo pour animer des écrans }
  3. Uses
  4.  MSGraph,Crt;
  5.  
  6. Const
  7.  jumper:Array[0..3] of String=('/O\', '-O-', '\O/', 'WOW');
  8.  
  9. Var
  10.  a,i:Integer;
  11.  oldvpage:Integer;
  12.  oldapage:Integer;
  13.  vc:_VideoConfig;
  14.  oldcursor:Boolean;
  15.  
  16. BEGIN { Début le programme principal }
  17.  _ClearScreen(_GClearScreen) ;
  18.  oldapage:=_GetActivePage;
  19.  oldvpage:=_GetVisualPage;
  20.  { Définir le mode vidéo pour une grande taille de texte }
  21.  a:=_SetVideoModeRows(_TextBW40,25);
  22.  _GetVideoConfig(vc);
  23.  If((a = 0)or(vc.NumVideoPages < 4))Then Begin
  24.   Writeln('Mode _TEXTBW40 non disponible ; appuyez sur Retour pour continuer');
  25.   ReadLn;
  26.   a:=_SetVideoMode(_DefaultMode);
  27.   Halt(0);
  28.  End;
  29.   { Éteignez le curseur clignotant. }
  30.  oldcursor:=_DisplayCursor(False);
  31.   { Dessinez une image sur chaque page. }
  32.  For i:=0 to 3 do Begin
  33.   _SetActivePage(i);
  34.   _SetTextPosition(12, 20);
  35.   _OutText(jumper[i]);
  36.  End;
  37.   { Parcourez les pages 0 à 3. }
  38.  Repeat
  39.   For i:=0 to 3 do Begin
  40.    _SetVisualPage( i );
  41.    Delay(500);
  42.   End;
  43.  Until KeyPressed;
  44.   { Restaurez tout avant de terminer le programme. }
  45.  a:=_SetVideoMode (_DefaultMode);
  46.  _SetActivePage(oldapage);
  47.  _SetVisualPage(oldvpage);
  48. END.

Le programme PAGES.PAS commence par un appel à _ClearScreen puis définit le mode vidéo à l'aide de la fonction _SetVideoModeRows. Le curseur est désactivé avec la fonction _DisplayCursor.

La boucle FOR dessine une image graphique sur chacune des quatre pages. La boucle va à chacune des pages vidéo et produit l'image graphique en utilisant la procédure _OutText. Lorsque vous exécutez ce programme, notez que vous ne voyez aucune de ces activités. Comme le dessin s'effectue sur les pages actives, il n'est pas visible à l'écran (la page visuelle).

Une fois les pages dessinées, la boucle REPEAT parcourt chaque page et en fait la page visuelle (afin que vous puissiez la voir), puis retarde 500 millisecondes entre les appels à _SetVisualPage.

Enfin, lorsqu'une touche est enfoncée, le programme se termine en restaurant le mode vidéo sur DefaultMode à l'aide de la fonction _SetVideoMode.

Animation bitmap

L'animation bitmap vous permet de dessiner des figures graphiques et de les entreposer en mémoire pour une utilisation ultérieure dans l'animation. La fonction _ImageSize détermine la quantité de mémoire requise pour stocker une image bitmap spécifiée. L'image est spécifiée en termes de rectangle englobant. La procédure _GetImage copie le bitmap des pixels à l'intérieur d'un rectangle spécifié dans une zone tampon en mémoire. La procédure _PutImage copie une image bitmap d'une mémoire tampon vers l'écran à un emplacement spécifié par le programme.

La procédure _PutImage utilise un paramètre CopyMode pour contrôler la façon dont l'image entreposée interagit avec ce qui est déjà à l'écran. Le paramètre CopyMode spécifie l'une des opérations d'affichage d'écran suivantes :

Constante Action
_Gand ET logique de l'image de transfert et de l'image d'écran.
_Gor Superposition de l'image de transfert sur l'image d'écran existante
_GPReset Transfert direct de la mémoire à l'écran ; couleur inversée
_GPSet Transfert direct de la mémoire à l'écran ; couleur inversée.
_Gxor Inversion d'écran uniquement lorsqu'un point existe dans l'image de transfert.

Les deux paramètres CopyMode les mieux adaptés à l'animation sont _Gxor et _GPSet.

L'animation réalisée avec _GPSet est plus rapide, mais efface l'arrière-plan de l'écran. En revanche, _Gxor est plus lent, mais préserve l'arrière-plan de l'écran.

L'animation avec _Gxor se fait avec les quatre étapes suivantes :

Le mouvement effectué avec ces quatre étapes laisse l'arrière-plan inchangé après la troisième étape. Le scintillement peut être réduit en minimisant le temps entre les étapes quatre et un, et en s'assurant qu'il y a suffisamment de temps entre les étapes 1 et 3. Si plus d'un objet est étant animé, chaque objet doit être traité en une fois, une étape à la fois.

S'il n'est pas important de préserver l'arrière-plan, l'animation peut être réalisée à l'aide de l'option _GPSet. Si la bordure du rectangle englobant autour de l'image est aussi grande ou plus grande que la distance maximale sur laquelle l'objet se déplacera, alors chaque fois que l'image est placée dans un nouvel emplacement, la bordure effacera toutes les traces de l'image dans l'ancien emplacement.

Utilisation d'images bitmap

Le processus d'animation à l'aide d'images bitmap suit ces huit étapes :

Un exemple d'animation bitmap

Le programme ANIMATE.PAS illustre ce processus en dessinant un rectangle puis en le réaffichant à des emplacements aléatoires sur l'écran.

  1. Program Animate;
  2.  { ANIMATE.PAS: Démonstration de l'animation à l'aide de tampons d'image }
  3. Uses
  4.  MSGraph,Crt;
  5. Const
  6.  max_buffer=65520;
  7.  
  8. Var
  9.  q:Integer;
  10.  vc:_VideoConfig;
  11.  buffer:Pointer;
  12.  imsize:LongInt;
  13.  x0,y0:Integer;
  14.  X,y:Integer;
  15.  
  16. BEGIN { Début du programme principal. }
  17.  _ClearScreen(_GClearScreen);
  18.   { Régle le mode vidéo et vérifie le succès }
  19.  q:=_SetVideoMode(_MaxResMode);
  20.  If(q = 0)Then Begin
  21.   WriteLn('Mode graphique indisponible ; appuyez sur RETURN pour continuer');
  22.   ReadLn;
  23.   q:=_SetVideoMode(_DefaultMode);
  24.   Halt(0);
  25.  End;
  26.   { Découvrez quelques caractéristiques de l'écran. }
  27.  _GetVideoConfig(vc);
  28.   { Dessinez et entreposez une figure simple. }
  29.  _SetColor(3);
  30.  x:=vc.NumXPixels div 4;
  31.  y:=vc.NumYPixels div 4;
  32.  _Rectangle(_GFillInterior,0,0,x,y);
  33.  imsize:=_ImageSize(0,0,x,y);
  34.  If(imsize > max_buffer)Then Begin
  35.   Writeln('Image trop grande.');
  36.   ReadLn;
  37.   Halt(0);
  38.  End
  39.   Else
  40.  Begin
  41.   GetMem(buffer,imsize);
  42.   If(buffer = NIL)Then Begin
  43.    WriteLn('Pas assez de mémoire de tas.');
  44.    ReadLn;
  45.    Halt(0);
  46.   End;
  47.  End;
  48.  _GetImage(0,0,x,y,buffer^);
  49.  _ClearScreen(_GClearScreen);
  50.   { Dessiner des axes centrés sur l'écran }
  51.  _SetColor(2);
  52.  x0:=vc.NumXPixels DIV 2 -1;
  53.  y0:=vc.NumYPixels DIV 2 -1;
  54.  _MoveTo(x0,0);
  55.  _LineTo(x0,vc.NumYPixels);
  56.  _MoveTo(0,y0);
  57.  _LineTo(vc.NumXPixels,y0); 
  58.  _SetTextPosition(1,1);
  59.  _OutText('_Gxor');
  60.  While Not KeyPressed do Begin
  61.   _PutImage(Random(vc.NumXPixels-x),Random(vc.NumYPixels-y), buffer^,_Gxor);
  62.   Delay(500);
  63.  End;
  64.  _ClearScreen(_GClearScreen);
  65.  q:=_SetVideoMode(_DefaultMode);
  66. END.

On obtiendra un résultat ressemblant à ceci :

Initialisation des graphiques et dessin de l'image

Le programme ANIMATE.PAS commence par effacer l'écran, initialiser le générateur de nombres aléatoires et régler le mode vidéo sur la résolution la plus élevée possible.

Le fragment de code suivant dessine et entrepose une image simple :

  1.  { Dessinez et entreposez une figure simple. }
  2.  _SetColor(3);
  3.  x:=vc.NumXPixels div 4;
  4.  y:=vc.NumYPixels div 4;
  5.  _Rectangle(_GFillInterior,0,0,x,y);
  6.  imsize:=_ImageSize(0,0,x,y);
  7.  If(imsize > max_buffer)Then Begin
  8.   Writeln('Image trop grande.');
  9.   ReadLn;
  10.   Halt(0);
  11.  End
  12.   Else
  13.  Begin
  14.   GetMem(buffer,imsize);
  15.   If(buffer = NIL)Then Begin
  16.    WriteLn('Pas assez de mémoire de tas.');
  17.    ReadLn;
  18.    Halt(0);
  19.   End;
  20.  End;
  21.  _GetImage(0,0,x,y,buffer^);
  22.  _ClearScreen(_GClearScreen); 

Allocation de mémoire

La procédure _Rectangle dessine un rectangle d'environ un seizième de la taille de l'écran. La fonction _ImageSize utilise les mêmes mesures de rectangle englobant pour déterminer la quantité de mémoire nécessaire pour contenir ce chiffre. La procédure GetMem alloue alors l'espace mémoire nécessaire à l'image. Comme GetMem peut allouer au maximum 65 520 octets (64K-16), vous devez vérifier la taille de l'image avant de demander la mémoire tampon. Si l'image est supérieure à 65 520 octets, vous devrez allouer des tampons supplémentaires et copier une partie de l'image dans chaque tampon.

La procédure _GetImage copie l'image de l'écran et l'entrepose dans la zone mémoire spécifiée par buffer. Enfin, la procédure _ClearScreen efface cette image de l'écran. Un programme plus complexe pourrait utiliser les pages actives et visuelles décrites dans la section précédente afin que l'image soit dessinée sur la page active et que la procédure _ClearScreen ne soit pas nécessaire.

Ensuite, le programme dessine un axe de coordonnées centré sur l'écran. Cela clarifiera plus tard comment l'image entreposée interagit avec les images déjà affichées à l'écran.

Affichage de l'image

Le programme appelle ensuite à plusieurs reprises _PutImage pour afficher l'image entreposée à des emplacements aléatoires sur l'écran. Le processus se termine lorsqu'une touche est enfoncée. Une fois qu'une touche est enfoncée, le programme se termine par un appel pour rétablir le mode vidéo.

  1.  While Not KeyPressed do Begin
  2.   _PutImage(Random(vc.NumXPixels-x),Random(vc.NumYPixels-y), buffer^,_Gxor);
  3.   Delay(500);
  4.  End;
  5.  _ClearScreen(_GClearScreen);
  6.  q:=_SetVideoMode(_DefaultMode);
  7. END.

La procédure _PutImage prend quatre paramètres. Les deux premiers spécifient les coordonnées x et y du coin supérieur gauche où l'image doit être affichée à partir de la mémoire tampon. Le troisième paramètre spécifie la mémoire tampon créée par GetMem et utilisée par _GetImage pour entreposer la bitmap. Enfin, le dernier paramètre spécifie l'interaction entre l'image entreposée et l'image actuellement affichée. Notez que dans ce cas (en utilisant le paramètre _Gxor) que l'image est inversée lorsqu'elle chevauche une figure actuellement affichée (comme les axes ou un autre rectangle).



Dernière mise à jour : Dimanche, le 28 août 2022