CODING ★ DE L'ARCADE A L'ACTION ★

De l'Arcade de l'Action n°32

Il y a des choses qui ne se disent pas. Certains les nomment tabous, histoire de cacher leur ignorance, et d'autres ne soupçonnent même pas leur existence, alors pensez-vous...

Il s'agit de la perle rare qui fera de vos animations saccadées et clignotantes de vrais dessins animés. Ça vous tente?

Mettons tout de suite les choses à leur place. Je ne veux pas me faire passer pour le dieu des CPC (genre M. Chaitou), car comme tout programmeur j'ai mes lacunes, et mes connaissances. C'est ainsi que je remarquais depuis de années (et un peu partout) une instruction qui paraît-il rend toutes les animations super fluides. N'estce pas votre cas?

AH BON!

C'est le Frame du Basic ou le &BD19 en Assembleur. A la lecture des manuels, cela paraît très alléchant mais personne jusqu'à ce jour ne s'est donné la peine de l'expliquer en détail, d'où l'inévitable déception de ceux qui s'y sont frottés. Nous allons ensemble, à raide de mes potes, réparer cette lacune (c'est pour cela que l'on s'appelle Cent Pour Cent, non ?).

LA DISTRIBUTION

Avant toute chose, passons aux politesses qui caractérisent la noblesse de notre âme. Or donc je vous présente mes potes. Le premier est Manu du déjà célèbre Logon Système (qui, au cas où vous l'ignoriez, est un groupe de sympathiques jeunes gens venant des quatre coins de l'Hexagone dans le but de faire des démos vachement pointues sur CPC) avec qui nous avons pris notre temps pour vous sortir ces deux pages (après de longues heures de discussions et d'essais foireux sur nos CPC, argh...). Notre travail devrait logiquement enlever ce voile gris posé depuis trop longtemps sur le rafraîchissement de l'écran.

Le second est EXXOS II, alias Thibault Bouchett qui nous donne sa version pour animer les sprites en utilisant la pile de l'ordinateur et plein de petits trucs sympa pour aller de plus en plus vite (vous retrouvez Thibault chez Franck le pas beau, il est en plus le cousin de l'auteur du méga listing du mois de janvier, mais chut, c'est une surprise).

BALAYER
POUR MIEUX VOIR

Vous savez tous que les données qui s'affichent à l'écran sont stockées sous forme binaire dans les 16 Ko supérieurs de la Ram (de &C000 à &FFFF). Si on laissait les choses telles quelles, rien n'apparaîtrait à l'écran. Pour remédier à cela, les données en Ram sont balancées au moniteur cinquante fois par seconde. (c'est le balayage ou rafraîchissement de l'écran).

Suivons, pour mieux comprendre, une animation en analysant de près son parcours.

Dans un premier temps, la mémoire écran (et non pas l'écran en tant que moniteur) est rempli avec les valeurs formant le sprite. Un instant plus tard, le balai écran se met au boulot. Il se dit: «tiens, et si j'envoyais ce beau monde à l'écran, histoire de ne pas laisser le pauvre gars qui me regarde dans le noir, hmmm ?»
C'est ainsi que vous verrez un beau dragon (ou je ne sais quelle bestiole) apparaître dans toute sa splendeur.
Quelques temps plus tard, le balai repasse et réaffiche les valeurs et ainsi de suite, tant que....

Le programmeur décide de déplacer le méga sprite un octet à gauche. Il l'efface (c'est cool car le balai n'est pas encore passé, donc l'effacement n'est pas encore visible pour le joueur) et le réaffiche à sa nouvelle position. Manque de bol, lors du réaffichage, le balai passe par là et...

C'EST LE CACA

Car la partie haute du sprite réaffiché apparaît correctement, alors que le reste n'est que trace du premier affichage, donc décalé d'un octet à droite. Il va de soit que si la routine d'affichage est synchronisée avec la fréquence de balayage, ce décalage ou clignotement apparaîtra toujours au même endroit (le plus souvent vers le haut de l'écran).
Pour remédier à cela, il existe plusieurs solutions. On peut, par exemple, optimiser ces routines d'animations de telle sorte qu'elles durent moins d'un trois-centième de seconde (ce qui évite par la même occasion les clignotements tant redoutés des débutants). Il suffit alors de se synchroniser avec le balai et le tour est joué. Ce n'est pas évident, surtout pour de gros sprites mais pas infaisable. L'autre solution est de travailler sur deux écrans (comme dans le jeu AMC) mais, je vous l'accorde, cette fois c'est vraiment pas évident.

MAIS COMMENT MARCHE CET ASPIRATEUR?

Sous Basic, on peut l'appeler par l'instruction FRAME (pas sur les 464) ou par le vecteur &BD19. La routine attend jusqu'au déclenchement du balai et vous rend la main ensuite (d'où le ralentissement dans vos déplacements). A partir de là, les choses deviennent simple. En effet, si vous travaillez avec une routine rapide, rien ne vous empêchera de l'appeler après le BD19, cela ne posera aucun problème.

