Déplacer un sprite soft proprementOn va enfoncer une porte ouverte, pour ne pas que le balayage passe au moment où on affiche le sprite, il suffit d'afficher le sprite quand le balayage est ailleurs. Il existe des méthodes pointues pour ne jamais avoir cet effet de cisaillement (Tearing). Certains comptent le temps machine que va prendre leur routine et calculent enpermanence où ils sont à l'écran. D'autres utilisent des techniques à double écran (double Buffer), travaillant tranquillement dans un écran quand c'est l'autre qui estaffiché. Mais la méthode la plus simple quand on est sûr d'avoir rapidement terminé, c'est d'attendre que le balayage soit en bas de l'écran pour afficher. C'est le PPI qui va nous permettre de lire l'état de la VBL. La routine n'est pas compliqué, on lit le port B du PPI (#F500) et c'est le bit 0 qui nous renseigne sur l'état de la VBL.Un décalage va mettre ce bit dans la retenue. waitVBL ld b,#F5 .loop in a,(c) : rra : jr nc,.loop retNe reste plus qu'à ajouter cette routine et à l'appeler avant chaque affichage!Téléchargez [ce sprite] si ce n'est pas déjà fait, puis assemblez ce code source (vous avez le droit de le lire, il est commenté de partout). BUILDSNA : BANKSET 0 ORG #100 RUN #100ld bc,#7F00+%10001100+%00 : out (c),c ; MODE 0 ; on règle quelques couleurs pour notre sprite ld bc,#7F00 : out (c),c : ld a,#54 : out (c),a ld bc,#7F01 : out (c),c : ld a,#44 : out (c),a ld bc,#7F02 : out (c),c : ld a,#5C : out (c),a ld bc,#7F03 : out (c),c : ld a,#5E : out (c),a ld bc,#7F04 : out (c),c : ld a,#4E : out (c),a ld bc,#7F05 : out (c),c : ld a,#43 : out (c),a ld bc,#7F06 : out (c),c : ld a,#4B : out (c),a ld iy,listePositions deplacerSprite call waitVBL ld c,(iy+0) : inc yl ; en n'incrémentant que le poids faible, on revient tout seul ; au départ au bout de 256 valeurs ld b,0 ; X=(iy+0) ld hl,80 ; Y=80 ld xl,21 ld xh,72 ld de,donnees_sprite call AfficheSprite jr deplacerSprite align 256 listePositions angle=0 repeat 256 defb sin(angle)*30+30 angle=angle+360/128 ; 2 périodes histoires d'aller plus vite rend waitVBL ld b,#F5 .loop in a,(c) : rra : jr nc,.loop ret AfficheSprite ; BC=coordonnée X (0-319) ; HL=coordonnée Y (0-199) ; DE=adresse des données du sprite ; XL=largeur du sprite en octets ; XH=hauteur du sprite en nombre de lignes push de ; on met DE dans la pile car le calcul d'adresse s'en sert call CalculeAdressePixel pop de ; et on récupère DE ; HL=destination écran ; DE=toujours l'adresse source des données ex hl,de ; on permute source et destination pour être utilisées ; avec l'instruction LDIR .afficheLignes ld b,0 ld c,xl ; chargeur la largeur d'une ligne push de ; on met l'adresse de début de la ligne de côté ldir ; copier la ligne de HL vers DE sur BC octets pop de ; on récupère l'adresse du début de ligne ; et on calcule le passage à la ligne suivante ex hl,de ; on permute HL et DE pour pouvoir faire des additions ld bc,#800 : add hl,bc : jr nc,.dansLeBloc ld bc,80-#4000 : add hl,bc ; changement de bloc! .dansLeBloc ex hl,de ; on permute à nouveau pour retrouver notre DE une ligne plus bas dec xh ; notre compteur de lignes jr nz,.afficheLignes ret ;------------------- CalculeAdressePixel ; BC=coordonnée X (0-159) ; HL=coordonnée Y (0-199) ; adresse de la ligne dans HL en résultat ld de,tableau add hl,hl ; adresses 16 bits, il faut indexer de 2 en 2 add hl,de ld a,(hl) : inc hl ld h,(hl) : ld l,a srl bc : add hl,bc ret ;------------------- adresse_ecran=#C000 largeur_ecran=80 tableau repeat 25 repeat 8 defw adresse_ecran adresse_ecran+=#800 rend adresse_ecran+=largeur_ecran adresse_ecran-=#4000 rend donnees_sprite incbin 'quiPique.bin'Le déplacement de notre sprite est beaucoup plus fluide et il n'y a plus d'effet de cisaillement. Encore une victoire de canard! Bon, dans les faits, on ne va pas se mentir, la routine est très lente, le sprite est gros, il s'en est fallu de peu qu'on continue à se manger le cisaillement quand même ^_^. On voit sur la capture ci-dessous que quand l'affichage est terminé (en bas du sprite), le balayage a déjà commencé à parcourir le haut du sprite! 
Roudoudou CPCrulez[Content Management System] v8.732-desktop/c Page créée en 595 millisecondes et consultée 24 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. |
|