Mes astuces en GFA BASIC, sur ATARI ST
(GfA Basic v3.x) par Dadu, 31/07/1992
Voici des astuces qui ne sont pas marquées dans les bouquins. Pour
plus d'informations, référez-vous à ces mêmes bouquins.
ADRESSES
Pour stocker un écran graphique ou le manipuler sur STF, il
nécessaire que l'adresse de son buffer soit multiple de 256.
Voilà ce qu'il faut:
ecran_phys%=MALLOC(32000) AND &HFFF00
Sans cela, vous aurez droit à de superbes décalages et plantages.
CHARGEMENT DES DONNES
Avec INPUT #1,line$ par ex. L'énorme problème est que lorsque le
GFA rencontre une virgule, il considère que la suite est une autre
ligne. Le seul "remède" est de remplacer la virgule par un autre
caractère peu utilisé (ex: @), et de le remplacer avec une
virgule, après que la ligne ait étée chargée.
DATA
En bout de ligne, on a du mal à mettre un texte avec des espaces.
Ex:
DATA CELA EST UN EXEMPLE,CECI AUSSI !
cela donne:
DATA CELA EST UN EXEMPLE,CECIAUSSI!
Le remède:
DATA CELA EST UN EXEMPLE,"CECI AUSSI !"
Le mieux étant:
DATA "CELA EST UN EXEMPLE","CECI AUSSI !"
EDIT, END
Je préfère EDIT, car l'on retourne dessuite à l'éditeur.
a$=INKEY$
L'ennui avec cette instruction, c'est qu'elle ne renvoie pas les
codes des touches de fonction, de HELP, de UNDO, ...
KEYTEST c'est du pipeau.
Le seul moyen, c'est d'aller voir directement dans le "hard":
t%=PEEK(&HFFFFC02)
On obtient le "scancode". Il ne correspond pas, bien sûr, au code
ascii (ce serait trop simple !).
INLINE
Cette instruction est très utile. C'est un peu comme le INCBIN
sous DevPac. A cette ligne, le .GFA contient une routine en
assembleur.
La routine doit être totalement relogeable, ne pas utiliser de
SECTION BSS (transférer cela dans la SECTION DATA), et se terminer
par un RTS.
Pour éviter les problèmes après la compilation, mieux vaut mettre:
$C+ au début du listing GFA.
MALLOC, MFREE
Ces instructions sont très utiles. Elles permettent de réserver de
la mémoire système (donc pas celle du GFA). L'avantage par rapport
à A$, c'est que MALLOC permet d'allouer des blocs mémoires de plus
de 32 Ko.
MFREE permet de libérer la mémoire allouée (Memory ALLOCation)
avec MALLOC. Il est indispensable avant que le PRG se soit terminé
(EDIT ou END).
RCALL et CALL
Ces instructions permettent d'exécuter des routines assembleur qui
sont en mémoire (INLINE, MALLOC, ...). La meilleure est RCALL car
elle permet simplement de mettre des valeurs dans les registres
(faire un DIM REG%(15)) qui pourront être pris en compte
simplement par la routine asm.
CALL peut faire cela aussi, mais la routine devra récupérer les
valeurs envoyées dans la pile (SP). Et c'est plus compliqué à
faire.
Il vaut mieux ne pas stocker (après l'avoir chargé) une
routine dans un A$ car le GFA peut déplacer la variable A$ en
mémoire pour ses besoins. Alors la routine asm peut ensuite
déconner.
J'ai même vu des fous (un listing de ST Replay 4), qui ont stocké
une routine dans un DIM A%(10000) (10000 étant la taille de la
routine). C'est vraiment le genre de truc à ne jamais faire.
RESERVE
Il faut savoir que d'origine, le GFA BASIC réserve toute la
mémoire disponible pour son propre usage. Donc si vous souhaitez
allouer de la mémoire avec MALLOC, ou utiliser un accessoire, ...,
cela ne sera pas possible par "manque de mémoire".
Cette instruction sert à spécifier la quantité d'octets que le GFA
BASIC réservera pour son propre usage (pour les DIM, et les
variables (A$, C%,...)). Donc le GFA restitue la mémoire au
système. En fait chaque programme en GFA devrait faire cela.
Lorsque le prg est terminé, avant de faire END ou EDIT, il faut
mettre un RESERVE (tout court, sans rien après). Il va restituer
au système la mémoire que le GFA s'était mis de côté.
Généralement, avec RESERVE 70000 on s'en sort dans la pluspart des
cas.
N'oubliez jamais qu'un SGET EXEMPLE$ prends 32000 octets dans la
réserve du GFA. Donc lorsque vous n'avez plus besoin de l'écran
EXEMPLE$, faites un EXEMPLE$=""
TEXTE (dépassement du)
Lorsqu'on fait un PRINT de plus de 80 caractères en moyenne
résolution (ou 40 en basse) tout est normal, le texte continue sur
la ligne suivante. Mais en compilé commencent les problèmes. Le
texte s'arrête à la dernière colonne de la première ligne !.
Il faut rajouter cette ligne (c'est un appel au VT 52):
PRINT CHR$(27);"v";
Elle autorise le dépassement le caractères. Il faut la remettre
après chaque changement de résolution.
SPRITE
Pour afficher un sprite en GFA, c'est à dire un bloc graphique à
travers lequel (couleur transparente: 0) on voit ce qu'il y avait
derrière.
Il faut le dessin du sprite, et son masque (son ombre colorée en
couleur 15). On prends ces dessin (par ex. dans une .PI1 que l'on
a chargé) avec GET, puis:
VSYNC
PUT 32,60,logo_masque$,4
PUT 32,60,logo$,7
TIMER
Il faut le diviser par 200 pour obtenir le nombre de secondes.
old_time%=TIMER
...
time%=(TIMER-old_time%)/200
VARIABLES, MALLOCS, FRE()
Il arrive que le GFA s'emmêle les pédales dans la gestion des
variables, et qu'il ne restitue pas la ram qui était occupée par
des variables.
L'instruction PRINT FRE() indique la mémoire disponible dans la
ram réservée au GFA. Si vous faites PRINT FRE(7) (on peut mettre
n'importe quel chiffre à la place de 7), le GFA va effectuer un
"Garbage Collection", c'est à dire qu'il va faire le ménage dans
les variables (voir paragraphe précédent).
Pour réserver un peu de mémoire facilement avec une variable
pour y stocker des données (c'est plus facile d'y traiter du
texte), on peut faire:
a$=SPACE$(20000)
Mais le mieux est:
a$=STRING$(20000,0) (cela vous évitera des bugs)
VSYNC
Cet instruction permet d'éviter:
o le clignotement lors de l'affichage d'un sprite,
o le décalage d'écran lors d'un changement de résolution (cela ne
marche pas à tout les coups. Turbo ST a tendance à augmenter le
taux d'échec lors des changements de résolution).
POUR ATTENDRE UNE TOUCHE:
J'utilise la routine qui suit. Elle renvoie le code ascii de la
touche dans t%, et le caractère majuscule dans t$. Comme cela
l'utilisateur n'a pas le souci de savoir si le clavier est en
majuscules ou en minuscules.
PROCEDURE t
t%=INP(2)
t$=UPPER$(CHR$(t%))
RETURN
c% c& c| c# TRUE FALSE
Une variable (ex: var) sans rien après son nom est considérée
être: var&
Dans l'ordre des variables qui occupent le plus de place:
c# 8 octets, permet d'atteindre les nombres les plus grands.
c% 4 octets, ne permet d'utiliser que des nombres positifs ou 0.
c& 2 octets, de -65000 à +65000.
c| 1 octets, de 0 à 254.
Le mieux est de prendre l'habitude de toujours rajouter un % après
la virgule. Le % est la taille minimale si l'on veut indiquer une
adresse de la mémoire. Après on peut si l'on veut étudier la
routine de plus près pour voir où l'on peut économiser de la
mémoire.
En fait on n'économise de la mémoire qu'avec les DIM, sinon,
le gain est négligeable. L'avantage c'est que le listing est plus
clair.
TRUE et FALSE sont très clair à utiliser. Ex: gateau!=TRUE La
variable ne peut avoir que 2 états: vrai ou faux. Lorsque le
gâteau aura été mangé, il suffira de mettre gateau!=FALSE
Logiquement la variable gateau ne devrait occuper qu'un bit (1/8
ème d'octet). En fait elle utilise un octet, c'est plus rapide à
gérer pour le GFA.