Obligement - L'Amiga au maximum

Jeudi 18 octobre 2018 - 20:34  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles en d'autres langues


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


Programmation : Assembleur - Création d'un sprite (1ère partie)
(Article écrit par Dominique Genot et extrait d'Amiga News Tech - juin 1990)


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 :
  • On redéfinit une liste Copper (rappelons qu'il s'agit des instructions que doit exécuter le Copper au cours du balayage de l'écran).
  • On remplace la liste Copper du système par la nouvelle.
Structure d'un sprite

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 :
  • Bit numéro : 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  • Correspondance : E7 E6 E5 E4 E3 E2 E1 E0 H8 H7 H6 H5 H4 H3 H2 H1
Mot de contrôle n° 2 :
  • Bit numéro : 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  • Correspondance : L7 L6 L5 L4 L3 L2 L1 L0 At _ _ _ _ E8 L8 H0
Avec les conventions suivantes :
  • H = position horizontale de la première ligne du sprite (x).
  • E = position verticale de la première ligne du sprite (y).
  • At = bit de contrôle d'attache.
  • L = position verticale de la dernière ligne + 1 (ou L = E + nombre de lignes du sprite).
E5 sera par exemple le bit 5 de la valeur désignant la position horizontale de la première ligne, codée en base 2 : si y=160, E=160=$A0=%0 1 0 1 0 0 0 0 0 donc E5=1 E8 E7 E6 E5 E4 E3 E2 E1 E0.

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 :

assembleur

La structure commencera par : dc.w $A05A,SA800

Il est possible d'utiliser cette petite routine qui fait le travail pour vous :

assembleur

Pour appeler cette routine dans l'exemple précédent :

assembleur

Le dessin du sprite

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 :
  • La largeur du sprite est obligatoirement de 16 pixels, ce qui ferait un mot de 16 bits pour une ligne du sprite. Mais ceci ne permettrait que deux couleurs : un pixel serait allumé (bit à 1) ou éteint (bit à 0, et il aurait alors la couleur du fond).
  • Pour éviter cela, chaque pixel est codé avec deux bits, ce qui lui autorise quatre couleurs : trois couleurs différentes ou celle du fond (transparent). Ceci oblige à utiliser deux mots de 16 bits pour faire une ligne du sprite (16 pixels horizontaux).
  • La hauteur du sprite, son nombre de lignes, est laissée à l'appréciation du programmeur...
  • Le DMA Copper, dans sa grande générosité, autorise huit sprites qu'il arrive à gérer en même temps. Ces sprites sont donc numérotés de 0 à 7 ! Il y a tout de même une limitation du point de vue des couleurs : les sprites 0 et 1 auront les mêmes couleurs, les sprites 2 et 3 auront les mêmes couleurs, etc.
Voici les correspondances entre bits et couleurs pour chaque sprite :

assembleur

Exemple : 1 ligne d'un sprite en assembleur donc deux mots de 16 bits pour 16 pixels.

dc.w %0011000000000000,%0101111111111111 ; pour le sprite n°1

De gauche à droite :
  • 1 pixel transparent (couleur du fond).
  • + 1 pixel de couleur 17.
  • + 1 pixel de couleur 18.
  • + 1 pixel de couleur 19.
  • + 12 pixels de couleur 17.
Rappel : les registres couleurs commencent en $DFF180 = coul 0 puis $DFF182 = coul 1.

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 :
  • Bit n°15 14 13 12 -> correspondance : rien !
  • Bit n°11 10 9 8 -> correspondance : rouge.
  • Bit n°7 6 5 4 -> correspondance : vert.
  • Bit n°3 2 1 0 -> correspondance : bleu.
Exemple : rouge = % 0000 1111 0000 0000 = $ 0F00.

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.

assembleur

Gestion du Copper

1. Préparation de la liste Copper

Les adresses des structures seront envoyées dans les registres $DFF 120 et suite :
  • $DFF120 = SPR0PTH = mot fort de l'adresse (Chip) de la structure sprite 0.
  • $DFF122 = SPR0PTL = mot faible de l'adresse de la structure sprite 0.
  • $DFF124 = SPR1PTH = mot fort de l'adresse (Chip) de la structure sprite 1.
  • $DFF122 = SPR1PTL = mot faible de l'adresse de la structure sprite 1.
Remarque : SPRxPTH(L) signifie SPRite numéro x PoinTer High (ou Low), c'est là que le système stocke l'adresse de la structure d'un sprite. Ces labels peuvent être utilisés par un assembleur digne de ce nom qui gère les fichiers "include".

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 bitplane 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 bitplane, 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 :

assembleur

Mais tout n'est pas aussi simple, car les adresses des structures dépendent de la localisation du programme, et il faut alors prévoir une routine qui prépare la liste Copper... Ceci est encore compliqué si l'on utilise un assembleur qui ne sait pas imposer de chargement en mémoire Chip : il faut donc réserver de la mémoire Chip, y recopier les données (lsite Copper, bitplane, structures des sprites), et ajuster enfin la liste Copper... (voir l'exemple depuis "run:" jusqu'à "dbra d1, relog3"). Les heureux utilisateurs de Devpac savent qu'il suffit d'ajouter une instruction "section bidon,CODE_C" avant les données pour que celles-ci soient chargées en mémoire Chip.

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 :

move.w #$0080,$DFF096 ; DMACON

...de remplacer la liste Copper du système par la nôtre :

move.l chiplist,$DFF080 ; COP1LCH et COP1LCL clr.w $DFF088 ; COPJMP1 = redémarrage copper1

...et de lancer le DMA Copper et le DMA bitplane dont la participation est nécessaire car l'écran a été redéfini :

move.w #$8380,$DFF096 ; DMACON -> DMA Copper et DMA bitplane activés

Le sprite devient alors visible à l'écran...

Ce programme a été écrit sous Devpac2 pour Commodore Revue. Il fonctionnera tel quel sous K-SEKA.

assembleur
assembleur

assembleur
assembleur
assembleur
assembleur
assembleur

Programme suivant

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 :

assembleur

Les mots de contrôle du deuxième sous-sprite sont calculés comme précédemment ce qui le définit comme un sprite de deux lignes de hauteur placé en x=180 et en y=208. Comme ces deux sous-sprites sont gérés par le Copper sous le nom de "sprite 0", il serait plus juste de dire que le Copper peut gérer huit structures...

Est-ce à dire que l'on peut définir autant de sprites que l'on veut ? Hélas, non ! Les limitations qui existent sont dûes 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 :

Ligne de structure
interprétée)
Position du raster (faisceau d'électron)
dc.w $A05A,$A800 Variable
Ligne de données n°1 Ligne 160
Ligne de données n°2 Ligne 161
Ligne de données n°3 Ligne 162
Ligne de données n°4 Ligne 163
Ligne de données n°5 Ligne 164
Ligne de données n°6 Ligne 165
Ligne de données n°7 Ligne 166
Ligne de données n°8 Ligne 167
dc.w $D05A,$D200 Ligne 168
Ligne 169 à 207 : rien pour cette structure
Ligne de données n°1 Ligne 208
Ligne de données n°2 Ligne 209
dc.w .....,..... Ligne 210

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.


[Retour en haut] / [Retour aux articles] [Article suivant]