Scroller dans toutes les directions - Courage, fuyons! Nous devons écrire des routines de scrolling suivant la logique des tableaux de transition de l'article précédent. Contrairement au scrolling vertical sur écran de 64, il n'est pas possible de se passer d'un test de rebouclage... ...à peu près partout où on touche l'adresse écran! À chaque fois qu'on décale l'écran vers le haut ou le bas, il faut gérer ce rebouclage. La gestion sur les passages de ligneest la plus facile, on se contente de réajuster avec RES et SET. NextLineHL ld a,h : add 8 : ld h,a : and #38 : ret nz ; tester le changement de bloc sur n'importe quelle page ld a,64 : add l : ld l,a : ld a,#C0 : adc h : ld h,a : res 3,h : ret PreviousLineHL ld a,h : sub 8 : ld h,a : and #38 : cp #38 : ret nz ; test du chgt de bloc (bis) ld a,l : add #C0 : ld l,a : ld a,#3F : adc h : ld h,a : set 3,h : retQuand on décale l'écran vers la droite ou la gauche, il faut aussi gérer ce rebouclage. Et là c'est plus pénible (nous verrons une astuce lors des optimisations).En attendant ce snipet fonctionne partout et sur toutes les lignes. ld a,h : and %11111000 : ld c,a : Mettre les 5 bits supérieurs de HL dans C inc hl ld a,h : and 7 : or c ; ne récupérer que la position dans le bloc et forcer le blocC'est pareil pour INC HL que DEC HL que ADD HL,BCNote : Quand on sait que la ligne est paire ET qu'on veut incrémenter, le RES 3,H fonctionne inc hl : res 3,h ; sur une ligne paireLe mieux étant de pouvoir se passer de rebouclage car tester tout le temps finit par coûter du temps machine, il peut être utile de noter qu'utiliser des tiles multiples de la largeur écran (4 pour 64, c'est ok!),la gestion du rebouclage n'est utile que sur la dernière incrémentation. Toutes les autres colonnes n'en ont pas besoin. Ceci étant dit, vous verrez en plusieurs endroits ces ajustements fastidieux dont il ne faut en oublier aucun. Et maintenant, place au code :)Le scroll vers la gauche va exécuter la routine d'affichage dans la continuité de son code, car c'est quand on remonte les adresses qu'on dessine en dernier. On aura le même déroulement pour le scroll vers le haut. ScrollGauche ld a,(ix+multi.colonne) : or a : jr nz,.goForScroll ld a,(ix+multi.mapOffset) : and 63 : ret z ; si on est sur la colonne zéro de la tile la plus à gauche... Bye! .goForScroll ld a,(ix+multi.HSSR) : bit 2,a : jr nz,.willDraw : add 4 : ld (ix+multi.HSSR),a : ret ; on ne change que le décalage et bye! .willDraw add 4 : and 15 : jr nz,.stillSSR ld hl,(ix+multi.crtcHL) : dec hl : ld (ix+multi.crtcHL),hl ; each word .stillSSR ld (ix+multi.HSSR),a ld hl,(ix+multi.adresseDebut) : ld a,h : and 7 : or l : jr nz,.skip : ld a,h : add 8 : ld h,a : .skip dec hl ; gérer le rebouclage à la décrémentation ld (ix+multi.adresseDebut),hl ld a,(ix+multi.colonne) : dec a : and 3 : ld (ix+multi.colonne),a : cp 3 : jr nz,.stillPosx : dec (ix+multi.mapOffset) : .stillPosx ld hl,(ix+multi.mapOffset) : ld bc,64 : exx ; HL'=adresse de la tile BC'=saut de ligne dans la tileMap ld de,(ix+multi.adresseDebut) ; DE=haut de la colonne à rafraichir ; accès direct à l'affichage d'une colonneL'affichage des colonnes, dans la continuité de la routine de scroll à gauche, doit tenir compte de la ligne courante dûe aux scrolls verticaux (avez-vous lu les articles sur le clipping de sprites?) afficheColonne ;------------------ ld a,(ix+multi.ligne) : or a : jr nz,.clipped ld yh,16 .loopTiles calculeAdresseTuileColonne 64 ld bc,#1004 : .loopColumn ld a,(hl) : ld (de),a : call NextLineDE ld a,l : add c : ld l,a : djnz .loopColumn dec yh : jr nz,.loopTiles ret ;---------- .clipped calculeAdresseTuileLigneColonne 64 ld a,64 : sub (ix+multi.ligne) : rrca : rrca : and 15 : ld b,a : ld c,4 ; la ligne contient un offset de ligne, on divise par 4 pour avoir le nombre de lignes .loopColumnC1 ld a,(hl) : ld (de),a : call NextLineDE : ld a,l : add c : ld l,a : djnz .loopColumnC1 ld yh,15 call .loopTiles ; dernière tuile clippée calculeAdresseTuileColonne 0 ld a,(ix+multi.ligne) : rrca : rrca : and 15 : ld b,a : ld c,4 ; la ligne contient un offset de ligne, on divise par 4 pour avoir le nombre de lignes .loopColumnC3 ld a,(hl) : ld (de),a : call NextLineDE : ld a,l : add c : ld l,a : djnz .loopColumnC3 retEnfin, la routine de scroll à droite. ScrollDroite ld a,(ix+multi.mapOffset) : and 63 : cp 64-16 : ret z ; gérer le bord droit ld a,(ix+multi.HSSR) : bit 2,a : jr z,.willDraw : sub 4 : ld (ix+multi.HSSR),a : ret .willDraw sub 4 : jr nc,.stillHSSR : jr z,.stillHSSR ld hl,(ix+multi.crtcHL) : inc hl : ld (ix+multi.crtcHL),hl ld a,12 .stillHSSR ld (ix+multi.HSSR),ald hl,(ix+multi.mapOffset) : ld bc,16 : add hl,bc : ld bc,64 : exx ; HL'=adresse de la tile BC'=saut de ligne dans la tileMap ld hl,(ix+multi.adresseDebut) : ld bc,64 : ld a,h : and %11111000 : ld d,a : add hl,bc : ld a,h : and 7 : or d ; gère le rebouclage de bloc! ex hl,de ; DE=haut de la colonne à rafraichir call afficheColonne ld a,(ix+multi.colonne) : inc a : and 3 : ld (ix+multi.colonne),a : jr nz,.stillPosx : inc (ix+multi.mapOffset) : .stillPosx ld hl,(ix+multi.adresseDebut) : inc hl : ld a,h : and 7 : or l : jr nz,.skip : ld a,h : sub 8 : ld h,a : .skip : ld (ix+multi.adresseDebut),hl retLa gestion du scrolling vers le bas ;--------------------------------------------------------------------- ScrollBas ;--------------------------------------------------------------------- ld hl,(ix+multi.mapOffset) : ld a,hi(tileMap+48*64) : cp h : ret z ; trop bas, on ne fait rien! ; la tuile en bas sera 16 lignes de tuiles plus bas, soit 1024 octets de tileMap de largeur 64 ld bc,16*64 : add hl,bc : exx ; ajouter 16x64 à l'offset de tuile car on va afficher en bas de l'écran + sauvegarde dans HL' ld de,(ix+multi.adresseDebut) ; écran carré, calculs simples, le bas revient en haut et vice versa :) call afficheTuilesHorizontales ; mettre à jour les informations courantes ld a,(ix+multi.ligne) : add 4 : cp 64 : jr nz,.pasDeChangementDeTuile ; ligne contient l'offset de début de la ligne suivante ld hl,(ix+multi.mapOffset) : ld bc,64 : add hl,bc : ld (ix+multi.mapOffset),hl : xor a ; passer à la tuile dessous .pasDeChangementDeTuile ld (ix+multi.ligne),a ; valider la ligne de tuile ld hl,(ix+multi.adresseDebut) : call NextLineHL : ld (ix+multi.adresseDebut),hl ld a,(ix+multi.VSSR) : add #10 : and #70 : ld (ix+multi.VSSR),a : jr nz,.pasDeChangementDeBloc ld hl,(ix+multi.crtcHL) : ld bc,32 : add hl,bc : ld (ix+multi.crtcHL),hl ; adresse CRTC augmente de 32 mots si le bloc change .pasDeChangementDeBloc retLa gestion du scrolling vers le hautScrollHaut ;--------------------------------------------------------------------- ld hl,(ix+multi.mapOffset) : ld a,hi(tileMap) : cp h : jr nz,.okPourLeScroll ; si on est près du début on doit contrôler le "Y" ld a,l : cp 63 : jr nc,.okPourLeScroll ; si on est sur la première ligne, on doit regarder la ligne de tuile! ld a,(ix+multi.ligne) : or a : ret z ; tout en haut, aurevoir! .okPourLeScroll ; on peut scroller!; mettre à jour les informations courantes ld a,(ix+multi.ligne) : sub 4 : jr nc,.pasDeChangementDeTuile ; ligne contient l'offset de début de la ligne suivante ld hl,(ix+multi.mapOffset) : ld bc,-64 : add hl,bc : ld (ix+multi.mapOffset),hl : ld a,60 ; passer à la dernière ligne de la tuile dessous .pasDeChangementDeTuile ld (ix+multi.ligne),a ; valider la ligne de tuile ld hl,(ix+multi.adresseDebut) : call PreviousLineHL : ld (ix+multi.adresseDebut),hl ld a,(ix+multi.VSSR) : sub #10 : and #70 : ld (ix+multi.VSSR),a : cp #70 : jr nz,.pasDeChangementDeBloc ld hl,(ix+multi.crtcHL) : ld bc,-32 : add hl,bc : ld (ix+multi.crtcHL),hl ; adresse CRTC baisse de 32 mots si le bloc change .pasDeChangementDeBloc ; on affiche après en remontant ld hl,(ix+multi.mapOffset) : exx ld de,(ix+multi.adresseDebut)L'affichage des lignes en tenant compte d'un éventuel décalage en colonne dû aux scrolls horizontaux. afficheTuilesHorizontales ;--------------------------- ld a,(ix+multi.colonne) : or a : jr nz,.routineClippee ld yh,16 .loop calculeAdresseTuileLigne 1 ldi 3 ld a,d : and %11111000 ldi : ld c,a : ld a,d : and 7 : or c : ld d,a ; rebouclage de bloc... dec yh : jr nz,.loop ret ;----------------- .routineClippee ;----------------- ld yh,15 ; on aura 15 sprites entiers et 2 sprites partiels calculeAdresseTuileLigneColonne 1 ld a,4 : sub (ix+multi.colonne) : ld c,a ld b,0 : ldir : dec de : ld a,d : inc de : and %11111000 : ld c,a : ld a,d : and 7 : or c : ld d,a ; rebouclage de bloc... .loop7 calculeAdresseTuileLigne 1 ldi 3 ld a,d : and %11111000 ldi : ld c,a : ld a,d : and 7 : or c : ld d,a ; rebouclage de bloc... dec yh : jr nz,.loop7 calculeAdresseTuileLigne 0 ld c,(ix+multi.colonne) ld b,0 : ldir : dec de : ld a,d : inc de : and %11111000 : ld c,a : ld a,d : and 7 : or c : ld d,a ; rebouclage de bloc... retTout le reste est déjà prêt, ne manque que le test des touches avec l'appel des fonctions et c'est parti :) (besoin des fichiers mapMulti.bin et mapMulti.tilemap) BUILDSNA : BANKSET 0 SNASET CPC_TYPE,4 ; modèle 6128+ conseillé ORG #100 : RUN #100 ;*** RMR2 tags + macro *** ASICOFF equ 0 : ROM0000 equ 0 : ROM4000 equ %01000 : ROM8000 equ %10000 : ASICON equ %11000ROM0 equ 0 : ROM1 equ 1 : ROM2 equ 2 : ROM3 equ 3 : ROM4 equ 4 : ROM5 equ 5 : ROM6 equ 6 : ROM7 equ 7 macro RMR2 tags ld a,{tags}+%10100000 ld b,#7F out (c),a mendstruct multi mapOffset defw HSSR defb ; 0-12 VSSR defb ; #00-#70 colonne defb ; 0-3 dans la tuile ligne defb ; 0-60 par pas de 4 dans la tuile adresseDebut defw crtc12 defb ; cache des bits de bank crtcHL defw ; adresse CRTC endstruct ; définition des constantes pour le curseur OCTET_CURSEUR_HAUT equ matriceClavier+0 : BIT_CURSEUR_HAUT equ 1 OCTET_CURSEUR_DROITE equ matriceClavier+0 : BIT_CURSEUR_DROITE equ 2 OCTET_CURSEUR_BAS equ matriceClavier+0 : BIT_CURSEUR_BAS equ 4 OCTET_CURSEUR_GAUCHE equ matriceClavier+1 : BIT_CURSEUR_GAUCHE equ 1 ld bc,#7F00+%10001100+%00 : out (c),c ; MODE 0 call UnlockAsic : RMR2 ASICON ld hl,palettePlus : ld de,#6400 : ld bc,32 : ldir : ld hl,#000 : ld (#6420),hl ; +border noir ld bc,#BC00+1 : out (c),c : ld bc,#BD00+32 : out (c),c ; Notre map fait 128 pixels de large, adaptez selon VOS besoins ld bc,#BC00+2 : out (c),c : ld bc,#BD00+42 : out (c),c ; Centrer l'écran en X ld bc,#BC00+6 : out (c),c : ld bc,#BD00+32 : out (c),c ; Hauteur de l'écran visible en lignes de caractères ld bc,#BC00+7 : out (c),c : ld bc,#BD00+34 : out (c),c ; Centrer l'écran en Y ld bc,#BC00+12 : out (c),c : ld bc,#BD30 : out (c),c ; adresse par défaut ld bc,#BC00+13 : out (c),c : ld bc,#BD00 : out (c),c ld ix,ecran1 : ld a,#C0 : call InitEcran LaBoucle call lectureMatriceClavier call WaitVBL ld ix,ecran1 ; notre structure écran par défaut pour aller scroller call UpdateHardware ld a,(OCTET_CURSEUR_BAS) : and BIT_CURSEUR_BAS : call z,ScrollBas ld a,(OCTET_CURSEUR_HAUT) : and BIT_CURSEUR_HAUT : call z,ScrollHaut ld a,(OCTET_CURSEUR_DROITE) : and BIT_CURSEUR_DROITE : call z,ScrollDroite ld a,(OCTET_CURSEUR_GAUCHE) : and BIT_CURSEUR_GAUCHE : call z,ScrollGauche jp LaBoucle lectureMatriceClavier ld hl,matriceClavier ld bc,#f782 out (c),c ld bc,#f40e ld e,b out (c),c ld bc,#f6c0 ld d,b out (c),c out (c),0 ld bc,#f792 out (c),c ld a,#40 ld c,d .loop ld b,d out (c),a ; sélectionner la ligne ld b,e ini ; lire et stocker dans notre tableau inc a inc c jr nz,.loop ld bc,#f782 out (c),c retmatriceClavier defs 10,#FF ;--------------------------------------------------------------------- MACRO calculeAdresseTuile increment exx : ld a,(hl) ; index de la tile dans A if {increment}==0 : elseif {increment}==1 : inc hl : else : add hl,bc : endif exx ; index de la tile dans A / HL'=tileMap ld hl,tuiles : ld b,a : ld c,0 : srl bc : srl bc : add hl,bc ; HL=adresse du début de la tuile MEND MACRO calculeAdresseTuileLigne increment calculeAdresseTuile {increment} ld a,(ix+multi.ligne) : add l : ld l,a ; HL=adresse du début de la tuile à la bonne ligne MEND MACRO calculeAdresseTuileColonne increment calculeAdresseTuile {increment} ld a,(ix+multi.colonne) : add l : ld l,a ; HL=adresse du début de la tuile à la bonne colonne MEND MACRO calculeAdresseTuileLigneColonne increment calculeAdresseTuile {increment} ld a,(ix+multi.ligne) : add (ix+multi.colonne) : add l : ld l,a ; HL=adresse du début de la tuile à la bonne ligne ET bonne colonne MEND ;--------------------------------------------------------------------- ScrollGauche ;--------------------------------------------------------------------- ld a,(ix+multi.colonne) : or a : jr nz,.goForScroll ld a,(ix+multi.mapOffset) : and 63 : ret z ; si on est sur la colonne zéro de la tile la plus à gauche... Bye! .goForScroll ld a,(ix+multi.HSSR) : bit 2,a : jr nz,.willDraw : add 4 : ld (ix+multi.HSSR),a : ret ; on ne change que le décalage et bye! .willDraw add 4 : and 15 : jr nz,.stillSSR ld hl,(ix+multi.crtcHL) : dec hl : ld (ix+multi.crtcHL),hl ; each word .stillSSR ld (ix+multi.HSSR),a ld hl,(ix+multi.adresseDebut) : ld a,h : and 7 : or l : jr nz,.skip : ld a,h : add 8 : ld h,a : .skip dec hl ; gérer le rebouclage à la décrémentation ld (ix+multi.adresseDebut),hl ld a,(ix+multi.colonne) : dec a : and 3 : ld (ix+multi.colonne),a : cp 3 : jr nz,.stillPosx : dec (ix+multi.mapOffset) : .stillPosx ld hl,(ix+multi.mapOffset) : ld bc,64 : exx ; HL'=adresse de la tile BC'=saut de ligne dans la tileMap ld de,(ix+multi.adresseDebut) ; DE=haut de la colonne à rafraichir ; accès direct à l'affichage d'une colonne ;------------------ afficheColonne ;------------------ ld a,(ix+multi.ligne) : or a : jr nz,.clipped ld yh,16 .loopTiles calculeAdresseTuileColonne 64 ld bc,#1004 : .loopColumn ld a,(hl) : ld (de),a : call NextLineDE ld a,l : add c : ld l,a : djnz .loopColumn dec yh : jr nz,.loopTiles ret ;---------- .clipped calculeAdresseTuileLigneColonne 64 ld a,64 : sub (ix+multi.ligne) : rrca : rrca : and 15 : ld b,a : ld c,4 .loopColumnC1 ld a,(hl) : ld (de),a : call NextLineDE : ld a,l : add c : ld l,a : djnz .loopColumnC1 ld yh,15 call .loopTiles ; dernière tuile clippée calculeAdresseTuileColonne 0 ld a,(ix+multi.ligne) : rrca : rrca : and 15 : ld b,a : ld c,4 .loopColumnC3 ld a,(hl) : ld (de),a : call NextLineDE : ld a,l : add c : ld l,a : djnz .loopColumnC3 ret ;--------------------------------------------------------------------- ScrollDroite ;--------------------------------------------------------------------- ld a,(ix+multi.mapOffset) : and 63 : cp 64-16 : ret z ; gérer le bord droit ld a,(ix+multi.HSSR) : bit 2,a : jr z,.willDraw : sub 4 : ld (ix+multi.HSSR),a : ret .willDraw sub 4 : jr nc,.stillHSSR : jr z,.stillHSSR ld hl,(ix+multi.crtcHL) : inc hl : ld (ix+multi.crtcHL),hl ld a,12 .stillHSSR ld (ix+multi.HSSR),ald hl,(ix+multi.mapOffset) : ld bc,16 : add hl,bc : ld bc,64 : exx ; HL'=adresse de la tile BC'=saut de ligne dans la tileMap ld hl,(ix+multi.adresseDebut) : ld bc,64 : ld a,h : and %11111000 : ld d,a : add hl,bc : ld a,h : and 7 : or d ; gère le rebouclage de bloc! ex hl,de ; DE=haut de la colonne à rafraichir call afficheColonne ld a,(ix+multi.colonne) : inc a : and 3 : ld (ix+multi.colonne),a : jr nz,.stillPosx : inc (ix+multi.mapOffset) : .stillPosx ld hl,(ix+multi.adresseDebut) : inc hl : ld a,h : and 7 : or l : jr nz,.skip : ld a,h : sub 8 : ld h,a : .skip : ld (ix+multi.adresseDebut),hl ret ;--------------------------------------------------------------------- ScrollBas ;--------------------------------------------------------------------- ld hl,(ix+multi.mapOffset) : ld a,hi(tileMap+48*64) : cp h : ret z ; trop bas, on ne fait rien! ; la tuile en bas sera 16 lignes de tuiles plus bas, soit 1024 octets de tileMap de largeur 64 ld bc,16*64 : add hl,bc : exx ; ajouter 16x64 à l'offset de tuile car on va afficher en bas de l'écran + sauvegarde dans HL' ld de,(ix+multi.adresseDebut) ; écran carré, calculs simples, le bas revient en haut et vice versa :) call afficheTuilesHorizontales ; mettre à jour les informations courantes ld a,(ix+multi.ligne) : add 4 : cp 64 : jr nz,.pasDeChangementDeTuile ; ligne contient l'offset de début de la ligne suivante ld hl,(ix+multi.mapOffset) : ld bc,64 : add hl,bc : ld (ix+multi.mapOffset),hl : xor a ; passer à la tuile dessous .pasDeChangementDeTuile ld (ix+multi.ligne),a ; valider la ligne de tuile ld hl,(ix+multi.adresseDebut) : call NextLineHL : ld (ix+multi.adresseDebut),hl ld a,(ix+multi.VSSR) : add #10 : and #70 : ld (ix+multi.VSSR),a : jr nz,.pasDeChangementDeBloc ld hl,(ix+multi.crtcHL) : ld bc,32 : add hl,bc : ld (ix+multi.crtcHL),hl ; adresse CRTC augmente de 32 mots si le bloc change .pasDeChangementDeBloc ret ;--------------------------------------------------------------------- ScrollHaut ;--------------------------------------------------------------------- ld hl,(ix+multi.mapOffset) : ld a,hi(tileMap) : cp h : jr nz,.okPourLeScroll ; si on est près du début on doit contrôler le "Y" ld a,l : cp 63 : jr nc,.okPourLeScroll ; si on est sur la première ligne, on doit regarder la ligne de tuile! ld a,(ix+multi.ligne) : or a : ret z ; tout en haut, aurevoir! .okPourLeScroll ; on peut scroller! ; mettre à jour les informations courantes ld a,(ix+multi.ligne) : sub 4 : jr nc,.pasDeChangementDeTuile ; ligne contient l'offset de début de la ligne suivante ld hl,(ix+multi.mapOffset) : ld bc,-64 : add hl,bc : ld (ix+multi.mapOffset),hl : ld a,60 ; passer à la dernière ligne de la tuile dessous .pasDeChangementDeTuile ld (ix+multi.ligne),a ; valider la ligne de tuile ld hl,(ix+multi.adresseDebut) : call PreviousLineHL : ld (ix+multi.adresseDebut),hl ld a,(ix+multi.VSSR) : sub #10 : and #70 : ld (ix+multi.VSSR),a : cp #70 : jr nz,.pasDeChangementDeBloc ld hl,(ix+multi.crtcHL) : ld bc,-32 : add hl,bc : ld (ix+multi.crtcHL),hl ; adresse CRTC baisse de 32 mots si le bloc change .pasDeChangementDeBloc ; on affiche après en remontant ld hl,(ix+multi.mapOffset) : exx ld de,(ix+multi.adresseDebut) ; on continue directement dans l'affichage des lignes ;--------------------------- afficheTuilesHorizontales ;--------------------------- ld a,(ix+multi.colonne) : or a : jr nz,.routineClippee ld yh,16 .loop calculeAdresseTuileLigne 1 ldi 3 ld a,d : and %11111000 ldi : ld c,a : ld a,d : and 7 : or c : ld d,a ; rebouclage de bloc... dec yh : jr nz,.loop ret ;----------------- .routineClippee ;----------------- ld yh,15 ; on aura 15 sprites entiers et 2 sprites partiels calculeAdresseTuileLigneColonne 1 ld a,4 : sub (ix+multi.colonne) : ld c,a ld b,0 : ldir : dec de : ld a,d : inc de : and %11111000 : ld c,a : ld a,d : and 7 : or c : ld d,a ; rebouclage de bloc... .loop7 calculeAdresseTuileLigne 1 ldi 3 ld a,d : and %11111000 ldi : ld c,a : ld a,d : and 7 : or c : ld d,a ; rebouclage de bloc... dec yh : jr nz,.loop7 calculeAdresseTuileLigne 0 ld c,(ix+multi.colonne) ld b,0 : ldir : dec de : ld a,d : inc de : and %11111000 : ld c,a : ld a,d : and 7 : or c : ld d,a ; rebouclage de bloc... ret ;--------------------------------------------------------------------- InitEcran ; IX = structure buffer ; A = poids fort de la page vidéo ld hl,tileMap ld (ix+multi.mapOffset),hl ld hl,0 ld (ix+multi.HSSR),h ld (ix+multi.VSSR),h ld (ix+multi.colonne),h ld (ix+multi.ligne),h ld (ix+multi.crtcHL),hl ld h,a : ld (ix+multi.adresseDebut),hl rrca : rrca : ld (ix+multi.crtc12),a ; Afficher les tuiles sur tout l'écran ld de,(ix+multi.adresseDebut) ld ix,tileMap ; on n'utilise plus la structure à partir de là ld yh,16 ; 16 tuiles en hauteur afficheLigne ld yl,16 ; nombre de tuiles en largeur push de ; sauvegarder l'adresse de début de ligne de l'écran afficheTuile push de ; sauvegarder l'adresse du début de la tuile à l'écran ld h,(ix+0) : inc ix : ld l,0 : srl hl : srl hl ; x 256 / 4 c'est la taille de nos tuiles (64 octets) ld bc,tuiles : add hl,bc ; on a l'adresse de la tile ld a,16 afficheLigneTuile push de : ldi 4 : pop de ld bc,#800 : ex hl,de : add hl,bc : jr nc,.novf : ld bc,64-#4000 : add hl,bc : .novf ex hl,de dec a : jr nz,afficheLigneTuile pop hl : ld bc,4 : add hl,bc : ex hl,de ; se placer juste à côté de la tuile précédente dec yl : jr nz,afficheTuile ld bc,48 : add ix,bc ; revenir à la ligne de tuile (64-16 dans notre cas) pop hl : ld bc,128 : add hl,bc : ex hl,de ; se placer sous les tuiles à gauche dec yh : jr nz,afficheLigne ret ;--------------------------------------------------------------------- NextLineHL ld a,h : add 8 : ld h,a : and #38 : ret nz ; tester le changement de bloc sur n'importe quelle page ld a,64 : add l : ld l,a : ld a,#C0 : adc h : ld h,a : res 3,h : ret PreviousLineHL ld a,h : sub 8 : ld h,a : and #38 : cp #38 : ret nz ; test du chgt de bloc (bis) ld a,l : add #C0 : ld l,a : ld a,#3F : adc h : ld h,a : set 3,h : ret NextLineDE ld a,d : add 8 : ld d,a : and #38 : ret nz ; tester le changement de bloc sur n'importe quelle page ld a,64 : add e : ld e,a : ld a,#C0 : adc d : ld d,a : res 3,d : ret ;--------------------------------------------------------------------- UpdateHardware RMR2 ASICON ld a,(ix+multi.HSSR) : or (ix+multi.VSSR) : or #80 : ld (#6804),a ld hl,(ix+multi.crtcHL) : ld a,h : and 3 : ld h,a : ld a,(ix+multi.crtc12) : or h : ld bc,#BC00+12 : out (c),c : inc b : out (c),a inc c : dec b : out (c),c : inc b : out (c),l RMR2 ASICOFF ret UnlockAsic ld bc,#BCFF out (c),c out (c),0 ld hl,%1001000011101010 .loop out (c),c ld a,h:rlca:ld h,l:ld l,a srl c:res 3,c and #88 or c ld c,a cp #4D jr nz,.loop ld a,#CD out (c),a : out (c),a ret WaitVBL ld b,#F5 : noVBL in a,(c) : rra : jr c,noVBL VBL in a,(c) : rra : jr nc,VBL : ret paletteplus: defw #323,#646,#5B3,#967,#A57,#B95,#6E4,#9B7,#C89,#ABA,#CE2,#DB8,#DB9,#EC6,#EC9,#EED align 256 : tuiles incbin 'mapMulti.bin' align 256 : tileMap include 'mapMulti.tilemap' ; et on se déclare deux structures pour un double buffer struct multi ecran1 struct multi ecran2Et voici notre scroll multi-directionnel 
On se retrouve l'année prochaine pour le passage en double buffer? Des optimisations? Roudoudou CPCrulez[Content Management System] v8.732-desktop/c Page créée en 180 millisecondes et consultée 44 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. |
|