# Un scrolltext en GFA Basic

Par The Beast
beast_typhoon@hotmail.com

Ce modeste article s'adresse surtout aux débutants en GFA (hé oui, il en reste encore !) ayant déjà quelques notions ainsi qu'à ceux qui sont intéressés par la programmation de démos oldschool. Pour les nouveaux, un scrolltext est tout simplement un texte qui défile en utilisant une fonte, le plus souvent au format Degas. Je vous propose de programmer un scrolltext horizontal avec une fonte en 16x16, le tout en 16 couleurs.

Avis aux graphistes

Avant d'entrer dans le vif du sujet, je voudrais m'adresser aux graphistes qui dessinent des fontes. La plupart des fontes que j'ai vues commencent par les 26 lettres de l'alphabet et finissent soit par les chiffres, soit par la ponctuation. Il faut savoir qu'il est bien plus pratique pour un codeur d'avoir les caractères de la fonte dans l'ordre des caractères ASCII du ST. Cela va du caractère 32 (espace) au 91 (le Z si je ne m'abuse). Ce qui donne ceci :

         !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ

N'oubliez pas qu'il y a le caractère "espace" juste avant le point d'exclamation. Bien que certaines fontes ne comportent que des lettres, le minimum vital est quand même d'avoir les lettres, les chiffres et un minimum de ponctuation (point, virgule, tiret, point d'exclamation, point d'interrogation, deux-points, les deux parenthèses et l'apostrophe). Si le graphiste ne veut pas dessiner tous les caractères, il doit laisser un blanc à la place.

Le principe

Avant de passer au source commenté, je vais vous expliquer en gros MA façon de faire un scrolltext. Je sais bien que ce n'est pas LA meilleure façon de procéder, mais elle marche et elle est assez rapide. Ça fait un petit bout de temps que je programme en GFA et je n'ai jamais fait un seul scrolltext. J'ai voulu faire un scrolltext qui se déplace par pas de 4 pixels, pour que ce ne soit ni trop lent, ni trop rapide. Chaque caractère à afficher doit être coupé en tranches de 4 pixels de large. Chaque tranche est affichée là où l'on veut que le scrolltext commence, et puis on décale la partie de l'écran qui doit accueillir le scroll pour afficher le morceau suivant. Et ainsi de suite. J'utilise l'écran physique et l'écran logique (voir l'excellent article d'Exyl à ce sujet).

J'utilise l'instruction RC_COPY, qui est une instruction puissante en GFA. Le mieux est encore d'utiliser BMOVE, mais il est moins pratique à mettre en oeuvre. En revanche, évitez GET et PUT, ces instructions prennent trop de temps machine.

Le listing du scrolltext

Vous devriez normalement retrouver le listing largement commenté, son inline (la fonte) ainsi que la version compilée dans une archive accompagnant le Toxic Mag.

         '
         ' Scrolltext en 16x16 - aout/septembre 1999
         ' Par The Beast/Typhoon pour le Toxic Mag 18
         ' Fonctionne en ST basse
         '
         RESERVE 5000
         INLINE fonte%,7520

La fonte en question est bien une image Degas de 32 Ko mais je l'ai découpée avec NeoChrome Master pour qu'elle prenne moins de place. Mine de rien, j'ai économisé pratiquement 25 Ko. Si vous préférez utiliser l'image d'origine de la fonte, voici ce qu'il aurait fallu mettre :

    INLINE image%,32034
    fonte%=image%+34
    ~XBIOS(6,L:image%+2)

La dernière ligne, c'est pour la palette de couleurs (voir plus loin). On continue :

         @start
         DO
           @texte("[[[[[[[[[[[[[[[[[[[[[[[[ ATTENTION VOICI UN SCROLLTEXT QUI PARLE POUR RIEN DIRE ! ",320,100)
         LOOP UNTIL PEEK(&HFFFFFC02)=57
         @fin

Notez que vous pouvez changer le texte ainsi que la position du scrolltext (veillez à n'utiliser que des majuscules). Voilà pour la partie principale du programme, il n'y a pas grand chose à rajouter. Voyons maintenant les procédures...

La procedure "start"

         PROCEDURE start
           old_phy%=XBIOS(2)
           old_log%=XBIOS(3)
           palette%=MALLOC(32)
           super%=GEMDOS(32,L:0)
           BMOVE &HFFFF8240,palette%,32

Ici, on stocke les adresses des écrans physique et logique pour les restituer à la fin du programme. La palette est sauvegardée. A noter que tout le programme tourne en superviseur.

           ecran1%=MALLOC(32256)
           buffer1%=AND(ADD(ecran1%,256),&HFFFFFF00)
           ecran2%=MALLOC(32256)
           buffer2%=AND(ADD(ecran2%,256),&HFFFFFF00)

Là, c'est un peu particulier. Sachez que sur STF, la mémoire écran ne peut pas être placée n'importe où, elle doit se trouver à une adresse multiple de 256. Ce n'est pas le cas sur STE, ce qui permet d'avoir des scrollings plus fins. La seconde ligne fait en sorte que la variable ecran1% pointe sur une adresse multiple de 256. Je vous encourage vivement à faire ceci. Pour en savoir plus, reportez-vous à l'article d'Exyl dans ce numéro.

           ~XBIOS(5,L:ecran2%,L:ecran1%,W:-1)
           CLS
           BMOVE ecran2%,ecran1%,32000

On déclare les deux écrans et on les nettoie à grand coup de CLS.

           pal$=SPACE$(32)
           pal$=MKI$(&H0)+MKI$(&HF0F)+MKI$(&H577)+MKI$(&H467)
                +MKI$(&H356)+MKI$(&H245)+MKI$(&H134)+MKI$(&H23)
                +MKI$(&H12)+MKI$(&H464)+MKI$(&H353)+MKI$(&H242)
                +MKI$(&H131)+MKI$(&H20)+MKI$(&H10)+MKI$(&H677)
             ~XBIOS(6,L:V:pal$)
         RETURN

Là, on installe la palette. Cette dernière n'étant pas présente dans le fichier INLINE, je l'ai rajoutée à la main. NeoChrome Master a aussi une option pour sauver la palette sous forme de source assembleur, facilement réutilisable en GFA.

Les procédures "texte" et "obtenir"

         PROCEDURE texte(txt$,posx&,posy&)
           longueur%=LEN(txt$)
           FOR i&=1 TO longueur%
             ch&=ASC(MID$(txt$,i&,1))
             @obtenir(ch&)

Après avoir calculé la longueur du texte, on recherche le code ASCII de chaque caractère, l'un après l'autre, et l'on va demander à obtenir son équivalent dans la fonte. Une autre méthode consiste à précalculer la place de chaque caractère dans un tableau afin de gagner un peu de temps machine (je ne l'ai pas fait car je ne suis pas sûr que cela économise tellement de temps machine).

             FOR j&=1 TO 4
               RC_COPY fonte%,x&+(j&*4)-4,y&,4,15 TO ecran1%,posx&-4,posy&

Les lettres sont affichées par pas de 4 pixels. On coupe tous les caractères par tranches de 4. Chaque caractère faisant 16 pixels de long, il faut donc faire 4 découpages par caractère. Chaque bloc est ainsi affiché en bout d'écran, prêt à être déplacé pour laisser la place au suivant.

               IF PEEK(&HFFFFFC02)=56
                 CARD{&HFFFF8240}=&H404
               ENDIF
               VSYNC
               CARD{&HFFFF8240}=&H0

Si l'on presse la touche ALTERNATE, la couleur du fond devient violette, sinon elle reste noire. En gros, c'est une technique qui sert à visualiser le temps machine occupé par la routine. A noter que CARD est bien plus rapide que SETCOLOR.

               RC_COPY ecran1%,4,posy&,posx&-4,15 TO ecran2%,0,posy&
               SWAP ecran1%,ecran2%
               ~XBIOS(5,L:ecran1%,L:ecran2%,W:-1)

On déplace d'un cran (c'est-à-dire de 4 pixels) vers la gauche tous les caractères déjà affichés. Notez bien que la copie se fait dans le second écran. Il suffit ensuite de mettre un p'tit coup d'XBIOS 5 et le tour est joué ! Avec cette méthode, on ne peut utiliser qu'une fonte de 32x32 maximum ; car avec une fonte de 64x64 et plus, des bugs dans l'affichage graphique apparaissent. Il faudrait alors utiliser BMOVE, un peu plus compliqué à mettre en oeuvre.

             NEXT j&
             EXIT IF PEEK(&HFFFFFC02)=57

