CODING ★ CRÉATION ET ANIMATION DE SPRITES ★

Graphic - CPC 27 - Creation et Animation de Sprites (CPC Revue)

Organisation de la mémoire écran

A - Adressage écran

Le sujet ayant déjà été traité dans CPC n° 16 p. 24, je me contenterai d'y ajouter un complément sous la forme du programme SCRNMAP.BAS, qui établit une carte complète de la mémoire écran.

B - Nombre de pixels disponibles selon le mode.

L'écran dispose d'une résolution verticale de 400 lignes, or le système n'en adresse que 200. Quel est donc ce mystère ? Essayez donc la ligne BASIC suivante :

10 FOR Y-0 to 399:PL0T 200,Y,1:NEXT

Une ligne se dessine sur la hauteur de l'écran. Maintenant, essayez :

10 FOR Y-0 to 399:STEP 2:PL0T 300,Y,1:NEXT

Surprise, la ligne est identique, mais se trace beaucoup plus rapidement. Ceci nous permet de constater que deux points de l'écran sont adressés simultanément dans le sens vertical et introduit la notion de PAS DE DEPLACEMENT. La résolution verticale restant inchangée dans les 3 modes, ce dernier SERA TOUJOURS DE DEUX.
Les choses se compliquent dans le sens horizontal. (Pas de mauvaises pensées, SVP !)

Nous disposons de 80 cases mémoire de 1 octet chacune et de 640 positions possibles soit 8 pixels * 80 cases. En mode 2 :

10 FOR X-0 to 639:PL0T X,100,1:NEXT

Trace une ligne en travers de l'écran. Ajouter une instruction STEP, 2 tracera un pointillé. On en déduit donc que dans 1 octet: 1 bit mis = 1 point allumé à l'écran : POKE &C000,&X10101010 allumera un pointillé en haut à gauche de l'écran. Essayez avec différentes valeurs binaires pour étudier le résultat et souvenez-vous qu'en BASIC, les valeurs de PAPER ou PEN sont exclusivement 0 pixel éteint et 1 pixel allumé.

EN MODE 2 LE PAS DE DEPLACEMENT SERA DE UN AVEC 639 POSITIONS POSSIBLES.

En mode 1, nous avons 4 couleurs simultanées pour PAPER - PEN (0 à 3) soit 00,01,10,11 en binaire. Deux bits sont donc nécessaires pour attribuer un stylo. Quoi que l'on fasse, un octet n'acceptera jamais que 8 bits, il devient donc nécessaire d'allumer deux points écran simultanément et nous ne disposerons plus que de 4 pixels au lieu de 8 par octet écran. 8/4 = 2. Vérifier en ajoutant step 2 à la ligne 10.

EN MODE 1 LE PAS DE DEPLACEMENT SERA DE DEUX AVEC 319 POSITIONS POSSIBLES.
En mode 0, c'est de 16 stylos simultanés dont nous disposons, donc de 0 à 1111 en binaire soit 4 bits. En suivant le raisonnement précédent, nous voyons qu'EN MODE 0 LE PAS DE DEPLACEMENT SERA DE QUATRE AVEC 159 POSITIONS POSSIBLES.

Notez que dans le calcul des coordonnées X & Y le 0 est inclusif.

C - Codage des couleurs

En mode 2, pas de problème : bit à 1 = couleur affectée à PEN 1, bit à 0 couleur affectée à PEN 0.

En mode 1, les couleurs de 0 à 3 sont codées comme suit :

Composition des 4 pixels de gauche à droite.

PIXEL : A B C D
BITS : 3&7 2&6 1&5 0&4
VALEUR : 0 1 1 1 1 0 0 0
PEN : 1 3 2 0

Remettons les choses en ordre :

BITS : 7 6 5 4 3 2 1 0
OCTET : 0 0 1 0 1 1 0 1 - 198 décimal

MODE 1 : POKE &C000, &X11000110 pour voir le résultat.

En mode 0, le codage des couleurs de 0 à 16 se réalise comme suit :

PIXEL : GAUCHE DROITE
BITS : 1-5-3-7 0-4-2-6
VALEUR : 0 1 1 0 1 0 1 0
PEN : 6 ;10

L'octet recomposé :

BITS : 7 6 5 4 3 2 1 0
OCTET : 0 0 1 0 1 1 0 1 = 45 décimal
MODE 0 : POKE &C000, &X00101101

Le programme "PIXELMAP" est conçu pour mettre en évidence ces particularités. En mode 1 & 2, vous pouvez entrer les codes directement en binaire ou en décimal. Si l'hexadécimal vous tente, précédez la valeur de "H". En mode O, les entrées ne sont acceptées qu'en décimal.

