Obligement - L'Amiga au maximum

Samedi 17 novembre 2018 - 03:23  

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 - Le traçage de droites avec le Blitter
(Article écrit par Frédéric Mazué et extrait d'Amiga News Tech - juillet 1990)


Aujourd'hui, nous allons nous intéresser à la capacité que possède le Blitter à tracer des droites. Mais cette fois ce n'est pas tout simple, c'est même plutôt ardu au premier abord.

Comme d'habitude, c'est l'initialisation de BLTSIZE qui fera démarrer le Blitter. La valeur dans ce registre informe le Blitter de la longueur de la droite, c'est-à-dire du nombre de points allumés composants celle-ci. Si BLTSIZE est initialisé avec la valeur 0, on aura la longueur maximum de 1024 points ce qui tombe on ne peut mieux car les largeurs et hauteurs maximum d'un bitplane sont également de 1024 points.

Peut-être pensez-vous qu'une longueur de 1024 points est insuffisante si la droite est en diagonale dans un super-bitplane ? Observez bien l'aspect d'une droite tracée par un ordinateur : ce n'est pas une droite ! En effet l'emplacement théorique d'un point d'une droite quelconque ne correspond généralement pas exactement à la position d'un pixel sur l'écran, ce qui fait qu'un ordinateur (en fait dans un Amiga le Blitter) doit se contenter d'allumer un des pixels les plus proches. Le Blitter, qui est une personne très ordonnée, n'allume pas les pixels les plus proches n'importe comment, mais remplace de petites portions de la droite à tracer par des "marches d'escalier".

Quelques essais permettraient de constater les choses suivantes :
  • Si la droite est peu inclinée (moins de 45°), les marches de l'escalier sont horizontales.
  • Si la droite est très inclinée (plus de 45°), les marches de l'escalier sont verticales.
  • Si la droite est inclinée à 45°, les marches se réduisent à un point, il n'y a pas vraiment d'escalier et le tracé est presque parfait.
Tout ceci n'est pas sans conséquence :
  • On remarque d'abord que la longueur exprimée en nombre de points d'une droite correspond à la différence des abscisses plus un, ou à la différence des ordonnées plus un des points de départ et d'arrivée de la droite selon que la droite est plus ou moins inclinée. Ceci a pour conséquence que la longueur d'une droite ne pourra jamais excéder 1024 points.
  • Le Blitter n'étant pas devin, il faudra lui communiquer l'inclinaison de la droite à tracer.
Malheureusement, le Blitter ne sait pas ce que c'est qu'un angle et à la place utilise les octants. Il faut comprendre que pour le Blitter un repère orthonormé est divisé en huit secteurs égaux (donc de 45°) d'où le nom d'octants. Voir la figure mais attention : le sens des Y croissants est vers le bas.

assembleur

Comment faire pour savoir "à la main" dans quel octant se situe une droite ? Très simple : il suffit d'utiliser la figure en plaçant le point de départ de la droite sur l'origine du repère, puis en plaçant le point d'arrivée selon ses coordonnées (attention au sens des Y). On voit ainsi dans quel octant se trouve la droite.

Généralisation

Si cette méthode peut à la rigueur convenir pour préparer le tracé d'une droite, elle est insupportable pour un nombre élevé de droites.

Voici comment il est possible de généraliser. On appelle x1,y1 les coordonnées du point de départ de la droite et x2,y2 les coordonnées du point d'arrivée de la droite. On appelle dx la valeur absolue de la différence des abscisses c'est-à-dire |x2-x1| et dy la valeur absolue de la différence des ordonnées c'est-à-dire |y2-y1|.

On a alors les relations suivantes :
  • Si x1<x2 et y1<y2 et dx<dy, la droite est dans l'octant 6.
  • Si x1<x2 et y1<y2 et dx>dy, la droite est dans l'octant 7.
  • Si x1>x2 et y1<y2 et dx<dy, la droite est dans l'octant 5.
  • Si x1>x2 et y1<y2 et dx>dy, la droite est dans l'octant 4.
  • Si x1<x2 et y1>y2 et dx<dy, la droite est dans l'octant 1.
  • Si x1<x2 et yl>y2 et dx>dy, la droite est dans l'octant 0.
  • Si x1>x2 et y1>y2 et dx<dy, la droite est dans l'octant 2.
  • Si x1>x2 et y1>y2 et dx>dy, la droite est dans l'octant 3.
Ce n'est pas tout : on ne peut pas communiquer directement un numéro d'octant au Blitter. Chaque octant est en fait codé sur 3 bits d'une façon assez hermétique qu'il n'est pas très intéressant d'analyser. Voyons directement le résultat :

Octant Code
0 6
1 1
2 3
3 7
4 5
5 2
6 0
7 4

Une routine pratique

Toutes ces relations ne sont en fait intéressantes que si elles sont utilisées dans un programme. Comme ma bonté n'a pas de limite, vous trouverez dans le listing d'exemple une routine nommée "recherche_octant" et qui en fait renvoie le code de l'octant concerné. Cette routine peut être utilisée dans vos programmes personnels sans problème.

Son principe est simple : le programme comporte un tableau des codes d'octants. La routine effectue les comparaisons des relations ci-dessus et fait un décalage du drapeau X dans le registre D4 à chaque comparaison. A la fin, D4 sert d'index pointant sur l'élément du tableau recherché. La routine effectue également un petit travail supplémentaire : elle regarde qui de dx et de dy est le plus grand puis range le résultat selon le cas dans les labels PDelta et GDelta ce qui sera utilisé pour l'initialisation de certains registres.

En effet, tous les registres du Blitter doivent être initialisés pour un tracé de droite. Le moins que l'on puisse dire est que les valeurs d'initialisation sont quelquefois bizarroïdes.

Voyons tout cela méthodiquement :

Registre BLTBDAT

Il doit contenir la valeur $8000. C'est-à-dire que seul le bit 15 est mis. Ce bit doit être décalé par le Blitter selon ses besoins puis l'envoyer en sortie dans BLTDDAT pour allumer les points.

Registre BLTBDAT

Il doit contenir la valeur de texture de la droite. Il faut comprendre que ce registre doit contenir une valeur de masque. Si la valeur est $ffff la droite est on ne peut plus complète et normale. La valeur $0000 peut servir à tracer par effacement dans une surface colorée. La valeur $ff00 peut servir à tracer des pointillés. N'hésitez pas à essayer différentes valeurs pour ce registre, les résultats sont parfois amusants.

Registre BLTAFWM

Ce registre doit obligatoirement contenir la valeur $ffff.

Registre BLTALWM

Comme le précédent, ce registre doit contenir la valeur $ffff.

Registre BLTAMOD

Il doit contenir la valeur 4*PDelta-4*GDelta : vous avez bien lu 4 et non pas 2.

Même si dans un certain livre qui n'en est pas à une bêtise près (Bible de l'Amiga) c'est 2*PDelta-2*GDelta qui est indiqué alors que 4*PDelta-4*GDelta est donné par l'Amiga ROM Kernel Manual. Il faut bien reconnaître que la valeur donnée par la Bible semble dans ce cas convenir également. Mais une fois n'est pas coutume et l'expérience montre d'une manière générale qu'il faut toujours faire confiance aux Amiga ROM Kernel Manual et pas aux autres si vous voulez que vos programmes fonctionnent convenablement.

