Suivez-nous sur X

|
|
|
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
|
|
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
|
|
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
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
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 :
- 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.
- 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.
- 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 :
- Utilisez aussi peu de VSprites que possible sur la même ligne.
- Essayez d'utiliser des VSprites ayant des couleurs identiques.
- 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 :
- Déclarer et initialiser des données de sprite pour chaque VSprite.
- Déclarer une structure VSprite pour chaque VSprite plus deux structures
supplémentaires pour deux VSprites factices.
- Décider des couleurs des VSprites.
- Déclarer une structure GelsInfo.
- Ouvrir la bibliothèque Graphics.
- Initialiser la structure GelsInfo.
- Initialiser la structure VSprite.
- Ajouter les VSprites à la liste des VSprites.
- Classer la liste GEL: SortGList().
- Dessiner la liste GEL: DrawGList().
- Mettre en marche le Copper et redessiner l'affichage.
[ MrgCop() et LoadView() ] ou [ MakeScreen() et RethinkDisplay() ]
- Utiliser les VSprites.
- 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 :
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 :
- Le déplacer en modifiant les champs X et Y de la structure VSprite.
- Changer l'image du VSprite en donnant à la structure VSprite un nouveau
pointeur sur d'autres données (graphiques) de sprite.
- 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 :
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.
|