1ère partie: ouvrir une fenêtre

Un article de GuruMed.

Ouverture de fenêtre

par StAn.

Vous aimeriez que votre dernier jeu tourne aussi bien sur cartes graphiques que sur l'AGA ? Le sujet est vaste et (parfois) compliqué, mais cette série d'articles devrait vous donner quelques idées sur la façon de procéder.

Tout d'abord, l'OS 3.0 ou supérieur est indispensable dès que l'on parle de programmation graphique système.

Ensuite, pour ceux qui auraient loupé ce "détail", vous aurez besoin des AutoDocs, la documentation officielle des bibliothèques de l'AmigaOS. Elles se trouvent dans l'archive du NDK 3.9 (Native Developer Kit) qui se trouve sur le site d'Amiga Inc, ou sur les CD Amiga Developer disponibles chez la plupart des revendeurs Amiga.

Plusieurs cas de figures peuvent se présenter: votre application peut afficher des bitmaps sans les modifier (ou presque), comme dans un jeu 2D classique, ou alors manipuler des graphismes pixel par pixel comme dans un moteur 3D software, par exemple.

Dans tous les cas, la première chose à faire est d'ouvrir une fenêtre, que ce soit sur le WB ou dans un écran privé. Nous allons d'abord étudier le cas d'un programme s'ouvrant sur le WB.


Ouvrir une fenêtre

