Obligement - L'Amiga au maximum

Jeudi 05 juin 2025 - 14:50  

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


Réseaux sociaux

Suivez-nous sur X




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

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : Amiga C Manual - VSprites
(Article écrit par Anders Bjerin et extrait d'Amiga C Manual - mars 1990)


Note : traduction par Serge Hammouche.

13. Les VSprites

13.1 Introduction

Les VSprites, ou sprites virtuels de leur nom complet, sont très proches des sprites matériels. Les VSprites ont les mêmes limitations telles une largeur maximum de 16 pixels et peuvent seulement utiliser trois couleurs (en réalité quatre couleurs, mais la première couleur agira comme couleur transparente). Cependant les VSprites sont supérieurs aux sprites matériels parce que vous pouvez utiliser bien plus de huit VSprites en même temps, et chaque VSprite peut avoir ses trois couleurs choisies dans une palette de 4096 couleurs. Le désavantage des VSprites comparés aux sprites matériels provient du fait que les sprites matériels sont complètement contrôlés par le matériel et donc très rapides alors que les VSprites sont partiellement gérés par logiciel et, à cause de cela, un peu plus lents.

13.2 Comment fonctionnent les VSprites

Les VSprites sont très proches des sprites matériels pour la bonne raison qu'ils sont en réalité affichés à l'aide des sprites matériels. Si vous voulez qu'un VSprite soit affiché en haut de l'écran et un autre plus bas, le système positionnera un sprite matériel en haut de l'écran puis changera son image afin qu'elle corresponde au dessin du VSprite. Les couleurs seront aussi automatiquement changées en modifiant la liste Copper (consultez le répertoire "Hacks" pour plus d'information sur les listes Copper).

Quand le balayage vidéo a passé le premier VSprite, le sprite matériel n'est plus utile et peut donc servir à nouveau. Le système peut alors utiliser le même sprite matériel pour afficher un autre VSprite, et ainsi de suite. Grâce à ça, vous pouvez disposer de bien plus de huit sprites en même temps à l'écran.

Si deux VSprites ou plus doivent être sur la même ligne à l'écran, nous avons besoin d'autres sprites matériels. Le système a huit sprites matériels à sa disposition, et peut donc afficher jusqu'à huit VSprites sur la même ligne.

Voici un exemple. Vous voulez afficher trois VSprites positionnés comme ci-dessous. Dans ce cas deux sprites matériels sont nécessaires. Le sprite matériel 1 sert à afficher les VSprites A et B. A et B ne sont pas sur la même ligne, et donc un seul sprite matériel est nécessaire. Cependant le VSprite C est sur la même ligne que B, et un second sprite matériel est donc nécessaire.

 -----
 | A |
 -----
   -----
   | B |    -----
   -----    | C |
            -----

13.2.1 Limitations

Il existe quelques limitations importantes à rappeler :
  1. Si vous avez réservé quelques sprites matériels pour votre propre usage, le système ne peut pas utiliser ces sprites et cela limitera le nombre maximum de VSprites sur la même ligne.

  2. Les sprites matériels 0 et 1, 2 et 3, 4 et 5, 6 et 7 partagent les mêmes couleurs (par paire). Si le sprite 0 est utilisé pour afficher un VSprite, l'ordinateur ne peut pas utiliser le sprite 1 pour afficher un autre VSprite sur la même ligne s'il possède des couleurs différentes. A cause de cela, il existe une limitation à un maximum de quatre VSprites de couleurs différentes sur la même ligne.

  3. Si vous affichez le VSprite sur un écran avec une profondeur de 5 ou plus (32 couleurs ou plus), vous pourrez voir d'étranges fluctuations des couleurs sur les lignes où sont placées les VSprites. Ceci est dû au fait que les VSprites utilisent alors les mêmes registres de couleur que l'écran, et que, comme indiqué précédemment, le système change en permanence ces couleurs pour correspondre aux couleurs des VSprites.
Si le système ne peut pas trouver un sprite matériel pour afficher un VSprite à cause de ces limitations, le VSprite ne sera tout simplement pas affiché.

13.2.2 Comment éviter ces limitations

Il existe plusieurs méthodes à suivre afin d'éviter ces limitations :
  1. Utilisez aussi peu de VSprites que possible sur la même ligne.
  2. Essayez d'utiliser des VSprites ayant des couleurs identiques.
  3. Si vous utilisez un affichage avec plus de 16 couleurs, vous devez utiliser uniquement les couleurs 16, 20, 24 et 28 (ce sont les couleurs transparentes, et ne seront donc pas modifiées par les VSprites).
13.3 Créer des VSprites

Si vous désirez utiliser des VSprites, vous devez :
  1. Déclarer et initialiser des données de sprite pour chaque VSprite.
  2. Déclarer une structure VSprite pour chaque VSprite plus deux structures supplémentaires pour deux VSprites factices.
  3. Décider des couleurs des VSprites.
  4. Déclarer une structure GelsInfo.
  5. Ouvrir la bibliothèque Graphics.
  6. Initialiser la structure GelsInfo.
  7. Initialiser la structure VSprite.
  8. Ajouter les VSprites à la liste des VSprites.
  9. Classer la liste GEL: SortGList().
  10. Dessiner la liste GEL: DrawGList().
  11. Mettre en marche le Copper et redessiner l'affichage.
    [ MrgCop() et LoadView() ] ou [ MakeScreen() et RethinkDisplay() ]
  12. Utiliser les VSprites.
  13. Supprimer les VSprites : RemVSprite()
Facile, n'est-ce pas ?

13.3.1 Données de VSprite

Les données pour les VSprites sont déclarées et initialisées comme des données normales de sprites. Souvenez-vous que toutes les données de sprite doivent être placées en mémoire Chip.

Exemple :

  UWORD chip donnees_vsprite[]=
  {
    0x0FF0, 0x0FF0,
    0x0FF0, 0x0FF0,
    0x0FF0, 0x0FF0,
    0x0FF0, 0x0FF0
  };

13.3.2 Structure VSprite

Vous devez déclarer une structure VSprite pour chaque VSprite que vous allez utiliser, et deux supplémentaires pour deux "VSprites factices". Les deux VSprites factices sont utilisées par le système GEL (GEL signifie Graphic ELements). Un des deux Vsprites factices est placé en tête de la liste GEL, et l'autre est placé en queue. Le système GEL peut alors classer la liste plus vite, et la vitesse est essentielle ici.

Exemple :

  struct VSprite tete, queue, vsprite;

La structure VSprite ressemble à ceci (déclarée dans le fichier entête "graphics/gels.h") :

struct VSprite
{
  struct VSprite *NextVSprite;
  struct VSprite *PrevVSprite;
  struct VSprite *DrawPath;
  struct VSprite *ClearPath;

  WORD OldY, OldX;
  WORD Flags;
  WORD Y, X;
  WORD Height;
  WORD Width;
  WORD Depth;
  WORD MeMask;
  WORD HitMask;
  WORD *ImageData;
  WORD *BorderLine;
  WORD *CollMask;
  WORD *SprColors;
  struct Bob *VSBob;
  BYTE PlanePick;
  BYTE PlaneOnOff;
  VUserStuff VUserExt;
};
  • NextVSprite : pointeur sur le prochain VSprite dans la liste.
  • PrevVSprite : pointeur sur le précédent VSprite dans la liste.
  • DrawPath : utilisé par les BOB.
  • ClearPath : utilisé par les BOB.
  • OldY : précédente position en Y.
  • OldX : précédente position en X.
  • Flags : les indicateurs (drapeaux) suivants peuvent être positionnés par l'utilisateur :
    • SUSERFLAGS : masque des drapeaux utilisateurs.
    • VSPRITE : mettez ce drapeau si vous utilisez la structure pour un VSprite.
    • MUSTDRAW : mettez ce drapeau si ce VSprite doit être dessiné.
      Les drapeaux suivants sont mis par le système :
    • GELGONE : ce drapeau est mis si le VSprite est en dehors des limites de l'écran et ne peut donc être affiché.
    • VSOVERFLOW : trop de VSprites sur la même ligne. Si le drapeau MUSTDRAW est mis, le système essaiera alors de le dessiner, mais le résultat pourra paraître étrange.
  • Y : position en X.
  • X : position en Y.
  • Height : la taille du VSprite.
  • Width : nombre de mots utilisés pour chaque ligne. Pour le moment un VSprite ne peut avoir que 16 pixels de large, ce qui correspond à deux mots.
  • Depth : nombre de plans. Un VSprite peut pour le moment utiliser seulement deux plans, trois couleurs et une transparente.
  • MeMask : ce qui peut entrer en collision avec le VSprite (Ceci sera expliqué dans une future version du manuel).
  • HitMask : ce que ce VSprite peut heurter (Ce sera expliqué dans une future version du manuel).
  • ImageData : pointeur sur les données (graphiques) du sprite.
  • BorderLine : (sera expliqué dans une future version du manuel).
  • CollMask : (sera expliqué dans une future version du manuel).
  • SprColors : pointeur sur une table de couleurs pour ce VSprite.
  • VSBob : utilisé si c'est un BOB (Sera expliqué dans une future version du manuel).
  • PlanePick : utilisé si c'est un BOB (Sera expliqué dans une future version du manuel).
  • PlaneOnOff : utilisé si c'est un BOB (Sera expliqué dans une future version du manuel).
  • VUserExt : vous pouvez utiliser ce champ comme vous le voulez. Vous pouvez ajouter ici des informations supplémentaires, etc. (il est en réalité déclaré comme une variable SHORT).
13.3.3 Table des couleurs

Chaque VSprite peut avoir ses trois couleurs propres parmi une palette de 4096. Les trois couleurs choisies sont placées dans un tableau de "WORD".

Exemple :

  WORD table_couleur[] = { 0x000F, 0x00F0, 0x0F00 };

13.3.4 Structure GelsInfo

Si vous voulez utiliser des VSprites ou des BOB, vous devez déclarer et initialiser une structure GelsInfo.

Exemple :

  struct GelsInfo ginfo;

La structure GelsInfo ressemble à ceci (déclarée dans le fichier entête "graphics/rastport.h") :

struct GelsInfo
{
  BYTE sprRsrvd;
  UBYTE Flags;
  struct VSprite *gelHead, gelTail;
  WORD *nextLine;
  WORD **lastColor;
  struct collTable *collHandler;
  short leftmost, rightmost, topmost, bottommost;
  APTR firstBlissObj, lastBlissObj;
};
  • sprRsrvd : quel sprite matériel doit être réservé pour servir de VSprites. Le bit zéro représente le premier sprite, le bit un le deuxième sprite et ainsi de suite. Si le bit est mis à 1, le sprite pourra être utilisé. Mettez le masque à 0xFF si tous les sprites peuvent servir de VSprites.
  • Flags : utilisé par le système.
  • gelHead : pointeur sur le premier VSprite factice.
  • gelTail : pointeur sur le second VSprite factice.
  • nextLine : quels sprites sont disponibles sur la prochaine ligne.
  • lastColor : pointeur sur un tableau des couleurs qui ont été utilisées le plus récemment.
  • collHandler : pointeur sur les routines de collision.
  • leftmost : utilisé par le système.
  • rightmost : utilisé par le système.
  • topmost : utilisé par le système.
  • bottommost : utilisé par le système.
  • firstBlissObj : utilisé par le système.
  • lastBlissObj : utilisé par le système.
13.3.5 Initialiser une structure GelsInfo

Après que vous ayez déclaré la structure GelsInfo, vous devez initialiser quelques champs importants. Tout d'abord, vous devez indiquer au système quels sprites il est autorisé à utiliser en tant que VSprites. Si tous les VSprites sont autorisés, initialisez le champ sprRsrvd à 0xFF. Si tous les sprites exceptés les deux premiers sont autorisés, initialisez le masque à 0xFC.

Vous devez aussi affecter le champ nextLine d'un pointeur sur un tableau de huit WORD, et le champ lastColor d'un pointeur sur un tableau de huit pointeurs de WORD.

Exemple :

  WORD prochaine_ligne[8];
  WORD *dernieres_couleurs[8];

  /* Tous les sprites exceptés les deux premiers peuvent servir de VSprites: */
  ginfo.sprRsrvd = 0xFC;

  ginfo.nextLine = prochaine_ligne;
  ginfo.lastColor = dernieres_couleurs;

Enfin, vous transmettez la structure GelsInfo au système en appelant la fonction InitGels(), et vous affectez le champ GelsInfo du Rastport d'un pointeur sur votre struture GelsInfo.
  • Synopsis : InitGels( tête, queue, ginfo );
  • tête : (struct VSprite *). Pointeur sur la première structure VSprite factice.
  • tail : (struct VSprite *). Pointeur sur la deuxième structure VSprite factice.
  • ginfo : (struct GelsInfo *). Pointeur sur une structure GelsInfo initialisée.
Exemple :

 /* Transmet la structure GelsInfo au système: */
 InitGels( &tete, &queue, &ginfo );

 /* Transmet au Rastport un pointeur sur la structure GelsInfo: */
 my_window->RPort->GelsInfo = &ginfo;

13.3.6 Initialiser la structure VSprite

La structure VSprite doit être initialisée. Vous devez positionner le VSprite, définir ses hauteur, largeur et profondeur. La largeur est limitée pour le moment à deux mots (16 pixels) et la profondeur est au maximum de deux (quatre couleurs). Vous devez aussi indiquer dans la structure que vous voulez un VSprite. Vous le faites en affectant "VSPRITE" au champ Flags. Enfin, vous devez attribuer à la structure des pointeurs sur la table de couleurs et les données graphiques.

Exemple :

vsprite.X = x;              /* Donne les positions en X et Y. */
vsprite.Y = y;
vsprite.Height = 16;        /* Fixe la hauteur à 16 lignes.   */
vsprite.Width = 2;          /* Fixe la largeur à 2 mots.      */
vsprite.Depth = 2;          /* Fixe la profondeur à 2 plans.  */
vsprite.Flags = VSPRITE;    /* Nous voulons un VSprite.       */
vsprite.SprColors = table_couleurs;  /* Pointeur sur la table de couleurs */
vsprite.ImageData = donnees_vsprite; /* Pointeur sur les données graphiques */

13.3.7 Ajouter le VSprite a la liste des VSprites

Quand toutes les structures sont initialisées nous ajoutons le nouveau VSprite à la liste. Cette opération est obtenue en appelant la fonction AddVSprite() avec pour paramètres un pointeur sur notre structure VSprite et un pointeur sur le RastPort.
  • Synopsis : AddVSprite( vsprite, rp );
  • vsprite : (struct VSprite *). Pointeur sur une structure VSprite initialisée.
  • rp : (struct RastPort *). Pointeur sur le RastPort.
Exemple :

  AddVSprite( &vsprite, my_window->RPort );

13.3.8 Préparer le système GEL

La dernière chose à faire pour voir le nouveau VSprite est de classer et dessiner la liste GEL, modifier la liste Copper et enfin redessiner l'affichage. Tout ceci est réalisé à l'aide de quatre fonctions : SortGList(), DrawGList(), MrgCop() et LoadView().

Si votre programme tourne sous Intuition, vous devrez utiliser les fonctions MakeScreen() et RethinkDisplay() au lieu de MrgCop() et LoadView().

SortGList() réorganise la liste de VSprite afin que les sprites affichés les plus bas à l'écran soient placés les plus loin dans la liste.
  • Synopsis : SortGList( rp );
  • rp : (struct RastPort *). Pointeur sur le RastPort.
DrawGList() affiche les VSprites sur le RastPort spécifié.
  • Synopsis : DrawGList( rp, vp );
  • rp : (struct RastPort *). Pointeur sur le RastPort.
  • vp : (struct ViewPort *). Pointeur sur le ViewPort.
MrgCop() réorganise la liste Copper. C'est grâce au Copper que chaque VSprite peut avoir ses propres couleurs.
  • Synopsis : MrgCop( view );
  • view : (struct View *). Pointeur sur la structure View dont la liste Copper doit être modifiée.
LoadView() va générer et montrer le nouvel affichage.
  • Synopsis : LoadView( view );
  • view : (struct View *). Pointeur sur la structure View qui doit être utilisée pour montrer l'affichage.
MakeScreen()
  • Synopsis : MakeScreen( screen );
  • screen : (struct Screen *). Pointeur sur l'écran (screen) qui doit être affecté.
RethinkDisplay() va réorganiser l'affichage complet. Remarquez que cette fonction va prendre assez longtemps pour s'exécuter, aussi utilisez-la uniquement en cas de nécessité absolue.
  • Synopsis : RethinkDisplay();
Exemple 1 (vous avez créé votre propre affichage)

  SortGList( my_rastport );
  DrawGList( my_rastport, my_viewport );
  MrgCop( my_view );
  LoadView( my_view );

Exemple 2 (votre programme tourne sous Intuition)

  SortGList( my_window->RPort );
  DrawGList( my_window->RPort, &(my_screen->ViewPort) );
  MakeScreen( my_screen );
  RethinkDisplay();

13.3.9 Modifier le VSprite

Une fois que vous avez votre VSprite, vous pouvez commencer à jouer avec. Vous pouvez alors :
  1. Le déplacer en modifiant les champs X et Y de la structure VSprite.
  2. Changer l'image du VSprite en donnant à la structure VSprite un nouveau pointeur sur d'autres données (graphiques) de sprite.
  3. Changer les couleurs du VSprite en donnant à la structure VSprite un nouveau pointeur sur une autre table de couleurs.
Cependant, quoi que vous fassiez avec le VSprite, vous devez toujours appeler les fonctions suivantes afin de voir les modifications :
  • SortGList();
  • DrawGList();
  • MrgCop();
  • LoadView();
ou :
  • SortGList();
  • DrawGList();
  • MakeScreen();
  • RethinkDisplay();
13.3.10 Supprimer des VSprites

Quand vous voulez supprimer un VSprite de la liste, vous devez appeler la fonction RemVSprite().
  • Synopsis : RemVSprite( vsprite );
  • vsprite : (struct VSprite *). Pointeur sur le VSprite que vous voulez supprimer.
Exemple :

  RemVSprite( &vsprite );

13.4 Un exemple complet

Voici un exemple complet d'utilisation de VSprites :

/* Exemple 1                            */
/* Cet exemple montre comment obtenir et utiliser un VSprite. Le  */
/* VSprite peut être déplacé par l'utilisateur grâce aux flèches. */

/* Comme nous utilisons Intuition, nous incluons ce fichier : */
#include <intuition/intuition.h>

/* Nous incluons ce fichier puisque nous utilisons les sprites : */
#include <graphics/gels.h>

/* Déclare les fonctions que nous allons utiliser : */
void main();
void nettoie();

struct IntuitionBase *IntuitionBase = NULL;
/* Nous devons ouvrir la bibliothèque Graphics puisque nous utilisons les sprites : */
struct GfxBase *GfxBase = NULL;

/* Déclare un pointeur sur une structure Screen : */ 
struct Screen *mon_ecran;

/* Déclare et initialise notre structure NewScreen : */
struct NewScreen mon_nouvel_ecran=
{
 0,             /* LeftEdge 	Doit toujours être égal à 0. */
 0,             /* TopEdge  	Sommet de l'écran.*/
 640,           /* Width   	Nous utilisons un écran haute résolution. */
 200,           /* Height  	Affichage NTSC (américain) non entrelacé. */
 2,             /* Depth   	4 couleurs. */
 0,             /* DetailPen 	Le texte sera affiché avec la couleur du registre 0. */
 1,             /* BlockPen 	Les blocs seront affichés avec la couleur du registre 1. */
 HIRES|SPRITES, /* ViewModes    Haute résolution, les sprites vont servir. */
 CUSTOMSCREEN,  /* Type         Votre écran personnalisé. */
 NULL,          /* Font   	Police de caractères par défaut. */
 "VSprites!",   /* Title        Nom de l'écran. */
 NULL,          /* Gadget  	Doit pour le moment être à 0. */
 NULL           /* BitMap  	Pas de Custom BitMap. */
};


/* Déclare un pointeur sur une structure Window : */ 
struct Window *ma_fenetre = NULL;

/* Déclare et initialise notre structure NewWindow : */
struct NewWindow ma_nouvelle_fenetre=
{
 0,             /* LeftEdge    Position en X de la fenêtre. */
 0,             /* TopEdge     Position en Y de la fenêtre. */
 640,           /* Width       Largeur 640 pixels. */
 200,           /* Height      Hauteur 200 lignes. */
 0,             /* DetailPen   Le texte sera affiché avec la couleur du registre 0. */
 1,             /* BlockPen    Les blocs seront affichés avec la couleur du registre 1. */
 CLOSEWINDOW|   /* IDCMPFlags  La fenêtre nous enverra un message si */
 RAWKEY,        /*             l'utilisateur a sélectionné le gadget de */
                /*             fermeture ou s'il a pressé une touche. */
 SMART_REFRESH| /* Flags       Intuition doit rafraîchir la fenêtre. */
 WINDOWCLOSE|   /*             Gadget de fermeture. */
 WINDOWDRAG|    /*             Gadget de déplacement. */
 WINDOWDEPTH|   /*             Gadgets de profondeur. */
 WINDOWSIZING|  /*             Gadget de taille. */
 ACTIVATE,      /*             La fenêtre doit être activée à son ouverture. */
 NULL,          /* FirstGadget Pas de gadget spécial (custom). */
 NULL,          /* CheckMark   Utilise le CheckMark d'Intuition. */
 "Utilisez les flèches pour déplacer le VSprite!", /* Titre */
 NULL,          /* Screen      Sera reliée plus tard à un écran personnalisé (custom screen). */
 NULL,          /* BitMap      Pas de Custom BitMap. */
 80,            /* MinWidth    Nous n'autoriserons pas que la fenêtre */
 30,            /* MinHeight   devienne plus petite que 80x30, ni */
 640,           /* MaxWidth    plus grande que 640x200. */
 200,           /* MaxHeight */
 CUSTOMSCREEN   /* Type        Relié à l'écran du Workbench. */
};


/* 1. Déclare et initialise des données */
/*  de sprite pour chaque VSprite:  */
UWORD chip donnees_vsprite[]=
{
 0x0180, 0x0000,
 0x03C0, 0x0000,
 0x07E0, 0x0000,
 0x0FF0, 0x0000,
 0x1FF8, 0x0000,
 0x3FFC, 0x0000,
 0x7FFE, 0x0000,
 0x0000, 0xFFFF,
 0x0000, 0xFFFF,
 0x7FFE, 0x7FFE,
 0x3FFC, 0x3FFC,
 0x1FF8, 0x1FF8,
 0x0FF0, 0x0FF0,
 0x07E0, 0x07E0,
 0x03C0, 0x03C0,
 0x0180, 0x0180,
};


/* 2. Déclare trois structures VSprite. Une servira, les deux autres sont factices: */
struct VSprite tete, queue, vsprite;


/* 3. Décide des couleurs du VSprite : */
/*             RGB   RGB   RGB */
WORD table_couleur[] = { 0x000F, 0x00F0, 0x0F00 };


/* 4. Déclare une structure GelsInfo : */
struct GelsInfo ginfo;


/* Cette variable booléenne nous indiquera si le VSprite fait partie de la liste ou non: */
BOOL vsprite_on = FALSE;


/* Ce programme n'ouvrira pas de fenêtre console si exécuté à partir du Workbench, mais nous n'écrirons */
/* donc rien. Des fonctions comme printf() ne devront donc pas être utilisées. */
void _main()
{
 /* La structure GelsInfo a besoin des tableaux suivants: */
 WORD prochaine_ligne[ 8 ];
 WORD *dernieres_couleurs[ 8 ];

 /* Position du sprite: */
 WORD x = 40;
 WORD y = 40;

 /* Direction de déplacement du sprite : */
 WORD x_direction = 0;
 WORD y_direction = 0;

 /* Variable booléenne utilisée pour la boucle while: */
 BOOL ferme_moi = FALSE;

 ULONG class; /* IDCMP */
 USHORT code; /* Code */

 /* Déclare un pointeur sur une structure IntuiMessage : */
 struct IntuiMessage *mon_message;


 /* Ouvre la bibliothèque Intuition : */
 IntuitionBase = (struct IntuitionBase *)
  OpenLibrary( "intuition.library", 0 );
 
 if( IntuitionBase == NULL )
  nettoie(); /* N'a pas pu ouvrir la bibliothèque Intuition ! */


 /* 5. Ouvre la bibliothèque Graphics :          */
 /* Puisque nous utilisons des sprites nous avons besoin d'ouvrir la bibliothèque Graphics : */
 GfxBase = (struct GfxBase *)
  OpenLibrary( "graphics.library", 0);

 if( GfxBase == NULL )
  nettoie(); /* N'a pas pu ouvrir la bibliothèque Graphics ! */


 /* Nous allons maintenant essayer d'ouvrir l'écran : */
 mon_ecran = (struct Screen *) OpenScreen( &mon_nouvel_ecran );

 /* Avons-nous ouvert l'écran avec succès ? */
 if(mon_ecran == NULL)
  nettoie();

 ma_nouvelle_fenetre.Screen = mon_ecran;

 /* Nous allons maintenant essayer d'ouvrir la fenêtre : */
 ma_fenetre = (struct Window *) OpenWindow( &ma_nouvelle_fenetre );
 
 /* Avons-nous ouvert la fenêtre avec succès ? */
 if(ma_fenetre == NULL)
  nettoie(); /* N'a pas pu ouvrir la fenêtre ! */


 /* 6. Initialise la structure GelsInfo : */

 /* Tous les sprites exceptés les deux premiers peuvent */
 /* servir à afficher les VSprites : ( 11111100 = 0xFC ). */
 ginfo.sprRsrvd = 0xFC;
 /* Si nous n'excluions pas les deux premiers sprites, les    */
 /* couleurs du pointeur de la souris pourraient être affectées. */


 /* Alloue de la mémoire à la structure GelsInfo : */
 ginfo.nextLine = prochaine_ligne;
 ginfo.lastColor = dernieres_couleurs;


 /* Donne au RastPort un pointeur sur la structure GelsInfo : */
 ma_fenetre->RPort->GelsInfo = &ginfo;


 /* Transmet la structure GelsInfo au système : */
 InitGels( &tete, &queue, &ginfo );


 /* 7. Initialise la structure VSprite : */

 vsprite.Flags = VSPRITE;   /* C'est un VSprite. */
 vsprite.X = x;             /* Position en X. */
 vsprite.Y = y;             /* Position en Y. */
 vsprite.Height = 16;       /* 16 lignes de haut. */
 vsprite.Width = 2;         /* Deux octets (16 pixels) de large. */
 vsprite.Depth = 2;         /* Deux bitplanes, 4 couleurs. */


 /* Pointeur sur les données du sprite : */
 vsprite.ImageData = donnees_vsprite;

 /* Pointeur sur la table de couleurs : */
 vsprite.SprColors = table_couleur;


 /* 8. Ajoute le VSprite à la liste des VSprites : */
 AddVSprite( &vsprite, ma_fenetre->RPort );

 /* Le VSprite est dans la liste. */
 vsprite_on = TRUE;


 /* Reste dans la boucle while jusqu'à ce que l'utilisateur */
 /* ait sélectionné le gadget de fermeture de la fenêtre :  */
 while( ferme_moi == FALSE )
 {
  /* Reste dans la boucle while aussi longtemps que nous */
  /* pouvons recevoir des messages avec succès :     */
  while(mon_message = (struct IntuiMessage *) GetMsg(ma_fenetre->UserPort))
  {
   /* Après que nous ayons reçu le message nous pouvons le lire et  sauver toute */
   /* valeur importante que nous pourrions vouloir vérifier plus tard : */
   class = mon_message->Class;
   code = mon_message->Code;

   /* Après que nous l'ayons lu nous répondons le plus vite possible : */
   /* RAPPEL ! N'essayez jamais de lire un message après que vous ayez */
   /* répondu ! Un autre processus pourrait l'avoir modifié. */
   ReplyMsg( mon_message );

   /* Teste quel indicateur IDCMP était envoyé : */
   switch( class )
   {
    case CLOSEWINDOW:   /* Quitte! */
        ferme_moi=TRUE;
        break; 

    case RAWKEY:     /* Une touche a été pressée ! */
        /* Teste quelle touche a été pressée : */
        switch( code )
        {
         /* Flèche vers le haut : */
         case 0x4C:   y_direction = -1; break; /* Pressée */
         case 0x4C+0x80: y_direction = 0; break; /* Relachée */

         /* Flèche vers le bas : */
         case 0x4D:   y_direction = 1; break; /* Pressée */
         case 0x4D+0x80: y_direction = 0; break; /* Relachée */

         /* Flèche vers la droite : */
         case 0x4E:   x_direction = 2; break; /* Pressée */
         case 0x4E+0x80: x_direction = 0; break; /* Relachée */

         /* Flèche vers la gauche : */
         case 0x4F:   x_direction = -2; break; /* Pressée */
         case 0x4F+0x80: x_direction = 0; break; /* Relachée */
        }
        break; 
   }
  }


  /* 12. Joue avec le VSprite : */

  /* Change les positions x/y : */
  x += x_direction;
  y += y_direction;

  /* Teste si le sprite ne sort pas de l'écran : */
  if(x > 320)
   x = 320;
  if(x < 0)
   x = 0;
  if(y > 200)
   y = 200;
  if(y < 0)
   y = 0;

  vsprite.X = x;
  vsprite.Y = y;


  /* 9. Classe la liste GEL : */
  SortGList( ma_fenetre->RPort );

  /* 10. Dessine la liste GEL : */
  DrawGList( ma_fenetre->RPort, &(mon_ecran->ViewPort) );

  /* 11. Met en marche le Copper et redessine l'affichage : */
  MakeScreen( mon_ecran );
  RethinkDisplay();
 }


 /* Libère toute la mémoire réservée : (ferme la fenêtre, */
 /* l'écran, les bibliothèques...)            */
 nettoie();

 /* FIN */
}


/* Cette fonction libère toute la mémoire réservée. */
void nettoie()
{
 /* 13. Supprime les VSprites : */
 if( vsprite_on )
  RemVSprite( &vsprite );

 if( ma_fenetre )
  CloseWindow( ma_fenetre );

 if(mon_ecran )
  CloseScreen( mon_ecran );

 if( GfxBase )
  CloseLibrary( GfxBase );

 if( IntuitionBase )
  CloseLibrary( IntuitionBase );

 exit();
}

Note : dans l'exemple ci-dessus, l'utilisation de la fonction principale "_main()" au lieu de "main()" est une astuce qui permet de bloquer l'ouverture d'une fenêtre "output" lorsque le programme est lancé depuis le Workbench. Cette astuce qui utilise du code C non standard fonctionne avec quelques compilateurs (Lattice SAS/C), mais provoquera une erreur à la compilation avec vbcc ou GCC : dans ce cas, remplacer "_main()" par "main()". Pour en savoir plus, Cf la rubrique 14.3 et 14.4 ici : obligement.free.fr/articles/amigacmanual_14_trucsetastuces.php.

13.5 Fonctions

InitGels()

Cette fonction transmet une structure GelsInfo déjà préparée au système.
  • Synopsis : InitGels( tête, queue, ginfo );
  • tête : (struct VSprite *). Pointeur sur la première structure VSprite factice.
  • tail : (struct VSprite *). Pointeur sur la deuxième structure VSprite factice.
  • ginfo : (struct GelsInfo *). Pointeur sur une structure GelsInfo initialisée.
AddVSprite()

Cette fonction ajoute un VSprite à la liste de VSprites.
  • Synopsis : AddVSprite( vsprite, rp );
  • vsprite : (struct VSprite *). Pointeur sur une structure VSprite initialisée.
  • rp : (struct RastPort *). Pointeur sur le RastPort.
SortGList()

Cette fonction réorganise la liste des VSprites afin que les sprites affichés les plus bas à l'écran soient placés les plus loin dans la liste.
  • Synopsis : SortGList( rp );
  • rp : (struct RastPort *). Pointeur sur le RastPort.
DrawGList()

Cette fonction affiche les VSprites sur le RastPort spécifié.
  • Synopsis : DrawGList( rp, vp );
  • rp : (struct RastPort *). Pointeur sur le RastPort.
  • vp : (struct ViewPort *) Pointeur sur le ViewPort.
MrgCop()

Cette fonction réorganise la liste Copper. C'est grâce au Copper que chaque VSprite peut avoir ses propres couleurs.
  • Synopsis : MrgCop( view );
  • view : (struct View *). Pointeur sur la structure View dont la liste Copper doit être modifiée.
LoadView()

Cette fonction va générer et montrer le nouvel affichage.
  • Synopsis : LoadView( view );
  • view : (struct View *). Pointeur sur la structure View qui doit être utilisée pour montrer l'affichage.
MakeScreen()

Cette fonction va recalculer l'affichage de l'écran.
  • Synopsis : MakeScreen( screen );
  • screen : (struct Screen *). Pointeur sur l'écran (screen) qui doit être affecté.
RethinkDisplay()

Cette fonction va réorganiser l'affichage complet. Remarquez que cette fonction va prendre assez longtemps pour s'exécuter, aussi utilisez-la uniquement en cas de nécessité absolue.
  • Synopsis : RethinkDisplay();
13.6 Exemples

Voici des exemples (dans le répertoire "Amiga_C_Manual/13.VSprites") de VSprites.

Exemple 1

Cet exemple montre comme obtenir et utiliser un VSprite. Le VSprite peut être déplacé par l'utilisateur à l'aide des touches fléchées.

Exemple 2

Cet exemple montre comment utiliser plusieurs VSprites, chacun ayant sa propre table de couleurs.

Exemple 3

Ce programme montre comment animer plusieurs (!) VSprites.


[Retour en haut] / [Retour aux articles] [Chapitre précédent : Les routines graphiques de bas niveau] / [Chapitre suivant : Trucs et astuces]