char
ou de short
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|00|00|00|01|01|01|00|00|00|00|00|00|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|00|01|01|01|01|01|01|00|00|00|00|00|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|01|01|01|01|01|01|01|01|01|01|00|00|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|01|01|01|01|00|00|01|01|01|01|01|00|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|01|01|01|01|00|00|00|01|01|01|01|00|00|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|01|01|01|01|01|01|00|01|01|01|00|00|00|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|01|01|01|01|01|01|01|01|01|01|01|00|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|00|00|00|01|01|01|01|01|01|01|01|01|01|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|00|00|00|01|01|01|01|01|01|01|01|01|01|01|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|00|00|00|00|01|01|01|01|01|01|01|01|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|00|00|00|00|00|00|01|01|01|01|00|00|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |00|00|00|00|00|00|00|00|00|00|00|00|01|00|00|00|00|00|00|00| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+Voici notre plan, en rouge est représentée la zone que l'on désire afficher. Dans cet exemple, seuls deux sprites différents sont utilisés, le sprite n°1 est mis en gras pour une meilleure visibilité. Ce plan pourrait être utilisé dans un RPG, pour représenter par exemple une île entourée d'eau, avec un lac au centre (le sprite 0 serait de l'eau et le sprite 1 serait de la terre).
272 <-----------------> ^ +-----------------+ | | ###### | | | ########## | | | #### ##### | | | #### #### | 160| | ###### ### | | | ########### | | | ########## | | | ###########| | | ######## | | | #### | v +-----------------+Les sprites n°1 seront représentés par '
#
', et les sprites n°0 par '
'.16 <----------------> ^ +----------------+----------------+----------------+--------------- | | | | ^ | | | | | | | | | | | | | | | | | | | 11| | | | | | 16| | 13 | | | | | | | | | |<----------->| | v | | | | | | |-------------+--|-------------+--|-------------+--|-------------+- | | | | | | | | | | | | | | | | | | v +----------------+----------------+----------------+--------------- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |-------------+--|-------------+--|-------------+--|-------------+- | | | | | | | | | | | | | | | | +----------------+----------------+----------------+--------------- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |-------------+--|-------------+--|-------------+--|-------------+- | | | | | | | |Je n'ai représenté qu'une partie de l'écran (en noir). En gris clair, j'ai représenté le grand écran virtuel : en fait, ce sont les limites entre les cases 16x16.
Comment utiliser la librairie dans vos programme ?
Avec TIGCC IDE, ajoutez les fichiers TileMap.a
et Tilemap.h
à votre projet, et tapez #include "TileMap.h"
dans votre fichier source.
Les fonctions de la librairie
Les fonctions fournies par la librairie peuvent se classer en deux catégories : les fonctions de bas niveau (puissantes, mais compliquées à utiliser) et les fonctions de haut niveau (beaucoup plus simple à utiliser, mais très légèrement moins efficaces).
Dans le cas général, les fonctions de haut niveau devraient suffir, mais si vous voulez faire un jeu complexe, et qui nécessite de la puissance ou si vous programmez en assembleur, alors vous devriez utiliser les fonctions de bas niveau.
Il est possible de faire avec les fonctions de haut niveau tout ce que l'on peut faire avec celles de bas niveau à l'exception de l'utilisation des tables de décalages de lignes.
Si vous programmez en assembleur, sachez que les paramètres des fonctions sont passés directement par les registres, reportez vous au header pour connaître les registres coresspondant aux paramètres d'une fonction.
char
ou de short
, à deux dimensions, ayant au minimum 8 lignes et 15 colonnes si on utilise des sprites 16x16, ou 16 lignes et 30 colonnes avec des sprites 8x8.char
pour les sprites 8x8, ou un tableau de 16 short
pour les sprites 16x16, contenant successivement chaque ligne du sprite.char
pour les sprites 8x8 ou 32 short
pour les sprites 16x16 qui est organisé comme ceci : ligne1/plan1, puis ligne1/plan2, puis ligne2/plan1, puis ligne2/plan2, etc... On appelle cela un format entrelacé. Le plan1 peut-être celui correspondant au gris clair au au gris foncé, cela n'a pas d'importance tant que vous respectez la même convention pour les écrans virtuels (voir plus bas).short
à deux dimensions : le nombre d'étape d'animation et le nombre d'animations. Chaque ligne représente une étape, et chaque colonne représente une animation, ainsi l'élément du tableau situé sur la colonne c
et la ligne l
sera le numéro du sprite de la l
ième étape de la c
ième animation.short
, car j'ai pensé que si vous utilisez des tiles animés vous aurez probablement beaucoup de sprites.char
à une dimension, de 128 éléments. Chaque élément représente le décalage individuel horizontal à ajouter à celui de la ligne courante lors de la recopie du grand écran virtuel vers l'écran. Les valeurs autorisées sont comprises entre 0 et 16.short
à une dimension, de 128 éléments. Chaque élément représente la valeur à ajouter à l'adresse source à la fin de chaque ligne lors de la recopie du grand écran virtuel vers l'écran. Toutes les valeurs sont permises, mais faites attention à ne pas sortir du grand écran virtuel.void DrawPlane(short x,short y,Plane *plane,void *dest,TM_Mode mode,TM_Type type);
plane
à partir des coordonnées x
et y
, dans l'écran (virtuel ou non) d'adresse dest
.plane
, type
et mode
ont des types particuliers, voici à quoi ils correspondent :plane
est l'adresse d'une structure de type Plane
, dont voici la définition :
typedef struct { void *matrix; // Matrice de tiles unsigned short width; // Largeur de la map void *sprites; // Tableau de sprites char *big_vscreen; // Grand écran virtuel long mask; // Contient le mask, lorsqu'on veut afficher en mode BLIT long reserved1; // Utilisé en interne (ne pas modifier) short force_update; // Pour forcer l'actualisation du grand écran virtuel. }Plane;
type
indique le type de plan : taille des sprites (8x8 ou 16x16), matrice codée sur des char ou sur des short, utilisation des niveaux de gris ou non. C'est un paramètre de type TM_Type
, ce type étant complexe, regardez dans le header si vous voulez vraiment savoir à quoi il correspond, mais ce n'est pas indispensable pour pouvoir utiliser la fonction, car j'ai défini des macros qui peuvent s'utiliser directement en paramètre (reportez vous à l'annexe à la fin de ce document pour les connaître).mode
permet de spécifier le mode d'affichage : RPLC
, OR
, XOR
, AND
, TRANW
, TRANB
ou BLIT
. Ce paramètre est de type TM_Mode
, ce type est également compliqué, si vous voulez savoir à quoi il correspond, regardez dans le header. J'ai également défini plusieurs macros qui peuvent être utilisées directement en paramètre, reportez vous à l'annexe à la fin de ce document.force_update
de votre Plane
, la fonction DrawBuffer
remettra ce champ à 0 après que l'actualisation ait eu lieu. Il est indispensable de faire ça à l'initialisation, avant que le plane n'ait été affiché.BLIT
, précisez au préalable la valeur du masque que vous voulez dans le champ mask
de votre Plane
.type
et mode
.void DrawAnimatedPlane(short x,short y,AnimatedPlane *plane,void *dest,TM_Mode mode,TM_AnimType type);
plane
à partir des coordonnées x
et y
, dans l'écran (virtuel ou non) d'adresse dest
.plane
est l'adresse d'une structure AnimatedPlane
, voici sa définition :typedef struct { Plane p; void *tabanim; // Matrice d'animations short nb_anim; // Nombre d'animations short nb_step; // Nombre d'étapes d'animation short step; // Numéro de l'étape d'animation courante short step_length; // Durée d'une étape (en nombre d'images) short frame; // Numéro de l'image de l'étape courante }AnimatedPlane;Cette structure contient donc un
Plane
suivi de toutes les informations nécessaires pour l'animer.Plane
ne contiendra pas des numéros de sprites, mais des numéros d'animation, et la fonction ira chercher le numéro de sprite correspondant dans la tableau d'animations tabanim
.mode
est exactement le même que pour la fonction précédente, reportez vous à l'annexe pour connaître toutes ses valeurs possibles.type
fonctionne comme dans la fonction précédente, mais ses valeurs possibles ne sont pas les mêmes, elles sont également données dans l'annexe.RefreshBuffer
RefreshBuffer
servent à mettre à jour le contenu du grand écran virtuel.void Refresh[Gray]BufferXY(short larg,void *tile,void *dest,void *sprts);
Gray
est optionnel, il indique si la fonction est en niveaux de gris ou non.X
indique la taille des sprites et peut prendre les valeurs 16
(sprites de 16x16 pixels) ou 8
(sprites de 8x8 pixels) seulement.Y
indique la taille des tiles de la matrice, peut prendre les valeurs W
(matrice de words [2 octets]) et B
(matrice d'octets).RefreshGrayBuffer16B
.larg
: largeur de la matrice de tiles.tile
: adresse du premier tile (celui dans le coin en haut à gauche) que vous voulez afficher dans le grand écran virtuel.dest
: adresse du grand écran virtuel de destination (il doit faire 5440 octets en noir et blanc, et 10880 octets en niveaux de gris).sprts
: adresse de la liste des sprites du plan.RefreshAnimatedBuffer
RefreshAnimatedBuffer
servent à mettre à jour le contenu du grand écran virtuel tout en animant ses tiles.void Refresh[Gray]AnimatedBufferXY(short larg,void *tile,void *dest,void *sprts,void *tabanim);
Gray
est optionnel, il indique si la fonction est en niveaux de gris ou non.X
indique la taille des sprites et peut prendre les valeurs 16
(sprites de 16x16 pixels) ou 8
(sprites de 8x8 pixels) seulement.Y
indique la taille des tiles de la matrice, peut prendre les valeurs W
(matrice de words [2 octets]) et B
(matrice d'octets).RefreshGrayBuffer16B
.larg
: largeur de la matrice de tiles.tile
: adresse du premier tile (celui dans le coin en haut à gauche) que vous voulez afficher dans le grand écran virtuel. Ce tile ne contiendra pas le numéro du sprite correspondant, contrairement à la fonction précédente, mais il contiendra un numéro d'animation.dest
: adresse du grand écran virtuel de destination (il doit faire 5440 octets en noir et blanc, et 10880 octets en niveaux de gris).sprts
: adresse de la liste des sprites du plan.tabanim
: adresse de la liste des numéros de sprites. C'est un tableau de short
à une dimension. L'élément n
de ce tableau contient le numéro du sprite correspondant à l'étape courante de l'animation n
.char matrix[MAP_WIDTH][MAP_HEIGHT]={...}; // Contient des n° d'animation short anim[NB_ETAPES][NB_ANIM]={...}; // Contient des n° de sprites short sprts[NB_SPRITES][16]={...}; // Contient les sprites (en noir et blanc) void _main(void) { char big_vscreen[BIG_VSCREEN_SIZE]; short old_sr,n_frame,n_etape; old_sr=OSSetSR(0x0200); n_frame=n_etape=0; do { if(!n_frame) // Si on est à la première image d'une étape, on rafraichit RefreshAnimatedBuffer(MAP_WIDTH,matrix,big_vscreen,sprts,anim[n_etape]); DrawBuffer_RPLC(big_vscreen,0,0,LCD_MEM); if(!(++n_frame % 16)) // Toutes les 16 images, on change d'étape d'animation n_etape = (n_etape+1) % NB_ETAPES; }while(!_keytest(RR_ESC)); OSSetSR(old_sr); }On note que la libraire est mal utilisée car les coordonnées passées à la fonction DrawBuffer sont nulles toutes les deux. C'est juste pour que l'exemple soit plus court.
anim
.anim
devient trop redondant. Dans ce cas, procédez autrement, n'utilisez qu'une liste de numéros de sprites (plutôt que NB_ETAPES
listes comme dans l'exemple), et mettez à jour directement la liste quand vous le voulez.DrawBuffer
DrawBuffer
recopient le contenu du grand ecran virtuel en le scrollant, vers un écran de taille normale (virtuel ou non).void Draw[Gray]Buffer[89]_MODE(void *src,short x,short y,void *dest);
Gray
est optionnel, il indique si la fonction est en niveaux de gris.89
est également optionnel, il permet de ne recopier vers la destination que la partie visible par une TI-89 (c'est donc beaucoup plus rapide).MODE
spécifie le mode d'affichage, il peut prendre les valeurs RPLC
, OR
, XOR
, AND
, TRANW
, TRANB
ou BLIT
. La description des différents modes d'affichage est disponible en annexe.RPLC
, et en niveaux de gris, on utilisera la fonction DrawGrayBuffer_RPLC
.
: adresse du grand écran virtuel que l'on souhaite afficher.x
: décalage horizontal à effectuer, en pixels (Attention : doit être compris en 0 et 31).y
: décalage vertical à effectuer, en pixels (Attention : doit être compris entre 0 et 31).dest
: adresse du l'écran de destination (sa taille doit être de 3840 octets en noir et blanc, et de 7680 octets en niveaux de gris).BLIT
sont légèrement différentes des autres, elles prennent un paramètre supplémentaire, le masque. Leurs prototypes sont de la forme :void Draw[Gray]Buffer[89]_BLIT(void *src, short x, short y, long mask, void *dest);
mask
contient la valeur du masque. Attention : ce masque est sur 32 bits, afin de permettre une plus grande souplesse d'utilisation, mais cela peut être à l'origine de problèmes si vous n'y faites pas attention.DrawBufferWithShifts
DrawBufferWithShifts
recopient le contenu du grand écran virtuel en le scrollant, vers un écran de taille normale, mais contrairement à la fonction précédente, il est possible de spécifier la valeur du décalage horizontal pour chaque ligne, et il est aussi possible de rajouter des décalages verticaux entre les lignes.void Draw[Gray]BufferWithShifts[89]_MODE(void *src,short x,short y,void *dest,char *dh,short *dv);
Gray
est optionnel, il indique si la fonction est en niveaux de gris.89
est également optionnel, il permet de ne recopier vers la destination que la partie visible par une TI-89 (c'est donc plus rapide).MODE
spécifie le mode d'affichage, il peut prendre les même valeurs que pour DrawBuffer
, c'est-à-dire : RPLC
, OR
, XOR
, AND
, TRANW
, TRANB
ou BLIT
. La description des différents modes d'affichage est disponible en annexe.src
: adresse du grand écran virtuel que l'on souhaite afficher.x
: décalage horizontal, en pixels (Attention : doit être compris entre 0 et 15).y
: décalage vertical, en pixels (Attention : doit être compris entre 0 et 15).dest
: adresse de l'écran de destination.dh
: adresse de la table de décalage horizontal. Lors de la recopie du grand écran virtuel vers la destination, pour chaque ligne, on ajoutera la valeur correspondante de la table à x
pour avoir le décalage horizontal de la ligne. Leur somme est comprise entre 0 et 31.dv
: adresse de la table de décalage vertical. Lors de la recopie du grand écran virtuel vers la destination, à la fin de la recopie de chaque ligne, on ajoutera la valeur correspondante de la table au pointeur qui contient l'adresse de la source (le grand écran virtuel à afficher). Ainsi pour afficher deux fois une même ligne, par exemple, il vous suffit de mettre la valeur -34
quelque part dans le tableau (et pour sauter une ligne, mettez 34
).BLIT
, comme pour DrawBuffer
, sont différentes en réalité, elles prennent un paramètre masque
supplémentaire, donc leurs prototypes sont de la forme :void Draw[Gray]BufferWithShifts[89]_BLIT(void *src,short x,short y,long mask,void *dest,char *dh,short *dv);
mask
contient la valeur du masque.RPLC
OR
XOR
AND
BLIT
mask
du Plane (ou bien le mask peut être passé directement en paramètre avec les fonctions de bas niveau). Un ET logique est effectué entre le mask
et la destination, puis le plan est affiché en mode OR. Ce mode peut être utile pour faire des effets de transitions.TRANW
TRANB
Matrice de char | Matrice de short | |||
---|---|---|---|---|
Sprites 8x8 | Sprites 16x16 | Sprites 8x8 | Sprites 16x16 | |
Noir et blanc | TM_8B | TM_16B | TM_8W | TM_16W |
Niveaux de gris | TM_G8B | TM_G16B | TM_G8W | TM_G16W |
Matrice de char | Matrice de short | |||
---|---|---|---|---|
Sprites 8x8 | Sprites 16x16 | Sprites 8x8 | Sprites 16x16 | |
Noir et blanc | TM_A8B | TM_A16B | TM_A8W | TM_A16W |
Niveaux de gris | TM_GA8B | TM_GA16B | TM_GA8W | TM_GA16W |
RPLC | OR | XOR | AND | BLIT | TRANW | TRANB | ||
---|---|---|---|---|---|---|---|---|
Noir et blanc | TI92+ | TM_RPLC | TM_OR | TM_XOR | TM_AND | TM_BLIT | ||
TI89 | TM_RPLC89 | TM_OR89 | TM_XOR89 | TM_AND89 | TM_BLIT89 | |||
Niveaux de gris | TI92+ | TM_GRPLC | TM_GOR | TM_GXOR | TM_GAND | TM_GBLIT | TM_GTRANW | TM_GTRANB |
TI89 | TM_GRPLC89 | TM_GOR89 | TM_GXOR89 | TM_GAND89 | TM_GBLIT89 | TM_GTRANW89 | TM_GTRANB89 |
BLIT
.
A faire
Dans une éventuelle future version, voici ce que je rajouterais (par ordre de priorité) :
Contact
Pour toute remarque, suggestion, report de bug, question, etc...
Julien Richard-Foy
julien.rf@wanadoo.fr