Obligement - L'Amiga au maximum

Dimanche 26 septembre 2021 - 14:59  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Quizz
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Trucs et astuces
 · Articles divers

 · Articles in english


Twitter

Suivez-nous sur Twitter




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

 · Menu des galeries

 · BD d'Amiga Spécial
 · Caricatures Dudai
 · Caricatures Jet d'ail
 · Diagrammes de Jay Miner
 · Images insolites
 · Fin de jeux (de A à E)
 · Fin de Jeux (de F à O)
 · Fin de jeux (de P à Z)
 · Galerie de Mike Dafunk
 · Logos d'Obligement
 · Pubs pour matériels
 · Systèmes d'exploitation
 · Trombinoscope Alchimie 7
 · Vidéos


Téléchargement

 · Documents
 · Jeux
 · Logiciels
 · Magazines
 · Divers


Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : Amiga C Manual - Les routines graphiques de bas niveau
(Article écrit par Anders Bjerin et extrait d'Amiga C Manual - mars 1990)


Note : traduction par Serge Hammouche.

12. Les routines graphiques de bas niveau

12.1 Introduction

Dans ce chapitre, nous examinerons les routines graphiques de bas niveau. Comme nous l'avons vu au chapitre 3 - Les graphismes, l'Amiga gère deux niveaux de graphisme différents. D'un côté, vous pourrez employer les routines graphiques de haut niveau qui utilisent des structures donnant de la flexibilité à votre programme, de l'autre, vous pourrez employer les routines graphiques de bas niveau qui permettent à votre programme un contrôle total sur tout le système graphique. Dans ce chapitre, nous verrons les routines graphiques de bas niveau.

On traitera des routines graphiques de bas niveau en deux parties. La première traitera de la manière dont on génère l'affichage. Ici, nous décrirons comment on choisit la définition d'un écran, son nombre de couleurs, s'il est en mode entrelacé ou non entrelacé, la taille des viewports, etc. La seconde partie traitera des outils de dessin qu'offre l'Amiga. Nous décrirons ici comment dessiner un seul point, des lignes, des polygones, comment changer la couleur, comment utiliser les patrons et les masques et nous verrons aussi les différents types de routines de remplissage, etc.

12.2 La création de l'affichage

Maintenant, nous jetons un coup d'oeil sur la manière dont on génère l'affichage. Cependant, avant de commencer à parler de ceci, il vaudra mieux que nous donnions des renseignements génériques sur les ordinateurs et le graphisme.

12.2.1 Une information d'ensemble

Nous décrirons ici comment est générée une image à l'affichage. Nous verrons aussi certains modes particuliers d'affichage comme le mode entrelacé, respectivement en haute et basse définition. Pour finir, nous parlerons du pixel et de l'emploi des plans de bits ("bitplanes" en anglais).

12.2.1.1 Comment fonctionne un moniteur (ou un poste de télévision)

L'image vidéo affichée sur un moniteur ou un téléviseur est réellement "dessinée" par un petit faisceau vidéo. Le faisceau vidéo commence son action dans le coin supérieur gauche de l'écran. Au fur et à mesure qu'il se déplace sur la droite, son intensité varie pour dessiner des points plus clairs ou plus foncés. Dès que ce faisceau a atteint le bord droit de l'écran, il se déplace vers le bord gauche et se positionne un peu plus bas. Puis, il se déplace à nouveau sur la droite et ainsi de suite.

Dans un affichage américain (NTSC), le faisceau se déplace de gauche à droite 262 fois (dans un affichage européen de type PAL, il se déplace 312 fois). Dès que le faisceau a atteint le bas de l'écran, il revient vers le coin supérieur gauche et tout le processus recommence. L'écran est ainsi "dessiné" 60 fois par seconde sur un moniteur NTSC et 50 fois par seconde sur un moniteur PAL.

Voici l'image vidéo sur un moniteur américain (NTSC) :

    1  ->---->---->---->   |
    2  ->---->---->---->   |
    3  ->---->---->---->   |
    |  et ainsi de suite...|
  261  ->---->---->---->   |
  262  ->---->---->---->   V

Comme vous pouvez le constater, vous pourriez avoir un affichage de plus de 262 (312) lignes, mais, habituellement, on n'utilise pas les toutes premières et dernières lignes car on pourrait difficilement les discerner. On vous recommande l'emploi d'un affichage de 200 lignes (256 en PAL) au maximum. Cependant, si vous souhaitiez utiliser des effets vidéo particuliers ou faire en sorte que l'écran cache l'intégralité de l'affichage, vous pourrez vous servir des 262 lignes (312). On fait référence à ce type d'effet particulier en parlant de suraffichage ("overscan" en anglais).

12.2.1.2 Le mode entrelacé

Un affichage américain normal a une taille totale de 200 lignes (un affichage PAL de 256). Cependant, l'Amiga a la particularité unique de pouvoir doubler cette quantité de lignes dans un même affichage, c'est-à-dire 400 lignes (512 en PAL). On appelle ce mode spécial le mode entrelacé.

La première fois que le faisceau se déplace sur l'écran, il trace toutes les lignes impaires (1, 3, 5, 7 ... 397, 399) et, la deuxième fois, toutes les lignes paires (2, 4, 6, 8 ... 398, 400).

Ce mode spécial peut engendrer un "scintillement" de l'écran, tout particulièrement si le contraste est élevé. Cela provient du fait que les lignes impaires sont dessinées 30 fois par seconde (25 fois en PAL) et que les lignes paires le sont 30 fois par seconde (25 fois en PAL). Si vous avez un écran avec une haute rémanence, vous n'aurez aucun problème, mais sur des moniteurs normaux à bon marché le scintillement peut devenir ennuyeux.

Première fois      Deuxième fois
        1 -------------
          ------------- 2
        3 -------------
          ------------- 4
        5 -------------
          ------------- 6
        7 -------------
          ------------- 8
       et ainsi de suite ...

12.2.1.3 La haute et la basse résolution

Il existe deux types de résolution horizontale différents. La basse résolution est de 320 pixels par ligne et la haute résolution de 640 (nombre de pixels double).

Il y a une différence importante entre ces deux modes de résolution. En basse résolution, vous pourrez avoir jusqu'à 32 couleurs et même utiliser le mode HAM ou Extra Half Bright (nous donnerons des explications plus loin), tandis qu'en haute résolution, vous pourrez employer seulement 16 couleurs ou moins.

Vous pourrez même employer l'affichage spécial en mode suraffichage. L'affichage aura alors une largeur maximale de 352 pixels en basse résolution et de 704 pixels en haute résolution.

12.2.1.4 Les pixels

L'affichage est constitué de petits points qu'on appelle "pixels". Comme nous l'avons expliqué ci-dessus, il peut y avoir 320 ou 640 pixels dans une ligne, ainsi que 200 ou 400 lignes (256 ou 512 en PAL).

Lorsque vous créez un affichage, vous allouez des zones de mémoire rectangulaires qui s'appellent plans de bits. Chaque octet de cette zone de mémoire représente un pixel.

Un affichage américain en haute résolution non entrelacé de 640x200 pixels aura besoin de 16 000 octets de mémoire pour chaque plan de bits.

Pour générer un tout petit écran (de 8x9 pixels) qui affichera un "A", le plan de bits ressemblera à ceci :

Ligne   Plan de bits 1
----------------------
  1      00000000
  2      00111100
  3      01000010
  4      01000010
  5      01111110
  6      01000010
  7      01000010
  8      01000010
  9      00000000

12.2.1.5 Les couleurs

Si vous voulez vous servir de différentes couleurs dans un écran, vous devrez employer plusieurs plans de bits. Tous les bits se trouvant au même emplacement dans chaque plan de bits représenteront alors un pixel. Avec deux plans de bits, vous pourrez avoir quatre combinaisons différentes pour chaque pixel. Trois plans de bits vous permettront huit combinaisons. Quatre plans de bits, seize combinaisons et, pour finir, cinq plans de bits trente-deux combinaisons.

Voici un exemple. Nous avons réservé de la mémoire pour deux plans de bits qui permettront de construire un tout petit affichage de 10 pixels par ligne, et d'une hauteur de quatre lignes.

 Ligne  Plan de bits 1  Plan de bits 2  Affichage (Couleur)
 ----------------------------------------------------------
   1    0000000000      0000000000      0000000000
   2    1111111111      0000000000      1111111111
   3    0000000000      1111111111      2222222222
   4    1111111111      1111111111      3333333333

Dans la première ligne, il y a de dix pixels de couleur 0 (00[b]=0[d]).
Dans la deuxième ligne, il y a de dix pixels de couleur 1 (01[b]=1[d]).
Dans la troisième ligne, il y a de dix pixels de couleur 2 (10[b]=2[d]).
Dans la quatrième ligne, il y a de dix pixels de couleur 3 (11[b]=3[d]).

Plus vous aurez de plans de bits, plus vous pourrez afficher de couleurs. Cependant, étant donné que vous aurez besoin d'un plus grand nombre de plans de bits, vous devrez allouer plus de mémoire.

 Plans de bits  Couleurs
 -----------------------
       1           2
       2           4
       3           8
       4          16
       5          32

12.2.2 Les éléments d'un affichage

12.2.2.1 Le raster

La zone dans laquelle vous pouvez dessiner s'appelle "raster". Elle est constituée de différents plan de bits les uns au-dessus des autres. Plus vous aurez de plans de bits, plus vous pourrez employer de couleurs en même temps. La largeur maximale du raster (RWidth) peut aller jusqu'à 1024 pixels ; sa hauteur (RHeight) aussi.

La partie du raster qui sera affichée s'appelle "ViewPort". Une structure de nom RasInfo contient les valeurs RxOffset et RyOffset qui déterminent quelle partie du raster on devra afficher dans le ViewPort. Le ViewPort a une largeur de DWide pixels et une hauteur de DHeight pixels (simple, n'est-ce pas ?).

Le raster :

    <- RxOffset ->
    --------------------------- A
    |          D   ViewPort   | | RyOffset
    |          H ------------ | V
  R |          e |XXXXXXXXXX| |
  H |          i |XXXXXXXXXX|-+-- Affichage de cette partie
  e |          g |XXXXXXXXXX| |
  i |          h ------------ |
  g |          t    DWidth    |
  h |                         |
  t |                         | 
    |                         |
    |                         |
    ---------------------------
            RWidth         

12.2.2.2 Le View

L'affichage vidéo est une zone où vous pourrez avoir un ou plusieurs ViewPorts. Cette zone s'appelle le "View" et les valeurs DxOffset et DyOffset de la structure View déterminent où il faudra positionner ce View dans l'affichage vidéo.

Vous pourrez donner à DxOffset et à DyOffset des valeurs négatives. Dans ce cas, le View sera plus à gauche et plus haut que d'habitude. La partie supérieure gauche du dessin sera difficile à discerner, par conséquent ce mode n'est pas recommandé dans des programmes d'affaires. Cependant, si vous écrivez des programmes de jeu ou vidéo, ce mode d'affichage particulier pourra s'avérer souvent utile.

Le View :

  <--> DxOffset
  ------------------------ A
  |   AFFICHAGE  VIDEO   | | DyOffset
  |  ------------------  | V
  |  |                |  |
  |  |                |  |
  |  |                |  |
  |  |      VIEW      |  |
  |  |                |  |
  |  |                |  |
  |  |                |  |
  |  ------------------  |
  |                      |
  ------------------------

12.2.2.3 Le ViewPort

Comme nous l'avons dit ci-dessus, le View peut avoir un ou plusieurs ViewPorts. Les valeurs DxOffset et DyOffset de la structure ViewPort indiquent où il faudra positionner le ViewPort dans le View.

  <--> DxOffset
  ------------------ A
  |      VIEW      | | DyOffset
  |  ------------  | V
  |  |          |  |
  |  | VIEWPORT |  |
  |  |          |  |
  |  ------------  |
  |                |
  ------------------

Il y a d'importantes restrictions sur le nombre de ViewPorts qu'on peut placer dans un View. Ces ViewPorts doivent être placés les uns au-dessous des autres, et espacés d'au moins une ou plusieurs lignes. Dès que le faisceau vidéo aura fini de dessiner la dernière ligne d'un ViewPort, l'Amiga aura besoin d'un peu de temps pour régler sa nouvelle définition, etc. dans le ViewPort suivant. Pendant que l'Amiga est en train de travailler sur l'écran suivant, le faisceau vidéo sera déjà descendu d'au moins une ligne (peut-être de plusieurs).

    Le View (L'affichage)
 --------------------------
 | Couleur d'arrière-plan |
 |  --------------        |
 |  | ViewPort 1 |        |
 |  |            |        |
 |  --------------        | ==> Une ligne au minimum devra
 |        --------------  |     séparer les ViewPorts.
 |        | ViewPort 2 |  |
 |        --------------  |
 --------------------------

La zone autour des ViewPorts sera remplie avec la couleur d'arrière-plan des ViewPorts.

Voici trois exemples :

1. Correct ! Les ViewPorts ne se chevauchent pas l'un l'autre, et il y a assez de place entre eux.

  ------------------------
  | -------------------- |
  | |                  | |
  | -------------------- |
  |    -------------     |
  |    |           |     |
  |    -------------     |
  | -------------------- |
  | |                  | |
  | -------------------- |
  ------------------------

2. Incorrect ! On doit placer les ViewPorts les uns au-dessous des autres, et non les uns à côté des autres.

  ------------------------
  | ---------  --------- |
  | |       |  |       | |
  | |       |  |       | |
  | |       |  |       | |
  | |       |  |       | |
  | |       |  |       | |
  | |       |  |       | |
  | |       |  |       | |
  | ---------  --------- |
  ------------------------

3. Incorrect ! Il doit y avoir de l'espace entre les divers ViewPorts (au minimum une ligne, peut-être plus d'une).

  ------------------------
  | -------------------- |
  | |                  | |
  | |                  | |
  | |                  | |
  | -------------------- |
  | |                  | |
  | |                  | |
  | |                  | |
  | -------------------- |
  ------------------------