Registre BLTBMOD

Il doit contenir la valeur 4*PDelta.

Registre BLTCMOD

Il doit contenir la largeur du bitplane exprimée en octets. Pour un écran de 320 points de large, il faut utiliser la valeur 40.

Registre BLTDMOD

Lui aussi doit contenir la largueur du bitplane exprimée en octets.

Registre BLTAPTH

Il doit contenir la valeur 4*PDelta-2*GDelta. De plus, si cette valeur est négative, il faudra placer le bit à 1 le bit SIGN du registre BLTCON1.

Registre BLTBPTH

Ce registre n'est pas utilisé pour le tracé de droite.

Registre BLTCPTH

Il doit contenir l'adresse du point de départ de la droite. Là encore, méfiez-vous de formules frelatées et utilisez celle-ci :

adresse du bitplane + y1*largeur du bitplane + x1/8

A titre indicatif, la Bible de l'Amiga donne :

adresse du bitplane + (nombre de lignes - y1 - 1)*nombre d'octets par ligne = 2*(x1/16)

Record battu ! Quand je vous disais qu'il valait mieux se méfier.

Registre BLTCON0

Ce registre doit être initialisé comme suit :

Bit numéro Nom Fonction
15 START3 Ces quatre bits correspondent à la position du...
14 START2 ...point de départ de la droite dans le mot...
13 START1 ...pointé par BLTCPTH et BLTDPTH...
12 START0 ...voir dans le programme d'exemple
11 USEA=1 Pour tracer une droire, c'est comme cela et pas autrement
10 USEB=0 Pour tracer une droire, c'est comme cela et pas autrement
9 USEC=1 Pour tracer une droire, c'est comme cela et pas autrement
8 USED=1 Pour tracer une droire, c'est comme cela et pas autrement
7 à 0 Minterms Ils doivent contenir la valeur $CA, ce qui
correspond à la combinaison aC+AB (!)