Le scrolltext peut être interrompu en appuyant sur ESPACE.

           NEXT i&
         RETURN
         PROCEDURE obtenir(ch&)
           IF ch&<=51            ! code ASCII inférieur ou égal à 51
             x&=(ch&-32)*16
             y&=0
           ELSE IF ch&=>72       ! code ASCII supérieur ou égal à 72
             x&=(ch&-72)*16
             y&=32
           ELSE                  ! code ASCII compris entre 50 et 71
             x&=(ch&-52)*16
             y&=16
           ENDIF
         RETURN

Ces dernière lignes ont pour but de déterminer les coordonnées de chaque caractère de la fonte. Les variables x& et y& vont ainsi indiquer à la routine de scrolltext où trouver les caractères dont elle a besoin.

La procédure "fin"

         PROCEDURE fin
           CLS
           ~XBIOS(5,L:old_log%,L:old_phy%,W:-1)
           BMOVE palette%,&HFFFF8240,32
           ~GEMDOS(32,L:super%)
           ~MFREE(ecran2%)
           ~MFREE(ecran1%)
           ~MFREE(palette%)
           RESERVE
           EDIT
         RETURN

Cette sous-routine sert à rendre la main au système d'exploitation de la façon la plus propre possible. Dans l'ordre : nettoyage de l'écran, restitution de l'écran logique et de l'écran physique, remise en état de la palette et nettoyage de la mémoire. Ne pas oublier non plus de se remettre en mode utilisateur. Fini !

Les limites

J'ai essayé cette routine sur un Falcon et un STE. J'ai quand même remarqué un truc très désagréable : si vous démarrez ce petit programme dans le dossier AUTO depuis un STE (et peut-être depuis un STF aussi), ça rame ! Un scrolltext en 16x16 va prendre presque 80% du temps machine, alors que depuis le bureau GEM, il ne va en utiliser que 10% environ. A quoi est-ce dû ? Je n'en suis pas sûr, mais je crois qu'il y a une histoire de blitter derrière tout ça. Mais en revanche, ça passe nickel sur Falcon, que ce soit en AUTO ou depuis le bureau.

Hasta la vista, baby !

J'en ai terminé pour cette fois. Si vous voulez améliorer les routines de scrolltext, n'hésitez pas à me faire parvenir vos programmes compilés ou bien, si vous êtes d'accord, vos sources (je les mettrai dans le prochain Toxic, avec votre autorisation). Mais attention, pas de routines en assembleur dans un INLINE ! Tout doit être fait en GFA ! Et pas d'instructions du style CARD ou POKE pour déplacer le scrolltext, c'est de la triche puisque ça équivaut à une instruction MOVE en assembleur ! 8-)