Animation avec les sprites hardComme évoqué dans le [ premier article sur les sprites hard ], les sprites hards possèdent leur propre mémoire qu'il faut écrire à chaquefois qu'on veut en changer le contenu. Ce ne sont pas des sprites hard "traditionnels" avec lesquels il n'y aurait que l'adresse des données à changer. En conséquence de quoi, voyons un peu comment nous pouvons en changer le contenu : Copie au LDIR La copie au LDIR est la plus simple. Relativement rapide, cela prendra 1544 nops pour la copie d'un seul sprite. Avec cette méthode, il n'est pas possible de changer tous les sprites hard à l'écran dans la frame (50Hz). Est-ce grave d'être lent? Pas obligatoirement, cette méthode peut être utilisée pour une première initialisation. ld hl,source_de_donnees ; 3 nops ld de,#4000 ; 3 nops ld bc,256 ; 3 nops ldir ; 255 x 6 + 5 nopsCopie au LDIMême technique mais en déroulant le LDIR, on gagne quelques nops, c'est pas foufou ld hl,source_de_donnees ; 3 nops ld de,#4000 ; 3 nops ld bc,256 ; 3 nops copieSprite ldi 32 jp p,copieSpriteBien entendu, on ne va pas dérouler pour chaque copie, on se fera une petite fonction de copie dédiée à copier les 256 octets d'un sprite Copie avec décompression à la volée Dans les techniques lentes, il est intéressant de grouper les pixels par deux. En effet, les données d'un sprite n'ont que 16 valeurs possibles (transparence + 15 couleurs). Ces valeurs n'occupent que 4 bits, on peut doncavoir les informations de deux pixels dans un octet. L'outil convgeneric va générer des groupes de pixels en mettant le premier pixel (celui de gauche) dans les 4 bits du bas et le deuxième pixel (celui de droite) dans les 4 bits du haut. Il faut savoir que l'ASIC ne décode pas toujours tous les bits. Dans le cas des sprites hard, il va IGNORER les 4 bits du haut de l'octet. On peut écrire ce qu'on veut. ld hl,#4000 ; adresse du premier pixel du premier sprite hard ld (hl),#55 ; on envoie #55 mais l'ASIC ne reçoit que #05 ld (hl),#F5 ; tout pareil, il faut considérer que la valeur passe par un filtre de type AND #FComme l'écriture dans l'ASIC va ignorer les bits superflux, la première écriture se fait normalement, on envoit l'octet directement sans utiliser de masque. Pour envoyer le deuxième octet, il faut décaler les bits, afin que les 4 bits du haut se retrouvent... ...en bas Vous pouvez jeter un oeil au [ schéma ] sur les décalages de la rubrique sur les instructions de rotations et décalages. Nous avons plusieurs candidats pour obtenir le résultat que l'on veut : SRL, SRA, RRCA, RLCA. Le SRL est le plus intuitif car il va vider la partie haute tout en décalant vers le bas. Par contre, l'instruction est lente, le coût total est de 8 nops. Le RRCA et le RLCA vont faire la ronde des bits. Comme ces instructions ne font que 1 NOP, l'opération est effectuée en 4 NOP seulement. 01101111 ; valeur de départ 11011110 ; après 1x RLCA 10111101 ; après 2x RLCA 01111011 ; après 3x RLCA 11110110 ; après 4x RLCAEt dans l'autre sens c'est pareil, mais différemment. 01101111 ; valeur de départ 10110111 ; après 1x RRCA 11011011 ; après 2x RRCA 11101101 ; après 3x RRCA 11110110 ; après 4x RRCAVoici le détail de la routine de copie à partir de pixels groupés. ld hl,source_de_donnees ; 3 nops ld de,#4000 ; 3 nops decrunchSprite ld a,(hl) : inc hl ; on lit deux pixels groupés qu'on met dans A ld (de),a : inc e ; copier le premier pixel, les 4 bits du haut sont ignorés rrca : rrca : rrca : rrca ; faire tourner l'octet source de 4 bits sur lui même ld (de),a : inc e ; écrire le deuxième pixel jr nz,decrunchSprite ;On descend à 2181 nops mais les données de nos sprites sont deux fois plus petites! À retenir ;) Avec une petite table de conversion, contenant l'octet pré-shifté de 4, et en alignant les données sources sur 128, on peut gratter un peu (256 nops). Et si on déroule un peu, on gagne encore un peu plus de 300 nops. La routine reste lente comme une copie au LDIR mais nos données sont deux fois plus petites, c'est excellent pour un usage peu exigeant. startingindex 0 align 256 tableDecale4 repeat 256,x defb x>>4 renddecrunchSprite ; HL = source alignée sur 128 octets ; DE = destination dans l'ASIC ld b,hi(tableDecale4) ; poids fort de la table de conversion dans B .loop repeat 8 ld a,(hl) : inc l : ld (de),a : inc e ld c,a ; on copie la valeur du groupe de pixel dans C pour indexer dans la table ld a,(bc) ; on va lire la valeur de notre table, 4 shifts d'un coup pré-calculés ld (de),a : inc e rend jr nz,.loop ret Rendez-vous dans l'[ article suivant ] pour voir une méthode performante et souvent adaptée au jeu. Roudoudou CPCrulez[Content Management System] v8.732-desktop Page créée en 130 millisecondes et consultée 6 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. |
|