Dans les 3 modes, donner - 1 renvoi au menu.

QU'EST-CE QU'UN SPRITE ?

Le SPRITE (Lutin in french), peut être défini comme une longue liste de DATAS. Elle contient les codes couleur de chaque case mémoire d'une image destinée à être représentée à l'écran. Cette dernière devant, de préférence, affecter la forme d'un rectangle, les hauteur et largeur de chaque dessin devront donc, obligatoirement, être connues du programme exploitant. Dans le cas où les dessins d'une table sont de taille différente, les dimensions de chacun seront incluses dans la table ainsi que quelques octets supplémentaires (3 dans le cas de SURGENE). Ces 3 octets sont dans la plupart des cas, un gaspillage de mémoire, mais dans des cas bien précis, (contrôle d'affichage, rang de priorité, miroirs, collisions etc.) ils éviteront d'avoir à recourir à une table d'état et de jongler avec des pointeurs supplémentaires.

Avantages du SPRITE :

Il permet l'affichage, le déplacement ou la modification d'un motif multicolore de taille quelconque. Cela de toutes les manières possibles et imaginables. C'est la seule manière concevable de réaliser une animation de qualité.
Inconvénients .

Bien que théoriquement réalisable en BASIC, le procédé demanderait des rafales de PEEK et POKE à l'intérieur des boucles FOR NEXT. Vous auriez le temps de lire plusieurs pages de votre revue favorite avant qu'un motif de quelques pixels ait fait le tour de l'écran. Dont. LANGAGE ASSEMBLEUR OBLIGATOIRE.

Gourmande en mémoire, la méthode exige le choix d'une programmation parfaitement adaptée à l'application souhaitée. De nombreuses possibilités d'animation vous seront présentées par la suite. Un programme spécial doit être utilisé pour créer les dessins, il a été publié dans les numéros précédents. (Pas trop usés, les doigts ?...)

La première décision à prendre sera l'organisation de la table de données. 2 solutions sont possibles :

Table à intervalles fixes

Cette organisation impose un intervalle constant entre chaque série de données. Si vos sprites sont tous de dimensions égales, son rendement sera optimum car l'accès aux données sera aussi rapide que possible. Si les différences entre taille maximum et minimum sont de l'ordre de quelques octets, vous gaspillerez un peu de place en mémoire. Mais avec des lignes de 100-200 octets et d'autres de 10, la solution 2 est la seule envisageable.

Il existe aussi un terme intermédiaire : supposons qu'un jeu d'arcade soit basé sur le principe suivant :
Une base d'envahisseurs représentée par un dessin de grande taille, libère un grand nombre de chasseurs de forme différente mais de même dimension (disons 30 sprites de 10 * 10 pixels), destinés à détruire votre vaisseau qui, lui, est de taille moyenne, (vicieux, n'est-ce pas ?)

Dans ce cas, vous devrez créer 2 tables. La première d'intervalle fixe contenant 30 envahisseurs, la seconde d'intervalle variable, contenant la base et votre chasseur.

STRUCTURE ET EXPLOITATION D'UNE TABLE A INTERVALLES FIXES

X est une constante égale à la dimension du plus grand sprite utilisé.

; SPT1 SPT2 SPT3 SPT4 SPT5 Etc
ADSP ----> !----------!----------!----------!----------!----------!----------!
; X X X X X X

ADSP = adresse où commence la table en mémoire.

Détaile d'un sprite :

!----------!----------!----------!----------!----------!----------!----------!--------
;01 ;02 ;03 Hauteur Longueur D1 D2 Etc

01, 02, 03 3 octets réservés pour usage divers. Les dimensions H & L de chaque rectangle étant les mêmes, il est donc inutile d'aller les chercher dans la table. Je ne les ai pas représentés ici car ils sont systématiquement inclus par SURGENE. D 1 = Code de la première case écran à remplir, D2 de la seconde etc...

Exemple de recherche dans une table de ce type :

LD A,NUMERO DU SPRITE RECHERCHE
LD DE,LONGUEUR D'UNE ZONE DE DONNEE (Constante X)
LD HL,ADRESSE DE LA TABLE (ADSP)
BOUCLE DEC A
JR Z ,TROUVE
ADD HL,DE ;ACSP = ADSP + X
JR BOUCLE
TROUVE ;A ce point HL pointe sur l'octet 01 du spnte recherché
INC HL ;sur 02
INC HL ;sur 03
INC HL ;sur H
INC HL ;sur L
INC HL ;sur la première case du sprite.

