Il nous reste une fonte et de l'espace disponible dans les bandes noires...Les Amstrad ne sont pas capable de réaliser des scrollings verticaux partiels simplement. Pas que ça soit impossible mais la technique est inutilisable hors démo et la complexitéest largement hors de portée de ces cours pour débutants. Pour commencer, nous allons scroller une bande noire, en fait déplacer les données de chaque ligne, une ligne plus haut. Note : Notre colonne fait 4 octets de large. ScrollBande ; HL=adresse du coin supérieur gauche de la colonne à scroller ld de,hl : ld a,h : add 8 : ld h,a ; calculer l'adresse de la ligne suivante ld xl,100 ; compteur 100 parce qu'on va faire deux copies par tout de compteur .scroll200 ldi : ldi : ldi : ld a,(hl) : ld (de),a ; copier 4 octets au dessus ld d,h ; la ligne courante devient la nouvelle destination ld a,h : add 8 : ld h,a ; on descend la ligne courante jr nc,.okBlock : ld bc,80-#4000 : add hl,bc : .okBlock ; nos pointeurs sont maintenant sur la droite, on copie à l'envers! ldd : ldd : ldd : ld a,(hl) : ld (de),a ld de,hl ; courante devient destination, on copie aussi le poids faible en cas d'ajustement de bloc ld a,h : add 8 : ld h,a ; on descend la ligne courante, on est sûr de rester dans le bloc dec xl : jr nz,.scroll200 retVous pouvez jouer à envoyer l'adresse du milieu de l'écran pour voir scroller le graph.
Et quand vous aurez fini de buller, vous revenez de suite bûcher votre assembleur nom didjou! Il nous reste des lettres à faire scroller! Si on décrit le processus de ce scrollText, une fois que l'on a déplacé toutes les lignes vers le haut, il faut... ...toutes? Non! La dernière ligne n'est pas déplacée, elle est copiée. Ce qui veut dire que la ligne du basse dédouble. Si on veut que quelque chose monte dans la colonne de Scroll, il faut l'insérer, ligne après ligne, en bas de la colonne. Plus détaillé, nous avons un texte dont il faut parcourir chaque lettrel'une après l'autre, et pour chaque lettre, nous devons parcourir l'une après l'autre chaque ligne de la lettre. Pour réaliser cela, il nous faut donc : - un pointeur sur le caractères courant - un pointeur vers le sprite courant - un compteur de la ligne de caractère en cours d'affichage À chaque tour, on affiche la ligne courante du caractère courant, on incrémente la ligne, si on termine la 17è ligne, on revient à zéro et on passe au caractère suivant. Idéalement on contrôle aussi qu'on ne soit pasau dernier caractère du texte pour revenir au début. Allez, au code! BUILDSNA : BANKSET 0 ORG #38 : EI : RET ORG #100 : RUN #100ld sp,#100 : ei ld bc,#7F00+%10001100+%00 : out (c),c ; MODE 0 ld hl,palette : ld bc,#7F00 setPalette out (c),c : inc c : inc b : outi : ld a,(hl) : or a : jr nz,setPalette LaBoucle call waitVBLstart ld iy,yeuxOuverts : pokeYeux=$-2 : call GestionEtape ld iy,doigts1 : pokeDoigts=$-2 : call GestionEtapeld hl,#C000+3 : call ScrollBande ld de,#C000+3+24*80+7*#800 ; ligne 199 en dessous call DisplayCharLine ld hl,#C000+72 : call ScrollBande ld hl,#C000+3+10*80 : ld de,#C000+72+24*80+7*#800 : ldi : ldi : ldi : ldi ; copie retardée jr LaBoucle ;--- waitVBLstart ld b,#F5 .loop in a,(c) : rra : jr c,.loop ; attendre l'absence de VBL waitVBL ld b,#F5 .loop in a,(c) : rra : jr nc,.loop ; attendre la VBL ret ;--- struct etape duree defb sprdata defw adrecran defw hauteur defb etapeSuivante defw pokeEtape defw dureeMin defb dureeMod defb endstruct ;--- yeuxOuverts defb 1 defw yeuxFermesdata defw #C000+80*7+#800*6+40 defb 21 defw yeuxFermes defw pokeYeux defb 4,3 yeuxFermes defb 1 defw yeuxOuvertsdata defw #C000+80*7+#800*6+40 defb 21 defw yeuxOuverts defw pokeYeux defb 30,31 doigts1 defb 1 defw doigts2data defw #C000+80*13+32+#800*2 defb 30 defw doigts2 defw pokeDoigts defb 15,15 doigts2 defb 1 defw doigts1data defw #C000+80*13+32+#800*2 defb 30 defw doigts1 defw pokeDoigts defb 15,15 ;--- DisplayCharLine .currentData ld hl,daFonte : ldi 4 : ld (.currentData+1),hl ; copier la ligne du char .currentStep ld a,17 : dec a : jr z,.currentChar ; décompter les lignes du sprite ld (.currentStep+1),a : ret ; .currentChar ld hl,LeTexte : inc hl : ld (.currentChar+1),hl ld a,17 : ld (.currentStep+1),a ; réarmer le compteur de lignes ld a,(hl) : cp 255 : jr nz,.texteOK ; choper le nouveau caractère ld hl,LeTexte : ld a,(hl) : ld (.currentChar+1),hl ; reinit du texte .texteOK ld l,a : ld h,0 : ld de,hl add hl,hl : add hl,hl : add hl,hl : add hl,hl ; x16 add hl,de ; x17 add hl,hl : add hl,hl ; x17 x4 ld de,daFonte : add hl,de ; données de la lettre en cours ld (.currentData+1),hl ; qu'on remet dans la routine de copie ret GestionEtape ; IY=etape ld a,(iy+etape.duree) : dec a : ld (iy+etape.duree),a : ret nz ; durée pas terminée, aurevoir ld hl,(iy+etape.sprdata) ld de,(iy+etape.adrecran) ld a,(iy+etape.hauteur) : ld xl,a call AfficheSprite ld de,(iy+etape.etapeSuivante) ld hl,(iy+etape.pokeEtape) : ld (hl),e : inc hl : ld (hl),d ld c,(iy+etape.dureeMod) : ld a,r : and c : add (iy+etape.dureeMin) ; A=nouvelle durée ld (de),a ; nouvelle duree de la nouvelle structure ret ;--- AfficheSprite ; HL=données du sprite ; DE=adresse écran en haut à gauche du sprite ; XL=hauteur du sprite .afficheLigne push de : ldi 12 : pop de ld a,d : add 8 : ld d,a ; ajouter #800 à DE jr nc,.nextLine ; pas de débordement, on est toujours dans le même bloc de lignes ld a,80 : add e : ld e,a ; on ajoute 80 (largeur d'une ligne en octets) pour passer au bloc suivant ld a,#C0 : adc d : ld d,a ; et on enlève #4000 (additionner #C000 c'est comme enlever #4000) .nextLine dec xl jr nz,.afficheLigne ret ;--- ScrollBande ; HL=adresse du coin supérieur gauche de la colonne à scroller ld de,hl : ld a,h : add 8 : ld h,a ; ligne suivante ld xl,100 .scroll200 ldi : ldi : ldi : ld a,(hl) : ld (de),a ; copier 4 octets au dessus ld d,h ; la ligne courante devient la nouvelle destination ld a,h : add 8 : ld h,a ; on descend la ligne courante jr nc,.okBlock : ld bc,80-#4000 : add hl,bc : .okBlock ; nos pointeurs sont maintenant sur la droite, on copie à l'envers! ldd : ldd : ldd : ld a,(hl) : ld (de),a ld de,hl ; courante devient destination, on copie aussi le poids faible en cas d'ajustement de bloc ld a,h : add 8 : ld h,a ; on descend la ligne courante, on est sûr de rester dans le bloc dec xl : jr nz,.scroll200 ret ;--- palette defb #54,#5C,#44,#56,#46,#4C,#55,#57,#45,#4E,#5F,#59,#4A,#43,#5B,#4B border defb #54,0 align 4 daFonte incbin 'daFonte.bin' doigts1data incbin 'doigts1.bin' doigts2data incbin 'doigts2.bin' yeuxOuvertsdata incbin 'yeuxOuverts.bin' yeuxFermesdata incbin 'yeuxFermes.bin' ; la commande Charset permet de 'renommer' les valeurs ASCII, ici on repart de zéro au lieu de 32 charset ' !"###&\'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz',0 LeTexte defb ' alors qui est le meilleur? ',255 charset org #C000 : incbin 'screen160.bin' Joyeux Noël! Pour pouvoir enregistrer cette intro sur un support exploitable par un CPC, rendez-vous dans le [3è et dernier article!] Roudoudou CPCrulez[Content Management System] v8.732-desktop Page créée en 032 millisecondes et consultée 29 foisL'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. |
|