Un nombre illimité de sprites?
Pour se détendre de toute cette théorie, on va jouer un peu avec les buffers pour un effet visuel bluffant qui n'aura d'autre intérêt que surprendre visuellement. Une quantité de sprites apparemment sans limite sur tout l'écran! Mais comment cela se peute? Ce peut-il? M'enfin! Comment cela est donc possible? En fait nous allons poser des sprites et ne jamais les effacer. Et pour donner l'illusion qu'ils bougent, nous allons utiliser 3 écrans vidéos en alternance. 
On réutilise le source précédent ou presque. On va tailler dedans, le raccourcir! Plus besoin de sauvegarde, plus besoin de restitution, il faut initialiser les 3 pages vidéos (incbin tout en bas du source). Enfin, il faut que les sprites suivent une trajectoire changeante pour bien remplir l'écran de partout. Pour la trajectoire, j'utilise un simple sinus que je lirai en changeant uniquement le poids faible de l'adresse. Ainsi, pour rappel, une fois qu'on incrémente la valeur 255 on revient à zéro. Pour que la lecture fonctionne correctement, il nous faut 256 valeurs ET que le début du tableau commence sur une adresse multiple de 256. Enfin, j'utiliserai deux tables car l'amplitude n'estpas la même en X et en Y. align 256 ma_table_sinus ang=0 repeat 256 defb sin(ang)*35+35 : ang=ang+360/256 rendL'amplitude en X par de zéro et va jusqu'à la largeur écran-largeur_sprite-1. L'amplitude en Y ira de 0 à hauteur_ecran-hauteur_sprite-1. Enfin, comme la valeur d'un sinus s'étends de -1 à 1, ilfaut diviser cette amplitude par 2 avant de la multiplier au sinus. Enfin on ajoutera l'amplitude divisée par 2 pour que nos nombres soient tous positifs. Si les sinus/cosinus sont un peuobscurs pour vous, n'hésitez pas à me faire des retours, on pourra faire des cours dessus et jouer avec plus en détail.On est partis? Utilisation de [hibouZéro] et [forêtZéro] 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 ;****************** BouclePrincipale ;****************** call waitVBLStart call waitVBLStart ; on attend d'être sûr que l'écran précédent soit complètement affiché ld a,#10 : ld b,#80 : call AfficherHibou ; call waitVBLStart call waitVBLStart ; on attend d'être sûr que l'écran précédent soit complètement affiché ld a,#20 : ld b,#C0 : call AfficherHibou ; call waitVBLStart call waitVBLStart ; on attend d'être sûr que l'écran précédent soit complètement affiché ld a,#30 : ld b,#40 : call AfficherHibou jr BouclePrincipale ;================================================================= ; parcourir les tables de sinus et envoyer les sprites à la suite ;================================================================= AfficherHibou push bc : ld bc,#BC00+12 : out (c),c : inc b : out (c),a : pop bc ld h,hi(sinuzix) : ld a,(sinusXpos) : ld l,a : ld c,(hl) ld de,donnees_sprite ld h,hi(sinusite) : ld a,(sinusYpos) : ld l,a : ld l,(hl) : ld h,0 ld xl,9 : ld xh,36 ; dimensions du sprite largeur/lignes call AfficheSprite ld hl,sinusXpos : inc (hl) : inc hl : inc (hl) ; bouger sur les sinus .dephase ld a,0 : inc a : and 15 : ld (.dephase+1),a : ret nz inc (hl) ; extra incrémentation tous les 16 passages pour varier la trajectoire trop régulière sinon ret sinusXpos defb 45 sinusYpos defb 0 waitVBLStart ld b,#F5 .loop in a,(c) : rra : jr c,.loop waitVBL .loop in a,(c) : rra : ret c : jr .loop ; ------------------------------- AfficheSprite ; BC=page + coordonnée X (0-79) / 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 call CalculeAdressePixel ; HL=destination écran ; DE=toujours l'adresse source des données ld bc,hl ; on utilise BC comme destination écran ld h,hi(tableTransparence) .afficheLignes ld a,xl : ld yl,a ; chargeur la largeur d'une ligne dans YL push bc ; on met l'adresse de début de la ligne de côté .pixelMasque ld a,(de) ; lire le sprite ld l,a ; octet du sprite dans L ld a,(bc) ; on récupère l'octet de l'écran and (hl) ; on applique le masque or l ; on fusionne avec la donnée du sprite ld (bc),a ; on remet dans l'écran inc bc inc de ; et on incrémente data+ecran dec yl jr nz,.pixelMasque pop bc ; on récupère l'adresse du début de ligne ; et on calcule le passage à la ligne suivante ; notre routine de passage à la ligne suivante, adaptée pour BC ld a,b : add 8 : ld b,a ; ajouter #800 à DE and #38 ; on teste si on déborde de la bank (passage de page+#3800 à page+#0000) jr nz,.nextLine ; pas zéro, on est toujours dans le même bloc de lignes ld a,80 : add c : ld c,a ; on ajoute 80 (largeur d'une ligne en octets) pour passer au bloc suivant ld a,#C0 : adc b : ld b,a ; et on enlève #4000 (additionner #C000 c'est comme enlever #4000) .nextLine dec xh ; notre compteur de lignes jr nz,.afficheLignes ret ;------------------- CalculeAdressePixel ; B=page vidéo #00, #40, #80 ou #C0 ; C=coordonnée X (0-79) ; HL=coordonnée Y (0-199) ; adresse de la ligne dans HL en résultat add hl,hl ; adresses 16 bits, il faut indexer de 2 en 2 ld a,lo(tableau) : add l : ld l,a : ld a,h : adc hi(tableau): ld h,a ld a,(hl) : inc hl ld h,(hl) : ld l,a add hl,bc ; ajouter la position X en octets et la page! ret ;------------------- adresse_ecran=#0000 largeur_ecran=80 tableau repeat 25 repeat 8 defw adresse_ecran adresse_ecran+=#800 rend adresse_ecran+=largeur_ecran adresse_ecran-=#4000 rend align 256 tableTransparence repeat 256,x px=x-1 ; car le compteur va par défaut de 1 à 256 et non 0 à 255 masque=0 if (px & (128|32|8|2))==0 masque|=128|32|8|2 ; pour cet octet on conservera les données écran endif if (px & (64|16|4|1))==0 masque|=64|16|4|1 ; pour cet octet on conservera les données écran endif defb masque rend align 256 sinusite ang=0 repeat 256 defb sin(ang)*80+80 : ang=ang+360/256 rend sinuzix ang=0 repeat 256 defb sin(ang)*35+35 : ang=ang+360/256 rend palette defb #4D,#54,#56,#5C,#46,#5E,#40,#47,#43,#4E,#4B,#4C,0 ; Rose en zéro donnees_sprite incbin 'hibouZero.bin' ; initialiser notre écran sur les trois pages! org #4000 : incbin 'foretZero.bin' org #8000 : incbin 'foretZero.bin' org #C000 : incbin 'foretZero.bin'Et voici un déroulé temporel dans chacune des banques avec l'affichage écran. On remarque (évidemment j'ai envie de dire) que l'écran a toujours un temps de retard, ceci est dû au fait que la mémoire est mise à jour avant que le balayage n'ait parcouru cette même mémoire. Le point d'arrêt pour réaliser ces séquences était posé juste au début de la routine qui affiche le hibou, lorsque la synchro est terminée. 
Roudoudou CPCrulez[Content Management System] v8.732-desktop/c Page créée en 201 millisecondes et consultée 26 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. |
|