Les opérations d'affichage peuvent commencer.

SURGENE est initialement conçu pour générer des tables à intervalles variables, cela n'interdit pas pour autant de créer aussi des tables à intervalles fixes. Procéder comme suit :

Déterminer préalablement la taille de grille nécessaire au dessin de la plus grande image. En hauteur : la dimension grille est égale au nombre de lignes requises par le motif. La longueur de grille correspond au nombre de cases mémoire * par le nombre de pixels contenus par une case. (2-4-8 selon mode écran). Une taille de la grille représente un pixel. Si ces propos vous laissent perplexe, revoyez le chapitre mémoire écran. Ensuite, pour créer votre table, utilisez toujours les MEMES DIMENSIONS DE GRILLE et lors de la sauvegarde, l'option GRILLE COMPLETE. Avec cette option, les lignes et colonnes vides sont considérées comme faisant partie du rectangle.

Le coin en haut à gauche de la grille représente le premier pixel de la première ligne du rectangle. Si votre sprite ne remplit pas la grille, déplacez-le sur ce point avant la sauvegarde, cela vous facilitera la vie (sauf cas particuliers dont on reparlera).
Si vous prenez la précaution de créer des dessins selon la formule : longueur de la grille / nombre pixels dans une case = résultat entier, vous allégerez considérablement le travail de programmation ultérieur. Notamment si vous désirez réaliser des effets de miroir.
En effet, le plus petit dénominateur est un octet complet. Si la dernière case mémoire du lutin n'est pas entièrement utilisée, SURGENE complète avec 1 ou plusieurs pixels de stylo 0. Un décalage dont il faudra tenir compte si l'on veut juxtaposer 2 sprites sans laisser une bande de pixels de la couleur du papier.

Table à intervalles variables

Dans ce cas les zones de stockage de chaque sprite sont de longueur différente. Il devient impossible de retrouver une zone par incrémentation régulière, d'où la nécessité de connaître à l'avance l'adresse qui exigera 2 octets par dessin. Ces deux octets ADSPT contiennent la valeur de l'adresse où commence les données du dessin SPT N. Cette table d'adresse est systématiquement générée par SURGENE.

STRUCTURE ET EXPLOITATION D'UNE TABLE A INTERVALLES VARIABLES

Tables des sprites

;SPT1 SPT2 ; SPT3 SPT4 ETC
;!----------!----------------------!----------!----------!--------
ADSPT1 | ;| ADSPT2 ADSPT3| ; | ADSPT4 |ADSPT5

Tables d'adresses

;ADSPT1 ADSPT2 ADSPT3 ADSPT4 ADSPT5 ETC
;!--------!--------!--------!--------!--------!--------!
ADTABLE1 2 oct 2 oct 2 oct 2 oct 2 oct 2 oct

Détail d'un sprite

Ici, les dimensions H & L, différentes pour chaque sprite, doivent être recherchées dans la table.

!--------|---------|---------|---------|---------|---------|---------|----
| 01 02 ;03 H ;L D1 D2 Etc
ADSPT | 3 oct. données diverse Hauteur Largeur

Recherche d'un sprite d'après une table d'adresses

LD A,NUMERO DU SPRITE
LD IX,ADTABLE Début de la table d'adresse dans IX
BOUCLE DEC A
JR Z,TROUVE
INC IX ; Adresse suivante
INC IX
JR BOUCLE
TROUVE Ici IX Pointe sur l'adresse qui contient l'adresse du dessin
LD L,(IX+0 ) Ne pas oublier que le Z80 range l'octet -faible
LD H,(IX+1) en premier
Ici HL Pointe sur le premier octet du sprite 01
INC HL ;02
INC HL ;03
INC HL ; Pointe sur l'octet contenant la hauteur
LD C,(HL) ; Hauteur dans C
INC HL ; Pointe sur 1'octet contenant la longueur
LD B,(HL) ; Longueur dans B
LD (DIMENSIONS), BC Les 2 sont rangées en mémoire
INC HL ; Pointe sur le premier pixel

L'affichage peut commencer

N'OUBLIEZ PAS QUE LA TABLE D'ADRESSE CONTIENT DES POINTEURS, C'EST A DIRE L'ADRESSE DE LA DONNEE A UTILISER ET QUE 2 OPERATIONS SUCCESSIVES SONT NECESSAIRES POUR EXTRAIRE CETTE DONNEE.

DETAIL DE LA STRUCTURE D'UNE TABLE DE TRAVAIL SURGENE

Table d'adresse

Adresse : Contenu

