L'affichage de sprite au XORPetit rappel sur les opérations logiques, en particulier celle de type [ XOR ]. table de vérité du XOR 0 XOR 0 = 0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR 1 = 0Le XOR est utilisé en chiffrement car son utilisation deux fois de suite avec la même valeur permet de retrouver la valeur d'origine. Cette propriété utilisée en cryptographiepeut aussi nous servir pour réaliser un affichage réversible d'un sprite!Au lieu d'écraser les données de l'écran comme nous le faisions, nous allons effectuer un XOR entre la donnée du sprite et l'écran. C'est la seule chose qui va changerde notre routine précédente de sprite. ld a,(de) ; prendre l'octet de l'écran destination xor (hl) ; faire le XOR ld (de),a ; remettre à l'écran inc hl : inc de ; incrémenter nos pointeursDans cette opération cryptographique, le sprite est la clef de chiffrement. Appliquer deux fois la clef (ou le sprite) fait revenir les données à leur état initial.Ainsi, on retrouve notre arrière plan. Seul problème, c'est moche dès que le sprite n'est pas au dessus de la couleur zéro. Jeu Sorcery utilisant l'affichage au XOR
Le programme suivant utiliser un fond uni sur la moitié droite de l'écran et un bitmap sur la moitié gauche de l'écran, ensuite nousallons déplacer notre sprite en X suivant la technique du [ TRON ] que vous avez bien sûr programmé précédemment. Ainsi on verra que tout se passe bien sur l'encre 0 mais que les effets secondaires sur du bitmap sont désagréables. Selon VOS besoins, sur un jeu comme Sorcery avec desdécors en majorité non franchissables, cette routine fait simplement le travail. Téléchargez [ce sprite] et [ce fond d'écran] puis assemblez ce code source. 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 ; définir notre coordonnée X et son incrément pour faire bouger le sprite tout seul ld hl,40 ; milieu écran en nombre d'octets ld (positionx),hl ld hl,1 ld (incrementx),hl ;**************** BouclePrincipale ;**************** ld bc,(positionx) ld hl,80 ; Y=80 pour être à peu prêt centré ld xl,9 : ld xh,36 ; dimensions du sprite largeur/lignes ld de,donnees_sprite : call AfficheSprite ld b,18 ; 3 frames tempo halt : djnz tempo ; le réafficher au même endroit pour l'effacer ld bc,(positionx) ld hl,80 ; Y=80 pour être à peu prêt centré ld xl,9 : ld xh,36 ; dimensions du sprite largeur/lignes ld de,donnees_sprite : call AfficheSprite ; déplacer notre sprite ld hl,(positionx) : ld bc,(incrementx) : add hl,bc : ld (positionx),hl ; gérer le "rebond" aux bords ld a,h : or l : jr nz,.pasGauche : ld hl,1 : ld (incrementx),hl : .pasGauche ld a,l : cp 79-9 : jr nz,.pasDroite : ld hl,-1 : ld (incrementx),hl : .pasDroite jr BouclePrincipale positionx defw 0 incrementx defw 0 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é ; Plus de LDIR ! .afficheXOR ld a,(de) : xor (hl) : ld (de),a inc hl : inc de dec c : jr nz,.afficheXOR 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 add hl,bc ; ajouter la position en OCTETS ! 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 palette defb #54,#56,#5C,#46,#5E,#40,#47,#43,#4E,#4B,#4C,0 ; black donnees_sprite incbin 'hibouNoir.bin' org #C000 : incbin 'middleForest.bin' Notre hibou s'affiche proprement (enfin si on excepte le scintillement) sur le fond noir. Par contre il devient difficilement lisible quand on l'affiche sur la forêt MAIS le fond se restitue bien. La prochaine étape va être de faire disparaitre ce scintillement en utilisant un double buffer. Roudoudou CPCrulez[Content Management System] v8.732-desktop/c Page créée en 643 millisecondes et consultée 28 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. |
|