C'est très simple; il suffit d'utiliser les fonctions OpenWindowTags() ou OpenWindowTagList() de intuition.library (il s'agit de la même fonction, mais les paramètres ne sont pas passés de la même manière). Exemple:


	
#include <intuition/intuition.h> // pour IntuitionBase, struct Window
                                 // et les tags WA_...
#include <proto/intuition.h>     // pour OpenWindowTags() et CloseWindow()
#include <proto/exec.h>          // pour OpenLibrary(), CloseLibrary() et WaitPort()
#include <stdio.h>               // pour puts()

struct IntuitionBase *IntuitionBase;

int main(void)
{
   struct Window *win=NULL;

   IntuitionBase = (struct IntuitionBase *) OpenLibrary( "intuition.library", 36 );
   if( !IntuitionBase ) {
      puts( "Impossible d'ouvrir intuition.library." );
      return 20;
   }

   win = OpenWindowTags( NULL,
            WA_Title,       (ULONG)"Pouet",
            WA_InnerWidth,  320,
            WA_InnerHeight, 240,
            WA_DragBar,     TRUE,
            WA_CloseGadget, TRUE,
            WA_DepthGadget, TRUE,
            WA_IDCMP,       IDCMP_CLOSEWINDOW,
            TAG_END );

   if( !win ) {
      puts( "Impossible d'ouvrir la fenêtre." );
      CloseLibrary( (struct Library *) IntuitionBase );
      return 10;
   }

   WaitPort( win->UserPort );
   CloseWindow( win );
   CloseLibrary( (struct Library *) IntuitionBase );
   return 0;
}

Voyons ce que fait ce programme pas à pas:

Tout d'abord, il ouvre la bibliothèque intuition. On demande la version 36, c'est-à-dire celle de l'OS 2.0, au minimum, car OpenWindowTags() n'existe que depuis l'OS 2.0.

   IntuitionBase = (struct IntuitionBase *) OpenLibrary( "intuition.library", 36 );

On teste toujours si l'ouverture d'une bibliothèque a réussi, et dans le cas contraire la solution choisie ici est de quitter le programme.

   if( !IntuitionBase ) {

      puts( "Impossible d'ouvrir intuition.library." );

      return 20;

   }

Ensuite, il ouvre la fenêtre.

   win = OpenWindowTags( NULL,

            WA_Title,       (ULONG)"Pouet",

            WA_InnerWidth,  320,

            WA_InnerHeight, 240,

            WA_DragBar,     TRUE,

            WA_CloseGadget, TRUE,

            WA_DepthGadget, TRUE,

            WA_IDCMP,       IDCMP_CLOSEWINDOW,

            TAG_END );

Le premier paramètre d'OpenWindowTags(), NULL, correspond à un pointeur sur une structure NewWindow. Ici nous choisissons la méthode la plus simple qui consiste à ne pas l'utiliser, et à utiliser uniquement les tags. Les tags permettent de faire tout ce que permet l'utilisation de la structure NewWindow et même plus, donc il n'y a aucun problème à ce niveau.

Quand aux paramètres suivants, les tags:

  • WA_Title permet de donner un titre à la fenêtre.
  • WA_InnerWidth et WA_InnerHeight servent à déterminer la taille de la fenêtre.

On fourni ici la taille intérieure de la fenêtre, c'est à dire que la bordure de la fenêtre n'est pas incluse. C'est le plus pratique quand vous connaissez la taille de ce que vous voulez afficher; mais il existe aussi les tags WA_Width et WA_Height si vous voulez spécifier la taille totale de la fenêtre.

  • WA_DragBar permet de dire si on veut que la fenêtre soit déplaçable ou non.
  • WA_CloseGadget sert à obtenir le gadget de fermeture.
  • WA_DepthGadget pour le gadget de profondeur.
  • WA_IDCMP sert à choisir les messages que l'on veut recevoir de la part d'intuition. Ici, on demande IDCMP_CLOSEWINDOW afin de savoir quand l'utilisateur clique sur le gadget de fermeture de la fenêtre. La liste complète des IDCMP se trouve dans l'autodoc de intuition/ModifyIDCMP().
  • et enfin TAG_END sert bien sûr à terminer la liste des tags... Ne l'oubliez pas :-).

Les tags peuvent être placés dans n'importe-quel ordre, et vous n'avez besoin d'inclure que ceux qui vous sont nécessaire. La liste complète se trouve dans le fichier intuition/intuition.h des includes système, ou dans l'autodoc de intuition/OpenWindow().

Comme vous le voyez, il est inutile de préciser qu'on veut ouvrir la fenêtre sur le WB: elle s'ouvre sur l'écran public par défaut.

Ne vous embêtez pas avec l'ancienne fonction OpenWindow(), elle a été remplacée par OpenWindowTagList() et OpenWindowTags() depuis l'OS 2.0. C'est par contre dans l'autodoc de OpenWindow() que vous trouverez la description de tous les tags utilisés pour ouvrir une fenêtre.


Ensuite, le programme vérifie que la fenêtre s'est bien ouverte. Il peut y avoir de nombreuses raisons pour que cela échoue, comme par exemple un manque de mémoire ou un écran trop petit pour contenir une fenêtre de la taille demandée, donc il faut toujours tester si l'ouverture a fonctionné.

   if( !win ) {

      puts( "Impossible d'ouvrir la fenêtre." );

      CloseLibrary( (struct Library *) IntuitionBase );

      return 10;

   }

Si la fenêtre ne s'est pas ouverte, on nettoie avant de s'en aller: ici il s'agit de fermer l'intuition.library.

   WaitPort( win->UserPort );

Ici, le programme attend de recevoir un message de la part d'intuition. Le seul que l'on puisse recevoir est un message d'appui sur le gadget de fermeture, puisque c'est le seul qu'on ait demandé.

Enfin, une fois que l'utilisateur a cliqué pour fermer la fenêtre, on la ferme, ainsi que l'intuition.library, et le programme se termine.

   CloseWindow( win );

   CloseLibrary( (struct Library *) IntuitionBase );

   return 0;


Voici venue la fin de cet article. "Déjà !", vous entends-je hurler... Oui, c'est très court, mais je reviendrai bientôt(tm) pour vous parler de l'allocation d'une palette et du tracé de graphiques au format chunky... (à moins qu'on ne me glisse à l'oreille de meilleures idées </suggestion habillement dissimulée>)

En attendant, vous pouvez essayer de tracer des trucs et des bidules dans votre fenêtre avec la graphics.library. Jettez par exemple un coup d'oeil du côté des fonctions Move(), Draw(), Text(), et SetAPen() pour choisir la couleur...