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 : C - Les BOB
(Article écrit par Pascal Amiable et extrait d'Amiga News Tech - janvier 1992)
|
|
Contrairement aux VSprites, qui utilisent les sprites matériels de l'Amiga,
les BOB sont gérés exclusivement par le Blitter. D'où le nom de BOB, d'ailleurs, contraction de Blitter Object.
Cette simple différence de gestion entraîne, comme vous l'allez pouvoir constater, quelques différences dans
la programmation de leur affichage... Comme le sprite virtuel, le BOB fait partie intégrante du GEL System.
Mais contrairement aux VSprites, qui, de par leurs liens avec les sprites matériels, sont indépendants
du champ de jeu, le BOB en fait partie intégrante. On peut donc utiliser un BOB comme une brosse (comme le
fait Deluxe Paint, par exemple) ou au contraire, simuler un sprite en sauvegardant la zone du champ de jeu correspondant
au rectangle englobant le BOB lors de son affichage, et en la réaffichant lorsque le BOB s'est déplacé.
Le BOB n'étant plus lié à un sprite matériel mais au champ de jeu, le nombre de couleurs que l'on peut associer
à un BOB est le même que celui du champ de jeu, ainsi que le contenu des registres de couleurs. Il vous faudra
donc faire attention à ne pas utiliser les mêmes registres pour ces deux éléments sous peine de voir le BOB
disparaître dans le champ de jeu. Dans un champ de jeu à 32 couleurs, on pourra par exemple utiliser les 16 premières
pour le fond et les 16 autres pour le ou les BOB.
La structure de données associée à un BOB contient des champs définissant sa structure propre ainsi qu'un pointeur
sur une structure VSprite qui contient la définition des attributs communs aux sprites virtuels et au BOB.
Ces données communes sont liées en grande partie à la position du BOB. Ainsi, il sera possible de gérer cette
position indépendamment du type d'élément manipulé. Il s'agit là d'une excellente initiative, évitant une
duplication inutile du code de gestion des positions.
Au niveau de la structure de données des BOB, nous allons étudier simplement les champs propres à la structure BOB
et les champs de la structure VSprite possédant une valeur spécifique. Pour la description du reste des données,
je vous renvoie à l'article du mois dernier sur les VSprites.
L'image du BOB
Vous vous rappelez sans doute que l'image d'un VSprite (limitée à 16 pixels en largeur) est définie par une
série de couples de deux mots de 16 bits, permettant pour chacun de définir une ligne du VSprite :
0x0fc3, 0x0000, /* ligne 1 du VSprite */
|
Pour un BOB, l'organisation des données est différente. Comme nous l'avons vu précédemment, un BOB
possède autant de couleurs que le champ de jeu auquel il est associé. De plus, un BOB n'est pas limité arbitrairement
dans ses dimensions, mais seulement par la taille du champ de jeu auquel il est associé. Ainsi, rien n'empêche de
réaliser un BOB de 64 pixels de large sur 100 lignes de haut.
Dans cet exemple, les dimensions ne sont pas choisies innocemment. En effet, la taille en largeur d'un BOB
doit être impérativement un multiple de 16 (nombre de mots de 16 bits). Par contre, sa hauteur s'exprime en
nombre de lignes sans contraintes.
Pour définir un BOB de 32 pixels de large sur deux lignes de haut, évoluant sur un écran à deux plans de bits, nous
déclarerons l'image associée à ce BOB de la manière suivante :
/* Bitplane 0 */
0x0000, 0xfce0, /* Première ligne */
0xcccc, 0x1111, /* Deuxième ligne */
/* Bitplane 2 */
0x1777, 0xfce0, /* Première ligne */
0x4444, 0x4444, /* Deuxième ligne */
|
Les couleurs
Le choix du registre de couleur associé à un pixel s'effectue de la même manière que pour les champs de jeu.
Le numéro du registre de couleur est induit par chaque bit de chaque biplane du BOB, le champ de jeu de plus
haut numéro étant le bit de poids le plus fort.
Par exemple les combinaisons possibles pour un BOB possédant deux plan de bits sont :
Bitplane 0 | 0 0 1 1
Bitplane 1 | 0 1 0 1
Couleur | 0 1 2 3
|
A première vue, lorsque l'on utilise un BOB de deux plans de bits sur un champ de jeu de trois plans de bits ou
plus, seuls les quatre premiers registres sont disponibles (0 à 3). Pour palier à ce problème, vous avez la
possibilité, grâce aux champs PlanePick et PlaneOff, de définir quels sont les registres qui vont
être réellement utilisés. Ils servent donc à établir une table de correspondance entre le numéro
de registre théorique (exemple : 0, 1, 2, 3) et le numéro réel du registre utilisé (exemple : 10, 11, 14, 15).
PlanePick permet d'associer à chaque plan de bits du BOB, un plan de bits du champ de jeu. Ainsi, si on reprend
l'exemple d'un BOB de deux biplanes sur un champ de jeu de cinq :
Numéro bitplane | 5 4 3 2 1
PlanePick | 0 1 0 1 0
|
Ceci entraînera l'écriture des données du plan de bits 0 du BOB dans le plan de bits 1 du champ de jeu et
le plan de bits 1 du BOB dans le plan de bits 4 du champ de jeu. Dans ce cas, les registres de couleurs utilisés ne
seront plus (0, 1, 2 et 3) mais (0, 2, 8 et 10). PlanePick ne permet toutefois pas toutes les combinaisons
possibles, d'où le champ PlaneOnOff.
Ce champ contient une valeur sur 6 bits, comme PlanePick, qui permet par un "OU"
logique entre chaque registre de couleur et sa valeur de modifier les registres choisis pour afficher
le BOB. Ainsi, si l'on positionne PlaneOnOff à 5, on obtiendra la combinaison suivante :
Registre 1 | 0 0 0 1 0
PlaneOnOff | 0 0 1 0 1
Reg. Réel | 0 0 1 1 1
|
Idem pour les autres registres, ce qui nous donne (0, 7, 13 et 15).
Pour obtenir dans notre exemple
précédent (10, 11, 14 et 15), nous aurions du placer les valeurs suivantes dans PlanePick et PlaneOnOff :
PlaneOnOff | 0 1 0 1 0
PlanePick | 0 0 1 0 1
|
Avantages et inconvénients
Un des principaux avantages d'utiliser des BOB par rapport à des VSprites, c'est qu'ils peuvent être
de la taille de votre choix, aussi bien en largeur qu'en hauteur. Ceci tant que vous avez encore assez de mémoire
Chip pour stocker leurs images. Par contraste, nous avions vu que le VSprite était limité à 16 pixels en
largeur.
Du point du vue des couleurs, nous sommes également loin de la limitation du VSprite (trois couleurs effectives,
plus une transparente). En effet, nous disposons pour le BOB du même nombre de couleurs que pour le champ de jeu
auquel il est attaché. Cela peut donc aller jusqu'à 4096 en mode HAM.
Pour les BOB, vous pouvez définir les priorités d'affichage, à l'aide des pointeurs Before et After qui leur
sont associés. Vous avez ainsi la maîtrise totale de l'affichage des objets en cas de recouvrement.
De part le fait que les BOB font partie intégrante du champ de jeu, leur utilisation est plus lente que celle
des VSprites. Il est d'ailleurs vivement conseillé d'utiliser un écran double tampon mémoire.
Il est ainsi possible de tracer dans un écran pendant que l'on affiche l'autre, rendant ainsi l'animation plus
fluide.
Les BOB utilisent, à taille et profondeur égale, plus de mémoire que les VSprites. En effet,
il est presque toujours nécessaire de positionner le drapeau SAVEBACK afin d'avoir une sauvegarde automatique
du fond. Dans ce cas, il faut donc la mémoire nécessaire à sauvegarder cette portion en plus de la mémoire liée
à l'image du BOB.
Programmation
Nous en savons désormais assez pour écrire un programme d'affichage et d'animation de BOB.
Ce programme va afficher des logos "ANT" en 16 couleurs sur un écran possédant lui aussi 16
couleurs. Les précisions nécessaires sont incluses dans le listing que j'ai le plus possible
commenté.
Le logo a été réalisé grâce à un utilitaire du domaine public. Il existe de nombreux programmes permettant
de vous aider dans la tâche fastidieuse consistant à inclure le source C d'une image dans un programme.
Vous trouverez une description de quelques-uns de ces logiciels dans cet
article.
/* --------------------------------------------------------------------- */
/* */
/* Programme d'affichage et d'animation de BOB */
/* */
/* Exemple de programmation des BOB */
/* */
/* P. AMIABLE 1991 */
/* */
/* --------------------------------------------------------------------- */
/* -----------------------------------------------------------------*/
/* */
/* Quelques includes utiles...... */
/* */
/* -----------------------------------------------------------------*/
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <stdio.h>
#include <graphics/gels.h>
/* -----------------------------------------------------------------*/
/* */
/* Les defines maintenants..... */
/* */
/* -----------------------------------------------------------------*/
#define INTUITION_REV 0L /* Version d'Intuition (la dernière) */
#define GFX_REV 0L /* Version de Graphics (la dernière) */
#define NBRBOBS 1 /* Nombre de BOB affichés simultanément à l'écran */
#define LARGEUR 64 /* Largeur en pixel du bob */
#define HAUTEUR 58 /* Hauteur en ligne du bob */
#define PROFONDEUR 4 /* Profondeur en plan de bits du BOB */
/* -----------------------------------------------------------------*/
/* */
/* Définition des variables externes */
/* */
/* -----------------------------------------------------------------*/
/* Declararation des fonctions définies dans le programme */
void referme();
void init();
void detruit_bobs();
void ouvrefenetre();
void refermegel();
int initgel();
void graphique();
void deplace();
int bidon();
struct Bob *cree_bob();
struct VSprite *cree_vsprites();
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct NewScreen nouvecran = {
0, 0, /* LeftEdge, TopEdge */
320, 256, /* Width, Height */
4, /* Depth, soit 16 couleurs possibles */
1, 0, /* DetailPen, BlockPen */
SPRITES, /* ViewModes valeur de 0 = basse resolution */
CUSTOMSCREEN, /* Type d'ecran */
NULL, /* Font -> NULL = fonts par defaut */
NULL, /* DefaultTitle pour le titre -> Aucun*/
NULL, /* gadgets, aucun*/
NULL }; /* adresse de la CustomBitmap -> aucune ici */
struct NewWindow nouvfenetre =
{
0, /* LeftEdge position en x de la fenêtre */
0, /* TopEdge position en y de la fenêtre */
320, /* Width 320 pixels de large */
256, /* Height 256 pixels de hauts */
0, /* DetailPen Le texte doit être écrit dans la couleur 0 */
1, /* BlockPen les blocks doivent être dans la couleur 1 */
CLOSEWINDOW, /* IDCMPFlags Rien de particulier */
WINDOWCLOSE|WINDOWSIZING|WINDOWDEPTH|ACTIVATE,
/* Flags cf article précédent sur Intuition */
NULL, /* FirstGadget Pas de gadgets personnels */
NULL, /* CheckMark Pas de Checkmark particulière */
"ANT a pris des couleurs" , /* Title Titre de la fenêtre */
NULL, /* Screen On attachera l'écran en cours de programme */
NULL, /* BitMap pas de Bitmap personnelle */
320, /* MinWidth La fenêtre ne peut être plus petite que 150x15 */
10, /* MinHeight ni plus grande que 150x15, bref elle */
320, /* MaxWidth reste comme elle est */
256, /* MaxHeight */
CUSTOMSCREEN /* Type On accroche la fenêtre au Workbench */
};
struct Window *fenetre = NULL;
struct Screen *ecran = NULL;
struct RastPort *rastport = NULL; /* pointeur vers le RastPort lié à l'écran */
struct ViewPort *viewport = NULL;
SHORT vitesse[] = { 1, 2, -1, -2 }; /* Echelle de vitesse utilisée */
SHORT xmouv[NBRBOBS], ymouv[NBRBOBS]; /* Direction de mouvement des bobs */
struct Bob *bob[NBRBOBS]; /* On va créer NBRBOBS BOB donc on se réserve les pointeurs nécessaires */
struct VSprite *vsprite; /* pointeur vers un vsprite qui va nous servir pour les BOB */
short max_cree = 0; /* nombre maxi de BOB crées */
struct VSprite *tete = NULL; /* Il faut toujours créer une liste de VSprite */
struct VSprite *queue = NULL; /* composée de deux sprites pour initialisé la structure Gels */
struct GelsInfo gelinfo; /* On accroche cette structure au RastPort pour créer les sprites */
UWORD chip bobimage[]= { /* donnée nécessaire à décrire l'image du sprite */
/*----- bitmap : largeur = 64, hauteur = 58 --------*/
/*------ plan 0: --------*/
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x80, 0x80, 0x0,
0x0, 0x120, 0x80, 0x0,
0x20, 0x30, 0x80, 0x0,
0x6a, 0x2c, 0x180, 0x40,
0xce, 0x3e, 0x187, 0x99a0,
0x1fb, 0x2a, 0x29f, 0xffe0,
0x3ff, 0x3a, 0x39e, 0xebe0,
0x64d, 0x8018, 0x18e, 0x3d80,
0xa34, 0x10, 0x110, 0x3380,
0x20, 0x0, 0x0, 0x0,
0x2000, 0x8, 0x8101, 0x20,
0x2000, 0x8035, 0x513, 0x2020,
0x2c80, 0xa01c, 0x6191, 0x33e0,
0x3700, 0x603c, 0xe79d, 0xffe0,
0x3e00, 0x3fac, 0xf705, 0x6fa0,
0x3900, 0x3f34, 0xd781, 0xc60,
0x2c9a, 0x5800, 0x600, 0x4240,
0x15e4, 0x2000, 0x1100, 0x80,
0x300, 0x8020, 0x4000, 0x0,
0x20, 0x0, 0x1291, 0x6780,
0x804, 0x8000, 0x1399, 0xe7e0,
0x3e91, 0xa038, 0x1590, 0xe1e0,
0x33ff, 0xc03c, 0x1f01, 0xe2c0,
0x3f7f, 0xe01c, 0xf91, 0xe240,
0x3b01, 0xc01c, 0x580, 0x100,
0x3900, 0x4004, 0x700, 0x2020,
0x3f00, 0x2000, 0x1, 0x21a0,
0x200, 0x0, 0x1, 0x180,
0x0, 0x2008, 0x1, 0xe0e0,
0x801, 0xa01c, 0x81, 0xc0e0,
0x1f00, 0xa03c, 0x280, 0x6020,
0x3e01, 0x603c, 0x381, 0x80a0,
0x3f01, 0xe038, 0x680, 0x0,
0x1701, 0xe03c, 0x601, 0x8020,
0x1a00, 0xc024, 0x281, 0xe020,
0x2900, 0x4000, 0x301, 0xa020,
0x400, 0x2000, 0x1, 0xe020,
0x0, 0x0, 0x301, 0xa020,
0x1f00, 0xe038, 0x100, 0xe000,
0x2701, 0xa03c, 0x580, 0x0,
0x3f80, 0xe03c, 0x580, 0x0,
0x1, 0xe03c, 0x781, 0xc000,
0x1, 0xa03c, 0x781, 0xe000,
0x1, 0xa024, 0x581, 0xe000,
0x0, 0x8010, 0x501, 0xe000,
0x0, 0x0, 0x401, 0xf800,
0x0, 0x800c, 0x682, 0x4200,
0x0, 0x6020, 0x180, 0x0,
0x0, 0xe010, 0x280, 0x0,
0x0, 0x2030, 0x700, 0x0,
0x0, 0x6030, 0x7ff, 0xff00,
0x0, 0x2030, 0x6ff, 0xf800,
0x0, 0x0, 0x359, 0xc000,
0x0, 0x2000, 0x4, 0x0,
0x0, 0x0, 0x420, 0x0,
0x0, 0x0, 0x0, 0x0,
/*------ plan 1: --------*/
0x0, 0x30, 0x0, 0x0,
0x0, 0x70, 0x0, 0x0,
0x8, 0xf8, 0x80, 0x0,
0x1c, 0x1f8, 0x90, 0x0,
0x3c, 0x3c, 0x98, 0x20,
0x7e, 0x3c, 0x198, 0x60,
0xfe, 0x3e, 0x19f, 0xffe0,
0x1ff, 0x2a, 0x29f, 0xffe0,
0x3ff, 0x3a, 0x39e, 0xebe0,
0x64d, 0x8018, 0x18e, 0x3d80,
0xa34, 0x10, 0x110, 0x3380,
0x20, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x10, 0x98, 0x8040,
0x600, 0x8, 0x201c, 0xe380,
0x1365, 0xa63c, 0x7999, 0xada0,
0x2a1b, 0xdc3c, 0x6e99, 0xefe0,
0x3cff, 0x783c, 0x7f99, 0xe7e0,
0x3fff, 0xf03c, 0x3f99, 0xe7e0,
0x3fff, 0xe03c, 0x3f99, 0xe7e0,
0x3fff, 0xe03c, 0x1f90, 0xe1e0,
0x3fff, 0xe03c, 0x1f81, 0xe2c0,
0x3fff, 0xe01c, 0xf91, 0xe240,
0x3b01, 0xc01c, 0x580, 0x100,
0x3900, 0x4004, 0x700, 0x0,
0x3f00, 0x2000, 0x0, 0x0,
0x200, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x2000,
0x0, 0x0, 0x1, 0x80c0,
0x0, 0x0, 0x0, 0x6040,
0x0, 0x4, 0x101, 0xe060,
0x2800, 0x0, 0x181, 0xe060,
0x2501, 0x2018, 0x501, 0xe060,
0x1601, 0xa03c, 0x481, 0xe020,
0x3b01, 0xc03c, 0x781, 0xe020,
0x3f01, 0xe03c, 0x781, 0xa020,
0x3f01, 0xe03c, 0x780, 0xe000,
0x3f01, 0xe03c, 0x780, 0x0,
0x3f81, 0xe03c, 0x780, 0x0,
0x1, 0xe03c, 0x780, 0x0,
0x1, 0xa03c, 0x780, 0x0,
0x1, 0xa024, 0x580, 0x0,
0x0, 0x8010, 0x500, 0x0,
0x0, 0x0, 0x400, 0x0,
0x0, 0x0, 0x1, 0xbc00,
0x0, 0x0, 0xf, 0xff80,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x4000, 0x100, 0x0,
0x0, 0x2020, 0x4a6, 0x0,
0x0, 0x20, 0x7fa, 0x0,
0x0, 0x0, 0x3c0, 0x0,
0x0, 0x0, 0x700, 0x0,
/*------ plan 2: --------*/
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x14, 0x100, 0x0,
0x0, 0x5, 0x1, 0x1400,
0x1b2, 0x27, 0x211, 0xc260,
0x5cb, 0x802f, 0x868f, 0xcc60,
0x1fcf, 0xc03f, 0x879f, 0xffe0,
0x3fc7, 0xc03f, 0xc79f, 0xffe0,
0x3fc3, 0xe03d, 0xc79f, 0xffe0,
0x3f81, 0xe03d, 0xe79d, 0xffe0,
0x3f80, 0xf03c, 0xe79d, 0xffe0,
0x3f00, 0x7fbc, 0xf79d, 0xefe0,
0x3f00, 0x3f3c, 0xf79d, 0xefe0,
0x3fff, 0xfe3c, 0x7f99, 0xefe0,
0x3fff, 0xfc3c, 0x7f99, 0xefe0,
0x3fff, 0xf83c, 0x7f99, 0xe7e0,
0x3fff, 0xf03c, 0x3f99, 0xe7e0,
0x3fff, 0xe03c, 0x3f99, 0xe7e0,
0x3fff, 0xe03c, 0x1f90, 0xe1e0,
0x3fff, 0xe03c, 0x1f81, 0xe2c0,
0x3fff, 0xe01c, 0xf91, 0xe240,
0x3b01, 0xc01c, 0x580, 0x100,
0x3900, 0x4004, 0x700, 0x0,
0x3f00, 0x2000, 0x0, 0x0,
0x200, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x4000,
0x0, 0x0, 0x1, 0x20,
0x0, 0x0, 0x1, 0xe000,
0x0, 0x0, 0x1, 0xe000,
0x0, 0x0, 0x1, 0xe000,
0x0, 0x4000, 0x1, 0xe000,
0x0, 0x4018, 0x201, 0xe000,
0x1, 0x602c, 0x281, 0xe000,
0x1, 0xe03c, 0x381, 0xf800,
0x1, 0xe03c, 0x783, 0xfe00,
0x0, 0xe038, 0x78f, 0xff80,
0x0, 0xe038, 0x780, 0x0,
0x0, 0x6030, 0x780, 0x0,
0x0, 0x6030, 0x7ff, 0xff00,
0x0, 0x6030, 0x7ff, 0xf800,
0x0, 0x2020, 0x7ff, 0xc000,
0x0, 0x2020, 0x7fe, 0x0,
0x0, 0x0, 0x7e0, 0x0,
0x0, 0x0, 0x700, 0x0,
/*------ plan 3: --------*/
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x1, 0x200,
0x0, 0x0, 0x10, 0x120,
0x0, 0x20, 0x1000, 0x1a0,
0x400, 0x2020, 0xa11, 0xe2e0,
0x601, 0xa038, 0x881, 0xe1e0,
0x1, 0xc03c, 0x781, 0xe1e0,
0x3d01, 0xe03c, 0x781, 0xe1e0,
0x3f01, 0xe03c, 0x781, 0xe0e0,
0x3f01, 0xe03c, 0x781, 0xe0e0,
0x3f01, 0xe03c, 0x781, 0xe0e0,
0x3f01, 0xe03c, 0x781, 0xe0e0,
0x3f01, 0xe03c, 0x781, 0xe060,
0x3f01, 0xe03c, 0x781, 0xe060,
0x3f01, 0xe03c, 0x781, 0xe060,
0x3f01, 0xe03c, 0x781, 0xe020,
0x3f01, 0xe03c, 0x781, 0xe020,
0x3f01, 0xe03c, 0x781, 0xe020,
0x3f01, 0xe03c, 0x781, 0xe020,
0x3f01, 0xe03c, 0x781, 0xe000,
0x3f81, 0xe03c, 0x781, 0xe000,
0x1, 0xe03c, 0x781, 0xe000,
0x1, 0xe03c, 0x781, 0xe000,
0x1, 0xe03c, 0x781, 0xe000,
0x1, 0xe03c, 0x781, 0xe000,
0x1, 0xe03c, 0x781, 0xf800,
0x1, 0xe03c, 0x783, 0xfe00,
0x0, 0xe038, 0x78f, 0xff80,
0x0, 0xe038, 0x780, 0x0,
0x0, 0x6030, 0x780, 0x0,
0x0, 0x6030, 0x7ff, 0xff00,
0x0, 0x6030, 0x7ff, 0xf800,
0x0, 0x2020, 0x7ff, 0xc000,
0x0, 0x2020, 0x7fe, 0x0,
0x0, 0x0, 0x7e0, 0x0,
0x0, 0x0, 0x700, 0x0};
UWORD tablecouleur[] = { /* table de couleur pour l'initialisation de l'écran */
0x0000,
0x0eca,
0x0f00,
0x0f16,
0x0f1c,
0x0c2e,
0x072e,
0x033e,
0x066e,
0x089d,
0x0bbd,
0x0aac,
0x099b,
0x099a,
0x0889,
0x0444
};
/* -----------------------------------------------------------------*/
/* Programme principal */
/* -----------------------------------------------------------------*/
main()
{
struct IntuiMessage *message;
SHORT i;
init();
ouvrefenetre(); /* ouverture de l'écran et de la fenêtre */
initgel(); /* initialisation du système de gestion des éléments graphiques */
graphique();
while(1)
{
deplace() ; /* on bouge les BOB par VSprite interposés */
message = (struct IntuiMessage *)GetMsg(fenetre->UserPort);
if (message)
{
switch(message->Class)
{
case CLOSEWINDOW:
for(i=0; i<max_cree; i++)
if(bob[i])
detruit_bobs(bob[i]->BobVSprite); /* on détruit les BOB créés */
refermegel(); /* on désalloue la structure gel créée par initgel() */
referme();
exit(TRUE);
break;
case INTUITICKS:
deplace();
break;
default:
break;
}
ReplyMsg(message);
}
}
}
/* -----------------------------------------------------------------*/
/* Init() Ouvre la bibliothèque */
/* -----------------------------------------------------------------*/
void init()
{
char *OpenLibrary();
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",INTUITION_REV);
if(!IntuitionBase)
{
exit(FALSE);
}
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GFX_REV);
if(!GfxBase)
{
referme();
exit(FALSE);
}
}
/* -----------------------------------------------------------------*/
/* ouvrefenetre() ouvre la fenetre et l'ecran */
/* -----------------------------------------------------------------*/
void ouvrefenetre()
{
void referme();
if(!(ecran =(struct Screen*)OpenScreen(&nouvecran))) /* on ouvre l'ecran */
{
referme();
exit(FALSE);
}
nouvfenetre.Screen = ecran; /* on attache la fenetre à ce dernier */
if(!(fenetre=(struct Window*)OpenWindow(&nouvfenetre)))
{
referme();
exit(FALSE);
}
viewport = &(ecran->ViewPort); /* viewport nécessaire pour la gestion des couleurs */
rastport = &(ecran->RastPort); /* rastport nécessaire pour tracer */
LoadRGB4(viewport, &tablecouleur[0], 16); /* on charge la table des couleurs */
}
/* -----------------------------------------------------------------*/
/* Cette fonction referme la fenetre et les bibliothèques */
/* -----------------------------------------------------------------*/
void referme()
{
if(fenetre) CloseWindow(fenetre);
if(ecran) CloseScreen(ecran);
if(IntuitionBase) CloseLibrary(IntuitionBase);
if(GfxBase) CloseLibrary(IntuitionBase);
}
/* -----------------------------------------------------------------*/
/* Cette fonction déplace les max_cree BOB */
/* -----------------------------------------------------------------*/
void deplace()
{
short i;
for (i=0; i<max_cree; i++)
{
vsprite = bob[i]->BobVSprite;
vsprite->X = xmouv[i]+vsprite->X; /* deplacement du VSprite */
vsprite->Y = ymouv[i]+vsprite->Y;
/* Test de dépassement de l'écran. */
if(vsprite->X >= 256 || vsprite->X <= 0) xmouv[i]=-xmouv[i];
if(vsprite->Y >= 192 || vsprite->Y <= 0) ymouv[i]=-ymouv[i];
}
SortGList(rastport); /* on réordonne la liste des VSprites */
DrawGList(rastport, viewport); /* On crée les instructions pour les sprites */
MakeScreen(ecran); /* on régénère l'écran*/
RethinkDisplay(); /* et on visualise le tout */
}
/* -----------------------------------------------------------------*/
/* routine appelée lors de la détection de collision */
/* -----------------------------------------------------------------*/
int bidon() /* elle ne fait rien */
{
return(0);
}
/* -----------------------------------------------------------------*/
/* Cette fonction initialise la structure Gels. */
/* -----------------------------------------------------------------*/
int initgel()
{
if ((tete = (struct VSprite *)AllocMem(sizeof /* on alloue le sprite de tete */
(struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0)
{
return(-1);
}
if ((queue = (struct VSprite *)AllocMem(sizeof /* on alloue le sprite de queue */
(struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0)
{
refermegel();
if (tete != NULL)
FreeMem(tete, sizeof(struct VSprite));
return(-2);
}
gelinfo.sprRsrvd = 0xFC; /* on n'utilise pas la paire (0,1) réservée pour le pointeur de souris */
if ((gelinfo.nextLine = (WORD *)AllocMem(sizeof(WORD) * 8,
MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
{
refermegel();
if (tete != NULL)
FreeMem(tete, sizeof(struct VSprite));
if (queue != NULL)
FreeMem(queue, sizeof(struct VSprite));
return(-3);
}
if ((gelinfo.lastColor = (WORD **)AllocMem(sizeof(LONG) * 8,
MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
{
refermegel();
if (tete != NULL)
FreeMem(tete, sizeof(struct VSprite));
if (queue != NULL)
FreeMem(queue, sizeof(struct VSprite));
return(-4);
}
/* Maintenant on prépare une table de pointeurs vers des routines qui
seront exécutées quand la fonction DoCollision détectera une collision
Nous étudierons le fonctionnement d'un tel système en détail le mois
prochain
*/
if ((gelinfo.collHandler = (struct collTable *)AllocMem(sizeof(struct
collTable), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
{
refermegel();
if (tete != NULL)
FreeMem(tete, sizeof(struct VSprite));
if (queue != NULL)
FreeMem(queue, sizeof(struct VSprite));
return(-5);
}
/* quand une partie d'un objet passe à travers les frontières il déclenche
l'appel à la routine de gestion de collision (pour le moment bidon())
*/
gelinfo.leftmost = 0;
gelinfo.rightmost = rastport->BitMap->BytesPerRow * 8 - 1;
gelinfo.topmost = 0;
gelinfo.bottommost = rastport->BitMap->Rows - 1;
rastport->GelsInfo = &gelinfo; /* on relie la structure GelsInfo au RastPort */
InitGels(tete, queue, &gelinfo ); /* et on accroche les sprite de tete et de queue */
SetCollision(0, bidon, &gelinfo); /* enfin on accroche une fonction de gestion de collision */
WaitTOF(); /* Attente de fin de trame */
}
/* -----------------------------------------------------------------*/
/* Cette fonction désalloue la structure gels . */
/* -----------------------------------------------------------------*/
void refermegel()
{
if (gelinfo.collHandler != NULL)
FreeMem(gelinfo.collHandler, sizeof(struct collTable));
if (gelinfo.lastColor != NULL)
FreeMem(gelinfo.lastColor, sizeof(LONG) * 8);
if (gelinfo.nextLine != NULL)
FreeMem(gelinfo.nextLine, sizeof(WORD) * 8);
if (gelinfo.gelHead != NULL)
FreeMem(gelinfo.gelHead, sizeof(struct VSprite));
if (gelinfo.gelTail != NULL)
FreeMem(gelinfo.gelTail, sizeof(struct VSprite));
}
/* -----------------------------------------------------------------*/
/* Cette fonction crée l'ensemble des éléments graphiques */
/* -----------------------------------------------------------------*/
void graphique()
{
int erreur;
int i,j,x,y;
erreur = initgel(&gelinfo, rastport);
for(i=0; i<NBRBOBS; i++) /* jusqu'au nombre maxi de sprites */
{
xmouv[i] = vitesse[RangeRand(4)]; /* on choisit une vitesse au hasard */
ymouv[i] = vitesse[RangeRand(4)];
x = 10 + RangeRand(246); /* et on calcule une position de départ */
y = 10 + RangeRand(182);
bob[i] = cree_bob(LARGEUR,HAUTEUR,PROFONDEUR,bobimage,0x3f,0x3f,x, y,SAVEBACK|OVERLAY);
if(bob[i] == 0)
break; /* plus de mémoire */
if (i > 0)
{
j = i-1;
bob[i]->After = bob[j]->Before; /* on distribue les priorités d'affichage */
bob[i]->After->Before = bob[j];
}
AddBob(bob[i], rastport); /* on ajoute les BOB au display */
max_cree++;
}
}
/* -----------------------------------------------------------------*/
/* Cette fonction détruit un bob et libére ses ressources */
/* -----------------------------------------------------------------*/
void detruit_bobs(vsprite)
struct VSprite *vsprite;
{
if (vsprite != NULL) {
if (vsprite->VSBob != NULL) {
if (vsprite->VSBob->SaveBuffer != NULL) {
FreeMem(vsprite->VSBob->SaveBuffer, sizeof(SHORT)*vsprite->Width*vsprite->Height*vsprite->Depth);
}
if (vsprite->VSBob->DBuffer != NULL) {
if (vsprite->VSBob->DBuffer->BufBuffer != 0) {
FreeMem(vsprite->VSBob->DBuffer->BufBuffer, sizeof(SHORT)*vsprite->Width*vsprite->Height*vsprite->Depth);
}
FreeMem(vsprite->VSBob->DBuffer, sizeof(struct DBufPacket));
}
FreeMem( vsprite->VSBob, sizeof(struct Bob));
}
if (vsprite->CollMask != NULL) {
FreeMem(vsprite->CollMask, sizeof(WORD)*vsprite->Height*vsprite->Width);
}
if (vsprite->BorderLine != NULL) {
FreeMem(vsprite->BorderLine, sizeof(WORD)*vsprite->Width);
}
FreeMem(vsprite, sizeof(struct VSprite));
}
}
/* -----------------------------------------------------------------*/
/* Cette fonction crée un bob */
/* -----------------------------------------------------------------*/
struct Bob *cree_bob(largeur,hauteur,profondeur,image,planepick,planeonoff,x,y,flags)
SHORT largeur; /* Largeur en pixels du BOB */
SHORT hauteur; /* hauteur en lignes du BOB */
SHORT profondeur; /* nombre de plans de bits associés à l'image du BOB */
WORD *image; /* pointeur sur la structure image associée au BOB */
SHORT planepick, planeonoff; /* les deux champs associés à PlanePick et PlaneOnOff */
SHORT x,y; /* la position du BOB lors de sa création */
SHORT flags; /* les flags divers associés au BOB */
{
struct Bob *b;
struct VSprite *v;
SHORT nb_mot;
nb_mot = (largeur+15)/16; /* on calcule le nombre de mot en largeur pour l'affichage */
/* On crée un vsprite sur lequel le bob va s'appuyer */
if(( v = cree_vsprites(hauteur,image,NULL,x,y,nb_mot,profondeur,flags)) == 0)
return(0) ;
v->PlanePick = planepick;
v->PlaneOnOff = planeonoff;
if(( b = (struct Bob *)AllocMem(sizeof(struct Bob),MEMF_PUBLIC | MEMF_CLEAR)) == 0)
return(0) ;
v->VSBob = b;
b->Flags = 0;
if((b->SaveBuffer = (WORD *)AllocMem(sizeof(SHORT)*nb_mot*hauteur*profondeur,
MEMF_CHIP|MEMF_CLEAR)) == 0)
{
FreeMem(b,sizeof(struct Bob));
return(0);
}
b->ImageShadow = v->CollMask;
b->Before = NULL;
b->After = NULL; /* les priorités d'affichages seront indiquées plus tard */
b->BobVSprite = v;
b->BobComp = NULL; /* il ne s'agit d'une partie d'un objet plus complexe */
b->DBuffer = NULL; /* il n'y a pas de double buffer */
return(b);
}
/* -----------------------------------------------------------------*/
/* Cette fonction crée un VSprite. */
/* -----------------------------------------------------------------*/
struct VSprite *cree_vsprites(hauteur, image, tablecol, x, y,nb_mot,profondeur,flags)
SHORT hauteur; /* hauteur du VSprite en nombre de lignes */
WORD *image; /* table de mots définissant l'image associée au sprite */
WORD *tablecol; /* table de trois mots définissant la couleur du sprite */
SHORT x, y; /* position intiale du sprite */
SHORT nb_mot,profondeur,flags;
{
struct VSprite *vsprite; /* on déclare un pointeur sur une structure VSprites */
if ((vsprite = (struct VSprite *)AllocMem(sizeof(struct VSprite),
MEMF_PUBLIC | MEMF_CLEAR)) == 0)
{
return(0);
}
vsprite->Flags = flags; /* C'est un bob */
vsprite->Y = y; /* position x et y relative à la zone d'affichage */
vsprite->X = x;
vsprite->Height = hauteur; /* initialise la hauteur du VSprite. */
vsprite->Width = nb_mot; /* largeur du bob associé au VSprite. */
vsprite->Depth = profondeur; /* 2^profondeur couleurs */
vsprite->MeMask = 1; /* réservé pour la détection de collision sur les frontières */
vsprite->HitMask = 1;
vsprite->ImageData = image; /* on associe l'image au vsprite */
if ((vsprite->BorderLine = (WORD *)AllocMem(sizeof(WORD)*nb_mot,
MEMF_PUBLIC | MEMF_CLEAR)) == 0)
{
FreeMem(vsprite, sizeof(struct VSprite));
return(0);
}
if ((vsprite->CollMask = (WORD *)AllocMem(sizeof(WORD)*hauteur*nb_mot,MEMF_CHIP | MEMF_CLEAR)) == 0)
{
FreeMem(vsprite, sizeof(struct VSprite));
FreeMem(vsprite->BorderLine, nb_mot*sizeof(WORD));
return(0);
}
vsprite->SprColors = tablecol; /* on indisque les couleurs du sprite */
vsprite->PlanePick = 0x00; /* on initialisera les valeurs plus tard */
vsprite->PlaneOnOff = 0x00;
InitMasks(vsprite); /* on crée le masque de collision et la bordure du VSprite */
return(vsprite);
}
|
Mise à jour de mai 2025 : une archive contenant le listing adapté à vbcc, et avec l'exécutable
compilé par vbcc, a été réalisée par Yann-Gaël Guéhéneuc et est disponible sur
obligement.free.fr/files/antbobs.lha.
|