Pour les puristes, voici la routine RAM qui peut être écrite directement pour gagner les quelques millisecondes perdues par les CALL, RET, etc.

     LD B,#F5
ATT: IN A,(C)
     RRA
     JR NC,ATT

Prenons l'exemple le plus foireux sur nos machines, les scrollings. Si on le place en bas (ou au milieu dans le cas d'une bonne programmation) tout reste parfait. Par contre, si le scroll doit se faire en haut de l'écran, le résultat laissera à désirer. Dans ce cas, on se synchronise avec le balai, non pas en haut de l'écran mais plus bas que le scrolling. Il faut alors attendre (mais dis-moi m'sieu, comment qu'est-ce que j'fais pour attendre un tout petit peu, humm ?)

C'est l'instruction HALT qui vous sauvera. Elle attend une interruption (300e de seconde). On appelle le &BD19, le premier HALT passe dans la routine (car elle est exécutée instantanément), le second attend le balai plusieurs lignes plus bas et c'est le moment pour balancer la routine. Capito ?

Pour en temps d'attente entre deux lignes est de 64 NOP. La preuve, les moniteurs sont dotés de 625 lignes (divisées par deux dans le cas de nos bécanes, donc 312,5 lignes réelles). Le temps que prend le micro pour exécuter un NOP est d'1 millionième de seconde. 64 * 312,5 = 2 0000. Cela fait bien un cinquantième de seconde, le temps pour le balai de faire son tour.

LE CADEAU DE THIBAULT

C'est, une petite routine de sprites de derrière les octets que vous modifierez à votre convenance. Sachez apprécier et consommez sans aucune retenue. Elle utilise la pile de l'ordinateur pour afficher les octets à l'écran.

Dans un premier temps, on note l'adresse d'appel des interruptions, que l'on garde bien au chaud en RST38 (cela après les avoir désactivés). Le code &C9 c'est pour le RET et &FB pour EI qu'on place en &38 (l'adresse qui est appelée tous les trois centièmes de seconde).

On fait pointer la pile sur les données du sprite à afficher après l'avoir mis au chaud également alors qu'HL pointe sur l'écran. Le registre BC contient dans B la largeur du sprite et dans C sa hauteur.

Les trois lignes qui suivent, vous les gardez bien au chaud, on en parlera plus tard.

SRL B effectue une rotation à droite du registre B, en deux mots B est divisé par deux (et ça fait cinq). Pour quoi ? Lors de l'affichage, on utilisera des POP qui désempilent comme vous le savez, des registres 16 bits (donc, deux octets). C'est ainsi qu'un sprite. de 8 octets de long sera popé  (si je puis m'exprimer ainsi) 4 fois.
A partir de là, B contient le nombre de POP à faire par ligne. On pourrait le sauver par un PUSH BC, mais l'accu restant inutilisé durant les opérations, on le met au boulot avec comme tâche de sauver le registre B (pour nous, LD A,B revient au PUSH BC classique). Le premier POP, E contient le premier octet du sprite et D le second. On les place à l'écran par les quatre lignes suivantes. Voici un truc assez étrange dans l'organisation de la mémoire écran.