Registre BLTCON1

ce registre doit être initialisé comme suit :

Bit numéro Nom Fonction
15 Texture3 Mêmes valeurs que pour START3-0
14 Texture2
13 Texture1
12 Texture0
11 à 7 Ces bits sont inutilisés et doivent être placés à 0
6 SIGN Doit être mis à 1 quand 4*PDelta-2*GDelta <0
5 Inutilisé : toujours 0
4 SUL Ces trois bits doivent être initialisés avec...
3 SUD ...le code de l'octant. Attention : décaler les bits...
2 AUL ...de code de deux positions à gauche
1 SING Lorsque ce bit est à 1, le Blitter trace la droite avec seulement un
point par ligne écran. Utile pour préparer un remplissage de surface
0 LINE=1 Pour activer le mode tracé de droite

Registre BLTSIZE

Ce registre doit être initialisé en dernier : c'est le signal de départ pour le Blitter.

Le contenu est donné par la formule : (GDelta+1)*64+2

Pour comprendre la raison du 64 et du 2, reportez-vous aux articles précédents. Certaines documentations peu sérieuses donnent la formule GDelta*64+2. Qu'en est-il exactement ? Voyons un exemple : x1=100 y1=100 x2=110 y2=110.

Ceci défini une droite à 45° (le Blitter placera donc un point par "escalier"). Comme le point x1,y1 fait partie de la droite, la droite comportera 11 points, il faut donc bien ajouter 1.

Autre exemple : dans un super bitplane x1=0 y1=0 x2=1023 y2=1023, 1023 est la valeur maximum pour une coordonnée.

GDelta=1023-0=1023. Il faut donc bien ajouter 1 pour obtenir 1024 points.

Il ne vous reste plus qu'à essayer le programme. Je me suis attaché à vous fournir un listing facile à comprendre. Pour cette raison, il n'est pas du tout optimisé. Il est possible par exemple de remplacer les instructions muls et divs par les instructions de décalage de bits appropriées afin de gagner en rapidité si la routine doit être appelée de nombreuses fois. Il est aussi possible de passer d'autres instructions avec une programmation astucieuse. Mais je laisse tout cela à votre sagacité car je le répète mon but était de vous fournir un listing clair.

assembleur
assembleur
assembleur
assembleur

Quelques mots encore

On a vu qu'il faut finalement beaucoup de travail pour programmer le tracé d'une pauvre petite droite. Il est peut-être plus judicieux de se contenter d'utiliser les routines de la graphics.library dans la plupart des cas. Une programmation directe du Blitter ne pouvant se justifier que pour un nombre très important de droites ou pour se faire plaisir lors de la programmation d'une Mégadémo.

Voilà, tout est dit sur le Blitter. J'aurai le plaisir de vous retrouver le mois prochain avec un petit programme amusant sur un tout autre sujet : les lecteurs de disquette.


[Retour en haut] / [Retour aux articles] [Article précédent]