Obligement - L'Amiga au maximum

Vendredi 24 mai 2019 - 04:48  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles en d'autres langues


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


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


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


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


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 playfield, 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 playfield 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 playfield, le nombre de couleurs que l'on peut associer à un BOB est le même que celui du playfield, 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 playfield. Dans un playfield à 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 playfield auquel il est associé. De plus, un BOB n'est pas limité arbitrairement dans ses dimensions, mais seulement par la taille du playfield 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 bitplanes, 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 playfields. Le numéro du registre de couleur est induit par chaque bit de chaque biplane du BOB, le playfield de plus haut numéro étant le bit de poids le plus fort.

Par exemple les combinaisons possibles pour un BOB possédant deux bitplanes 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 bitplanes sur un playfield de trois bitplanes 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 bitplane du BOB, un bitplane du playfield. Ainsi, si on reprend l'exemple d'un BOB de deux biplanes sur un playfied 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 bitplane 0 du BOB dans le bitplane 1 du playfield et le bitplane 1 du BOB dans le bitplane 4 du playfield. 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 playfield 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 playfield, 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 bitplane 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 bitplanes 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);

}


[Retour en haut] / [Retour aux articles] [Article précédent]