Imaginez HL pointant quelque part dans cette zone. Pour se déplacer à droite, on incrémente ce registre ( INC HL ) ? Eh bien mes amis sa chez qu'incrémenter L suffit car il n'y aura jamais de débordement (sauf dans quelques rares cas d'écrans reformatés).

POUR CASSER LE GROS BLOC

On boucle sur l'ensemble des mots (double octet) de la ligne et vient ensuite le fameux &BC26. Pour le comprendre, suivez mon raisonnement.

Dans un cas classique, on sauve au départ l'adresse écran que l'on ressort en fin de transfert d'octet. On calcule l'adresse se trouvant juste en dessous par un BC26 ou les petites routines que vous avez vues les mois précédents. Cette fois, on ne sauve rien du tout, on fait les transferts et, avant d'additionner le &800 à HL, on retire les octets déplacés. Cela donne HL = HL - 12 (le 12 étant une pure fiction de ma part), suivi de ADD HL,&800 ou mieux encore ADD HL,&800-12 (&800-12=&7F4). C'est ainsi que l'on voit DE accompagné d'un &0700, ce qui nous laisse la place pour réajuster le tire en plaçant la bonne valeur dans E (qui n'est absolument pas égale à zéro comme on pourrait le croire sur le listing). C'est le rôle des trois lignes qui étaient restées au chaud tout à l'heure. Le reste n'est que remise en place de la pile et des interruptions.

;
        ORG 40000
;
        DI
        LO      HL, (&38)       ;mais, qu'est-ce ti di dou dou
        LD      (RST38),HL      ;place au chaud .
        LD      HL,&C9FB        ;RET EI
        LD      (&38),HL        ;et v'lan
        LD      (PILE),SP       ;OU est la pile?
        LD      SP,(ADRSPR)     ;l1lerci je note
        LD      HL,(ADDECR)     ;voici l'ecran
        LD      BC,(CARACT)     ;voici la longueur et hauteur du
sprite
        LD      A,B             ;; comme un PUSH
        NEG                 ;   ;; Pour le BC26 (0800h-longueur du sprite)
        LD      (MODIFI+01),A   ; recitifie le BC26
        SRL     B             ;  ; div  par deux
RAMBC1  LD      A,B             ;; on stock dans A
RAMBC2  POP     DE             ; ; 2 premier octet a l'ecran
        LD      (HL),E          ; et de d'un
        INC     L             ;  ; c'est mieux que INC HL
        LD      (HL),0          ; et de deux
        INC     L             ;  ; et en plus ca marche
        DJNZ    RAMBC2          ; longueur/2 ?
        LD      B,A             ;; comme un POP
MOOIFI  LD      DE,&700         ;; D=7, mais E n'est pas a 0
        ADD     HL,DE           ;; BC26 de POUM
        JR      NC,RAMBC3
        LD      DE,&C050
        ADD     HL,DE
RAMBC3  DEC     C             ;  ;hauteur OK ?
        JP      NZ RAMBCl       ;ah bon, et ben au boulot
;
        LD      SP,(PILE)       ;je reprends ma pile
        LD      HL, (RST38)     ;et les inters
        LD      (&38),HL        ;je remets tout en place
        EI                     ; ;OK pour les inters
        RET                 ;   ;;salut
;
PILE    DW      0             ;  ;je stocke la pile
RST33   DW      0             ;  ;et l'adresse des inters
ADDECR  DW      &C000           ;;je pointe a l'ecran
ADRSPR  DW      10000           ;;et moi sur la table du sprite
CARACT  DB      16             ; ;moi je suis 18 hauteur
        DB      4             ;  ;et moi 18 largeur


Poum et ses potes, ACPC n°32, Decembre 1990 p73-74

★ ANNÉE: 1990
★ AUTEUR: Alain Massoumipour

Page précédente : De l'Arcade de l'Action n°31
★ AMSTRAD CPC ★ DOWNLOAD ★

Je participe au site:
» Newfile(s) upload/Envoye de fichier(s)
★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » De l'Arcade de l'Action n°28
» Coding » De l'Arcade de l'Action n°33
» Coding » De l'Arcade de l'Action n°31
» Coding » De l'Arcade de l'Action n°29
» Coding » De l'Arcade de l'Action n°30

QUE DIT LA LOI FRANÇAISE:

L'alinéa 8 de l'article L122-5 du Code de la propriété intellectuelle explique que « Lorsque l'œuvre a été divulguée, l'auteur ne peut interdire la reproduction d'une œuvre et sa représentation effectuées à des fins de conservation ou destinées à préserver les conditions de sa consultation à des fins de recherche ou détudes privées par des particuliers, dans les locaux de l'établissement et sur des terminaux dédiés par des bibliothèques accessibles au public, par des musées ou par des services d'archives, sous réserve que ceux-ci ne recherchent aucun avantage économique ou commercial ». Pas de problème donc pour nous!

CPCrulez[Content Management System] v8.7-desktop
Page créée en 014 millisecondes et consultée 1233 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.