Suivez-nous sur X

|
|
|
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,
ALL
|
|
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
|
|
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
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Assembleur - Modes entrelacé et Extra Half-Brite
(Article écrit par Philippe Rivaillon et extrait d'Amiga News Tech - mai 1992)
|
|
Nous savons maintenant ouvrir un écran... Avant de commencer à
étudier les différents modes graphiques, voyons ce que nous pouvons faire avec ce que nous savons.
Je ne vous ferai pas l'insulte d'évoquer le changement du contenu des registres de couleurs à l'aide du Copper
(c'est pourtant ce que je suis en train de faire...) : c'est l'un des premiers effets vidéo qu'un débutant
programme. De la même manière, en changeant les pointeurs écran et le registre BPLCON1 (décrit plus bas),
on peut faire de nombreux effets : défilements, ondulations, enroulements d'images, rotations horizontales...
Bref, on peut disposer chaque ligne de plan de bits comme on le désire, il suffit de laisser libre cours à son
imagination. Notez que certains de ces effets sont aussi réalisables à l'aide de changement de modulos :
cela permet d'alléger la liste Copper et donc d'accélérer l'ensemble (on change uniquement deux registres).
Toujours en modifiant les modulos, on peut faire un effet de reflet du haut de l'écran dans le bas de celui-ci :
arrivé à la ligne voulue, on met une valeur négative dans les modulos qui permettra de réafficher les lignes de
plans de bits dans le sens inverse (on peut même en afficher une sur deux si l'on veut).
Au fait, pour réaliser ces effets en plein écran, il faut pouvoir accéder aux dernières lignes de balayage avec
le Copper. Pour cela, une fois arrivé à la ligne $FF, il faut faire un Wait($FFDF,$FFFE) et après on
recommence la numérotation des lignes à 0.
BPLCON1 $DFF102 2e registre de contrôle des plans de bits
|
Bit |
Nom |
Fonction |
15-8 |
- |
Inutilisés |
7-4 |
PF2H3-0 |
Ces bits permettent de définir le décalage des plans pairs. La
valeur varie de 0 à 15, ce qui permet de compléter le décalage des pointeurs vidéo,
puisque ceux-ci ont une précision d'un mot. |
3-0 |
PF1H3-0 |
Idem pour les plans impairs. |
Note : ce registre est accessible en écriture uniquement. Grâce à lui, on peut positionner
les lignes plans de bits au pixel près. Il est donc indispensable à la plupart des effets vidéo.
A la recherche du bit 9
Certains d'entre vous ont déjà dû se rendre compte que dans les précédents exemples, un mystérieux
bit 9 était mis à un dans BPLCON0, alors que je n'y faisais pas référence avant... Ce bit a pour
nom COLOR, et il doit être impérativament mis à 1 pour tout travail avec un écran couleur conventionnel.
Si ce n'est pas le cas, l'information vidéo sera codée différemment. D'une manière générale,
laissez-le toujours à 1. Voilà, nous pouvons continuer le coeur léger.
Le mode entrelacé : tout en finesse
Pourquoi ne pas avoir traité ce mode de résolution en même temps que les deux autres ? Cela
vient du fait que sa mise en oeuvre n'est pas aussi simple que pour ceux-ci : elle ne se
résume pas au simple positionnement d'un bit dans le registre BPLCON0, comme nous allons bientôt le voir.
Ce qu'il faut savoir sur le mode entrelacé est qu'il double le nombre de lignes
affichées sans la moindre restriction : pas de réduction du nombre de couleurs, pas de choix
spécial de la résolution horizontale (Lores, Hires, Super Hires et même Productivity) ni du
mode graphique (HAM, Dual Playfield ou Half-Bright).
Mais c'est un miracle, me direz-vous : deux fois plus de lignes affichées et pas une seule
restriction ! Pas vraiment, car ce mode apporte un inconvénient de taille :
un scintillement énervant de l'écran.
Cela vient du fait que dans ce mode, l'Amiga n'est pas assez rapide pour envoyer une image complète
au moniteur tous les 50e de seconde. Il décompose donc son envoi en deux temps : d'abord les
lignes paires de l'image, puis les lignes impaires. Il faut donc 2/50e de seconde, soit 1/25e,
pour former une image complète, fréquence à laquelle l'oeil humain perçoit nettement les moindres
changements. L'Amiga, quant à lui, n'a pas réellement de surplus de travail : il transmet au moniteur
le même nombre de données, que l'on soit en entrelacé ou non, ce qui explique qu'il n'y ait aucune
restriction à l'utilisation de ce mode.
Mais pourquoi diable l'Amiga ne peut-il envoyer toute l'image d'un coup ? Pour répondre à cette
question, il faut expliquer un peu le fonctionnement d'un téléviseur conventionnel... Quand vous
regardez la télévision, votre poste ne reçoit pas toute l'image d'un coup, pour des raisons de rapidité
de transmission et d'affichage, mais une demi-image tous les 50e de seconde (60e de seconde en NTSC par
exemple aux États-Unis) : d'abord les lignes paires puis les lignes impaires. C'est exactement la même
chose pour la plupart des moniteurs. Seuls les moniteurs dits multisynchros possèdent un mécanisme
de balayage assez rapide pour afficher en un 50e de seconde une image complète d'une résolution
verticale de 400 lignes et plus. Mais ces moniteurs coûtent chers, et les concepteurs de l'Amiga
ont préféré le rendre compatible avec tout type de moniteur et téléviseur.
Quelle est la conséquence de tout ceci ? Premièrement, l'Amiga n'est pas ralenti par l'utilisation de
ce mode graphique. Deuxièmement, il est impossible de faire du 50 images par seconde en mode entrelacé,
puisque l'image n'est complète que tous les 25e de seconde. Troisièmement, et c'est beaucoup plus grave,
l'image a tendance à scintiller (effet visible aussi à la télévision).
Pour remédier à cela, et si vous êtes fortuné, vous pouvez toujours investir dans l'achat d'une carte
désentrelaceur et d'un moniteur multisynchro (la carte Flicker-Fixer désentrelace l'image pour
la rendre compatible avec le moniteur multisynchro). Les heureux possesseurs d'A3000 n'auront pas
ce désagrément puisque un désentrelaceur est inclus dans la version de base (normal pour une machine
de ce gabarit, où le coût n'est pas le premier souci).
Mais cessons de disserter sur l'entrelacé et voyons plutôt comment le mettre en oeuvre... Je ne reviendrai
pas sur l'ouverture de l'écran, mais vous rappellerai tout de même de ne pas vous en faire pour la fenêtre :
elle reste la même pour tous les modes graphiques (Hires exclu). De plus, songez à réserver suffisamment
de mémoire (deux fois plus que s'il n'y avait pas l'entrelacé).
Pour déclencher le mode entrelacé, il faut positionner à 1 le 2e bit de BPLCON0. Le problème est que
l'ordinateur ne se charge pas lui-même de distribuer soit les lignes paires, soit les lignes impaires :
c'est donc à vous de le faire.
Le plus simple est de faire deux listes Copper : l'une initialisera les registres nécessaires pour
pointer sur les lignes impaires (COP_IMP) et l'autre fera la même chose pour les lignes paires (COP_PAI).
Pour cela, inutile d'adopter une structure de plans de bits particulière : il suffit d'initialiser les modulos
de façon à sauter une ligne sur deux, les pointeurs écrans à la première ligne dans COP_IMP et à la
deuxième ligne dans COP_PAI. Si vous voulez faire des effets vidéo en entrelacé à l'aide du Copper,
n'oubliez pas que vous devez aussi les décomposer en deux demi-écrans de lignes paires et impaires.
Une fois les deux listes Copper prêtes, il existe plusieurs possibilités : soit l'on fait pointer chacune
sur l'autre, soit l'on se charge de cette tâche "à la main" à chaque retour du spot (par interruption
ou boucle d'attente). On peut aussi de la même manière modifier soi-même les pointeurs écrans à chaque
retour du spot (ceci permet de n'avoir qu'une seule liste Copper). A mon humble avis, la première solution
est de loin la plus pratique, mais tous les goûts sont dans la nature...
Ensuite se pose un second problème : comment savoir quelle liste Copper doit être "envoyée"
en premier ? En effet, en cas d'erreur, le rendu sera très laid puisque les lignes paires et impaires seront
inversées. Pour cela, nous avons des registres très pratiques :
VPOSR $DFF004 Position verticale haute (lecture)
VPOSW $DFF02A Position verticale haute (écriture)
|
Bit |
Nom |
Fonction |
15 |
LOF |
Indicateur de type de lignes affichées en mode entrelacé : 0 pour les lignes
pairs et 1 pour les impaires. |
14-1 |
- |
Inutilisés |
0 |
V8 |
Bit de plus fort poids de la position verticale du rayon électronique, grâce
auquel on peut savoir si le spot a dépassé la ligne 255. |
J'en profite pour citer aussi ces registres jumelés, qui permettent à l'occasion de se synchroniser avec l'écran :
VHPOSR $DFF006 Position verticale et horizontale (lecture)
VHPOSW $DFF02C Position verticale et horizontale (écriture)
|
Bit |
Nom |
Fonction |
15-8 |
V7-V0 |
Bits de plus faible poids de la position verticale du spot |
7-0 |
H8-H1 |
Position horizontale du spot (la précision est de 1/160e de la largeur de l'écran (280 ns)) |
C'est en lisant le bit LOF que l'on va savoir par quelle liste Copper commencer. Mais il
faut savoir que ce bit ne sera significatif que si l'on est déjà en mode entrelacé : il faut
donc déclencher le mode entrelacé, attendre la suppression de trame ("vertical blanking"), et enfin choisir quelle
liste Copper débutera, suivant la valeur de LOF.
Enfin, un exemple !
L'exemple ci-dessous utilise la méthode la plus simple, celle des deux listes Copper pointant chacune
sur l'autre. L'écran ouvert est en basse résolution entrelacé et fait 320x400. Il dispose d'un plan de bits
unique (monochrome).
* Programme sur SEKA V3.2 *
*
* Appuyez sur le bouton gauche puis le droit
*
START:
bsr SAVE_ALL
; TYPE BITMAP
; Initialisation des pointeurs de plans de bits dans la liste Copper
move.l #ECRAN,d1
move.w d1,PLAN1+6 ; 16 bits bas
swap d1
move.w d1,PLAN1+2 ; 3 bits hauts
swap d1
add.l #1024*265/8,d1 ; Pointe sur 2ème plan de bits
move.w d1,PLAN2+6
swap d1
move.w d1,PLAN2+2
move.w #%0000000000100000,$dff096 ; vire sprites
; Autorisation copper et affichage
move.w #%1000001110000000,$dff096
; On lance la liste Copper
move.l #COPPERLIST,$DFF080 ; adresse
move.w #$0,$DFF088 ; redémarrage du Copper
wait1:
btst #6,$bfe001
bne.s wait1
; TYPE IFF
; Initialisation des pointeurs de plans de bits dans la liste Copper
move.l #ECRAN,d1
move.w d1,PLAN1_2+6 ; 16 bits bas
swap d1
move.w d1,PLAN1_2+2 ; 3 bits hauts
swap d1
add.l #1024/8,d1 ; Pointe sur 2ème plan de bits
move.w d1,PLAN2_2+6
swap d1
move.w d1,PLAN2_2+2
move.w #%0000000000100000,$dff096 ; vire sprites
; Autorisation copper et affichage
move.w #%1000001110000000,$dff096
; On lance la liste Copper
move.l #COPPERLIST2,$DFF080 ; adresse
move.w #$0,$DFF088 ; redémarrage du Copper
wait2:
btst #2,$dff016
bne.s wait2
bsr RESTORE_ALL
rts
save_all:
move.b #%10000111,$bfd100
move.l 4,a6
jsr -132(a6)
move.l $6c,save_vecteur_irq
move.w $dff01c,save_intena
or.w #$c000,save_intena
move.w $dff002,save_dmacon
or.w #$8100,save_dmacon
move.w #$7fff,$dff096
move.w #$7fff,$dff09a
move.w #%1000011111000000,$dff096
move.w #%1100000000100000,$dff09a
rts
restore_all:
move.l save_vecteur_irq,$6c
move.w #$7fff,$dff09a
move.w save_intena,$dff09a
move.w #$7fff,$dff096
move.w save_dmacon,$dff096
move.l 4,a6
lea name_glib,a1
moveq #0,d0
jsr -552(a6)
move.l d0,a0
move.l 38(a0),$dff080
clr.w $dff088
move.l d0,a1
jsr -414(a6)
jsr -138(a6)
rts
save_intena:dc.w 0
save_dmacon:dc.w 0
save_vecteur_irq:dc.l 0
name_glib:dc.b 'graphics.library',0
even
COPPERLIST:
dc.w $0100,$A200 ; résolution, nb plan de bits
dc.w $0180,$0000 ; couleur 0
dc.w $0182,$0f00 ; couleur 1
dc.w $0184,$00f0 ; couleur 2
dc.w $0186,$000f ; couleur 3
dc.w $008e,$2069 ; DIWSTRT
dc.w $0090,$29c9 ; DIWSTOP
dc.w $0092,$0030 ; DDFSTRT
dc.w $0094,$00D8 ; DDFSTOP
dc.w $0108,$0028 ; modulo plans impaires
dc.w $010a,$0028 ; modulo plans paires
PLAN1:
dc.w $00e0,$0000 ; plan de bits 1
dc.w $00e2,$0000
PLAN2:
dc.w $00e4,$0000 ; plan de bits 2
dc.w $00e6,$0000
dc.w $ffff,$fffe ; FIN COPPERLIST
COPPERLIST2:
dc.w $0100,$A200 ; résolution, nb plan de bits
dc.w $0180,$0000 ; couleur 0
dc.w $0182,$0f00 ; couleur 1
dc.w $0184,$00f0 ; couleur 2
dc.w $0186,$000f ; couleur 3
dc.w $008e,$2069 ; DIWSTRT
dc.w $0090,$29c9 ; DIWSTOP
dc.w $0092,$0030 ; DDFSTRT
dc.w $0094,$00D8 ; DDFSTOP
dc.w $0108,$0028+$0080 ; modulo plans impaires
dc.w $010a,$0028+$0080 ; modulo plans paires
PLAN1_2:
dc.w $00e0,$0000 ; plan de bits 1
dc.w $00e2,$0000
PLAN2_2:
dc.w $00e4,$0000 ; plan de bits 2
dc.w $00e6,$0000
dc.w $ffff,$fffe ; FIN COPPERLIST
ECRAN: ;(doit être en mémoire CHIP)
blk.b 33920,$f0 ;1024/265 -> rayures
blk.b 33920,$0f ;1024/265 -> rayures inversées
|
Le sixième plan de bits : le mode Extra Half-Bright (EHB)
Nous allons enfin pouvoir utiliser un sixième plan de bit. Comme vous pouvez vous en douter, ce
plan de bits va nous permettre de multiplier par deux le nombre de couleurs affichées à l'écran : on passe
donc de 32 à 64 couleurs. Bien entendu, ce mode n'est pas utilisable en haute résolution (640 points
verticaux) et encore moins en très haute résolution (1280 points verticaux). Par contre, il reste
évidemment compatible avec le mode entrelacé.
Ne vous frottez pas trop vite les mains : n'oubliez pas que nous ne disposons que de 32 registres de
couleurs. Comment donc définir 64 couleurs à l'aide de 32 registres ? Ceux que l'anglais ne rebute
pas auront tout de suite deviné le subterfuge car "half-bright" signifie demi-intensité...
Les 32 couleurs supplémentaires seront déduites des 32 premières en diminuant leur intensité de moitié
(chaque composante RVB subit une division par deux). Par exemple, si on met la valeur $417 dans la
couleur 0, la couleur 33 vaudra $203.
On peut résumer cet état de fait de la façon suivante : pour chaque point de l'écran, si le bit
correspondant dans le sixième plan de bits est nul, tout se passe normalement. Si au contraire ce bit est à 1,
on divise l'intensité du point par deux.
Bien entendu, ce mode graphique est tout de même intéressant, malgré ses sérieuses contraintes : il permet
de réaliser facilement des effets d'éclairages ou d'ombrages à l'aide de masques dans le sixième plan de bits,
ou plus simplement d'avoir plus de dégradés si l'on se débrouille bien. Il s'agit de bien choisir ses
couleurs : évitez de prendre des couleurs sombres pour vos couleurs primaires puisque les couleurs déduites
le sont déjà. De plus, vous risqueriez de ne plus voir de différences entre les deux.
La mise en oeuvre est si simple que je ne ferai pas de programme d'exemple... Tout se passe avec
le registre BPLCON0 : il suffit de sélectionner 6 plans de bits et de mettre à 1 le bit 7. Par exemple,
en 320x200, il faudrait mettre #$6280 dans BPLCON0.
Le mois prochain, ce sera le tour du tant controversé mode HAM. A bientôt !
|