Résumé des fonctions, structures, constantes et
variables Allegro utilisées par les programmes vus en cours
Systématiques pour les programmes allegro
#include
<allegro.h>
Inclusion du fichier en-tête de
la librairie qui contient les diverses déclarations.
En fait contient des listes de #include sur d'autres fichiers .h
d'allegro
Les curieux peuvent consulter le dossier include dans le dossier
CodeBlocks/MinGW
int
allegro_init();
Lance les services de la librairie mais
n'ouvre pas de mode graphique.
Impératif au début du main (juste après les
déclarations des variables)
END_OF_MAIN();
Truc technique qui permet de compiler
le même source sur windows/linux/OSX
Doit impérativement être
présent juste après l'accolade fermante du main
Initialisation graphique
int
desktop_color_depth();
void
set_color_depth(int depth);
desktop_color_depth retourne la
"profondeur couleur" effective de l'affichage système
"profondeur couleur" = nombre de bits utilisés pour stocker un
pixel (8 / 15 / 16 / 24 / 32)
Sur les systèmes récents le résultat est souvent
de 32 bits (4 octets pour chaque pixel)
Pour garantir un fonctionnement optimal sur la machine, on indiquera
à allegro cette profondeur :
set_color_depth(desktop_color_depth());
juste avant l'ouverture du mode graphique
int
set_gfx_mode(int card, int w, int h, int v_w, int v_h);
GFX_AUTODETECT_WINDOWED
GFX_AUTODETECT_FULLSCREEN
Ouvre un affichage en mode graphique en
précisant le type card
- soit sur une fenêtre en utilisant
GFX_AUTODETECT_WINDOWED
- soit en plein écran en utilisant
GFX_AUTODETECT_FULLSCREEN
w et h indiquent la largeur et la hauteur souhaitées (640x480
800x600 1024x768 ...)
Nous n'utiliserons pas v_w et v_h : mettre à 0 pour ignorer
Retourne une valeur non nulle en cas de problème (à
tester...)
Divers, messages, problèmes
Affichage ecran
screen : extern BITMAP *screen;
C'est l'identifiant de l'écran
réel :
A utiliser à chaque fois qu'on veut dessiner ou écrire
sur la sortie graphique
Convient pour toutes les fonctions prenant un BITMAP * en
paramètre :
directement utiliser screen comme 1er paramètre des fonctions de
dessin
SCREEN_W
SCREEN_H
Largeur (Width) et Hauteur (Height) de
la sortie graphique.
Permet de retrouver les valeurs w et h utilisées lors du
set_gfx_mode
Ne peuvent être modifiés pour changer la taille de la
sortie graphique
(pour changer la taille il faut relancer le mode graphique)
void
clear_bitmap(BITMAP *bitmap);
Efface (en noir) l'image en
paramètre.
Exemple pour effacer l'écran :
clear_bitmap(screen);
void
clear_to_color(BITMAP *bitmap, int color);
Efface avec une couleur l'image en
paramètre.
Exemple pour effacer l'écran avec un fond blanc :
clear_to_color(screen,makecol(255,255,255));
Couleurs
Une couleur est
déterminée par trois composantes rouge/vert/bleu
"Couleur" ne veut pas forcément dire coloré :
0/0/0 -> Noir 128/128/128 ->
Gris 255/255/255 -> Blanc
Dans allegro une couleur est stockée dans un int.
C'est le type attendu au niveau d'un paramètre de dessin color
Pour passer de rouge/vert/bleu vers une couleur utiliser makecol
Pour passer d'une couleur vers rouge/vert/bleu utiliser getr, getg, getb
Pour poser un pixel de couleur (sur screen ou sur une BITMAP) utiliser
putpixel
Pour lire la couleur d'un pixel (sur screen ou sur une BITMAP) utiliser
getpixel
Couleur spéciale pour transparence : voir
Sprites
et bitmaps avec transparences
int
makecol(int r, int g, int b);
Pour fabriquer l'entier
représentant une couleur à partir de Red/Green/Blue
Chaque composante est donnée entre 0 (minimum) et 255 (maximum)
Exemple pour fabriquer du rose on met rouge à 100% et vert et
bleu à 50%
int couleur;
...
couleur=makecol(255,127,127);
rectfill(screen,0,0,800,100,couleur);
Ou directement (sans passer par une variable)
rectfill(screen,0,0,800,100,makecol(255,127,127));
Permet d'accéder aux 3
composantes rouge vert et bleu d'une couleur.
Chaque composante est entre 0 (minimum) et 255 (maximum)
Exemple pour récupérer les composantes couleur du pixel
en x y sur l'écran :
int couleur,rouge,vert,bleu;
...
c = getpixel(screen,x,y);
rouge=getr(c); vert=getg(c);
bleu=getb(c);
Poser ou lire un seul pixel d'une
BITMAP ou de l'écran
voir ci-dessous dans "Affichage graphique"
Affichage graphique : dessiner
Drawing
primitives
Fonctions de dessin
géométrique et de changements de couleurs des images
Lien ci-dessus pour accéder à la liste de toutes les
primitives de dessin
En général le premier paramètre attend un BITMAP *
Pour dessiner à l'écran directement on met
screen à ce niveau
Rappel : l'origine (0,0) est en haut à gauche de la
fenêtre graphique
L'axe des x est orienté de gauche à droite
L'axe des y est orienté de haut
en bas
void
putpixel(BITMAP *bmp, int x, int y, int
color);
Poser un seul pixel de couleur sur une
BITMAP ou sur l'écran (screen) en x y
La couleur précédente du pixel est écrasée.
Avec la fonction putpixel on peut en principe dessiner toutes les
formes possibles
(puisque toute forme est composée d'ensembles de pixels de
couleurs particulières)
Exemple pour dessiner une fonction mathématique ( ici une
sinusoïde -> #include <math.h> )
for (x=0;x<800;x++)
putpixel( screen, x,
300-100.0*sin(0.01*x) , makecol(255,255,255) );
Si on veut remplir toute une zone rectangulaire on fera une double
boucle imbriquée
Exemple pour faire un dégradé à l'écran
avec rouge croissant horizontalement et vert verticalement
for (y=0;y<256;y++)
for (x=0;x<256;x++)
putpixel(screen,x,y,makecol(x,y,128));
int
getpixel(BITMAP *bmp, int x, int y);
Lire la couleur du pixel de la BITMAP
ou de l'écran (screen) en x y
La valeur récupérée est un int, équivalent
à une couleur obtenue avec un makecol
Exemple pour tester si le pixel à l'écran en x y est du
rouge pur :
if ( getpixel(screen,x,y) = = makecol(255,0,0) )
...
Souvent pour pouvoir traiter la couleur de manière
spécifique il faudra décomposer en rgb
Voir getr/getg/getb rubrique Couleurs ci dessus
void
line(BITMAP *bmp, int x1, int y1, int x2,
int y2, int color);
Trace un segment de droite de (x1,y1)
à (x2,y2)
void
rect(BITMAP *bmp, int x1, int y1, int x2,
int y2, int color);
void
rectfill(BITMAP *bmp, int x1, int y1, int
x2, int y2, int color);
Rectangle contour et Rectangle plein
(x1,y1) : coordonnées du coin supérieur gauche
(x2,y2) : coordonnées du coin inférieur droit
void
circle(BITMAP *bmp, int x, int y, int
radius, int color);
void
circlefill(BITMAP *bmp, int x, int y, int
radius, int color);
Cercle et Cercle plein (disque)
(x,y) : coordonnées du centre
radius : rayon
void
ellipse(BITMAP *bmp, int x, int y, int
rx, int ry, int color);
void
ellipsefill(BITMAP *bmp, int x, int y,
int rx, int ry, int color);
Ellipse et Ellipse pleine (disque vu de
coté)
Les axes de l'ellipse sont nécessairement orientés sur le
repère
( ne permet pas de dessiner une ellipse oblique à l'écran
)
(x,y) : coordonnées du centre
rx et ry : rayon horizontal et rayon vertical
Images mémoires - BITMAP - et copies de
zones - blit -
Une BITMAP est une structure qui
contient les données d'une image
A part "screen" qui est une BITMAP particulière (écran
réel, visible)
les BITMAPs correspondent à des images en mémoire
(invisibles)
Pour rendre visible l'image d'une BITMAP on utilisera la fonction blit
de la BITMAP contenant l'image vers la BITMAP screen :
blit(image,screen,...);
Le buffer "page" (pour un affichage double buffer) est une BITMAP
créée
à la taille de l'écran et qui sert à construire la
prochaine image d'une animation,
une fois cette image construite sur le buffer "page" on le blit
à l'écran (screen)
typedef
struct BITMAP ...
La structure qui contient les images
allegro (chargées depuis fichiers ou dessinées par
programme)
Les BITMAPs seront toujours
déclarées et utilisées comme pointeurs :
// Declaration d'une BITMAP "bmp"
BITMAP *bmp;
// Attention sur les déclarations multiples
de
mettre l'étoile à chaque fois
BITMAP *image1, *image2;
Comme on déclare un "pointeur sur quelque chose" on est dans le
cadre de
l'allocation dynamique.
Pour allouer une BITMAP on ne fera pas un malloc mais on utilisera des
fonctions allegro :
- create_bitmap (pour une image vierge, à dessiner)
- load_bitmap
(pour une image venant d'un fichier .bmp)
Pour accéder à la largeur et à la hauteur d'une
BITMAP (après création ou chargement)
bmp->w // largeur
(width)
bmp->h // hauteur (height)
BITMAP *create_bitmap(int width, int height);
Allouer et initialiser une BITMAP
"vide" de taille width(largeur) x height(hauteur) pour dessiner dessus.
En fait la mémoire de l'image est réservée mais
pas nettoyée : pour avoir une image vierge il faut effacer.
On peut réutiliser plusieurs fois la même BITMAP :
effacer/redessiner effacer/redessiner ...
Dans ce cas on ne refait pas create_bitmap à chaque fois !
Par contre si on a terminé d'utiliser une BITMAP et qu'on est
sûr de ne plus jamais l'utiliser
alors il faut la libérer (destroy_bitmap). Ceci est facultatif
si le programme se termine juste après.
Exemple : déclarer, créer, effacer une BITMAP, dessiner
des diagonales dessus et afficher à l'écran
BITMAP *bmp;
... (initialisation du mode graphique allegro...)
bmp=create_bitmap(200,100);
clear_bitmap(bmp);
...
line(bmp,0,0,199,99,makecol(255,255,255));
line(bmp,0,99,199,0,makecol(255,255,255));
blit(bmp,screen,0,0,SCREEN_W/2-100,SCREEN_H/2-50,200,100);
BITMAP *load_bitmap(const char *filename, RGB *pal);
Charge l'image d'un fichier .bmp (ou
.tga ou .pcx) dans une BITMAP créée sur mesure.
Retourne le pointeur sur la BITMAP en cas de succès, NULL en cas
d'échec (à tester)
Nous n'utilisons pas les palettes : on indiquera NULL dans le
paramètre pal.
Le fichier doit se trouver à la racine du projet (avec main.c
...)
pendant le développement avec codeblocks.
Plus tard (version "release") il faudra mettre les images au niveau du
.exe
On peut créer un sous répertoire pour regrouper toutes
les images,
dans ce cas le nom de fichier ressemblera à
"mes_images/mickey.bmp" ...
Une BITMAP créée avec load_bitmap a un contenu initial
qui correspond à l'image du fichier,
mais elle se comporte comme une BITMAP usuelle : on peut l'effacer,
dessiner dessus...
(dans ce cas bien sûr le contenu graphique initial est
altéré ou perdu)
Comme pour create_bitmap, quand on a terminé de l'utiliser il
faut la libérer (destroy_bitmap)
Il faut éviter de recharger
sans arrêt le même fichier image (load_bitmap dans la
boucle de jeu)
Si on veut afficher plusieurs
fois, on charge le fichier image une fois pour toute dans une BITMAP
(avant d'entrer dans la boucle de jeu, phase de chargement du jeu) puis
on blit cette BITMAP
chaque fois que c'est nécessaire.
Exemple pour charger "mon_image.bmp" et afficher au milieu de
l'écran (voir prog3_0 cours2) :
BITMAP *image;
... (initialisation du mode graphique allegro...)
image=load_bitmap("mon_image.bmp",NULL);
if (!image)
... (problème)
...
blit(image,screen,0,0, (SCREEN_W-image->w)/2,
(SCREEN_H-image->h)/2, image->w, image->h);
int
save_bitmap(const char *filename, BITMAP
*bmp, const RGB *pal);
Sauve l'image d'une BITMAP dans un
fichier .bmp (ou .tga ou .pcx)
Retourne un entier différent de 0 en cas d'échec
(à tester si nécessaire)
Nous n'utilisons pas les palettes : on indiquera NULL dans le
paramètre pal.
L'image se retrouve à la racine du projet (codeblocks) ou
à coté du .exe (release)
Exemple pour sauver "ma_bitmap.bmp" (voir prog2_0 cours2) :
BITMAP *img;
... (initialisation du mode graphique allegro...)
img=create_bitmap(400,200);
... effacer, dessiner dans img
save_bitmap("ma_bitmap.bmp",img,NULL);
void
blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int
dest_x, int dest_y, int width, int height);
Copie une zone rectangulaire de la
BITMAP source vers la BITMAP
destination.
La source est inchangée, la zone destination est
écrasée, tout contenu préalable est perdu.
Source et/ou dest sont des pointeurs sur BITMAP ( images
créées ou chargées, ou screen )
Il est fréquent de vouloir afficher la totalité d'une
BITMAP image en x y sur une BITMAP plus grande :
blit(image, grande, 0, 0, x, y, image->w,
image->h);
Dans ce cas la BITMAP "grande" peut être l'écran (screen)
ou le buffer (page)
Noter que les coordonnées se réfèrent toujours au
coin supérieur gauche des rectangles concernés.
Enfin dans la technique du double buffer, pour afficher le buffer
"page" à l'écran :
BITMAP *page;
...
page=create_bitmap(SCREEN_W, SCREEN_H);
...
... dans la boucle de jeu :
effacer, dessiner sur le buffer puis actualiser l'écran
réel :
blit(page, screen, 0, 0, 0,
0, SCREEN_W, SCREEN_H);
Copie une zone rectangulaire de la
BITMAP source vers la BITMAP
destination en étirant
ou en comprimant l'image dans le rectangle source de telle sorte qu'il
rentre dans la taille de destination.
Cette fonction peut permettre d'utiliser par exemple une image de fond
qui n'a pas la bonne taille
pour remplir l'écran, mais attention si le rapport
largeur/hauteur est différent l'aspect sera anamorphosé
D'autre part cette fonction est plus lente qu'un simple blit et le
résultat est de moins bonne qualité
que si on utilise une image à la bonne taille
(préalablement recadrée ou
ré-échantillonnée avec paint...)
Exemple pour afficher un fond de taille arbitraire en plein
écran (sur le buffer) :
stretch_blit(decor, page, 0, 0, decor->w,
decor->h, 0, 0, SCREEN_W, SCREEN_H);
Sprites et bitmaps avec transparences,
fonctions draw_sprite et masked_blit
Blitting
and sprites
Lors de l'affichage avec une fonction de type draw_sprite (toutes les
fonctions avec sprite dans leur nom)
ou avec masked_blit, les pixels qui ont exactement la couleur
spéciale magenta ne sont pas dessinés.
A ces emplacements sur la bitmap destination (le plus souvent il s'agit
du buffer) les pixels ne sont pas modifiés.
L'effet obtenu est donc une "transparence" : les zones marquées
avec la couleur spéciale restent invisibles,
le fond ou tout ce qui a été affiché
avant
sur la page (dans la
chronologie de la boucle de jeu) n'est pas écrasé.
On appellera généralement "sprite" ces images
d'éléments graphiques posés sur un fond magenta.
La transparence n'est pas obligatoirement autour du graphisme, on peut
aussi faire des "fenêtres".

image sur fond blanc (ou
autre)
image sur fond transparent

résultats après avoir fait un draw_sprite sur un fond
déjà en place
Techniquement la couleur reconnue comme transparente est
rouge 255 vert 0 bleu 255.
Avec votre logiciel d'édition d'image il faut bien s'assurer
d'obtenir exactement cette couleur.
Le problème se pose rarement mais si vous souhaitez avoir un
sprite avec du magenta qui ne soit pas
invisible il suffit d'utiliser un couleur proche mais non identique :
rouge 254 vert 0 bleu 254.
Vous pouvez aussi dessiner avec la couleur transparente à
l'intérieur du programme directement sur une bitmap,
ce qui permet par exemple de faire des "trous" sur un sprite : utilisez
une primitive graphique et makecol(255,0,255)
Voir la documentation
Blitting
and sprites pour une liste complète des options d'affichage
des sprites (échelles, rotations...)
void
draw_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y);
Dessine la totalité de l'image
sprite sur la bitmap bmp,
en évitant de dessiner là où les pixels du sprites
sont transparents.
Attention par rapport à un blit, ici
la destination est indiquée
avant la source.
Les coordonnées x y seront celles du coin supérieur
gauche du rectangle de l'image source
dans le repère de la bitmap destination.
Ceci est équivalent à l'appel masked_blit(sprite,
bmp, 0, 0, x, y, sprite->w, sprite->h);
On utilisera plutôt draw_sprite quand on dessine de petits
éléments mobiles (acteurs)
et plutôt masked_blit quand on dessine de grandes images avec
transparences (avant-plans)
ou quand on souhaite avoir un contrôle fin de la
géométrie (plus de paramètre)
Dessine des versions symétriques
horizontalement/verticalement du sprite de départ.
void
masked_blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int
dest_x, int dest_y, int width, int height);
Très proche de draw_sprite mais
disposant de plus de paramètres de réglages
et plutôt utilisé pour des grandes images (avant-plans)
Les paramètres et l'utilisation sont les mêmes que pour
blit
la seule différence étant
que les pixels de couleur transparente ne sont pas affichés : la
transparence est prise en compte.
Affichage texte
Text
output
Fonctions d'écriture de texte
sur des images (par exemple l'écran screen)
Lien ci-dessus pour accéder à la liste de toutes les
primitives de texte
font
: extern FONT *font;
Police de caractère par
défaut d'allegro
Pas très jolie mais nécessaire pour afficher simplement
des textes
void
textprintf_ex(BITMAP *bmp, const FONT *f, int x, int y, int color, int bg,
const char *fmt, ...);
Equivalent au printf mais affiche le
texte où on veut quand on veut sur une image
bmp : image destination (par exemple screen )
f : utiliser font à ce niveau
(x,y) : coordonnées du coin supérieur gauche du bloc de
texte
color : couleur du texte (makecol...)
bg : couleur du fond (makecol ...) ou -1 pour un fond transparent
fmt,... : une chaine formatée comme pour un printf
Exemple pour afficher un score (int score;) en (100,10) rouge fond
transparent à l'écran
textprint_ex(screen, font, 100, 10,
makecol(255,0,0), -1, "SCORE=%d", score);
Ne connait pas \n : pour un retour ligne faire un autre affichage avec
y croissant
Gestion clavier
int
install_keyboard();
A appeler une fois après
init_allegro pour signaler que le programme utilise le clavier
key : extern volatile
char key[KEY_MAX];
Tableau de booléens (Vrai/Faux)
indiquant si "là tout de suite maintenant" une touche est
enfoncée
Voir le lien ci-dessus pour une liste des noms correspondant aux
différentes touches
Exemple pour tester si la touche espace est enfoncée (alors
effacer écran)
if (key[KEY_SPACE])
clear_bitmap(screen);
Exemple pour faire une boucle qui tourne tant que Echap n'est PAS
appuyé
while (!key[KEY_ESC])
{
...
...
}
int
keypressed();
Version allegro équivalente de
kbhit()
Booléen : est-ce qu'une touche a été
appuyée ?
Si oui retourne Vrai
Si non retourne Faux (n'attend pas qu'un caractère soit
entré)
int
readkey();
Version allegro équivalente de
getch()
Retourne un code correspondant a une touche effectivement appuyée
Si aucune touche n'a été appuyée alors attend
qu'une touche le soit :
ceci peut être pratique pour faire un test en pausant
l'exécution.
Caster le code retourné en char pour avoir le caractère
ascii correspondant à la touche
Faire un décalage binaire à droite de 8 bits pour obtenir
le scancode (KEY_SPACE KEY_ESC ...)
Voir exemples 6_0 et 6_1 du cours 1 pour un exemple d'usage en situation
void
set_keyboard_rate(int delay, int repeat);
Modifie les caractéristiques de
l'auto-répétition du clavier.
Ne concerne PAS l'approche "instantanée" par scancodes
(key[KEY_SPACE] ...)
Ne concerne que l'approche buffer : keypressed et readkey
delay : au bout de combien de ms une touche reste appuyée pour
lancer la répétition
repeat : temps en ms entre deux répétitions une fois que
la répétition est lancée
Passer 0,0 pour désactiver toute répétition
automatique
Gestion souris
int
install_mouse();
A appeler une fois après
init_allegro pour signaler que le programme utilise la souris
void
show_mouse(BITMAP *bmp);
S'utilise le plus souvent directement
sur l'écran : show_mouse(screen);
A appeler une fois APRES l'ouverture du
mode graphique pour montrer le curseur de souris
Si la souris n'a pas été installée (pas d'appel
à install_mouse) alors la souris du bureau
est quand même visible sur l'écran graphique mais n'est
pas utilisable dans le programme
Si la souris à été installée mais qu'il n'y
a pas d'appel à show_mouse alors la souris
est utilisable dans le programme (mouse_b/mouse_x/mouse_y) mais le
pointeur reste invisible.
Utiliser une souris visible en mode plein écran
( GFX_AUTODETECT_FULLSCREEN )
nécessite des précautions supplémentaires (lire
attentivement la doc technique)
mouse_b : extern
volatile int mouse_b;
Contient l'état
instantané des boutons de la souris.
mouse_b&1 : Booléen vrai si le bouton gauche est
enfoncé, faux sinon
mouse_b&2 : Booléen vrai si le bouton droit est
enfoncé, faux sinon
Attention si votre test est dans une boucle de gestion
d'événements
il y a toutes les chances pour qu'il soit validé plusieurs fois
de suite
alors que l'utilisateur n'a cliqué qu'une seule fois
(car le bouton est resté enfoncé pendant plusieurs tours
de boucle)
Ceci n'est pas forcément souhaitable... (mérite
réflexion)
mouse_x : extern
volatile int mouse_x;
mouse_y : extern
volatile int mouse_y;
Coordonnées instantanées
de la souris (bout du pointeur)
Accessible même si la souris est invisible (pas de show_mouse)
à condition d'avoir fait install_mouse