Les rasters sont un effet très utilisé dans les démos et même dans certains jeux. Ils permettent d'afficher autant de couleurs de la palette qu'on le souhaite sur n'importe quelle zone de l'écran (y compris le border). Nous allons voir ici comment on peut réaliser de telles prouesses sur CPC, en commençant d'abord par des rasters élémentaires puis en allant vers des structures de rasters de plus en plus complexes.
— Basé sur l'article publié dans Quasar CPC numéro 1, Perfectionnement à l'Assembleur, par OffseT.
Dans cette rubrique, nous allons vous expliquer comment il faut s'y prendre pour réaliser des rasters comme on en voit dans toutes les démos. Certes, les meilleurs rasters sont souvent ceux qu'on ne voit pas… mais, en guise d'introduction, nous allons voir comment réaliser des rasters de base, à savoir des barres de couleurs à l'écran.
Ne trouvez vous pas qu'il est triste de devoir travailler en mode 0 pour disposer de 16 couleurs alors que l'on peut facilement en avoir 27 en mode 21) ? Eh bien, la solution c'est les rasters ! La technique consiste à changer la couleur de telle ou telle encre durant le balayage de l'écran. Ainsi, on peut facilement donner l'illusion d'avoir des tonnes de couleurs affichées en même temps !
La petite merveille qui permet cela, c'est de Gate Array2). Il permet entre autre3) de gérer les banks, les roms et les couleurs. Il est entièrement contrôlé à partir du port &7F
et, pour modifier les couleurs, sa programmation se fait en deux temps.
La première étape consiste à signaler quelle encre on désire modifier. Là, c'est très simple, on envoie directement le numéro de l'encre à l'aide du OUT (C),registre
. Il y a tout de même une exception : pour le border on doit envoyer la valeur 16. Ensuite, pour spécifier la couleur, c'est un peu plus complexe. Celle-ci, doit lui être envoyée en numérotation “Hardware” (voir tableau). De plus, pour compléter les bits4) on doit y ajouter 64. Compris ? Parfait !
Voici par exemple comment on pourrait s'y prendre pour sélectionner l'encre 0 et la mettre en blanc brillant :
LD BC,&7F00 OUT (C),C LD C,11+64 OUT (C),C
Maintenant, à partir de là, il va falloir prendre en considération quelques éléments annexes pour arriver à faire des rasters. En premier lieu, pour ne pas être dérangé lors des phases de synchronisation, je vous conseille simplement de geler les interruptions système. Mais pas avec DI
car les HALT
5), ne seraient plus utilisables. Simplement, pokez un EI:RET
en &38
. J'allais z'oublier ! Pour que votre raster soit toujours au même endroit sur l'écran, il est important d'attendre que le balayage vidéo revienne en haut de l'écran et ainsi de positionner votre raster en fonction de la synchronisation verticale. C'est un signal du CRTC accessible via le PPI qui permet cela…. mais c'est une autre histoire. Si vous n'avez pas envie de vous lancer là dedans, utilisez simplement le vecteur &BD19
du système, il fait tout le boulot.
Voyez le programme d'exemple et entraînez-vous car l'étape suivante sera de mettre les rasters en mouvement !
|
|
|
Télécharger le listing au format Maxam 1.5
; Exemple de raster élémentaire ; par OffseT pour Quasar CPC numéro 1 ; Org &5000 di ; Disable Interrupt ld hl,(&38) ; On sauve les vieilles ld (inter),hl ; Interruptions ld hl,&c9fb ; On met les nouvelles ld (&38),hl ; EI et RET ei ; Enable Interrupt Prog ld b,&f5 ; On sélectionne le Port B du PPI Synchro in a,(c) ; On pique son contenu rra ; On teste si le Bit0=1 jp nc,synchro ; Si Bit0=0 alors on attend la fin ; du balayage halt ; On attend que le balayage arrive halt ; à peu près au milieu de l'écran halt ; Patience... halt ; Ouf, le dernier ! ds 20 ; On se calle en début de ligne... ld b,&7f ; On sélection le Gate Array ld hl,raster ; HL pointe sur la table de couleurs Boucle ld a,(hl) ; On charge la couleur dans A cp 255 ; Si A=255 alors... jp z,key ; On saute au test clavier ld c,16 ; On sélectionne le border out (c),c ; Et hop là ! out (c),a ; On le met à la couleur ld c,0 ; On sélectionne l'encre 0 out (c),c ; Et hop là ! out (c),a ; On la met elle aussi à la couleur inc hl ; On pointe sur la couleur suivante ds 32 ; On attend la fin de la ligne... jp boucle ; C'est reparti pour un tour ! ; ; Test de la barre espace ; Key ld bc,&f40e ; No comment ici, out (c),c ; c'est pas les rasters... ld bc,&f6c0 out (c),c xor a out (c),a ld bc,&f792 out (c),c ld bc,&f645 out (c),c ld b,&f4 in a,(c) ld bc,&f782 out (c),c ld bc,&f600 out (c),c rla jp c,prog ; Bref, si pas espace alors ; on repart pour un tour... di ; Disable Interrupt ld hl,(inter) ; On récupère les anciennes ld (&38),hl ; interruptions ei ; Enable Interrupt ret ; Retour à la case départ ; ; Les datas... ; Inter dw 0000 Raster db 20+64,4+64,21+64,23+64,31+64,19+64,11+64 db 3+64,10+64,14+64,12+64,28+64,20+64 db 255
— Basé sur l'article publié dans Quasar CPC numéro 2, Perfectionnement à l'Assembleur, par OffseT.
Après avoir vu le principe de base des rasters, je vais donc vous expliquer comment on doit s'y prendre pour les faire bouger à l'écran. Dès lors, partant du principe que l'affichage d'un raster à l'écran n'a plus de secret pour vous, sa mise en mouvement est fort simple. Il s'agit tout simplement de jongler entre le raster et un tableau. Ainsi, on fait une table pour le raster, puis on la sauve dans le tableau qui est ensuite envoyé à l'écran.
Je m'explique : soit un raster stocké dans un tableau et un tableau dans lequel sera stocké le raster ! C'est plus clair comme ça non ? Bref, voici donc un algorithme que l'on peut suivre :
Comme il n'y a rien de plus clair qu'un programme d'exemple (si, si, je vous assure), vous en trouverez un entièrement commenté ci-dessous.
Ce programme d'exemple est en fait une variante de l'intro d'affichage du menu principal de Quasar CPC 2. Mais il va de soi que si vous avez compris le système, rien ne vous empêche de faire un raster qui rebondit ou même, qui suit les courbes de sinus ou qui tient compte de l 'énergie cinétique et, pourquoi pas, une animation sur le principe des oscillateurs harmoniques…
Télécharger le listing au format Maxam 1.14
; ; Programme d'exemple de mise en mouvement d'un raster avec un tableau ; De plus ce programme restitue des couleurs (à modifier dans "Image") ; pour donner l'illusion qu'une image s'affiche sous le raster... ; En deux mots c'est pratiquement le meme programme que celui de l'intro ; du menu principal de Quasar. ; ; Note...vous remarquerez que le tableau est stocke a l'envers, ; etrange non ? ; Org &8000 Ent Nolist Long Equ 12 ; Long = nbre de lignes du raster + 1 ; ; Adieu les interruptions !!! ; di ; Tout ceci sert a installer un ld hl,(&38) ; EI, RET ld (inter),hl ; en &38 pour eviter d'utiliser des ld hl,&c9fb ; HALT et pouvoir donc se ld (&38),hl ; synchroniser sur les interruptions Prog ld b,&f5 ; Synchronisation verticale Synchro in a,(c) ; On attend le debut du rra ; video... jp nc,synchro ; puis on se barre ! ds 36 ; On attend le debut de la ligne ld hl,image ; suivante (synchro horizontale) ld bc,&7f00 ; On selectionne le papier out (c),c ; Et hop ! outi ; On envoie les couleurs de l'image inc b ; Encre 0 inc c ; Hop ! out (c),c ; Encre 1 outi ; Hop ! inc b ; C'est pas fini ! inc c ; Patience... out (c),c ; Encre 2 outi ; Hop ! inc b ; La fin approche... inc c ; Encre 3 out (c),c ; Hop la ! outi ; C'est fini... inc b ; On remet b comme il faut... ld hl,tableau ; On pointe sur la tableau Loop2 ld a,(hl) ; Hop ! cp 0 ; Si 0 Alors fin raster donc... jp z,suite ; On passe a la suite ! ld c,16 ; Selection du Border out (c),c ; Hop ! out (c),a ; Modif du border ld c,0 ; Selection de l'encre 0 out (c),c ; Modif de l'encre 0 out (c),a ; Hop ! inc hl ; On passe a la ligne suivante ds 32 ; Patience... jp loop2 ; C'est reparti pour un tour... Suite ld a,64+20 ; On remet tout a zero ld c,1 ; Encre 1 out (c),c ; Hop ! out (c),a ; Zero inc c ; Encre 2 out (c),c ; Hop ! out (c),a ; Zero inc c ; Encre 3 out (c),c ; Hop ! out (c),a ; Zero xor a ; On se prepare pour ld hl,(courant); reinitialiser le tableau ld b,long ; juste ou il le faut... Loop3 ld (hl),20+64 ; C'est tout bete dec hl ; Une petit boucle djnz loop3 ; s'occupe de tout ! ld hl,(courant); On passe a la ligne inc hl ; suivante... ld (courant),hl; On sauve pour savoir ou cp (hl) ; on en est au prochain coup ! jp z,fin ; Si fin tableau bye ! ld de,raster ; Sinon on y sauve le raster... ld b,long ; Ne me demandez pas pourquoi Loop1 ld a,(de) ; je n'ai pas fait avec LDDR ou ld (hl),a ; LDIR car se serais trop long a inc de ; expliquer... dec hl ; Vous comprendrez bien par djnz loop1 ; meme... jp prog ; On repart pour une VBL ! Fin ei ; Ici, pas de miracle ld hl,(inter) ; On restitue le systeme ld (&38),hl ; proprement avant de ret ; partir... ; ; Datas ; ; Couleurs de l'image a restituer (MODE 1) Image db 64+20,64+30,64+10,64+14 ; Raster a faire defiler...Attention ! ; Il doit commancer par zero et les ; couleurs doivent etre mise a l'envers ! Raster db 0 db 64+20,64+4,64+21,64+23,64+31,64+19 db 64+11,64+10,64+14,64+12,64+28 ; Le tableau ou l'on stockera le raster Tableau db 0 ds 310,64+20 db 0 ; Sauvegarde Interruptions Inter dw 0000 ; Pointeur du tableau Courant dw tableau+long-1
— Basé sur l'article publié dans Quasar CPC numéro 13, CPC plus, par SNN.
Comme vous le savez sûrement, il est possible de provoquer autant d'interruptions que de lignes sur le CPC+ (si vous ne le savez pas, allez jeter un coup d'oeil ici et là). Il suffit de poker le numéro de la ligne à l'adresse &6800
(le registre PRI de l'ASIC) du RMR2 (si l'acronyme RMR2 ne vous parle pas, vous avez le droit d'aller lire l'article sur le Gate Array). Le programme d'interruption est nommé ”OOOPS
” (tellement plus simple !) et il est appelé par le JP
qui se trouve en &38
. Notons que nous aurons pris soin de sauver dans SAUVINT
l'adresse en &39
. C'est plus pro, tout de même.
… que je ne savais pas. C'est Zik qui me l'a appris et ça m'a bien aidé à faire ce programme : lorsqu'une interruption est déclenchée (qu'elle soit - ou non - standard), un DI
est exécuté afin de prévenir l'incommensurable bordel d'une deuxième interruption pendant la première. Il faudra donc penser à faire un EI
sinon, vous pourrez toujours attendre6)…
Elle commence par une sauvegarde bourrin des registres (AF, BC, DE… mais pas de PUSH SP
! Ok ?). On, gère ensuite un petit compteur pour les tons de bleu (qui pourrait être remplacé par une table, rien de plus simple) et un compteur du numéro de ligne (label LIGNE
) de la prochaine interruption. Classique. On oublie RMR2, on rend les bonnes valeurs à chaque registre, on fait le EI
de Zik (merci encore pour ta réponse si rapide par le net) et RET
.
Voyez-vous la remarque ; “FAIRE QUELQUE CHOSE” ? Eh bien vous pouvez mettre là n'importe quoi : une animation de sprites, un raster (pourquoi pas ?), un scrolling, bref… tout ce que vous voulez. Offset me rétorquera que c'est le propre des interruptions. Vrai.
Bon courage et à bientôt. Et prout à Offset, Mick'ro, Madram et Siou. C'est dit.
Télécharger le listing au format Maxam 1.5
ORG &3000 NOLIST DI LD HL,(&39) LD (SAUVINT),HL CALL DELOCK XOR A LD (FINI),A DI LD HL,OOOPS LD (&39),HL LD BC,&7FB8 OUT (C),C CALL FINAL LD BC,&7FA0 OUT (C),C EI START LD B,&F5 SYNCHRO IN A,(C) RRA JR NC,SYNCHRO ; FAIRE QUELQUE CHOSE KEY LD BC,&F40E OUT (C),C LD BC,&F6C0 OUT (C),C XOR A OUT (C),A LD BC,&F792 OUT (C),C LD BC,&F640 OUT (C),C LD B,&F4 IN A,(C) LD BC,&F782 OUT (C),C LD BC,&F600 OUT (C),C RLA RLA JP C,START JP FIN OOOPS PUSH AF PUSH DE PUSH BC PUSH HL PUSH IX PUSH IY LD A,(FINI) OR A JP NZ,AIE LD BC,&7FB8 OUT (C),C LD A,(COMPT) INC A LD (COMPT),A LD (&6400),A LD A,(LIGNE) ADD A,10 LD (LIGNE),A LD (&6800),A LD A,(LIGNE) CP 155 CALL Z,FINAL LD BC,&7FA0 OUT (C),C AIE POP IY POP IX POP HL POP BC POP DE POP AF EI RET FINAL XOR A LD (&6400),A LD A,5 LD (&6800),A FINAL2 LD (LIGNE),A XOR A LD (COMPT),A RET FIN LD A,1 LD (FINI),A LD BC,&7FB8 OUT (C),C XOR A LD (&6800),A CALL FINAL2 LD BC,&7FA0 OUT (C),C DI LD HL,(SAUVINT) LD (&39),HL EI LD A,2 CALL &BC0E RET DELOCK DI LD E,17 LD HL,TABASIC LD BC,&BC00 SASIC LD A,(HL) OUT (C),A INC HL DEC E JR NZ,SASIC RET TABASIC DB 255,0,255,119,179 DB 81,168,212,98,57,156 DB 70,43,21,138,205 DB 238 SAUVINT DS 2 COMPT NOP LIGNE NOP FINI NOP