|
|||||||||||||||||||||||||||||||||||||||||||
|
Séquence admiration La bibliothèque graphique (Graphics Support Library) a deux buts principaux. Elle fournit une interface simple aux mécanismes complexes de l'affichage de l'Amiga ainsi qu'un accès procédural aux fonctions de tracé, de rendu des coprocesseurs spécialisés. C'est assez complexe, à la fois à comprendre et à expliquer, aussi je ne passerai en revue que les routines de base de la graphic.library. Cette bibliothèque fournit plusieurs structures de données permettant de définir et de manipuler de la mémoire vidéo. La mémoire vidéo est la mémoire qui est organisée en plans pixels. Chaque plan mémoire contient un seul bit de codage pour chaque pixel de l'écran. Un affichage normal contient de un à cinq plans mémoire (selon le nombre de couleurs). Cela veut dire que chaque pixel peut être défini par un nombre de bits variable de 1 à 5. La combinaison des bits dans la constitution du pixel peut donc prendre une valeur allant de 0 à 31, selon le nombre de plans mémoire utilisés dans la mémoire vidéo. Cette valeur correspondra à un des 32 registres de couleurs de l'Amiga. La valeur d'un pixel est utilisée comme index dans le registre de couleur matériel. Chaque registre de couleur a une largeur de 12 bits, donc chaque registre de couleur peut décrire une valeur parmi 4096 (212 car un bit ne peut prendre que deux valeurs). Le résultat est que l'Amiga peut afficher 32 couleurs simultanément et que chacune de ces couleurs peut prendre une teinte parmi 4096. Les structures de base de la bibliothèque graphique sont le BitMap et le RastPort (raster port). La structure BitMap définit le nombre de plans de bits groupés ensemble pour former l'affichage dans la mémoire. La structure RastPort est un recueil des paramètres nécessaires au rendu du BitMap de la mémoire vidéo. Ce rendu d'image est effectué par les routines graphiques, les routines de texte ou les routines d'animations d'objets. On va un peu détailler les composants principaux de la structure RastPort.
La bibliothèque graphique fait souvent appel au pinceau "RastPort" lors de la réalisation des rendus. Ce pinceau décrit le registre de couleurs utilisées ainsi que la position à l'affichage lors du tracé de lignes, de l'écriture de texte et du remplissage de surface. Le pinceau primaire utilisé pour le rendu de base est le pinceau d'avant-plan (FgPen) appelé également pinceau A. On utilise le pinceau d'arrière-plan, ou pinceau B, pour des rendus plus élaborés, comme la création de motifs, l'écriture de texte sur motifs ou fond coloré. La routine SetAPen() définit la valeur du pinceau, qui spécifie la valeur d'un des 32 registres de couleur. Le pinceau possède également des coordonnées dans un RastPort donné. On utilise Move() pour définir ou changer la position du pinceau, le point de départ de lignes ou la ligne de base d'une chaîne de caractères. Tracé de lignes et remplissage de rectangles Tracer une ligne ne demande que quatre étapes. Prenons un exemple d'une procédure écrite en C. ![]() Tout d'abord, on initialise la couleur du pinceau. Le nombre de pinceaux disponibles dépend du nombre de plans de bits que l'on a dans le BitMap. On définit ensuite le "drawing mode", qui est généralement JAM1 pour les lignes simples. Enfin, on déplace le pinceau de la position de départ à la position d'arrivée. Par conséquent, la fonction DrawLine(Rport,1,JAM1,10,10,15,25); va tracer une ligne de la couleur n°1 en partant de la position (10,10) vers la position (15,25). En effet, la fonction Draw() tire le pinceau vers sa nouvelle position en laissant une trace derrière lui. Move() est donc l'équivalent de "Déplacer avec le pinceau levé" et Draw() de "Déplacer avec le pinceau baissé". Une fois définies, les variables d'état du pinceau et du mode de dessin ne changent pas tant qu'on ne les réinitialise pas. On n'a pas besoin de tout redéfinir chaque fois qu'on trace une petite ligne (heureusement...). La bibliothèque graphique possède également des routines pour remplir des rectangles parallèles aux axes verticaux ou horizontaux avec une couleur donnée. La fonction RectFill() utilise le pinceau et le mode définis dans les précédents appels aux opérateurs du RastPort. La routine accepte deux coordonnées comme paramètres : les coins supérieurs gauche et inférieur droit du rectangle à colorier. Dans une configuration peu encombrée au niveau processes, la bibliothèque graphique peut créer approximativement un millier de rectangles de 96x96 pixels par plans de bits par seconde. Impression de texte On peut aussi utiliser les pinceaux pour afficher du texte. La position du pinceau détermine l'endroit de l'écriture. La coordonnée en "x" donne la position en pixels du premier caractère. La coordonnée "y" donne la position de la ligne de base. On utilise le pinceau primaire pour dessiner les caractères. Le mode JAM1 écrit des caractères de la couleur du pinceau FgPen, et la structure BitMap est vue en transparence à travers les blancs et les trous des lettres. Le mode JAM2 utilise à la fois la couleur de fond et la couleur de premier plan. Comme en JAM1, les caractères sont écrits avec la couleur de FgPen, mais l'entourage des lettres est maintenant de la couleur du BgPen. Dans ce cas, le BitMap situé au-dessous est masqué. Le mode InverseVid combine les deux modes JAM pour inverser les couleurs des deux pinceaux. Pour initialiser les pinceaux et le mode de dessin en texte, on utilise les mêmes routines que pour le tracé de lignes. Les valeurs des pinceaux et du mode sont établies grâce aux fonctions SetAPen(), SetBPen() et SetDrMd(). On déplace le pinceau avec Move(). On peut alors appeler la routine Text() pour introduire le texte dans le RastPort. Comme pour les lignes, il n'y a pas besoin de redonner à chaque fois les paramètres. Si on fait plusieurs appels à Text(), les lignes suivantes seront correctement espacées et auront la même ligne de base que la première. Exemple de procédure en C : ![]() ![]() Séquence Intuition Intuition est l'interface graphique de l'Amiga qui permet grâce à des mécanismes simples de créer et de gérer des affichages qui gèrent le multitâche. Intuition permet d'appeler, au travers de procédures simples, des aspects très complexes du système. De plus, on n'a pas besoin de comprendre le fonctionnement de ces procédures pour les appeler. Un des buts d'Intuition est de faciliter la tâche des programmeurs en simplifiant le plus possible l'interface avec le noyau. Intuition fournit des outils permettant de créer un environnement intuitif (d'où son nom) pour l'utilisateur et en même temps commode pour le développeur d'applications. L'écran est l'unité de base de l'affichage Intuition. Un écran est une combinaison d'adresses en mémoire vidéo et d'instructions matérielles capables de transcrire ces adresses en affichage véritable. Le mémoire vidéo "écran" est utilisée pour toutes les fonctions de la bibliothèque graphique, et tous, les composants de l'affichage Intuition sont finalement générés par ces fonctions, en mémoire vidéo. On utilise la bibliothèque graphique pour créer les écrans d'affichage. Quand on crée des écrans, il remplissent normalement toute la place disponible. Je fais ici une distinction entre l'écran physique (celui où il y a les traces de doigts) et l'écran virtuel au sens Intuition. La bibliothèque graphique va alors ordonner aux coprocesseurs graphiques de créer l'affichage désiré, comme spécifié dans la structure de donnée de l'écran. C'est en fait un peu le même principe que le RastPort. On peut générer des affichages directement avec la bibliothèque graphique, sans passer par Intuition (c'est beaucoup moins... intuitif). Créer un écran comporte plusieurs étapes, pendant lesquelles il faut utiliser les bonnes routines avec les bons arguments. Intuition nous aide en réduisant la création d'un affichage à deux étapes :
Séquence défenestration Les fenêtres sont des zones d'affichage distinctes qu'on ouvre à l'intérieur des écrans Intuition (display-output) ; écrire dans une fenêtre n'entraîne aucun changement pour les autres fenêtres de l'écran ou des autres écrans. Il y a ici la notion d'objet informatique qui entre en compte, mais ce serait assez compliqué et long à expliquer. Les fenêtres sont à la fois souples et simples à créer : beaucoup d'applications les exploitent (bien qu'il soit possible d'utiliser directement la mémoire vidéo, sans ouvrir de fenêtre). Les fenêtres peuvent changer de taille, être déplacées et passer les unes devant les autres, aussi bien par l'utilisateur que par programmation. Quand un utilisateur manipule une fenêtre, il peut décider d'accepter les changements effectués par programmation ou bien repositionner les fenêtres comme il le souhaite. L'utilisateur peut décider quelle fenêtre sera active en entrée à un moment donné (input window), mais on peut outrepasser ça en programmation. En effet, on peut écrire dans n'importe quelle fenêtre ouverte, active ou non, selon ce qui se passe dans le système. Parce qu'une application peut complètement ignorer la forme, la position et l'état d'une fenêtre, chaque fenêtre peut se comporter comme un "terminal virtuel" pour cette application. L'application peut, en fait, juste demander à Intuition comment ouvrir et fermer une fenêtre, et alors ouvrir le périphérique console (console.device) pour gérer les entrées/sorties, comme si elle était connectée sur un terminal ANSI classique (ANSI : American National Standard Institute). On ouvre une fenêtre comme un écran, en initialisant une structure de données, NewWindow et en appelant la routine OpenWindow(). On a également besoin de spécifier le type de fenêtre désiré. Type de fenêtres
Gadgets système
Séquence... sourions (menus et IDCMP) Le système de menus Intuition permet au développeur de grouper ensemble et d'afficher les options et fonctionnalités du programme qu'il conçoit. Les items de menus peuvent être des images graphiques ou de simples intitulés de texte et on peut les positionner comme on le souhaite. On peut avoir deux niveaux de menus hiérarchiques pour présenter les items. L'utilisateur peut choisir les options avec la souris ou à l'aide de raccourcis claviers. Les items de menus sélectionnés sont reconnus par Intuition à l'aide des IDCMP (Intuition Direct Communications Message Ports) qui sont des structures standard de communications d'Exec (vous vous souvenez ?) simplifiées pour l'usage des développeurs. Quand Intuition établit un IDCMP, elle alloue et initialise les deux ports requis par la structure de communication (un pour envoyer le message et un pour recevoir la réponse). On n'a pas besoin de connaître les méthodes de création et de maintien des ports de communication : on a seulement besoin de connaître comment recevoir des messages. Les messages reçus proviennent d'évènements clavier, de mouvements de souris, de clics de souris, d'accès disque et d'évènements Intuition (gestion des fenêtres par exemple) et transitent par les IDCMP. L'autre méthode de recevoir des données est de passer par le "console.device", qui en se comportant comme un terminal triture les données pour les transformer en codes ASCII ou en séquences d'échappement ANSI. Les programmes désirant se baser principalement sur les capacités de terminal virtuel de l'Amiga utiliseront préférentiellement le "console.device" plutôt que les IDCMP. Séquence conclusion Voilà comment une machine que Jay Miner avait créée pour en faire un simulateur de vol a pu évoluer vers un système informatique complet et complexe. Ceci est juste une introduction à Exec, Graphics et Intuition, il faudrait consacrer 30 pages à chaque bibliothèque pour en explorer toutes les possibilités.
|