12.2.2.4 La BitMap

La zone dans laquelle vous pouvez dessiner s'appelle (comme nous l'avons déjà dit) le raster. Le raster lui-même est constitué d'une ou plusieurs bitmaps. Une bitmap est une zone de mémoire rectangulaire. Chaque bit de cette zone représente un petit point (le pixel). Vous pouvez employer plusieurs bitmaps, ce qui veut dire que chaque point est constitué de différents bits (un bit pour chaque bitmap) et que la valeur binaire de ces bits détermine la couleur qui sera employée.

  BitMap 0      BitMap 1      BitMap 2      Couleur
  -------------------------------------------------------------
  0000011111    0000000000    0000000000 |  0000011111
  0000011111    1111111111    0000000000 |  2222233333
  0000011111    0000000000    1111111111 |  4444455555
  0000011111    1111100000    1111111111 |  6666677777

            De binaire à décimal
  -----------------------------------------
  | Binaire  Décimal  |  Binaire  Décimal |
  |-------------------+-------------------|
  | 00000         0   |  10000        16  |
  | 00001         1   |  10001        17  |
  | 00010         2   |  10010        18  |
  | 00011         3   |  10011        19  |
  |                   |                   |
  | 00100         4   |  10100        20  |
  | 00101         5   |  10101        21  |
  | 00110         6   |  10110        22  |
  | 00111         7   |  10111        23  |
  |                   |                   |
  | 01000         8   |  11000        24  |
  | 01001         9   |  11001        25  |
  | 01010        10   |  11010        26  |
  | 01011        11   |  11011        27  |
  |                   |                   |
  | 01000        12   |  11000        28  |
  | 01101        13   |  11101        29  |
  | 01110        14   |  11110        30  |
  | 01111        15   |  11111        31  |
  -----------------------------------------

Plus vous aurez de bitmaps, plus vous pourrez employer de couleurs. L'Amiga vous permet d'avoir jusqu'à six plans de bits avec certaines restrictions :
  • Un plan de bits (deux couleurs) : pas de restriction.
  • Deux plans de bits (quatre couleurs) : pas de restriction.
  • Trois plans de bits (huit couleurs) : pas de restriction.
  • Quatre plans de bits (16 couleurs) : un seul plan (playfield).
  • Cinq plans de bits (32 couleurs) : un seul plan (playfield), basse résolution.
  • Six plans de bits (64 couleurs) : un seul plan (playfield), basse résolution, Half Bright.
  • Six plans de bits (4096 couleurs) : un seul plan (playfield), basse résolution, HAM.
12.2.3 La création d'un affichage

Lorsque vous créerez un affichage, vous devrez d'abord déclarer et initialiser un certain nombre de structures importantes. Ces structures sont les suivantes :
  1. Structure View
  2. Structure ViewPort
  3. Structure ColorMap
  4. Structure BitMap
  5. Structure RasInfo
Dès que vous aurez initialisé ces structures, vous pourrez appeler trois fonctions [MakeVPort(), MrgCop() et LoadView()] et votre nouvel affichage sera mis en place.

12.2.3.1 Le View

Un View peut être constitué d'un ou plusieurs ViewPorts. Vous aurez même la possibilité d'avoir plusieurs Views en même temps dans la mémoire de l'Amiga, mais vous pourrez faire afficher un seul View à la fois. L'avantage d'avoir plusieurs Views est que vous pourrez montrer à l'utilisateur une image (un View) tandis que l'ordinateur dessine une autre image (dans un autre View).

Le View est doté d'un nombre de variables importantes qui indiquent la position du View, s'il doit être ou non en mode entrelacé, ainsi que les pointeurs sur le premier ViewPort, etc.

12.2.3.1.1 La structure View

La structure View ressemble à ceci [telle qu'elle est définie dans le fichier d'en tête "view.h"] :

