|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Un sprite ("lutin" en français) est une image gérée par le Copper. Cette image préparée par le programmeur est reproduite à l'écran par le Copper. Cette reproduction n'est pas permanente et elle doit être refaite à chaque balayage de l'écran par le faisceau d'électrons. Que doit faire le programmeur ? D'après ce qui précède, il faut : 1. Définir le dessin, c'est-à-dire préciser les pixels qui seront visibles, avec quelle couleur et à quel endroit ils seront affichés. Ceci fait partie de la "structure" du sprite. 2. Prévenir le Copper qu'il doit gérer ce sprite, c'est-à-dire activer le DMA Copper après lui avoir indiqué l'adresse des données qui forment le sprite : l'adresse de sa structure. Ceci est réalisé en deux étapes :
1. La position et la hauteur du sprite La structure doit commencer par deux mots de contrôle (à calculer). Ces deux mots de contrôle indiquent au DMA Copper la position horizontale et verticale de la première ligne du sprite et celle de la dernière ligne + 1 (ce qui indiquera au Copper le nombre de lignes du sprite). Il faut rappeler qu'une ligne du sprite aura une épaisseur de 1 pixel (un point lumineux). Sa position sur l'axe horizontal peut varier en haute ou en basse résolution de 130 à 460 : sur toute la largeur visible de l'écran. Sa position sur l'axe vertical peut varier de 38 à 300 : sur toute la hauteur visible de l'écran. Ces valeurs sont données à quelques pixels près ; il est possible de les vérifier ou de les affiner en changeant les coordonnées du sprite dans le programme exemple. Précisons que si la position du sprite est en dehors de l'écran, le système ne le dessine pas, sans nous envoyer pour autant un de ces Gurus dont il a le secret... L'origine de l'écran visible est en haut à gauche et correspond à la colonne 130 (x = 130) et à la ligne 38 (y = 38). Dans tous les cas, les positions horizontales et verticales peuvent être supérieures à 255, et sont donc codées sur 9 bits, cela donne une disposition d'enfer : Mot de contrôle n°1 :
En fait, E et H fixent la position du coin supérieur gauche du sprite. Le bit de contrôle d'attache permet, s'il est à 1, de combiner deux sprites de quatre couleurs pour en faire 1 de 16 couleurs : 15 couleurs plus celle du fond. Pour simplifier, supposons que les sprites sont indépendants donc que le bit At est à 0. Exemple de calcul des mots de contrôle, pour un sprite de 8 lignes que l'on veut dessiner aux coordonnées x=180 et y=160 : Il est possible d'utiliser cette petite routine qui fait le travail pour vous : On place dans la structure des mots de données dont chaque bit indique comment le pixel correspondant doit être visible. D'un point de vue pratique, ces mots seront définis bit par bit donc en binaire (précédés du signe "%"). Plusieurs paramètres entrent en jeu :
De gauche à droite :
Chaque couleur est un mélange des trois primaires : Rouge, Vert, Bleu. Chaque primaire peut prendre 16 intensités différentes, elle est donc codée sur 4 bits. Donc 12 bits sont nécessaires pour définir une couleur :
En assembleur, cela sera fait pour la couleur 1 par : move.w #$F00,$DFF182 placée au début du programme. Les couleurs peuvent aussi être modifiées (pendant le balayage de l'écran par le faisceau d'électrons) par une instruction MOVE placée dans la liste Copper. Dans cet exemple : dc.w $182,$F00 ou bien dc.w color1,$F00. La fin de la structure La structure doit se terminer par deux mots nuls : dc.w 0,0. Exemple d'une structure sprite complète : ce sprite aurait une hauteur de 8 pixels, il représenterait un petit rectangle. L'intérieur et les bords du rectangle auraient des couleurs différentes. 1. Préparation de la liste Copper Les adresses des structures seront envoyées dans les registres $DFF 120 et suite :
Ces pointeurs sont modifiés par le système au cours du balayage de l'écran, et doivent être restaurés avant chaque balayage, d'où la nécessité de les réinitialiser dans une liste Copper personnelle. On définit dans cette liste Copper la taille de l'écran utilisé avec DIWSTRT et DIWSTOP, ainsi que les cycles DMA alloués au DMA du plan de bits avec DDFSTRT et DDFSTOP. Rentrer dans le détail nous entraîneraient trop loin ; les valeurs utilisées dans le programme exemple sont conseillées, elles définissent l'écran le plus large possible quand on utilise huit sprites en basse résolution (LOW-RES). On définit aussi dans cette liste Copper l'adresse du plan de bits, le mode de résolution, etc. avec les registres BPLCON et BPLMOD. On définit finalement les couleurs qui seront utilisées et, nous y arrivons, les adresses des structures des sprites. Même les sprites inutilisés doivent être redéfinis, on leur attribuera alors l'adresse d'une structure vide (comportant 0,0 comme mots de contrôle). Tout ceci est réalisé dans la liste Copper par des instructions "MOVE ...". Supposons par exemple que la structure du sprite 1 soit à l'adresse $20000, on placerait dans la liste Copper : 2. Installation de la liste Copper Quand la structure et la liste Copper sont prêtes, il faut initialiser le DMA Copper. Il suffit de désactiver le DMA Copper :
...de remplacer la liste Copper du système par la nôtre :
...et de lancer le DMA Copper et le DMA plan de bits dont la participation est nécessaire car l'écran a été redéfini :
Le sprite devient alors visible à l'écran... Ce programme a été écrit sous Devpac2 pour Commodore Revue. Il fonctionnera tel quel sous K-SEKA. Le programme suivant (dernier listing juste au-dessus) dessine un "S" avec un sprite. Pour vous entraîner, essayez de dessiner plusieurs sprites et peut-être même de créer un "super-sprite" en collant côte-à-côte huit sprites : le résultat aura alors 128 pixels de large. Complément sur les structures Il vous semble inutile de finir une structure par deux mots nuls, étant donné que les mots de contrôle indiquent au Copper le nombre de lignes de celle-ci. Il y a à cela une raison très simple : une structure peut contenir plusieurs sprites qui sont "chaînés" les uns aux autres. L'ensemble correspondra pour le Copper au sprite 0 par exemple. Pour ajouter un sprite à la chaîne, on remplace les mots de fin (0,0) par les mots de contrôle du sprite supplémentaire, suivis de ses données et de deux mots de fin nuls. La nouvelle structure ressemblerait à ceci : Est-ce à dire que l'on peut définir autant de sprites que l'on veut ? Hélas, non ! Les limitations qui existent sont dues au fonctionnement du Copper et à la taille de l'écran . En effet, le DMA Copper, quand il gère cette structure, commence par lire la première ligne (logique !). Il voit qu'il s'agit de $A05A et de $A800, il va donc attendre la ligne 160 avant de commencer son travail en ce qui concerne cette structure. Arrivé à la ligne 160, il attend la colonne 180 et reproduit la première ligne du premier sous-sprite à l'écran. A la ligne suivante (161), il reproduit la deuxième ligne du premier sous-sprite, etc. Il arrive donc à la ligne 168 quand il lit et interprète les deux mots de contrôle $D05A et $D200. Il ne pourra commencer de reproduire la première ligne du deuxième sous-sprite qu'à partir de la ligne 169. Conclusion : le deuxième sous-sprite ne sera dessiné que si sa première ligne commence au-delà de la ligne-écran 169. Dans l'exemple choisi, cela ne poserait pas de problème car 208 est une ligne-écran située en dessous de 169. Pour schématiser le déroulement des opérations du Copper :
Si on ajoute un troisième sous-sprite, il ne pourra pas être placé avant la ligne 211 ! Par contre, il n'y a pas de limitation en ce qui concerne sa position sur la ligne 211. Sachant que ce qui vient d'être dit est valable pour les huit structures, il est possible de dessiner et d'animer une vingtaine de sprites ou plus... Dans la limite où ils tiennent sur l'écran, ce qui étend considérablement les possibilités de défilement ! Le mois prochain : comment animer les sprites sous IRQ.
|