21856 - : Mode écran requis par les sprites.
21857 - : Nombre de dessins.
21858 - 59 : Pointeur de la table des encres.
21860 - 61 : Pointeur du premier sprite
21862 - 63 : du second
21864 - 65 : et tant qu'il y aura des sprites... (air connu).

Table sprites

Emplacement du premier sprite = 21856 + 4 octets + (Nombre de sprites * 2), ou plus simplement : contenu de 21860 : LD HL, (21860).

Les deux premiers octets à cet emplacement sont à la disposition de l'utilisateur. Le suivant permet de déterminer si le sprite a été conçu en miroir. 0 si non. 1 si HM, 2 si MV, 3 si MD. Si vous n'utilisez pas de miroir, cet octet est libre. Les octets 4 & 5 contiennent la hauteur et la longueur du sprite.
Emplacement second sprite = 21856 + 4 + (nombre de sprites * 2) + la longueur du premier sprite. (égale à hauteur sprite * longueur sprite) + 5 octets. Ou bien contenu de 21862. Et ainsi de suite. Table des encres : elle est située à la suite du dernier sprite de la table et utilise : 1 octet par stylo de 1 à 1 5, 3 ou 1 (selon le mode). Elle est terminée par un octet # FF pour en marquer la fin. Ces octets contiennent le numéro d'encre affecté au stylo pointé. Ils sont initiali-sés lors de l'option purge.

L'étude de cette structure révèle que, si vous avez décidé de créer une table à intervalles fixes, de nombreux octets deviennent inutiles. Notamment la table d'adresse et les données concernant hauteur et longueur. Soit 4 octets par sprite ou bien 7 ; si vous n'utilisez pas les octets de données. Une bonne connaissance des LDIR et LDDR vous permettra de créer un programme optimisant ce type de table. Sinon, l'option "merge" de SURGENE vous offre un palliatif.

1 - Pour concaténer 2 tables, le programme découpe en 4 fichiers différents, la table présente en mémoire et les sauvegarde sur le disque sous les noms : a - TN.BIN : les noms des sprites : A l'adresse 19256
b - TI.BIN : la table des encres : A l'adresse 20256
c - TA.BIN : la table des adresses : A l'adresse 21 856
d - TS.BIN : la table des sprites : A l'adresse 21856 + 4 + (nombre de sprites * 2). C'est cette dernière qui nous intéresse car elle contient les seules données des sprites. Vous pouvez donc éliminer la table des adresses par ce moyen. Ce sera toujours ça de gagné. Vous n'êtes, dans ce cas, pas tenu de pousser le "MERGE" jusqu'à la fin. "Répondez N" quand le programme, demande s'il doit .changer une table. Vous retournerez au menu juste après la création des 4 fichiers.

STRUCTURE DE LA TABLE CHANTIER

L'adresse 21856 contient toujours #FF. Le premier octet de donnée du sprite (contenu de l'adresse indiquée par le pointeur de sprite), renferme le mode dans lequel a été conçu le sprite. La table des encres n'est pas créée, le premier pointeur (21858-59) indique au programme l'adresse où devra commencer le sprite suivant.
En 19256 figure un buffer de 100*10 octets. Ce dernier contient les noms affectés aux sprites.

19256 NOM1
19266 NOM2

L'octet de remplissage est #20 En 20256 c'est un buffer de 16 * 100 octets, destiné à contenir les numéros d'encres attribués à chaque sprite. Le stylo 0 n'est jamais pris en compte. Un code #FF termine chaque série. La série 100 en 21841 (jamais utilisée) contient le nom de la table. L'octet de remplissage est #E5.

CPC n° 27

★ ANNÉE: 1988
★ AUTEUR: MICHEL MAIGROT
 

★ AMSTRAD CPC ★ DOWNLOAD ★

Other platform tool:
» coding  graphic-CPC  27-creation  et  animation  de  sprites  CCDATE: 2012-07-10
DL: 364
TYPE: PDF
SiZE: 2328Ko
NOTE: 3 pages/PDFlib v1.6

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding Src's » Especial Graficos por Marize Benayas Pazos (Amstrad Especial)
» Coding Src's » Recursive Squares (Amstrad Computer User)
» Coding Src's » Titulares sinuosos (Amstrad Personal)
» Coding Src's » Graphic - Skulls (Amstrad Computer User)
» Coding Src's » Graphic - 3-D Cube on Amstrad
» Coding Src's » Jord
Je participe au site:
» Vous avez des infos personnel, des fichiers que nous ne possédons pas concernent ce programme ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 741 millisecondes et consultée 2863 fois

L'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.