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 : GFA Basic - Image Intuition
(Article écrit par Denis Obriot et extrait d'Amiga News Tech - janvier 1990)
|
|
Après avoir vu comment définir un gadget et comment l'utiliser, nous allons définir une image Intuition.
Mais au préalable, nous devons apprendre à faire le ménage dans la mémoire de l'Amiga. En effet, le
GFA Basic ne libère pas la mémoire réservée par la fonction MALLOC, ce qui peut causer quelques surprises
en cas d'utilisation répétée du programme test du mois dernier.
II faut donc libérer cette mémoire avant de quitter le programme, ce qui s'effectue par
la fonction MFREE (voir page 46 du manuel GFA). Pour nos gadgets, cela donne :
...où "gadget%" représente l'adresse de la structure Gadget et "44" est le nombre d'octets
occupés par cette structure. Rajoutez donc les lignes nécessaires dans le programme du mois
dernier. Il ne faut pas oublier non plus d'enlever le gadget de la liste des gadgets de
la fenêtre, grâce à la fonction :
RemoveGadget (fenêtre%,gadget%)
|
...où "fenêtre%" est l'adresse de la fenêtre du gadget et "gadget%", l'adresse de la structure Gadget.
L'image a la parole
Une image Intuition est un élément graphique qui peut être attaché à un ou plusieurs autres
objets d'Intuition, comme les fenêtres ou, dans le cas qui nous intéresse, les gadgets.
La mise en place d'une image s'effectue en deux parties : on définit dans un premier temps
les différents paramètres de l'image et dans un deuxième temps, ses données graphiques.
Voyons d'abord la première partie, qui est bien sûr une structure C.
STRUCT Image
{ SHORT LeftEdge; /* Coordonnées du point supérieur */
SHORT TopEdge; /* gauche de l'image en pixels */
SHORT Width; /* Largeur en pixels */
SHORT Heigth; /* Hauteur en pixels */
SHORT Depth; /* Nombre de plans de bits */
USHORT *ImageData; /* Pointeur sur les données graphiques */
UBYTE PlanePick; /* Masque des plans de bits utilisés par l'image */
UBYTE Plane0nOff; /* Masque des plans de bits forcés à 1 */
STRUCT Image *NextImage /* Pointeur sur l'image suivante */
}
|
La procédure "initimage" commence par la réservation de 20 octets dans la mémoire
publique. Ces données peuvent se trouver aussi bien dans la mémoire Fast
que dans la mémoire Chip - ce qui n'est pas le cas pour les données graphiques,
comme nous le verrons un peu plus loin. Ensuite, il faut remplir la structure avec
les différents paramètres.
- x&, l& et h& n'appellent pas de commentaires particuliers.
- prof& indique le nombre de plans de bits de l'image. Par exemple, une image en
deux couleurs nécessite un plan de bits, tandis qu'une image en huit couleurs en nécessite
trois (20=8).
- ImageData% désigne l'adresse des données graphiques.
- PlanePick% permet d'indiquer quels seront les plans utilisés pour tracer
l'image. Exemple : pour une image de profondeur 1 dans un écran à 16 couleurs (profondeur 4),
en mettant à 1 le bit n, l'image sera placée dans le plan de bits n :
PlanePick& = &x0010 - l'image en couleur 2 (plan de bits 1)
PlanePick& = &x1000 - l'image en couleur 8 (plan de bits 3)
- PlaneOnOff& permet de forcer à 1 tous les points d'un plan de bits. Dans
l'exemple précédent, avec PlanePick& = &x0010 et PlaneOnOff& = &x1000, les
points allumés seront de la couleur 2+8 soit 10 et les points éteints seront de
la couleur 8. Dans le cas d'une image de profondeur supérieure à 1, le principe
est identique mais PlanePick& doit avoir autant de bits mis que la profondeur de
l'image et PlaneOnOff& ne doit pas avoir plus de (profondeur de l'écran - profondeur
de l'image) bits mis. Et bien sûr, les bits ne doivent pas être communs, sinon on
obtient des effets imprévus. Exemple : pour une profondeur d'image de 2 et une profondeur
d'écran de 4, on peut déclarer PlanePick& = &x1001 et PlaneOnOff& = &x0110.
- Finalement, nous plaçons dans NextImage% l'adresse de la prochaine image
à dessiner ou zéro s'il n'y en a pas d'autre, ce qui permet de chaîner plusieurs
images entre elles.
Voyons maintenant l'organisation mémoire des données graphiques. Pour une fois, nous
n'avons pas à faire à une structure C, mais à un tableau de WORDs (mots de 16 bits dont
le signe est sans importance), celui-ci étant obligatoirement situé en mémoire Chip
afin d'être accessible aux coprocesseurs. Les points sont rangés ligne par ligne et
plan de bits par plan de bits, alignés sur seize bits. Prenons pour exemple un petit damier
avec quatre couleurs :
Image de profondeur 2, largeur 2 et hauteur 2.
Chaque carré représente un pixel, les chiffres à l'intérieur indiquant sa couleur.
Une ligne doit obligatoirement être un nombre entier de WORDs. Notre image occupera
donc deux WORDs pour un plan de bits (un par ligne) ; la profondeur étant de 2, elle nécessite
deux plans de bits, ce qui fait un total de quatre WORDs.
La couleur de chaque pixel est obtenue par la formule suivante :
couleur = (20*point plan 0) + (21*point plan 1) + ... + (2 profondeur * point plan profondeur)
|
...où "point plan n" vaut soit 0, soit 1.
Pour le point de couleur 1, il faut mettre à 1 le bit dans le plan 1 et à 0
dans le plan 2. Ce qui donne pour notre exemple :
&x0000000000000010, &x0000000000000010
&x0000000000000010, &0000000000000010
|
Afin de permettre au dessin relativement aisé de notre image, nous allons la stocker
sous forme de DATAs en utilisant les nombres binaires et en incorporant à notre routine
une boucle de lecture. Dans notre exemple, les data seront donc :
DATA &b0000000000000010 ! ligne 1 plan-bit 1
DATA &b0000000000000010 ! ligne 2 plan-bit 1
DATA &b0000000000000001 ! ligne 1 plan-bit 2
DATA &b0000000000000010 ! ligne 2 plan-bit 2
|
Si tout ne vous semble pas encore très clair, analyser la définition des images dans le listing 1.
Il ne reste plus qu'à donner l'ordre à Intuition de tracer l'image pour nous, ce qui est
effectué par la fonction :
DrawImage(RasPort%,Image%,LeftOffset&,TopOffset&)
|
Le RasPort est une structure C dont l'étude n'entre pas dans le cadre de cet article.
Notons quand même qu'il existe pour une fenêtre, un écran ou une boîte de dialogue, et
que son adresse est trouvée par :
rasport% = WINDOW(Numéro Fenêtre) + 50 pour une fenêtre
rasport% = SCREEN(Numéro Écran) + 84 pour un écran
|
Le programme 1 montre la définition de deux images Intuition chaînée toutes deux et
utilisant les mêmes données graphiques, et d'une image sans données graphiques, qui est
en fait un rectangle coloré, grâce à une utilisation astucieuse de PlaneOnOff.
Programme 1
Voyons maintenant comment utiliser nos images dans les gadgets. C'est ce qui montre le
listing 2. Il reprend le programme de démo du mois dernier, et ajoute des images à nos gadgets.
Nous avons vu la dernière fois les zones "image%" et "imageselect%". C'est à cet endroit
que nous plaçons les adresses des structures Image correspondant au gadget au repos et
au gadget sélectionné. Une petite précision : "Flags" prend ici la valeur 6, soit
&X010101 (le bit 2 indique que les champs "GadgetRender" et "SelectRender"
pointent sur des structures Image ; si ce bit 4 est mis à 0, ils pointent sur des structures
Border - que nous verrons une prochaine fois).
Enfin, la fonction Intuition RemoveGlist que nous utilisons ici pour enlever les gadgets,
permet d'enlever une liste de gadgets en une seule instruction, en précisant le premier
ainsi que le nombre de gadgets à retirer.
Programme 2
Notre prochain rendez-vous sera consacré à l'étude de deux nouveaux types de gadgets :
les gadgets de chaîne et les gadgets proportionnels. En attendant, je vous souhaite à tous
une bonne et chouette Amigannée.
|