[HP49g] Manipulation de Grobs et de sprites

par HPThifu



Introduction

Dans un premier tutorial, nous avons vu le fonctionnement de la mémoire graphique de la HP49g, ainsi que la manière d'agir dessus pour remplir l'écran d'un motif répétitif. Le but de ce tutorial est de présenter l'utilisation d'images plus complexes.
Nous pouvons distinguer deux types principaux d'images:

( Les appellations GROB et SPRITE que j'utilise ici ont pour seul but de clarifier la lecture de la suite du tutorial, car 'GROB' est la contraction de 'GRaphic OBject', et donc désigne tous les objets graphiques, dont les sprites. Les sprites sont donc un sous-ensemble des grobs. )


Affichage d'un GROB à l'écran

Le but de cette première partie est d'afficher sur l'écran une image. Nous allons commencer par une image qui remplira tout l'écran (131x64 pixels).


Comme nous l'avons vu dans le premier turorial, la mémoire graphique contient 5 pixels en plus dans chaque rangée, afin d'obtenir pour l'affichage un nombre rond d'octets. Par conséquent, chaque ligne fait 136 pixels de long, soit 17 octets.
Pour éviter les problèmes de décalage lors de la lecture en mémoire de l'image, les dimensions de celle-ci doivent être 136x64 pixels. Je vous conseille pour éditer les images la librairie Paint de Fabien VIGER disponible sur hpcalc. Elle offre de nombreuses fonctions non disponibles sur la HP par défaut (remplissage, ...).
Tapez HEX pour être en mode hexadécimal. Entrez #88, puis #40. Ensuite tapez BLANK. Cela crée normalement un GROB tout blanc sur le niveau 1 de la pile, de dimensions #88hx#40h pixels, soit 136x64 pixels. Vous pouvez donc lancer Paint pour l'éditer, puis le sauvegarder dans une variable ('MonGrob', par exemple).

L'algorithme est très simple: on utilise les deux registres d'adresse du processeur D0 et D1. L'un pointe sur le début de la mémoire graphique, l'autre sur le début de l'image, puis on copie par paquets de 8 octets (le contenu d'un registre de travail A,B,C ou D). On aura donc (136*64) pixels, soit (136*64)/8 octets, soit (136*64)/(8*8) copies à effectuer, soit 136 répétitions de la boucle.



Nous allons intégrer les données de l'image dans le programme lui-même, au moyen de la fonction MACRO de l'assembleur MASD. On a sauvegardé l'image sous un nom précis (ici, 'MonGrob'), et l'on veille à ce que cette variable soit dans le même répertoire que le code source du programme. Puis, dans le code source, on rappelle les données de l'image avec la syntaxe suivante:
/MonGrob
L'inconvénient d'intégrer les images directement dans le programme est d'augmenter la taille de celui-ci. En revanche, cela permet d'obtenir un seul fichier (et évite donc le risque de suppression accidentelle de l'image nécessaire au bon fonctionnement du programme). Cela permet aussi d'éviter que quelqu'un ne modifie l'image de VOTRE application :).

Ceci fournit l'occasion de découvrir une astuce fréquente lors de l'insertion d'objets dans un programme. Comment obtenir l'adresse exacte de l'objet inséré? On utilise pour cela le saut GOSUBL. En effet, à l'instar du GOSUB du langage BASIC, le GOSUBL sauvegarde l'adresse du départ du saut pour pouvoir y revenir une fois la sous-fonction terminée (par un RTN, un RTNYES...).

Lors d'un saut avec retour (GOSUB, GOSUBL, GOSBVL), le processeur stocke l'adresse de l'instruction suivante sur une sorte de petit pile, appelée 'Return Stack', ou RSTK.

Un exemple: (les adresses augmentent de 5 en 5 pour simplifier; ce n'est pas le cas en réalité.)
3FA00 ...blablabla... % Code précédent
3FA05 GOSUBL SousPartie % Saut. RSTK contient donc 3FA0A
3FA0A A=A&B A % Suite du programme
...
......
3FA60 *SousPartie % Label de sous-fonction
3FA65 ...blablabla... % La sous-fonction de elle-même
3FA70 RTN % L'exécution reprend donc en 3FA0A


Bon, ça va ? On va donc pouvoir récupérer l'adresse du début de l'objet:
GOSUBL Suite % Le saut, qui sauvegarde l'adresse suivante, c'est-à-dire celle du début de l'objet
/MonGrob % Insertion de l'objet
*Suite % Le label du saut
C=RSTK % On récupère sur la 'Return Stack' l'adresse de l'objet
D1=C % D1 pointe donc sur le début de l'image


Muni de la théorie... Taïaut ! On y va:

!NO CODE % Directives au compilateur MASD
!RPL %
:: % Début du programme
%
TURNMENUOFF % On enlève les menus
%
CODE % Début de la partie assembleur
SAVE % Sauvegarde l'état interne de la HP (équivalent à GOSBVL SAVPTR)
%
GOSUBL Suite % Le saut, qui sauvegarde l'adresse suivante, c'est-à-dire celle du début de l'objet
/MonGrob % Insertion de l'objet
*Suite % Le label du saut
C=RSTK % On récupère sur la 'Return Stack' l'adresse de l'objet
D1=C % D1 pointe donc sur le début de l'image
%
SCREEN % Renvoie dans A.A l'adresse de la mémoire graphique...
D0=A % ...et D0 point dessus.
% On va donc copier de D1 vers D0
LC 00087 % Compteur de boucle: 136 en hexadécimal: #88h, moins 1: #87h
{ % Début du bloc
A=DAT1 16 % On prend 16 quartets (8 octets, 64 bits) à l'adresse D1
DAT0=A 16 % et on les colle à l'adresse D0
D0=D0+16 % On pointe 8 octets plus loin sur l'écran
D1=D1+16 % On pointe 8 octets plus loin dans l'image
C=C-1 A % On décrémente le compteur de boucles
UPNC % Et on voit si on boucle
} % Fin de bloc
%
LOAD % On restaure l'état interne
ENDCODE % Fin du code assembleur
%
WaitForKey % On attend une pression de touche
DROP % Ménage...
DROP %
%
; %
@ % Fin de code source


L'image va rester affichée tant que vous n'avez pas appuyé sur une touche. Pour modifier l'image, modifiez le grob 'MonGrob', puis recompilez le programme avec la commande ASM.

Bon, j'espère que ce petit aperçu de l'utilisation d'une image en assembleur vous a un peu clarifié les idées...
La documentation sur les sprites arrive bientôt, ainsi qu'éventuellement la gestion des touches.

Pour de plus amples informations sur la manière d'assembler un programme, je vous conseille mon tutorial (partie 1) :), disponible sur hpcalc et bientôt sur hp-network, ainsi que la documentation officielle de l'assembleur intégréà la HP: MASD, doc disponibles sur ces deux sites.

Pour éditer confortablement les sources, le meilleur traitement de texte est sans contexte Emacs (v1.07) disponible sur hpcalc.

Je suis ouvert à toutes les suggestions, et j'essaierai de répondre le plus rapidement possible à vos e-mails.

HPThifu



Pour tous commentaires :|, encouragements :), ou critiques :(, merci de m'envoyer un e-mail
© HPThifu 2001