struct View
{
  struct ViewPort *ViewPort;
  struct cprlist *LOFCprList;
  struct cprlist *SHFCprList;
  short DyOffset, DxOffset;
  UWORD Modes;
};
  • ViewPort : pointeur sur le premier ViewPort de l'affichage.
  • LOFCprList : pointeur sur une structure cprlist utilisée par le Copper (expliquée plus loin).
  • SHFCprList : pointeur sur une structure cprlist utilisée par le Copper, si la structure est en mode entrelacé (lorsque l'affichage est en mode entrelacé, on utilise LOFCprList et SHFCprList).
  • DyOffset : ordonnée Y de l'affichage.
  • DxOffset : abscisse X de l'affichage.
  • Modes : si l'affichage doit être en mode entrelacé, vous mettrez à 1 le drapeau LACE. Si l'affichage devait être relié à un signal vidéo externe, à l'aide d'un Genlock, vous mettrez à 1 le drapeau GENLOCK_VIDEO.
12.2.3.1.2 Préparation d'une structure View

Après avoir déclaré une structure View, vous devrez la préparer. Pour ce faire, vous appellerez la fonction InitView() avec un pointeur sur une structure View comme seul paramètre :

struct View my_view;  /* Déclaration d'une structure View. */

InitView( &my_view ); /* Préparation de celle-ci. */

Si vous souhaitez positionner le View à un endroit précis de l'affichage, vous devrez donner des valeurs DxOffset et DyOffset en rapport. Par exemple :

my_view.DxOffset = 20; /* 20 pixels à droite. */
my_view.DyOffset = 50; /* 50 lignes plus bas. */

Si vous souhaitez utiliser un affichage en mode entrelacé, vous devrez aussi mettre à 1 le drapeau "LACE". Par exemple :

my_view.Modes = LACE;

12.2.3.2 Les Viewports

Comme nous l'avons dit auparavant, chaque View peut être composé d'un ou plusieurs ViewPorts. Chaque ViewPort peut avoir sa propre résolution, un nombre de couleurs et une taille qui lui seront propres.

12.2.3.2.1 La structure Viewport

La structure ViewPort ressemble à ceci [telle qu'elle est définie dans le fichier d'en-tête "view.h"] :

struct ViewPort
{
  struct ViewPort *Next;
  struct ColorMap *ColorMap;
  struct CopList *DspIns;
  struct CopList *SprIns;
  struct CopList *ClrIns;
  struct UCopList *UCopIns;
  SHORT DWidth, DHeight;
  SHORT DxOffset, DyOffset;
  UWORD Modes;
  UBYTE SpritePriorities;
  UBYTE reserved;
  struct RasInfo *RasInfo;
};
  • Next : pointeur sur le prochain ViewPort dans le View, s'il y en a plusieurs, autrement NULL.
  • ColorMap : pointeur sur une structure ColorMap qu'on utilise pour ce ViewPort (voir ci-dessous pour avoir plus de renseignements sur la structure ColorMap).
  • DspIns : utilisé par le Copper.
  • SprIns : instructions de couleur propres aux sprites.
  • ClrIns : instructions de couleur propres aux sprites.
  • UCopIns : utilisé par le Copper.
  • DWidth : taille horizontale du ViewPort.
  • DHeight : taille verticale du ViewPort.
  • DxOffset : abscisse X du ViewPort dans le View.
  • DyOffset : ordonnée Y du ViewPort dans le View.
  • Modes : mode d'affichage pour ce ViewPort. On pourra employer les drapeaux suivants :
    • HIRES : mettez ce drapeau à 1 si vous voulez avoir un ViewPort en haute résolution, autrement le système emploiera la basse résolution.
    • LACE : mettez ce drapeau à 1 si vous voulez avoir un ViewPort en mode entrelacé, autrement le système le mettra en mode non entrelacé.
    • SPRITES : mettez ce drapeau à 1 si vous voulez avoir des sprites dans ce ViewPort.
    • HAM : mettez ce drapeau à 1 si vous voulez employer le mode d'affichage spécial "Hold And Modify". L'affichage devra être en basse résolution et employer six plans de bits. Permet d'afficher 4096 couleurs en même temps.
    • EXTRA_HALFBRITE : mettez ce drapeau à 1 si vous voulez employer le mode d'affichage spécial "Extra Half Bright". L'affichage devra être en basse résolution et employer six plans de bits. Permet d'utiliser 64 couleurs.
    • DUALPF : mettez ce drapeau à 1 si vous voulez vous servir d'un plan double.
    • PFBA : mettez ce drapeau à 1 si vous souhaitez que le plan 1 se trouve au-dessus du plan 2. Si vous ignorez ce drapeau, les priorités seront inversées.
    • GENLOCK_VIDEO : mettez ce drapeau à 1 si on doit pouvoir mélanger l'affichage à un autre signal vidéo, à l'aide d'un genlock.
      Remarque : vous pourrez combiner plusieurs de ces modes, si vous le souhaitez. Seulement, n'oubliez pas de mettre un "|" entre chaque drapeau. Par exemple, pour créer un ViewPort en haute résolution en mode entrelacé, vous devrez mettre ce champ à "HIRES|LACE".
  • SpritePriorities : priorité des sprites de ce ViewPort.
  • reserved : quels sprites sont réservés ; il ne peut être utilisé (voir le chapitre sprites et VSprites pour plus de renseignements).
  • RasInfo : pointeur sur une structure RasInfo.
12.2.3.2.2 Préparation d'une structure ViewPort

Après avoir déclaré une structure ViewPort, vous devrez la préparer (comme nous l'avons fait pour la structure View). Pour ce faire, vous appelerez la fonction InitVPort() avec un pointeur sur une structure ViewPort comme seul paramètre :

/* Déclaration de la structure View: */
struct ViewPort my_view_port;

/* Préparation de celle-ci: */
InitVPort( &my_view_port );

Une fois que vous aurez préparé la structure, vous pourrez placer les valeurs voulues dans les différents champs (voici à titre d'exemple) :
  • my_view_port.Next = NULL; : si nous avons plusieurs ViewPorts dans le même View, nous les relierons ensemble, autrement mettre NULL.
  • my_view_port.DWidth = WIDTH; : fixe la largeur voulue.
  • my_view_port.DHeight = HEIGHT; : fixe la hauteur voulue.
  • my_view_port.DxOffset = 0; : coordonnées X du ViewPort dans le View
  • my_view_port.DyOffset = 0; : coordonnées Y du ViewPort dans le View.
  • my_view_port.Modes = HIRES|LACE; : mettre les drapeaux voulus (par exemple, haute résolution entrelacée).
  • my_view_port.RasInfo = &my_ras_info; : pointeur sur la structure RasInfo de ce ViewPort.
12.2.3.3 La ColorMap

Chaque ViewPort a sa propre liste de couleurs. Celles-ci sont stockées dans une structure ColorMap qui renferme des informations du type suivant : le nombre de couleurs utilisant l'affichage, quelles couleurs, et - pour chaque couleur - ses valeurs RVB (intensité de Rouge + Vert + Bleu).

12.2.3.3.1 La structure ColorMap

La structure ColorMap ressemble à ceci [telle qu'elle est définie dans le fichier d'en-tête "view.h"] :

struct ColorMap
{
  UBYTE Flags;
  UBYTE Type;
  UWORD Count;
  APTR ColorTable;
};

12.2.3.3.2 Déclaration et initialisation d'une structure ColorMap

Pour déclarer et initialiser une structure ColorMap, vous n'aurez qu'à appeler la fonction GetColorMap(). Celle-ci s'occupera de tout : vous n'aurez qu'à indiquer à la fonction combien de couleurs vous souhaitez utiliser.

Voici comment on se réserve une liste de couleurs et on la relie à ViewPort :

my_view_port.ColorMap = GetColorMap( 32 );

Vous ne devrez pas oublier de vérifier que le système vous a bien réservé la liste (map) de couleurs demandée. Par exemple :

if( my_view_port.ColorMap == NULL )
  clean_up(); /* sortir */

12.2.3.3.3 Fixer les valeurs RVB

Dès que vous avez obtenu votre structure ColorMap, vous devrez fixer les valeurs RVB (Rouge, Vert, Bleu) de chaque couleur. Chaque couleur peut être un mélange de rouge, de vert et de bleu dans un rapport allant de 0 à 15. En hexa, cela ira de 0x0 à 0xF.

Voici quelques exemples :

  valeur RVB  Couleur
  -----------------------
  0xF00       Rouge
  0x0F0       Vert
  0x00F       Bleu
  0x600       Rouge foncé
  0x060       Vert foncé
  0x006       Bleu foncé
  0xFF0       Jaune
  0x000       Noir
  0x444       Gris foncé
  0x888       Gris clair
  0xFFF       Blanc

Étant donné que chaque valeur RVB peut prendre seize niveaux différents, vous pourrez définir jusqu'à 16*16*16=4096 couleurs différentes.

Si vous préparez une structure ColorMap devant utiliser quatre couleurs, vous devrez lui fournir une table de couleurs avec des valeurs RVB.

/* 1. Déclaration d'une table de couleurs RVB : */
UWORD my_color_table[] =
{
  0x000, /* Noir */
  0xF00, /* Rouge */
  0x0F0, /* Vert */
  0x00F, /* Bleu */
};

/* 2. Déclaration du pointeur : */
UWORD *pointer;

/* 3. Fixer le pointeur pour qu'il pointe sur la table de couleurs : */
pointer = (UWORD *) my_view_port.ColorMap->ColorTable;

/* 4. Fixez les couleurs : */
for( loop = 0; loop < 4; loop++ )
  *pointer++ = my_color_table[ loop ];

12.2.3.3.4 Libérer la mémoire occupée par la ColorMap

Lorsque votre programme ferme un ViewPort, vous ne devrez pas oublier de libérer la mémoire occupée par la ColorMap. Vous pourrez le faire à l'aide de la fonction FreeColorMap() :

FreeColorMap( my_view_port.ColorMap );

12.2.3.4 La BitMap

Comme nous l'avons déjà dit, la BitMap est une zone de mémoire rectangulaire où chaque bit représente un pixel. Par la combinaison de deux ou plusieurs BitMaps, chaque pixel sera représenté par une combinaison de deux ou plusieurs bits qui déterminent les couleurs qu'il faudra employer. Le pointeur sur chaque BitMap, les renseignements concernant sa taille, etc. sont tous stockés dans la structure BitMap.

12.2.3.4.1 La structure BitMap

La structure BitMap ressemble à ceci [telle qu'elle est définie dans le fichier d'en-tête "gfx.h"] :

struct BitMap
{
  UWORD BytesPerRow;
  UWORD Rows;
  UBYTE Flags;
  UBYTE Depth;
  UWORD pad;
  PLANEPTR Planes[ 8 ];
};
  • BytesPerRow : combien d'octets on utilise pour chaque rangée.
  • Rows : combien il y a de rangées.
  • Flags : renseignements supplémentaires sur les BitMaps (actuellement non utilisés).
  • Depth : combien il y a de plans de bits.
  • pad : espace supplémentaire.
  • Planes : une liste de huit pointeurs (PLANEPTR est un pointeur sur une BitMap).
12.2.3.4.2 Déclaration et initialisation d'une structure BitMap

Vous déclarez la structure comme d'habitude et vous l'initialisez à l'aide de la fonction InitBitMap(). Vous devrez fournir à cette fonction un pointeur sur votre structure BitMap ainsi que tout renseignement concernant sa taille et sa profondeur (combien de plans de bits seront utilisés).
  • Synopsis : InitBitMap( bitmap, profondeur, largeur, hauteur );
  • bitmap : (struct BitMap *). Pointeur sur la BitMap.
  • profondeur : (long). Combien de plans de bits seront utilisés.
  • largeur : (long). Largeur du raster.
  • hauteur : (long). Hauteur du raster.
Les renseignements concernant la taille et la profondeur d'une BitMap sont utilisés dans un programme en plusieurs endroits, par conséquent, je vous recommande de définir un certain nombre de constantes au début du programme et de les employer par la suite au lieu d'écrire explicitement ces valeurs, lors de l'appel. Ceci vous permettra de changer plus facilement quelque chose, du moment que vous aurez à changer le code à un seul endroit, et ceci vous évitera beaucoup de fautes d'écriture.

Exemple :

#define WIDTH  320 /* largeur 320 pixels.              */
#define HEIGHT 200 /* hauteur 200 lignes.              */
#define DEPTH    5 /* 5 plans de bits permettent d'avoir 32 couleurs. */

struct BitMap my_bit_map;

InitBitMap( &my_bit_map, DEPTH, WIDTH, HEIGHT );

12.2.3.4.3 Réservation de mémoire pour le raster

Dès que vous aurez initialisé la structure Bitmap, il sera temps de réserver de la mémoire pour chaque plan de bits. Vous pourrez réserver la mémoire nécessaire à l'affichage par la fonction AllocRaster() :
  • Synopsis : pointeur = AllocRaster( largeur, hauteur );
  • pointeur : (PLANEPTR). Pointeur sur la zone de mémoire demandée ou NULL s'il n'y a pas assez de mémoire.
  • largeur : (long). Largeur de la BitMap.
  • hauteur : (long). Hauteur de la BitMap.
Étant donné que vous pourriez avoir à réserver plusieurs plans de bits, le mieux serait d'inclure la fonction AllocRaster() dans une boucle. N'oubliez pas de vérifier que le système vous a bien alloué la mémoire que vous avez demandée ! Pour terminer, il est probable que la mémoire obtenue soit remplie d'octets inutiles et il vaudra mieux la vider avant de vous en servir. L'emploi du Blitter est la méthode plus rapide pour vider une zone de mémoire rectangulaire de grande taille; pour ce faire appelez la fonction BltClear() :
  • Synopsis : BltClear( pointeur, octets, drapeaux );
  • pointeur : (char *). Pointeur sur la zone de mémoire à vider.
  • octets : (long). Les 16 bits de rang inférieur informent le Blitter sur nombre d'octets existant par rangée et les 16 bits de rang supérieur l'informent sur le nombre de rangées existantes. Cette valeur est calculée automatiquement pour vous à l'aide de la macro RASSIZE(). Donnez seulement à RASSIZE() la largeur et la hauteur correctes et la macro retournera une valeur correcte. La définition de [RASSIZE() se trouve dans le fichier "gfx.h".]
  • flags : (long). Met à 1 le bit 0 pour obliger la fonction à attendre tant que le Blitter n'en a pas terminé avec votre demande.
Voici un exemple de comment on alloue la mémoire d'affichage, on en vérifie la disponibilité et on la vide (n'oubliez pas que vous devrez libérer toute la mémoire que vous aurez demandée ! voir ci-dessous pour plus de renseignements)

for( loop = 0; loop < DEPTH; loop++ )
{
  my_bit_map.Planes[ loop ] = AllocRaster( WIDTH, HEIGHT );

  if( my_bit_map.Planes[ loop ] == NULL )
    clean_up(); /* Sortir */

  BltClear( my_bit_map.Planes[ loop ], RASSIZE( WIDTH, HEIGHT ), 0 );
}

12.2.3.5 Le RasInfo

La structure RasInfo contient des renseignements sur l'endroit où se trouve la structure BitMap, ainsi que sur les valeurs x/y du raster. Si vous utilisez le mode d'affichage spécial plan double (dual playfields), la structure contiendra aussi un pointeur sur le deuxième plan.

12.2.3.5.1 La structure RasInfo

La structure RasInfo ressemble à ceci [telle qu'elle est définie dans le fichier d'en-tête "view.h"] :

struct RasInfo
{
  struct RasInfo *Next;
  struct BitMap *BitMap;
  SHORT RxOffset, RyOffset;
};
  • Next : si vous employez le mode d'affichage spécial plan double, ce pointeur contiendra l'adresse du deuxième plan (la structure RasInfo du premier plan contiendra un pointeur sur la structure RasInfo du deuxième plan dont le pointeur pointera sur NULL).
  • BitMap : pointeur sur la BitMap.
  • RxOffset : valeur X du raster (en changeant les valeurs RxOffset et RyOffset, vous aurez la possibilité de faire défiler rapidement tout le raster à l'écran).
  • RyOffset : valeur Y du raster.
12.2.3.5.2 Déclaration et initialisation d'une structure RasInfo

Voici un exemple de déclaration et d'initialisation d'une structure RasInfo :

/* Déclaration d'une structure RasInfo : */
struct RasInfo my_ras_info;

/* Préparation de la structure RasInfo : */
my_ras_info.BitMap = &my_bit_map; /* Pointeur sur la structure */
                                  /* BitMap.                   */
my_ras_info.RxOffset = 0;         /* Le coin supérieur gauche  */
my_ras_info.RyOffset = 0;         /* du raster sera situé dans */
                                  /* le coin supérieur gauche  */
                                  /* de l'affichage.           */
my_ras_info.Next = NULL;          /* Plan unique - une         */
                                  /* seule structure RasInfo   */
                                  /* sera nécessaire.          */

12.2.3.6 MakeVPort()

Dès que vous aurez initialisé toutes les structures nécessaires, vous devrez préparer le matériel de l'Amiga (tout particulièrement le Copper) pour que ces structures puissent créer l'affichage voulu. Chaque ViewPort pourra avoir sa résolution propre, sa taille, sa liste de couleurs, etc. et par conséquent, vous devrez préparer chaque ViewPort par un appel de la fonction MakeVPort().
  • Synopsis : MakeVPort( view, viewport );
  • view : (struct View *). Pointeur sur le View du ViewPort.
  • viewport : (struct ViewPort *). Pointeur sur le ViewPort.
Note : vous devez préparer chaque ViewPort que vous emploierez.

12.2.3.7 MrgCop()

Toutes les instructions destinées à un affichage particulier du ViewPort, en même temps que les instructions utilisées par les registres matériels des sprites devront être reliées avant que vous puissiez réaliser un affichage. Toutes ces instructions sont reliées les unes aux autres par le simple appel de la fonction MrgCop(). MrgCop() réunira dans une liste toutes les instructions d'affichage des coprocesseurs.
  • Synopsis : MrgCop( view );
  • view : (struct View *). Pointeur sur le View.
12.2.3.8 LoadView()

A la fin, vous pourrez alors montrer l'affichage. Vous pourrez le faire en appelant la fonction LoadView() :
  • Synopsis : LoadView( view );
  • view : (struct View *). Pointeur sur le View.
Vous devrez vous souvenir qu'à partir de maintenant, vous avez créé votre propre affichage et qu'à la fin du programme vous devez restaurer l'affichage d'origine ! Pour ceci, vous devrez sauvegarder le pointeur sur l'affichage d'origine avant de lancer votre propre affichage. Vous trouverez un pointeur sur le View courant dans la structure GfxBase.

struct View *old_view;

old_view = GfxBase->ActiView;

12.2.4 La fermeture d'un affichage

Quand vous arrêterez votre affichage, vous ne devrez pas oublier qu'il vous faut restaurer le View d'origine en appelant la fonction LoadView() avec un pointeur sur la structure View d'origine :

LoadView( old_view );

Vous devrez aussi rendre la mémoire qui vous a été réservée automatiquement lors de l'appel aux fonctions MakeVPort() et MrgCop(). Par conséquent, vous devrez appeler la fonction FreeVPortCopLists() pour chaque ViewPort que vous aurez créé.
  • Synopsis : FreeVPortCopLists( viewport );
  • view : (struct ViewPort *). Pointeur sur le ViewPort.
Vous devrez aussi appeler la fonction FreeCprList() pour chaque View que vous aurez créé. Vous transmettrez à la fonction un pointeur sur la structure CprList (LOFCprList). Si vous avez crée un View en mode entrelacé, vous devrez aussi libérer une structure CprList particulière (SHFCprList) que le système utilise seulement pour les Views en mode entrelacé.
  • Synopsis : FreeCprList( cprlist );
  • cprlist : (struct cprlist *). Pointeur sur la structure CprList (LOFCprList) du View. Si le View était en mode entrelacé vous devrez aussi appeler la fonction FreeCprList() avec un pointeur sur la SHFCprList.
Vous devrez aussi libérer la mémoire d'affichage que vous aviez demandée pour le raster. Vous pourrez libérer le raster en appelant la fonction FreeRaster() avec un pointeur sur un plan de bits. Il vous faudra faire appel à cette fonction pour chaque plan de bits que vous aviez alloué !
  • Synopsis : FreeRaster( bitplane, width, height );
  • bitplane : (PLANEPTR). Pointeur sur un plan de bits.
  • width : (long). Largeur du plan de bits.
  • height : (long). Hauteur du plan de bits.
Pour finir, vous devrez libérer la structure ColorMap qui a été allouée et initialisée automatiquement par la fonction GetColorMap(). Vous libérerez une liste de couleurs en appelant la fonction FreeColorMap().
  • Synopsis : FreeColorMap( colormap );
  • colormap : (struct ColorMap *). Pointeur sur la structure ColorMap.
Voici un exemple de comment on met fin à un affichage :

/* 1. Restaurer le View d'origine : */
LoadView( old_view );

/* 2. Désallouer les instructions d'affichage du ViewPort : */
FreeVPortCopLists( &my_view_port );

/* 3. Désallouer les instructions d'affichage du View : */
FreeCprList( my_view.LOFCprList );

/* 4. Désallouer la mémoire d'affichage, pour chaque plan de bits : */
for( loop = 0; loop < DEPTH; loop++ )
  FreeRaster( my_bit_map.Planes[ loop ], WIDTH, HEIGHT );

/* 5. Désallouer la ColorMap: */
FreeColorMap( my_view_port.ColorMap );

12.2.5 Un exemple

Voici un exemple de comment ouvrir un affichage NTSC (américain) en haute résolution. Voilà ce qu'il faut faire :
  1. Préparer le View.
  2. Préparer le ViewPort.
  3. Préparer la ColorMap.
  4. Préparer la BitMap.
  5. Préparer le RasInfo.
  6. Préparer le matériel de l'Amiga avec MakeVPort() et MrgCop().
  7. Montrer le nouveau View.
  8. Le View est en place et vous en faites ce que vous voulez.
  9. Restaurer le View d'origine.
  10. Libérer toutes les ressources et sortir.
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>

#define WIDTH  640 /* Largeur 640 pixels (haute résolution).          */
#define HEIGHT 200 /* Hauteur 200 lignes (NTSC non entrelacé).        */
#define DEPTH    3 /* trois plans de bits, ce qui donne huit couleurs.*/
#define COLOURS  8 /* 2^3 = 8                                         */

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

struct View my_view;
struct View *my_old_view;
struct ViewPort my_view_port;
struct RasInfo my_ras_info;
struct BitMap my_bit_map;
struct RastPort my_rast_port;

UWORD my_color_table[] =
{
  0x000, /* Couleur 0, Noir        */
  0x800, /* Couleur 1, Rouge       */
  0xF00, /* Couleur 2, Rouge clair */
  0x080, /* Couleur 3, Vert        */
  0x0F0, /* Couleur 4, Vert clair  */
  0x008, /* Couleur 5, Bleu        */
  0x00F, /* Couleur 6, Bleu clair  */
  0xFFF, /* Couleur 7, Blanc       */
};

void clean_up();
void main();

void main()
{
  UWORD *pointer;
  int loop;

  /* Ouverture de la bibliothèque Intuition : */
  IntuitionBase = (struct IntuitionBase *)
    OpenLibrary( "intuition.library", 0 );
  if( !IntuitionBase )
    clean_up( "Impossible d'ouvrir la bibliothèque Intuition !" );

  /* Ouverture de la bibliothèque Graphics :  */
  GfxBase = (struct GfxBase *)
    OpenLibrary( "graphics.library", 0 );
  if( !GfxBase )
    clean_up( "Impossible d'ouvrir la bibliothèque Graphics !" );

  /* Sauvegarde du View courant, afin de le restaurer par la suite : */
  my_old_view = GfxBase->ActiView;

  /* 1. Préparation de la structure View et attribution d'un */
  /*    pointeur sur le premier ViewPort :                   */
  InitView( &my_view );
  my_view.ViewPort = &my_view_port;

  /* 2. Préparation de la structure ViewPort structure et affectation */
  /*    d'un certain nombre de valeurs importantes :                  */
  InitVPort( &my_view_port );
  my_view_port.DWidth = WIDTH;         /* Fixer la largeur.        */
  my_view_port.DHeight = HEIGHT;       /* Fixer la hauteur.        */
  my_view_port.RasInfo = &my_ras_info; /* Fournit un pointeur sur  */
                                       /* RasInfo.                 */
  my_view_port.Modes = HIRES;          /* Haute résolution.        */

  /* 3. Prendre la liste de couleurs, la relier au ViewPort et la  */
  /*    préparer :                                                 */
  my_view_port.ColorMap = (struct ColorMap *) GetColorMap( COLOURS );
  if( my_view_port.ColorMap == NULL )
    clean_up( "IMPOSSIBLE de prendre une ColorMap!" );

  /* Prendre un pointeur sur la liste de couleurs :                */
  pointer = (UWORD *) my_view_port.ColorMap->ColorTable;

  /* Fixer les couleurs :    */
  for( loop = 0; loop < COLOURS; loop++ )
    *pointer++ = my_color_table[ loop ];

  /* 4. Préparer la BitMap : */
  InitBitMap( &my_bit_map, DEPTH, WIDTH, HEIGHT );

  /* Allouer la mémoire pour le raster: */
  for( loop = 0; loop < DEPTH; loop++ )
  {
    my_bit_map.Planes[ loop ] = (PLANEPTR) AllocRaster( WIDTH, HEIGHT );
    if( my_bit_map.Planes[ loop ] == NULL )
      clean_up( "IMPOSSIBLE d'allouer assez de mémoire pour le raster !" );

    /* Vide la mémoire d'affichage à l'aide du Blitter : */
    BltClear( my_bit_map.Planes[ loop ], RASSIZE( WIDTH, HEIGHT ), 0 );
  }
  
  /* 5. Préparer la structure RasInfo : */
  my_ras_info.BitMap = &my_bit_map; /* Pointeur sur la structure BitMap.  */
  my_ras_info.RxOffset = 0;         /* Le coin supérieur gauche du raster */
  my_ras_info.RyOffset = 0;         /* se situera dans le coin supérieur  */
                                    /* de l'affichage.                    */
  my_ras_info.Next = NULL;          /* Un seul plan - on aura besoin      */
                                    /* d'une seule structure RasInfo.     */

  /* 6. Création de l'affichage : */
  MakeVPort( &my_view, &my_view_port );
  MrgCop( &my_view );

  /* 7. Préparer le RastPort et lui fournir un pointeur sur la BitMap. */
  InitRastPort( &my_rast_port );
  my_rast_port.BitMap = &my_bit_map;

  /* 8. Afficher le nouveau View : */
  LoadView( &my_view );

  /* 9. Votre View est affiché et vous pouvez  */
  /*    en faire ce que bon vous en semblera.  */

  /* 10. Restaurer le View d'origine : */
  LoadView( my_old_view );

  /* 11. Libérer toutes les ressources allouées et sortir. */
  clean_up( "THE END" );
}

/* Retourne toutes les ressource allouées : */
void clean_up( message )
STRPTR message;
{
  int loop;

  /* Libère automatiquement les structures d'affichage allouées : */
  FreeVPortCopLists( &my_view_port );
  FreeCprList( my_view.LOFCprList );
  
  /* Désalloue la mémoire d'affichage, un plan de bits après l'autre : */
  for( loop = 0; loop < DEPTH; loop++ )
    if( my_bit_map.Planes[ loop ] )
      FreeRaster( my_bit_map.Planes[ loop ], WIDTH, HEIGHT );

  /* Désalloue la ColorMap : */
  if( my_view_port.ColorMap ) FreeColorMap( my_view_port.ColorMap );

  /* Fermeture de la bibliothèque Graphics : */
  if( GfxBase ) CloseLibrary( GfxBase );

  /* Fermeture de la bibliothèque Intuition : */
  if( IntuitionBase ) CloseLibrary( IntuitionBase );

  /* Affiche le message et sort : */
  printf( "%s\n", message ); 
  exit();
}

12.3 Le dessin

Nous avons déjà dit comment on crée et on ouvre un affichage ; maintenant, nous verrons les différentes routines de dessin présentes dans l'Amiga. L'Amiga vous permet non seulement de tracer des points et des lignes simples, mais aussi des images complexes. Pour augmenter l'effet, on peut combiner ces routines avec des masques et avec des modèles multicolores. L'Amiga offre en outre trois méthodes différentes pour dessiner des objets pleins. Vous pourrez en outre faire défiler, copier et combiner logiquement des zones rectangulaires grâce à la rapidité du Blitter.

12.3.1 Le RastPort

Avant de commencer à utiliser les routines de dessin, vous aurez encore à déclarer et à initialiser une structure supplémentaire ("pas plus d'une !", je vous entends dire). La raison pour laquelle nous avons besoin d'une structure supplémentaire est que la majorité des routines de dessin auront besoin de connaître la couleur du crayon, le masque et le modèle (j'en parlerai plus loin dans ce chapitre) que vous aurez choisis. Ce type de renseignement est par conséquent renfermé dans une structure qui s'appelle RastPort.

12.3.1.1 La structure RastPort

La structure RastPort ressemble à ceci [telle qu'elle est définie dans le fichier d'en-tête "rastport.h"] (par chance, en général, vous n'aurez pas à vous préoccuper beaucoup pour cette structure).

struct RastPort
{
  struct Layer *Layer;
  struct BitMap *BitMap;
  USHORT *AreaPtrn;
  struct TmpRas *TmpRas;
  struct AreaInfo *AreaInfo;
  struct GelsInfo *GelsInfo;
  UBYTE Mask;
  BYTE FgPen;
  BYTE BgPen;
  BYTE AOlPen;
  BYTE DrawMode;
  BYTE AreaPtSz;
  BYTE linpatcnt;
  BYTE dummy;
  USHORT Flags;
  USHORT LinePtrn;
  SHORT cp_x, cp_y;
  UBYTE minterms[8];
  SHORT PenWidth;
  SHORT PenHeight;
  struct TextFont *Font;
  UBYTE AlgoStyle;
  UBYTE TxFlags;
  UWORD TxHeight;
  UWORD TxWidth;
  UWORD TxBaseline;
  WORD TxSpacing;
  APTR *RP_User;
  ULONG longreserved[2];
  UWORD wordreserved[7];
  UBYTE reserved[8];
};
  • Layer : pointeur sur une structure Layer.
  • BitMap : pointeur sur la structure BitMap de ce RastPort.
  • AreaPtrn : pointeur sur un tableau de valeurs USHORT utilisé pour créer le modèle de remplissage de la zone à dessiner.
  • TmpRas : pointeur sur une structure TmpRas. Celle-ci est utilisée par les fonctions AreaMove(), AreaDraw() et AreaEnd() (voir ci-dessous pour plus de renseignements).
  • AreaInfo : pointeur sur une structure AreaInfo. Celle-ci aussi est utilisée par les fonctions AreaMove(), AreaDraw() and AreaEnd().
  • GelsInfo : pointeur sur une structure GelsInfo. Celle-ci est utilisée par les routines d'animation (VSprite et BOS).
  • Mask : ce masque vous permet de déterminer quels plans de bits devront être concernés par les routines de dessin. Le premier bit représente le plan de bits 0, le deuxième représente le plan de bits 1 et ainsi de suite. Si ce bit est activé (1), le plan de bits sera concerné. Si ce bit n'est pas activé (0), le plan de bits ne sera pas concerné par les routines de dessin.
    Par exemple, si la valeur du masque est fixée à 0xFF (0xFF en hexadécimal = 11111111 en binaire), tous les plans de bits seront concernés par les routines de dessin. Si la valeur du masque est fixée à 0xF6 (0xF6 en hexadécimal = 11110110 en binaire), le plan de bits zéro et le trois ne seront pas concernés.
  • FgPen : couleur du crayon de premier plan.
  • BgPen : couleur du crayon d'arrière-plan.
  • AOlPen : couleur du crayon pour AreaFill Outline.
  • DrawMode : il existe quatre types de modes différents de dessin :
    • JAM1 : là où vous écrirez, le système emploiera le crayon de premier plan pour restaurer la couleur d'origine et, là où vous n'écrirez pas, l'arrière-plan ne sera pas modifié. Par exemple, fixons FgPen à la couleur cinq et le mode de dessin à JAM1. Maintenant, si vous écrivez un pixel, celui-ci aura la couleur cinq et la couleur d'arrière-plan ne sera pas modifiée (une couleur reste "bloquée" dans le raster).
    • JAM2 : là où vous écrirez, le système emploiera le crayon de premier plan pour restaurer la couleur d'origine et, là où vous n'écrirez pas, l'arrière-plan ne sera pas modifié. Par exemple, fixons FgPen à la couleur cinq, BgPen à la couleur six et le mode de dessin à JAM2. Maintenant, si vous écrivez un pixel, ce pixel aura la couleur cinq, si vous écrivez un caractère, ce caractère aura la couleur cinq et la couleur d'arrière-plan aura la couleur six (deux couleurs restent "bloquées" dans le raster).
    • COMPLEMENT : chaque pixel que vous dessinerez sera dessiné dans la couleur binaire complémentaire. Là où vous écrirez des 1, les bits correspondants dans le raster seront inversés. L'avantage avec ce mode de dessin est que si vous écrivez deux fois au même endroit, le dessin d'origine sera restauré.
    • INVERSVID : on emploie ce mode seulement avec du texte et il est combiné soit avec JAM1 soit avec JAM2.
    • INVERSVID|JAM1 : seul l'arrière-plan est dessiné avec FgPen.
    • INVERSVID|JAM2 : l'arrière-plan est dessiné avec FgPen et les caractères avec BgPen.
  • AreaPtSz : la hauteur d'un modèle devra être une puissance de deux et cette valeur (2^x) est stockée ici. Si AreaPtSz est fixé à 4, le modèle aura une hauteur égale à 2^4=16 lignes (si vous utilisez des modèles multicolores, la valeur d'AreaPtSz devra être négative. Mettez AreaPtSz à -3 si vous voulez employer un modèle multicolore d'une hauteur de huit lignes. 2^3=8).
  • linpatcnt : utilisé pour créer le modèle de ligne.
  • dummy : zone de mémoire de vidange où le système stocke les valeurs "bidon".
  • Flags : si le drapeau AREAOUTLINE est mis à 1 toutes les "routines AreaFill" traceront un filet autour des zones remplies par l'intermédiaire de AOlPen. Si le RastPort à un double tampon le drapeau, DBUFFER est mis à 1.
  • LinePtrn : 16 bits utilisés pour le modèle de ligne. Une valeur 0x9669 (en hexadécimal) créera le modèle suivant : 1001011001101001.
  • cp_x : position courante X du crayon.
  • cp_y : position courante Y du crayon.
  • minterms : espace mémoire supplémentaire.
  • PenWidth : largeur du crayon (les routines de dessin ne s'en servent pas).
  • PenHeight : hauteur du crayon (les routines de dessin ne s'en servent pas).
  • Font : pointeur sur une structure TextFont.
  • AlgoStyle : mode de jeu de caractères généré de manière algorithmique (par exemple, si la fonte n'accepte pas le mode souligné, gras ou italique, l'Amiga pourra les générer en utilisant certains algorithmes).
  • TxFlags : drapeaux spéciaux pour le texte.
  • TxHeight : hauteur du jeu de caractères.
  • TxWidth : largeur nominale du jeu de caractères.
  • TxBaseline : position de la ligne de base du texte.
  • TxSpacing : intervalle entre caractères.
  • RP_User : variables spéciales et zones de mémoire qui ne nous sont pas utiles. Réservées pour l'usage interne de l'Amiga et pour les versions à venir du système graphique.
  • longreserved : idem.
  • wordreserved : idem.
  • reserved : idem.
Remarque : vous aurez rarement besoin de changer ou d'examiner ces valeurs directement. Normalement, pour changer certaines valeurs, vous emploierez (et devrez employer) les fonctions décrites par la suite.

12.3.1.2 La préparation d'un RastPort

Pour préparer un RastPort, vous devrez déclarer une structure RastPort et l'initialiser en appelant la fonction InitRastPort() avec un pointeur sur le RastPort comme seul paramètre.
  • Synopsis : InitRastPort( rast_port );
  • rast_port : (RastPort *). Pointeur sur le RastPort qui doit être initialisé.
La dernière chose que vous aurez à faire, ce sera de fournir à votre RastPort un pointeur sur votre structure BitMap. Voici un court exemple :

/* 1. Déclaration d'une structure RastPort : */
struct RastPort my_rast_port;

/* 2. Initialisation du RastPort par l'intermédiaire */
/* de la fonction InitRastPort() :                   */
InitRastPort( &my_rast_port );

/* 3. Fournir au RastPort un pointeur sur votre structure BitMap : */
/* [Nous partons du principe que la structure BitMap a été         */
/* déclarée et initialisée de manière correcte, comme expliqué     */
/* ci-dessus].                                                     */
my_rast_port.BitMap = &my_bit_map;

12.3.2 Les crayons pour dessiner

Pour dessiner, les routines de dessin de bas niveau emploient trois types différents de crayons :
  • FgPen : le crayon de premier plan est celui qu'on emploie le plus couramment.
  • BgPen : le crayon d'arrière-plan est employé habituellement pour dessiner dans l'arrière-plan, par exemple si vous êtes en train d'écrire un texte.
  • AOlPen : le crayon Areaoutline est employé pour encadrer des zones qui seront remplies par les routines AreaFill.
Remarque : le mode de dessin détermine quels crayons seront employés.

Vous utiliserez la fonction SetAPen() pour changer la couleur de FgPen :
  • Synopsis : SetAPen( rast_port, new_colour );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • new_colour : (long). La valeur d'une nouvelle couleur.
Vous utiliserez la fonction SetBPen() pour changer la couleur de BgPen :
  • Synopsis : SetBPen( rast_port, new_colour );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • new_colour : (long). La valeur d'une nouvelle couleur.
Vous emploierez la macro SetOPen() pour changer la couleur de AOlPen.

Remarque : il ne s'agit pas d'une fonction. Il s'agit réellement d'une macro qui est définie dans le fichier en-tête "gfxmacros.h". Si vous voulez vous servir de cette macro, vous ne devrez pas oublier d'inclure ce fichier dans votre programme.
  • Synopsis : SetOPen( rast_port, new_colour );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • new_colour : (long). La valeur d'une nouvelle couleur.
12.3.3 Les modes de dessin

Cinq modes de dessin différents sont acceptés par l'Amiga :
  • JAM1 : FgPen sera employé, l'arrière-plan est inchangé (une couleur est "bloquée" dans un raster).
  • JAM2 : FgPen sera employé comme crayon de premier plan tandis que l'arrière-plan (là où, par exemple, vous êtes en train d'écrire un texte) sera rempli avec la couleur de BgPen (deux couleurs sont "bloquées" dans un raster).
  • COMPLEMENT : chaque pixel concerné sera dessiné dans sa couleur binaire complémentaire. Là où vous aurez écrit des 1, les bits correspondants dans le raster seront inversés.
  • INVERSVID|JAM1 : ce mode est employé seulement avec du texte. Seul l'arrière-plan du texte sera dessiné avec FgPen.
  • INVERSVID|JAM2 : ce mode est employé seulement avec du texte. L'arrière-plan du texte sera dessiné avec FgPen, tandis que les caractères seront dessinés avec BgPen.
Pour fixer le mode de dessin, vous emploierez la fonction SetDrMd() :
  • Synopsis : SetDrMd( rast_port, new_mode );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • new_mode : (long). Le nouveau mode de dessin. Mettre l'un des modes suivants : JAM1, JAM2, COMPLEMENT, INVERSVID|JAM1 ou INVERSVID|JAM2.
12.3.4 Les modèles

Les routines de dessin de l'Amiga vous offrent la possibilité d'employer des modèles. Vous pourrez employer aussi bien des modèles de ligne que des modèles de bloc ; ces derniers pourront être en deux ou plusieurs couleurs. Les modèles de ligne sont parfaits pour dessiner des diagrammes, des bords, etc. On pourra employer les modèles de bloc pour remplir n'importe quel type d'objet à l'écran par l'intermédiaire des routines de remplissage. La variété des couleurs et les divers modèles vous offrent une grande flexibilité pour créer des affichages intéressants et plaisants à regarder.

12.3.4.1 Les modèles de ligne

Les modèles de ligne ont une largeur de 16 bits et chaque bit représente un point. Au démarrage, les modèles de ligne sont mis à 0xFFFF (1111111111111111), ce qui génère des lignes pleines. Pour créer un modèle qui alterne deux points et deux espaces, puis à nouveau deux points et ainsi de suite, vous devrez mettre le modèle de ligne à 0xCCCC (1100110011001100).

Vous pourrez changer le modèle de ligne en vous servant de la macro SetDrPt(). Remarque : il ne s'agit pas d'une fonction. Il s'agit réellement d'une macro qui est définie dans le fichier en-tête "gfxmacros.h". Si vous souhaitez employer cette macro, vous n'oublierez pas d'inclure ce fichier dans votre programme.
  • Synopsis : SetDrPt( rast_port, line_pattern );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • line_pattern : (UWORD). Le modèle. Chaque octet représente un point. Pour créer des lignes pleines vous mettrez la valeur de modèle à 0xFFFF [en hexadécimal] (1111111111111111 [en binaire]).
Voici quelques modèles couramment employés, ainsi que leurs valeurs correspondantes :

  Description                  Modèle [bin]      Valeur du modèle [hex]
  ---------------------------------------------------------------------
  ligne pleine                 1111111111111111  0xFFFF
  ligne largement pointillée   1111000011110000  0xF0F0
  ligne moyennement pointillée 1100110011001100  0xCCCC
  ligne peu pointillée         1000100010001000  0x8888
  ligne fantôme                1010101010101010  0xAAAA

12.3.4.2 Les modèles de bloc

Les modèles de bloc ont une largeur de 16 bits et une hauteur de lignes égale à une puissance de deux (1, 2, 4, 8, 16, 32, ... ). Par conséquent, pour créer un modèle de bloc, vous devrez déclarer et initialiser une matrice de UWORDS. Chaque bit de la matrice représentera un point. Pour créer un modèle avec beaucoup de petits carrés, vous devrez déclarer et initialiser une matrice plus ou moins de la manière suivante :

UWORD area_pattern =
{
  0xF0F0, /* 1111000011110000 */
  0xF0F0, /* 1111000011110000 */
  0xF0F0, /* 1111000011110000 */
  0xF0F0, /* 1111000011110000 */
  0x0F0F, /* 0000111100001111 */
  0x0F0F, /* 0000111100001111 */
  0x0F0F, /* 0000111100001111 */
  0x0F0F, /* 0000111100001111 */
};

Pour fixer le modèle, vous appellerez la macro SetAfPt() en lui donnant comme paramètres un pointeur sur votre RastPort et le nouveau modèle. Remarque : il ne s'agit pas d'une fonction. Il s'agit réellement d'une macro qui est définie dans le fichier en-tête "gfxmacros.h". Si vous souhaitez employer cette macro, n'oubliez pas d'inclure ce fichier dans votre programme.
  • Synopsis : SetAfPt( rast_port, area_pattern, pow2 );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • area_pattern : (UWORD) Pointeur sur une matrice de UWORDS qui créera le modèle. Chaque bit de la matrice représente un point.
  • pow2 : (BYTE). Le modèle sera égal à deux à la puissance de la hauteur de lignes pow2. Si la hauteur du modèle est égale à une ligne, on devra mettre pow2 à 0, si elle est égale à deux lignes, on devra mettre pow2 à 1, si elle est égale à quatre lignes, on devra mettre pow2 à 2, et ainsi de suite (si vous employez des modèles multicolores, pow2 devra avoir une valeur négative. Par conséquent, pour un modèle multicolore ayant une hauteur de seize lignes, vous devrez donner à pow2 une valeur de -4 [2^4 = 16]).
12.3.4.3 Les modèles multicolores

Vous pourrez même créer des modèles multicolores. Dans ce cas, vous devrez déclarer une matrice avec une profondeur de deux ou supérieure à deux. Plus grande sera la profondeur de la matrice, plus on pourra utiliser de couleurs. Chaque niveau représente un plan de bits.

Voici une matrice de modèles de bloc qui produit huit carrés de couleur différente. Pour avoir huit couleurs, vous aurez besoin d'une matrice avec une profondeur de trois. Le modèle ressemblera à ceci (les nombres indiquent les registres de couleur qui seront employés) :

  0123
  0123
  4567
  4567

UWORD area_pattern =
{
  {         /* Plane 0          */
    0x0F0F, /* 0000111100001111 */
    0x0F0F, /* 0000111100001111 */
    0x0F0F, /* 0000111100001111 */
    0x0F0F  /* 0000111100001111 */
  },
  {         /* Plane 1          */
    0x00FF, /* 0000000011111111 */
    0x00FF, /* 0000000011111111 */
    0x00FF, /* 0000000011111111 */
    0x00FF  /* 0000000011111111 */
  },
  {         /* Plane 2          */
    0x0000, /* 0000000000000000 */
    0x0000, /* 0000000000000000 */
    0xFFFF, /* 1111111111111111 */
    0xFFFF  /* 1111111111111111 */
  }
}; 

Lorsque vous emploierez les modèles multicolores, la valeur de pow2 dans la macro SetAfPt() devra être négative. Mettez tout simplement un signe moins devant la valeur en question et les routines de dessin comprendront que vous allez employer des modèles multicolores.

Lors de l'emploi des modèles multicolores, le mode de dessin devra être fixé à JAM2, FgPen à la couleur 255 et BgPen à la couleur 0 :

/* Préparation pour dessiner avec des modèles multicolores : */
SetDrMd( &my_rast_port, JAM2 );
SetAPen( &my_rast_port, 255 );
SetBPen( &my_rast_port,   0 );

/* Fixe le modèle : (hauteur 4 lignes -> pow2 = 2 [2^2], multicol. -2)
SetAfPt( &my_rast_port, area_pattern, -2 );

12.3.5 Le masque de modèle

Pour créer des effets particuliers, vous pourrez "déconnecter" les plans de bits de votre raster de sorte qu'ils ne soient pas concernés par les routines de dessin. Le premier bit du masque représente le premier plan de bits, le deuxième bit le deuxième plan de bits et ainsi de suite. Un 1 signifie que le plan de bits pourra être concerné, tandis qu'un 0 voudra dire que le plan de bits ne sera aucunement concerné. Pour "déconnecter" les plans de bits zéro et deux, il faudra mettre la valeur du masque à 0xFA [en hexa] = 11111010 [en binaire].

On trouve la variable de masque "Mask" dans la structure RastPort : my_rast_port.Mask = 0xFF (on pourra modifier tous les plans de bits).

12.3.6 Dessiner un seul pixel

On dessine un seul pixel en employant la fonction WritePixel().
  • Synopsis : WritePixel( rast_port, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • x : (long). Abscisse X du pixel.
  • y : (long). Ordonnée Y du pixel.
12.3.7 Lire un seul pixel

Vous emploierez la fonction ReadPixel() afin de déterminer la couleur d'un pixel donné. Vous lui fournirez seulement un pointeur sur votre RastPort, ainsi que les coordonnées du pixel, et la fonction retournera la valeur de la couleur du pixel.
  • Synopsis : colour = ReadPixel( rast_port, x, y );
  • colour : (long). ReadPixel retourne la valeur de la couleur du pixel indiqué (couleur qui va de 0 à 255 ) ou -1 si les coordonnées se situent en dehors du raster.
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui contient le pixel que vous souhaitez examiner.
  • x : (long). Abscisse X du pixel.
  • y : (long). Ordonnée Y du pixel.
12.3.8 Positionnement du curseur

Avant de commencer à tracer des lignes ou à écrire un texte, il vous faudra positionner le curseur (l'endroit à partir duquel la ligne/le texte seront dessinés). Le curseur n'est pas quelque chose de visible à l'utilisateur, il n'est représenté que par les coordonnées du crayon qui sert à dessiner. Vous pourrez trouver la position du curseur dans les variables cp_x et cp_y du RastPort.

On modifie la position du curseur en appelant la fonction Move().
  • Synopsis : Move( rast_port, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • x : (long). Nouvelle valeur de l'abscisse X.
  • y : (long). Nouvelle valeur de l'ordonnée Y.
12.3.9 Le texte

Dans ce chapitre, nous n'entrerons pas dans le détail sur la manière dont on écrit des caractères/un texte. Cependant, je voudrais au moins expliquer l'affichage à l'écran des caractères courants.

Pour afficher du texte, vous emploierez la fonction Text(). Celle-ci a besoin d'un pointeur sur le RastPort concerné, d'un pointeur sur une chaîne de caractères de texte et, pour finir, d'une valeur qui l'informe sur le nombre de caractères qu'on souhaite afficher. A chaque appel de la fonction on pourra afficher seulement une ligne ; la fonction ne fait ni formatage ni ajustement de la ligne.
  • Synopsis : Text( rast_port, string, nr_of_chr );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • string : (char *). Pointeur sur la chaîne de caractères de texte qui doit être affichée.
  • nr_of_chr : (long). Le nombre de caractères à afficher.
Cet exemple affiche "Hello" à l'écran :

  Text( &my_rast_port, "HELLO", 5 );

12.3.10 Dessiner des lignes simples

Vous pourrez dessiner des lignes simples en faisant appel à la fonction Draw(). Celle-ci tracera une ligne à partir de l'abscisse X courante jusqu'à une ordonnée Y à n'importe quel endroit à l'intérieur du Raster.
  • Synopsis : Draw( rast_port, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • x : (long). Nouvelle valeur de l'abscisse X.
  • y : (long). Nouvelle valeur de l'ordonnée Y.
Voici un exemple qui dessinera un triangle à l'écran :

Move( &my_rast_port, 100, 100 ); /* Aller à la position de démarrage. */
Draw( &my_rast_port, 300, 100 ); /* Dessiner les trois lignes.   */
Draw( &my_rast_port, 200, 200 );
Draw( &my_rast_port, 100, 100 );

12.3.11 Dessiner plusieurs lignes

Pour dessiner plusieurs lignes, nous emploierons la fonction PolyDraw(). Celle-ci a besoin d'un pointeur sur une matrice de coordonnées, d'une valeur qui l'informe du nombre de paires de coordonnées (x,y) qui seront employées et naturellement d'un pointeur sur le RastPort qui est concerné. La fonction dessine une ligne à partir de l'abscisse X courante jusqu'à la première ordonnée Y. Puis une deuxième ligne jusqu'à la deuxième ordonnée Y et ainsi de suite.
  • Synopsis : PolyDraw( rast_port, number, coordinates );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • number : (long). Le nombre de coordonnées (x,y) indiquées dans la matrice.
  • coordinates : (short *). Pointeur sur une matrice de coordonnées.
Voici un exemple qui dessine lui aussi un triangle à l'écran :

/* Trois coordonnées : */
WORD coordinates[] =
{
  300, 100,
  200, 200,
  100, 100
};

/* Aller à la position de démarrage : */
Move( &my_rast_port, 100, 100 );

/* Dessiner des lignes : */
PolyDraw( &my_rast_port, 3, coordinates );

12.3.12 Dessiner des rectangles pleins

Pour dessiner des rectangles pleins, vous emploierez la fonction RectFill() (remarquez que, dans ce cas, les modèles de bloc sont opérationnels).
  • Synopsis : RectFill( rast_port, minx, miny, maxx, maxy );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • minx : (long). Coin gauche du rectangle.
  • miny : (long). Coin supérieur du rectangle.
  • maxx : (long). Coin droit du rectangle.
  • maxy : (long). Coin inférieur du rectangle.
12.3.13 Le remplissage "flood"

Quand on doit remplir des objets complexes, on emploiera le remplissage flood. Il existe deux types différents de remplissage flood. Le mode Délimitation et le mode Couleur. En mode délimitation, la nouvelle couleur remplira toute la surface : le flood s'arrêtera seulement lorsqu'il rencontrera un bord de la même couleur que AOlPen. En mode couleur, seront concernés tous les pixels de la même couleur se trouvant l'un près de l'autre. Le flood prendra fin dès qu'il rencontrera une couleur différente.

Vous pourrez faire le remplissage flood d'un objet, en employant la fonction Flood().
  • Synopsis : Flood( rast_port, mode, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • mode : (long). Le mode qu'on devra employer. Si vous souhaitez employer le mode Couleur, mettez la variable de mode à 1, pour vous servir du mode Délimitation, mettez la variable de mode à 0.
  • x : (long). Abscisse X où devra commencer le remplissage flood.
  • y : (long). Ordonnée Y où devra commencer le remplissage flood.
Voici un exemple qui permettra de dessiner et de remplir un rectangle. Nous donnerons à AOlPen la même couleur qu'à FgPen, ainsi le remplissage flood s'arrêtera dès qu'il rencontrera les bords, en mode Délimitation.

/* Donner à AOlPen la même couleur que FgPen : */
SetOPen( &my_rast_port, my_rast_port.FgPen );

/* Dessiner un triangle : */
Move( &my_rast_port, 100, 100 );
Draw( &my_rast_port, 300, 100 );
Draw( &my_rast_port, 200, 200 );
Draw( &my_rast_port, 100, 100 );

/* Le remplir (en utilisant le mode Délimitation) : */
Flood( &my_rast_port, 0, 200, 150 );

12.3.14 Dessiner des surfaces déjà remplies

L'Amiga permet de dessiner des surfaces qui seront directement remplies. Vous choisissez un emplacement et l'Amiga commence à dessiner l'objet que vous avez choisi. Cependant, l'utilisateur ne s'apercevra de rien étant donné que l'Amiga ne tracera aucune ligne. En effet, les lignes sont stockées dans la liste d'un vecteur et seront dessinées lorsque vous aurez terminé l'objet (quand vous le "fermerez").

12.3.14.1 Les structures AreaInfo et TmpRas

Pour gérer ces structures il vous faudra faire un certain nombre de choses :

1. Créer un tampon où sera stockée la liste de tous vos sommets. Vous aurez besoin de cinq octets par sommet, ainsi, pour créer un tampon de 100 lignes, vous aurez besoin de 500 octets. Naturellement, le tampon devra être aligné "au mot", par conséquent vous devrez déclarer le tampon en tant que suite de mots et non en tant que suite d'octets. Du moment qu'il y a deux octets dans chaque mot, 500 octets signifiera 250 mots. Exemple :

UWORD my_buffer[ 250 ];

2. Déclarer une structure AreaInfo (declarée dans le fichier "rastport.h".). Exemple :

struct AreaInfo my_area_info;

3. Combiner le tampon et la structure AreaInfo par l'intermédiaire de la fonction InitArea(). Celle-ci a besoin d'un pointeur sur une structure AreaInfo, d'un pointeur sur un tampon de mémoire et d'une valeur qui l'informera sur le nombre de sommets qui pourront être stockés dans le tampon. Exemple :

InitArea( &my_area_info, my_buffer, 100);

4. Déclarer une structure TmpRas (déclarée elle aussi dans le fichier "rastport.h".). Exemple :

struct TmpRas my_tmp_ras;

5. Réserver un plan de bits assez grand pour pouvoir y stocker tous vos objets. Normalement, vous créerez un plan de bits qui aura la même taille que votre affichage. Exemple :

PLANEPTR my_bit_plane;
   my_bit_plane = AllocRaster( 320, 200 );
   if( my_bit_plane == NULL )
     exit();

6. Initialiser et relier la structure TmpRas et la mémoire supplémentaire en faisant appel à la fonction InitTmpRas(). Celle-ci a besoin d'un pointeur sur une structure TmpRas, d'un pointeur sur une zone de mémoire d'affichage supplémentaire et, pour finir, d'une valeur qui l'informera sur la taille de la mémoire supplémentaire, taille qu'on pourra calculer par l'intermédiaire de la macro RASSIZE(). Exemple :

InitTmpRas( &my_tmp_ras, my_bit_plane, RASSIZE( 320, 200 ) );

7. Informer le RastPort de l'endroit où il pourra trouver les structures AreaInfo et TmpRas. Exemple :

my_rast_port.AreaInfo = &my_area_info;
my_rast_port.TmpRas = &my_tmp_ras;

8. Avant la fin de votre programme, vous devrez désallouer la mémoire d'affichage que vous aviez réservée. Utilisez la fonction FreeRaster(). Exemple :

FreeRaster( my_bit_plane, 320, 200 );

12.3.14.2 AreaMove(), AreaDraw() et AreaEnd()

Une fois que les structures TmpRas et AreaInfo auront été initialisées et que le RastPort sait où il pourra les trouver, vous pourrez commencer à employer les fonctions AreaFill. La première chose que vous voudrez probablement faire sera de vous déplacer à un nouvel endroit où vous voudrez commencer à dessiner. Ceci se fait, en faisant appel à la fonction AreaMove().
  • Synopsis : AreaMove( rast_port, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • x : (long). Abscisse X de démarrage.
  • y : (long). Ordonnée Y de démarrage.
Maintenant, vous pouvez commencer à dessiner en employant la fonction AreaDraw(). Remarque : l'utilisateur ne s'apercevra de rien, vous verrez le résultat lorsque vous "fermerez" le polygone. A ce moment, l'Amiga le dessinera et le remplira.
  • Synopsis : AreaDraw( rast_port, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • x : (long). Nouvelle abscisse X.
  • y : (long). Nouvelle ordonnée Y.
Faites attention à ne pas dessiner en dehors du raster, ceci pourrait bloquer le système !

Dès que votre objet est prêt, appelez la fonction AreaEnd() : l'Amiga fermera le polygone et le remplira. Il ne vous faudra pas nécessairement fermer le polygone, l'Amiga dessinera la dernière ligne automatiquement, si cela est nécessaire (si vous appelez AreaMove(), avant d'avoir fermé le polygone, l'Amiga le fermera automatiquement avant de commencer à dessiner le nouveau polygone).
  • Synopsis : AreaEnd( rast_port );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
12.3.14.3 Mettre hors service la fonction Outline

Les surfaces qu'on remplit par l'intermédiaire des fonctions AreaFill seront délimitées avec AOlPen. Cependant, vous pourrez mettre hors service la fonction Outline, si vous n'en avez pas besoin. Il vous suffira simplement d'appeler la macro BNDROFF() (déclarée dans le fichier d'en-tête "gfxmacros.h") en lui fournissant comme seul paramètre un pointeur sur votre RastPort.
  • Synopsis : BNDROFF( rast_port );
  • rast_port : pointeur sur le RastPort où on devra désactiver la fonction Outline.
12.3.14.4 Un exemple

Voici un exemple :

#define WIDTH  320
#define HEIGHT 200

/* Déclaration des structures AreaInfo et TmpRas : */
struct AreaInfo my_area_info;
struct TmpRas my_tmp_ras;

/* Tampon pour les sommets : (100 lignes, 5 octets par sommet, soit */
/* 500 octets, autrement dit 250 mots. Tampon aligné "au mot".      */
UWORD my_buffer[ 250 ];

/* Pointeur sur la mémoire d'affichage qu'on devra allouer : */
PLANEPTR my_bit_plane;

/* Initialisation de la structure AreaInfo. */
/* Préparation pour les 100 sommets :       */
InitArea( &my_area_info, my_buffer, 100);

/* Allocation de la mémoire d'affichage : */
my_bit_plane = AllocRaster( WIDTH, HEIGHT );

/* Avons-nous réussi à nous faire allouer la mémoire? */
if( my_bit_plane == NULL )
  exit();

/* Préparation de la structure TmpRas : */
InitTmpRas( &my_tmp_ras, my_bit_plane, RASSIZE( WIDTH, HEIGHT ) );

/* Informer le RastPort de l'endroit où il pourra trouver */
/* ces structures :                                       */
my_rast_port.AreaInfo = &my_area_info;
my_rast_port.TmpRas = &my_tmp_ras;

/* Dessiner un carré plein : */
AreaMove( my_rast_port,   0,   0 );
AreaDraw( my_rast_port, 100,   0 );
AreaDraw( my_rast_port, 100, 100 );
AreaDraw( my_rast_port,   0, 100 );
AreaEnd( my_rast_port );

/* Désallouer la mémoire supplémentaire : */
FreeRaster( my_bit_plane, WIDTH, HEIGHT );

12.3.15 Mettre le raster à une couleur donnée

Vous pouvez mettre tout le raster à une couleur donnée en faisant appel à la fonction SetRast().
  • Synopsis : SetRast( rast_port, colour );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • colour : (long). Le registre de couleur avec lequel vous voulez remplir tout le raster.
12.3.16 Le Blitter

Le Blitter est une puce à l'intérieur de l'Amiga qui est spécialisée dans le déplacement et la combinaison logique de grandes zones de mémoire rectangulaires. Il déplace et travaille avec une énorme quantité de données et peut, par conséquent, effectuer beaucoup de travail pénible qui exigerait beaucoup de temps du processeur principal. A la place, celui-ci peut se concentrer sur des tâches plus importantes.

Le Blitter, qui est dans Agnus/Fat Agnus, est le héros des possibilités graphiques fascinantes de l'Amiga. On pourra l'employer pour remettre à zéro, pour faire défiler et pour copier d'importantes zones de mémoire. A la différence d'autres Blitters, il peut aussi combiner logiquement des zones de mémoire (nous en parlerons plus loin) et par conséquent il peut faire un tas de choses bien plus intéressantes que le simple déplacement des données.

12.3.16.1 Vidage de zones mémoire rectangulaires

Vous pourrez remettre à zéro des zones mémoire en faisant appel à la fonction BltClear(). L'avantage représenté par l'emploi de cette fonction est que celle-ci travaille avec le Blitter qui est une puce rapide pour la remise à zéro de la mémoire.
  • Synopsis : BltClear( memory, count, drapeaux );
  • memory : (char *). Pointeur sur la zone de mémoire qu'on doit remettre à zéro.
  • count : (long). Nombre d'octets qu'on doit remettre à zéro. Si vous remettez à zéro la mémoire d'affichage, vous pourrez employer la macro RASSIZE() pour calculer combien d'octets sont utilisés par l'affichage.
  • flags : (long). Écrire 0 pour permettre à l'ordinateur de continuer pendant que le blitter travaille ou écrire 1 pour forcer le programme à attendre le Blitter.
12.3.16.2 Défilement d'une zone rectangulaire

En utilisant la fonction ScrollRaster(), vous ferez défiler à l'écran une partie du raster. Cette fonction travaille en collaboration avec le Blitter et par conséquent elle est très rapide. On pourra faire défiler une partie du raster horizontalement ou verticalement. Cette partie du raster sera perdue et la nouvelle partie sera remplie avec BgPen.
  • Synopsis : ScrollRaster( rp, dx, dy, minx, miny, maxx, maxy );
  • rp : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • dx : (long). Déplacement delta sur le plan des X (un chiffre positif déplacera la zone vers la droite, un chiffre négatif la déplacera sur la gauche).
  • dy : (long). Déplacement delta sur le plan des Y (un chiffre positif déplacera la zone vers le bas, un chiffre négatif la déplacera vers le haut).
  • minx : (long). Coin gauche du rectangle.
  • miny : (long). Coin supérieur du rectangle.
  • maxx : (long). Coin droit du rectangle.
  • maxy : (long). Coin inférieur du rectangle.
12.3.16.3 Copier des surfaces rectangulaires

Lorsque vous aurez à copier des zones mémoire rectangulaires, vous pourrez employer aussi bien BltBitMap() que ClipBlit(). Tout simplement on devra employer BltBitMap() lorsque vous aurez à copier des données sans vouloir vous embêter avec les couches ("layers") de recouvrement (fenêtres), etc. En cas contraire, vous emploierez ClipBlit() si vous voulez faire attention aux couches de recouvrement, etc.

BltBitMap() copie les BitMaps directement sans faire attention aux couches de recouvrement.
  • Synopsis : BltBitMap( sbm, sx, sy, dbm, dx, dy, w, h, flag, m, t );
  • sbm : (struct BitMap *). Pointeur sur la BitMap "source".
  • sx : (long). Décalage dans le plan des X de la source.
  • sy : (long). Décalage dans le plan des Y de la source.
  • dbm : (struct BitMap *). Pointeur sur la BitMap "destination".
  • dx : (long). Décalage dans le plan des X de la destination.
  • dy : (long). Décalage dans le plan des Y de la destination.
  • w : (long). Largeur de la zone mémoire qui devra être copiée.
  • h : (long). Hauteur de la zone mémoire qui devra être copiée.
  • flag : (long). Cette valeur informe le Blitter du type d'opérations logiques à effectuer. Voir ci-dessous pour plus de renseignements.
  • m : (long). Ici, vous pourrez définir un masque de BitMap et dire au Blitter quels plans de bits devront et ne devront pas être employés. Le premier bit représente le premier plan de bits, le deuxième bit représente le deuxième plan de bits et ainsi de suite. Si le bit est activé (1) on emploiera le plan de bits correspondant, autrement (0) on n'emploiera pas ce plan de bits. Pour mettre hors service les plans de bits zéro et deux, mettez la valeur de masque à 0xFA (11111010). Pour employer tous les plans de bits mettez la valeur de masque à 0xFF (11111111).
  • t : (char *). Si la copie fait des recouvrements et si ce pointeur pointe sur une partie de la mémoire Chip, la mémoire sera employée pour y stocker une zone temporaire. Cependant, normalement, vous n'aurez pas à vous occuper de cette valeur.
ClipBlit() copie les BitMaps en se servant des Rastports, par conséquent, la fonction fera attention aux couches de recouvrement et on devra l'employer s'il y a des fenêtres dans l'affichage.
  • Synopsis : ClipBlit( srp, sx, sy, drp, dx, dy, w, h, drapeau );
  • srp : (struct RastPort *). Pointeur sur le RastPort "source".
  • sx : (long). Valeur dans le plan des X de la source.
  • sy : (long). Valeur dans le plan des X de la source.
  • drp : (struct RastPort *). Pointeur sur le RastPort "destination".
  • dx : (long). Valeur dans le plan des X de la destination.
  • dy : (long). Valeur dans le plan des X de la destination.
  • w : (long). Largeur de la zone de mémoire qui devra être copiée.
  • h : (long). Hauteur de la zone de mémoire qui devra être copiée.
  • flag : (long). Cette valeur informe le Blitter du type d'opérations logiques à effectuer. Voir ci-dessous pour plus de renseignements.
Comme nous l'avons dit ci-dessus, le Blitter peut combiner des données entre la zone source et la zone destination. Le premier des quatre bits les plus à gauche dans le champ drapeau détermine quels calculs devront être effectués.

Si le bit le plus à gauche est mis (valeur égale à 0x80), le résultat sera une combinaison de la source et de la destination. Si le second bit le plus à gauche est mis (valeur égale à 0x40), le résultat sera une combinaison de la source et de la destination inversée. Si le troisième bit le plus à gauche est mis (valeur égale à 0x20), le résultat sera une combinaison de la source inversée et de la destination. Si le quatrième bit le plus à gauche est mis (valeur égale à 0x10), le résultat sera égal à une inversion de la source et de la destination. Voir la table suivante :

  Bit        Valeur  Log
  ----------------------
  1000 0000  0x80    SD
                     _
  0100 0000  0x40    SD
                     _
  0010 0000  0x20    SD
                     __
  0001 0000  0x10    SD

Pour effectuer une copie normale, le résultat devra être seulement S. Vous pourrez l'avoir en mettant la valeur du drapeau à 0xc0 [en hexadécimal] (11000000 [en binaire]). La formule mathématique serait alors la suivante :

        _         _
  SD + SD = S(D + D) = S

Si vous voulez que la source soit inversée (S), mettez la valeur du drapeau à 0x30 [en hexadécimal] (00110000 [en binaire]). La formule mathématique serait alors la suivante :

  _    __   _     _    _
  SD + SD = S(D + D) = S

Si vous voulez que la destination soit inversée (D), mettez la valeur du drapeau à 0x50 [en hexadécimal] (01010000 [en binaire]). La formule mathématique serait alors la suivante :

   _   __   _     _    _
  SD + SD = D(S + S) = D

Voici un exemple qui copie une zone rectangulaire d'un RastPort de nom "source_rp" dans un autre RastPort de nom "destination_rp". La zone rectangulaire a une largeur de WIDTH pixels et une hauteur de HEIGHT lignes.

ClipBlit( &source_rp,      /* RastPort source.                      */
          0, 0,            /* Coin supérieur gauche de source.      */
          &destination_rp, /* RastPort destination.                 */
          0, 0,            /* Coin supérieur gauche de destination. */
          WIDTH, HEIGHT,   /* Taille de la zone de mémoire.         */
          0xC0 );          /* Copie normale.                        */

12.4 Les fonctions

InitView()

Cette fonction initialisera une structure View.
  • Synopsis : InitView( view );
  • view : (struct View *). Pointeur sur le View qui doit être initialisé.
InitVPort()

Cette fonction initialisera une structure ViewPort.
  • Synopsis : InitVPort( view_port );
  • view_port : (struct ViewPort *). Pointeur sur le ViewPort qui devra être initialisé.
GetColorMap()

Cette fonction alloue et initialise une structure ColorMap.
  • Synopsis : colormap = GetColorMap( colours );
  • colormap : (struct ColorMap *). GetColorMap retourne un pointeur sur la structure ColorMap qu'elle a allouée et initialisée ou NULL s'il n'y a pas assez de mémoire.
  • colours : (long). Une valeur qui indique le nombre de couleurs voulu que devra stocker la structure ColorMap (1, 2, 4, 8, 16, 32).
FreeColorMap()

Cette fonction désalloue la mémoire fournie par la fonction GetColorMap(). N'oubliez pas de libérer toute la mémoire que vous avez réservée. Pour chaque fonction GetColorMap(), il devrait y avoir une fonction FreeColorMap().
  • Synopsis : FreeColorMap( colormap );
  • colormap : (struct ColorMap *). Pointeur sur la structure ColorMap retournée par GetColorMap() que maintenant vous voulez désallouer.
InitBitMap()

Cette fonction initialise une structure BitMap.
  • Synopsis : InitBitMap( bitmap, depth, width, height );
  • bitmap : (struct BitMap *). Pointeur sur la BitMap.
  • depth : (long). Nombre de plans de bits utilisés.
  • width : (long). Largeur du raster.
  • height : (long). Hauteur du raster.
AllocRaster()

Cette fonction réserve la mémoire d'affichage (un plan de bits).
  • Synopsis : pointer = AllocRaster( width, height );
  • pointer : (PLANEPTR). Pointeur sur la zone de mémoire allouée ou NULL si le système n'a pu réserver assez de mémoire.
  • width : (long). Largeur de la BitMap.
  • height : (long). Hauteur de la BitMap.
BltClear()

Cette fonction remet à zéro des grandes zones rectangulaires de mémoire. Cette fonction travaille avec le Blitter et, par conséquent, elle est très rapide.
  • Synopsis : BltClear( pointer, bytes, drapeaux );
  • pointer : (char *). Pointeur sur la zone de mémoire.
  • bytes : (long). Les 16 bits de poids faible informent le Blitter du nombre d'octets par rangée et les 16 bits de poids fort du nombre de rangées. Cette valeur est calculée automatiquement pour vous par l'intermédiaire de la macro RASSIZE(). Fournissez seulement à RASSIZE() la largeur et la hauteur correctes et celle-ci retournera une valeur correcte [RASSIZE() est définie dans le fichier en-tête "gfx.h".].
  • flags : (long). Mettez le bit 0 pour forcer la fonction à attendre tant que le Blitter n'a pas fini son travail.
MakeVPort()

Cette fonction prépare le matériel de l'Amiga (tout particulièrement le Copper) pour afficher un ViewPort. Remarque : vous devrez préparer chaque ViewPort que vous allez utiliser !
  • Synopsis : MakeVPort( view, viewport );
  • view : (struct View *). Pointeur sur le View du ViewPort.
  • viewport : (struct ViewPort *). Pointeur sur le ViewPort.
MrgCop()

Cette fonction réunit toutes les instructions de l'affichage et prépare le View pour l'afficher.
  • Synopsis : MrgCop( view );
  • view : (struct View *). Pointeur sur le View.
LoadView()

Cette fonction fait démarrer l'affichage d'un View. N'oubliez pas, en fermant votre View, qu'il vous faudra revenir au View d'origine (voir les exemples pour plus de détails).
  • Synopsis : LoadView( view );
  • view : (struct View *). Pointeur sur le View.
FreeVPortCopLists()

Cette fonction rendra au système toute la mémoire qui aura été allouée automatiquement par la fonction MakeVPort(). N'oubliez pas d'appeler FreeVPortCopLists() pour chaque ViewPort que vous aurez créé !
  • Synopsis : FreeVPortCopLists( viewport );
  • view : (struct ViewPort *). Pointeur sur le ViewPort.
FreeCprList()

Cette fonction rendra au système toute la mémoire qui aura été allouée automatiquement par la fonction MrgCop().
  • Synopsis : FreeCprList( cprlist );
  • cprlist : (struct cprlist *). Pointeur sur la structure cprlist (LOFCprList) du View. Si le View était en mode entrelacé, vous devrez aussi appeler la fonction FreeCprList avec un pointeur sur SHFCprList.
FreeRaster()

Cette fonction désallouera la mémoire d'affichage (un plan de bits). N'oubliez pas de désallouer tous les plans de bits !
  • Synopsis : FreeRaster( bitplane, width, height );
  • bitplane : (PLANEPTR). Pointeur sur un plan de bits.
  • width : (long). Largeur du plan de bits.
  • height : (long). Hauteur du plan de bits.
FreeColorMap()

Cette fonction rendra au système toute la mémoire qui aura été allouée par la fonction GetColorMap(). N'oubliez pas de désallouer toute la mémoire que vous aurez réservée. Pour chaque fonction GetColorMap() il devrait y avoir une fonction FreeColorMap().
  • Synopsis : FreeColorMap( colormap );
  • colormap : (struct ColorMap *). Pointeur sur la structure ColorMap retournée par GetColorMap() que maintenant vous voulez désallouer.
InitRastPort()

Cette fonction initialise un RastPort.
  • Synopsis : InitRastPort( rast_port );
  • rast_port : (RastPort *). Pointeur sur le RastPort qui doit être initialisé.
SetAPen()

Cette fonction changera la couleur de FgPen.
  • Synopsis : SetAPen( rast_port, new_colour );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • new_colour : (long). Une nouvelle valeur de couleur.
SetBPen()

Cette fonction changera la couleur de BgPen.
  • Synopsis : SetBPen( rast_port, new_colour );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • new_colour : (long). Une nouvelle valeur de couleur.
SetOPen()

Cette macro changera la couleur de AOlPen. Remarque : il ne s'agit pas d'une fonction. En réalité, il s'agit d'une macro définie dans le fichier en-tête "gfxmacros.h". Si vous souhaitez utiliser cette fonction, il vous faudra vous souvenir d'inclure ce fichier dans votre programme.
  • Synopsis : SetOPen( rast_port, new_colour );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • new_colour : (long). Une nouvelle valeur de couleur.
SetDrMd()

Cette fonction changera le mode de dessin.
  • Synopsis : SetDrMd( rast_port, new_mode );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • new_mode : (long). Le nouveau mode de dessin. Mettre l'un des modes suivants : JAM1, JAM2, COMPLEMENT, INVERSVID|JAM1 ou INVERSVID|JAM2.
    • JAM1 : FgPen sera employé, l'arrière-plan est inchangé (une couleur est "bloquée" dans un raster).
    • JAM2 : FgPen sera employé comme crayon de premier plan tandis que l'arrière-plan (là où vous êtes en train d'écrire un texte) sera rempli avec la couleur de BgPen (deux couleurs sont "bloquées" dans un raster).
    • COMPLEMENT : chaque pixel concerné sera dessiné dans sa couleur binaire complémentaire. Là où vous aurez écrit des 1, les bits correspondants dans le raster seront inversés.
    • INVERSVID|JAM1 : ce mode est employé seulement avec du texte. Seul l'arrière-plan du texte sera dessiné avec FgPen.
    • INVERSVID|JAM2 : ce mode est employé seulement avec du texte. L'arrière-plan du texte sera dessiné avec FgPen, tandis que les caractères seront dessinés avec BgPen.
SetDrPt()

Cette fonction fixera le modèle de ligne.
  • Synopsis : SetDrPt( rast_port, line_pattern );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • line_pattern : (UWORD). Le modèle. Chaque bit représente un point. Pour créer des lignes pleines, vous mettrez la valeur de modèle à 0xFFFF [en hexadécimal] (1111111111111111 [en binaire]).
SetAfPt()

Cette fonction fixera les modèles de bloc.
  • Synopsis : SetAfPt( rast_port, area_pattern, pow2 );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • area_pattern : (UWORD). Pointeur sur une matrice de UWORDS qui créera le modèle. Chaque bit de la matrice représente un point.
  • pow2 : (BYTE). Le modèle sera égal à deux à la puissance de la hauteur de lignes pow2. Si la hauteur du modèle est égale à une ligne, on devra mettre pow2 à 0, si elle est égale à deux lignes, on devra mettre pow2 à 1, si elle est égale à quatre lignes, on devra mettre pow2 à 2, et ainsi de suite (si vous employez des modèles multicolores, pow2 devra avoir une valeur négative. Par conséquent, pour un modèle multicolore ayant une hauteur de seize lignes, vous devrez donner à pow2 une valeur de -4 [2^4 = 16]).
WritePixel()

Cette fonction dessinera un seul pixel.
  • Synopsis : WritePixel( rast_port, x, y );
  • rast_port : (struct RastPort *) Pointeur sur le RastPort qui est concerné.
  • x : (long). Abscisse X du pixel.
  • y : (long). Ordonnéé Y du pixel.
ReadPixel()

Cette fonction lit la valeur de la couleur d'un pixel.
  • Synopsis : colour = ReadPixel( rast_port, x, y );
  • colour : (long). ReadPixel retourne la valeur de la couleur du pixel indiqué (couleur qui va de 0 à 255 ) ou -1 si les coordonnées se situent en dehors du raster.
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui contient le pixel que vous souhaitez examiner.
  • x : (long). Abscisse X du pixel.
  • y : (long). Ordonnée Y du pixel.
Move()

Cette fonction change la position du crayon graphique.
  • Synopsis : Move( rast_port, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • x : (long). Nouvelle valeur de l'abscisse X.
  • y : (long). Nouvelle valeur de l'ordonnée Y.
Text()

Cette fonction affiche du texte dans le raster.
  • Synopsis : Text( rast_port, string, nr_of_chr );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • string : (char *). Pointeur sur la chaîne de caractères de texte qui doit être affichée.
  • nr_of_chr : (long). Le nombre de caractères à afficher.
Draw()

Cette fonction dessine des lignes simples de la position courante jusqu'à la nouvelle position indiquée.
  • Synopsis : Draw( rast_port, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • x : (long). Nouvelle valeur de l'abscisse X.
  • y : (long). Nouvelle valeur de l'ordonnée Y.
PolyDraw()

Cette fonction dessinera des lignes multiples.
  • Synopsis : PolyDraw( rast_port, number, coordinates );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • number : (long). Le nombre de coordonnées (x,y) indiquées dans la matrice.
  • coordinates : (short *). Pointeur sur une matrice de coordonnées.
RectFill()

Cette fonction dessinera des rectangles pleins.
  • Synopsis : RectFill( rast_port, minx, miny, maxx, maxy );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • minx : (long). Coin gauche du rectangle.
  • miny : (long). Coin supérieur du rectangle.
  • maxx : (long). Coin droit du rectangle.
  • maxy : (long). Coin inférieur du rectangle.
Flood()

Cette fonction effectuera un remplissage flood pour des objets complexes.
  • Synopsis : Flood( rast_port, mode, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • mode : (long). Le mode qu'on devra employer. Si vous souhaitez employer le mode Couleur, mettez la variable de mode à 1, pour vous servir du mode Délimitation, mettez la variable de mode à 0.
  • x : (long). Abscisse X où devra commencer le remplissage flood.
  • y : (long). Ordonnée Y où devra commencer le remplissage flood.
AreaMove()

Cette fonction fera démarrer le processus pour un nouveau polygone.
  • Synopsis : AreaMove( rast_port, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • x : (long). Abscisse X de démarrage.
  • y : (long). Ordonnée Y de démarrage.
AreaDraw()

Cette fonction ajoutera un nouveau sommet dans la liste du vecteur.
  • Synopsis : AreaDraw( rast_port, x, y );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • x : (long). Nouvelle abscisse X.
  • y : (long). Nouvelle ordonnée Y.
AreaEnd()

Cette fonction mettra fin au processus, dessinera et remplira le polygone.
  • Synopsis : AreaEnd( rast_port );
  • rast_port : (struct RastPort *) Pointeur sur le RastPort qui est concerné.
BNDROFF()

Cette macro (déclarée dans le fichier "gfxmacro.h") mettra hors service le mode Outline.
  • Synopsis : BNDROFF( rast_port );
  • rast_port : Pointeur sur le RastPort où l'on devra désactiver la fonction Outline.
SetRast()

Cette fonction met tout un Raster à la couleur indiquée.
  • Synopsis : SetRast( rast_port, colour );
  • rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • colour : (long). Le registre de couleur avec lequel vous voulez remplir tout le raster.
ScrollRaster()

Cette fonction fera défiler sur l'écran une zone rectangulaire d'un raster.
  • Synopsis : ScrollRaster( rp, dx, dy, minx, miny, maxx, maxy );
  • rp : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
  • dx : (long). Déplacement delta sur le plan des X (un chiffre positif déplacera la zone vers la droite, un chiffre négatif la déplacera sur la gauche).
  • dy : (long). Déplacement delta sur le plan des Y (un chiffre positif déplacera la zone vers le bas, un chiffre négatif la déplacera vers le haut).
  • minx : (long). Coin gauche du rectangle.
  • miny : (long). Coin supérieur du rectangle.
  • maxx : (long) Coin droit du rectangle.
  • maxy : (long) Coin inférieur du rectangle.
BltBitMap()

Cette fonction copie des parties des BitMaps directement sans s'occuper des couches (layers) de recouvrement.
  • Synopsis : BltBitMap( sbm, sx, sy, dbm, dx, dy, w, h, flag, m, t );
  • sbm : (struct BitMap *). Pointeur sur la BitMap "source".
  • sx : (long). Offset dans le plan des X de la source.
  • sy : (long). Offset dans le plan des Y de la source.
  • dbm : (struct BitMap *). Pointeur sur la BitMap "destination".
  • dx : (long). Offset dans le plan des X de la destination.
  • dy : (long). Offset dans le plan des Y de la destination.
  • w : (long) Largeur de la zone de mémoire qui devra être copiée.
  • h : (long). Hauteur de la zone de mémoire qui devra être copiée.
  • flag : (long). Cette valeur informe le Blitter du type d'opérations logiques à effectuer. Voir ci-dessous pour plus de renseignements.
  • m : (long). Ici, vous pourrez définir un masque de BitMap et dire au Blitter quels plans de bits devront et ne devront pas être employés. Le premier bit représente le premier plan de bits, le deuxième bit représente le deuxième plan de bits et ainsi de suite. Si le bit est activé (1), on emploiera le plan de bits correspondant, autrement (0) on n'emploiera pas ce plan de bits. Pour mettre hors service les plans de bits zéro et deux, mettez la valeur de masque à 0xFA (11111010). Pour employer tous les plans de bits, mettez la valeur de masque à 0xFF (11111111).
  • t : (char *). Si la copie fait des recouvrements et si ce pointeur pointe sur une partie de la mémoire Chip, la mémoire sera employée pour y stocker une zone temporaire. Cependant, normalement, vous n'aurez pas à vous occuper de cette valeur.
ClipBlit()

ClipBlit() copie les BitMaps en se servant des Rastports, par conséquent, la fonction fera attention aux couches de recouvrement et on devra l'employer s'il y a des fenêtres dans l'affichage.
  • Synopsis : ClipBlit( srp, sx, sy, drp, dx, dy, w, h, drapeau );
  • srp : (struct RastPort *). Pointeur sur le RastPort "source".
  • sx : (long). Offset dans le plan des X de la source.
  • sy : (long). Offset dans le plan des Y de la source.
  • drp : (struct RastPort *) Pointeur sur le RastPort "destination".
  • dx : (long). Offset dans le plan des X de la destination.
  • dy : (long). Offset dans le plan des Y de la destination.
  • w : (long). Largeur de la zone de mémoire qui devra être copiée.
  • h : (long). Hauteur de la zone de mémoire qui devra être copiée.
  • flag : (long). Cette valeur informe le Blitter du type d'opérations logiques à effectuer. Voir ci-dessous pour plus de renseignements.
12.5 Exemples

Voici des exemples (dans le répertoire "Amiga_C_Manual/12.LowLevelGraphics") montrant des routines graphiques de bas niveau :

Exemple 1

Cet exemple vous montre comment créer votre propre affichage et comment on le remplit avec un tas de pixels de sept couleurs différentes.

Exemple 2

Cet exemple vous montre comment créer un grand raster et un petit affichage. Nous remplissons le raster avec un tas de pixels de sept couleurs différentes et, en modifiant les valeurs de RxOffset et de RyOffset, dans la structure RasInfo, le raster défilera dans toutes les directions. Cette méthode pour faire défiler un grand dessin à grande vitesse est employée dans beaucoup de jeux et je l'ai moi-même employée dans mon jeu de course automobile "Car".

Exemple 3

Cet exemple vous montre comment créer un affichage qui couvre tout l'écran. On appelle cette méthode "Suraffichage" et on l'utilise en premier lieu dans les programmes vidéo et graphiques, mais on peut aussi s'en servir dans des jeux pour rendre un affichage plus attrayant.

Exemple 4

Cet exemple montre comment ouvrir deux ViewPorts différents dans un même affichage. Le premier ViewPort est en basse résolution et emploie 32 couleurs, tandis que le deuxième est en haute résolution et emploie seulement deux couleurs.

Exemple 5

Cet exemple montre comment ouvrir un ViewPort en mode entrelacé.

Exemple 6

Cet exemple montre comment ouvrir un ViewPort en mode double plan. Le plan 1 utilise quatre couleurs et a été placé au-dessous du plan 2 qui utilise seulement deux couleurs (transparent et gris). Le plan 1 est rempli d'un tas de points et défile dans tout l'écran, tandis que le plan 2 est fixe et est rempli de cinq rectangles gris.

Exemple 7

Cet exemple montre comment créer un ViewPort en utilisant le mode d'affichage spécial "Hold And Modify".

Exemple 8

Cet exemple montre coment on utilise les fonctions suivantes : SetAPen(), SetBPen(), SetOPen(), SetDrMd(), SetDrPt(), WritePixel(), ReadPixel(), Move(), Draw(), Text() et, pour finir, PolyDraw().

Exemple 9

Cet exemple montre comment faire le remplissage "flood" d'un dessin et comment dessiner des rectangles pleins (avec des modèles simples et multicolores).

Exemple 10

Cet exemple montre comment on emploie les fonctions Area Fill. [ AreaMove(), AreaDraw() et AreaEnd() ].

Exemple 11

Cet exemple montre comment on copie des zones de mémoire rectangulaires en se servant du Blitter.


[Retour en haut] / [Retour aux articles] [Chapitre précédent : AmigaDOS] / [Chapitre suivant : VSprites]