IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Programmation de la Game Boy Advance : affichage des tiles 2/3

Réjouissez-vous car nous allons enfin nous préoccuper d'afficher des cartes composées de tiles. Simple d'emploi, le processus fait toutefois appel à de nombreux registres.

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Introduction

L'épisode précédent de nos folles aventures à l'intérieur de la GameBoy Advance a marqué la description des cartes et des tiles au sein du matériel. Pour mémoire, les données relatives aux tiles se trouvent présentes dans les "character base blocks" et les informations de la carte sont placées dans les "screen base blocks". Nous avons à notre disposition quatre "character base blocks" de 16ko chacun et 32 "screen base blocks" de 2ko chacun. L'exemple étudié ici utilise uniquement un background en mode rotation et en 256 couleurs. Le cas particulier des backgrounds en mode texte sera étudié plus tard.

Les données de la carte sont représentées par un ensemble d'octets désignant chacun un tile. Ainsi, puisque chaque tile se voit numéroté sur un octet, nous ne pouvons employer plus de 256 tiles distincts. Puisque la représentation de chaque tile nécessite 64 octets, nous pouvons vérifier par le calcul la taille des "character base blocks" : 256 * 64 = 16 384 octets, soit 16ko.

La taille maximale en pixel d'une carte est de 1024 pixels par 1024. Or chaque tile occupe une surface de 8 pixels par 8. Nous ne pouvons donc avoir au maximum que (1024 / 8) * (1024 / 8) = 16 384 tiles pour une carte. Puisque chaque tile se voit désigné dans la carte par un octet, une carte occupe au maximum 16ko, soit la taille exacte d'un "character base block".

2. Contrôle des backgrounds

Pour contrôler un background, qui désigne une surface d'affichage pour une carte et ses tiles, le programmeur doit manipuler un registre de 16 bits. Il existe quatre registres de contrôle, pour les quatre backgrounds possibles : les registres REG_BG*CNT. Les deux premiers bits de ces registres définissent la priorité d'affichage (entre 0 et 3) du background. Les deux bits suivants désignent le "character base block" choisi. Puis les bits 4 et 5 restent inusités. Viennent deux bits concernant les drapeaux de mosaïque et de couleur. Le drapeau de mosaïque permet de réaliser les effets de pixellisation couramment employés dans les jeux. Le second drapeau définit le nombre de couleurs des tiles, la valeur 1 correspondant au mode 256 couleurs et la valeur 0 au mode 16 couleurs. Les bits 8 à 12 spécifient le numéro de "screen base block" sélectionné. Le bit 13 constitue le drapeau de retour de flot (ou "wraparound"). Si ce bit possède la valeur 1, la carte sera répétée lorsqu'un des bords sera atteint par défilement, autrement rien n'apparaît. Enfin, les deux derniers bits servent à sélectionner la taille de la carte. Le tableau numéro un précise la taille prise par la carte pour les différentes valeurs de ces bits.

Taille 0 1 2 3
Rotation 256*256 512*256 256*512 512*512
Texte 128*128 256*256 512*512 1024*1024

Pour simplifier la création et la manipulation des cartes, particulièrement lors de rotations et de mises à l'échelle, nous créons une structure relativement simple décrite dans le listing numéro un. Les noms des différents attributs de la structure sont suffisamment explicites pour que vous en compreniez le rôle. Les deux pointeurs tileData et mapData ne sont pas indispensables à la création et à l'affichage d'une carte. Toutefois, ils trouvent leur utilité si vous souhaitez modifier la carte en temps réel. Ainsi, pour accéder au tile de coordonnées (x, y) de la carte, vous pourrez rédiger la ligne de code suivante :

 
Sélectionnez
monBackground->mapData[x + y * 64] = tileNo;

La multiplication par 64 possède une explication très simple si nous considérons une carte de taille 2 en mode rotation, soit une carte de 512 pixels par 512. Avec de telles données, la carte possède (512 / 8) = 64 lignes de tiles contenant chacune (512 / 8) = 64 colonnes. L'accès aux éléments des cartes se veut aisé avec les backgrounds en mode rotation. Pour les backgrounds en mode texte, qui ne peuvent employer de vecteur linéaire puisque n'étant pas "carrés", les choses se compliquent un peu.

 
Sélectionnez
/* Listing 1 */
typedef struct t_Background
{
  u16* tileData;
  u16* mapData; 
  u16 size; 
  u8 mosaic,
     colorMode,
     number,
     charBaseBlock,
     screenBaseBlock,
     wrapAround;
} Background, *pBackground;

3. Création et affichage d'une carte

La création d'une carte suppose en premier lieu de se munir d'une planche de tiles. Il s'agit simplement d'une image carrée dont les dimensions sont multiples de 8. A l'aide d'un outil de conversion de sprites en code C nous créons les données relatives aux tiles. Nous devons ensuite nous saisir d'un éditeur de carte. Celui-ci permet de charger la planche de tile, de choisir la taille de la carte, de dessiner la carte à l'aide des tiles puis d'exporter le résultat sous forme de fichier C. Les différents éléments relatifs à la génération de notre carte trouvent place sur le CD-Rom dans le sous-répertoire "tools/" de notre programme. Nous générons ainsi les fichiers tiles.c et map.c.

Une fois créée notre structure de background, nous devons procéder à son affichage. L'ensemble de ces opérations se trouve dans la fonction initBackground() du fichier main.cpp du programme. Dans notre exemple, nous créons le background 2 d'une taille de 512 pixels par 512, adressé au "character base block" 3 et au "screen base block" 31. La méthode enableBackground() de l'en-tête background.h active la carte en remplissant le registre approprié. Ainsi pour notre background 2 nous exécuterions :

 
Sélectionnez
REG_BG2CNT = bg->size | (bg->charBaseBlock << 8) |
  (bg->screenBaseBlock << 2) |
  bg->colorMode | bg->mosaic;

Souvenez-vous cependant de la mise en place du mode graphique. Jusqu'à présent, nous utilisions les modes graphiques 3 et 4 pour afficher des images. Vous devez donc modifier l'instruction de sélection du mode graphique pour activer le mode 2, qui autorise les backgrounds de type rotation.

 
Sélectionnez
REG_DISPCNT = MODE_2 | BG2_ENABLE | OBJ_ENABLE | OBJ_MAP_1D;

Remarquez également la mise en place du drapeau BG2_ENABLE. En omettant ce drapeau, notre background ne pourrait apparaître. Si vous modifiez le numéro de background associé à la structure, pensez également à modifier le drapeau d'activation des backgrounds.

Même si tout a été mis en place correctement jusqu'à présent, notre programme n'a aucune chance d'afficher une carte. Il manque en effet le chargement des données de la carte en mémoire. Le listing deux présente cette étape en détail. Ces quelques lignes chargent dans l'ordre la palette de couleur des tiles, les tiles eux-mêmes (avec des instructions DMA) puis la carte. La division par deux est justifiée par le fait que nos copies agissent sur des segments de 16 bits de données tandis que les zones mémoire sources recèlent des données enregistrées sur 8 bits.

 
Sélectionnez
/* Listing 2 */
for (int i = 0; i < 256; i++)
  palette[i] = tilesPalette[i];

REG_DMA3SAD = (u32) tilesData;
REG_DMA3DAD = (u32) bg2->tileData;
REG_DMA3CNT = tiles_WIDTH * tiles_HEIGHT / 2 | DMA_16NOW;

u16* temp = (u16 *) map;
for (int i = 0; i < 64 * 64 / 2; i++)
  bg2->mapData[i] = temp[i];

4. Téléchargements

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006 Romain Guy. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.