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 - Les plasmas
(Article écrit par Thomas Landspurg et extrait d'Amiga News Tech - janvier 1992)
|
|
Ces derniers temps, les plasmas ont déferlé sur vos écrans... Encore un effet que seul l'Amiga était
capable d'offrir, et qui se révèle d'une étonnante simplicité.
Le principe est simple : il suffit de créer une énôôôrme lsite Copper qui ne contient quasiment que
des instructions de changement de couleur. Classiquement, les changements de couleur se font au début
de la ligne de raster (ce qui donne les effets de "barres de Copper" bien connus), mais ici, on change
la couleur plusieurs fois durant la même ligne (en l'occurrence 53 fois).
Il n'y donc aucune image "réelle" affichée (0 plan de bits), seulement des changements de couleur, mais le
résultat est saisissant ! De plus, vous pouvez toujours ajouter une image par-dessus ou par-dessous
ces plasmas.
Les couleurs mises dans la liste Copper sont prises dans un tableau (tabcol) puis rangées dans la
liste Copper à l'aide du Blitter pour plus de rapidité. Deux mouvements de sinus sont appliqués lors du
transfert, ce qui donne cet effet de vague sur la composante X. Une double superposition de sinus est
appliquée aussi sur Y, en jouant sur le retard vidéo à chaque ligne. Le mouvement est donc composé de
quatre sinus, deux sur X et deux sur Y. Il y a donc huit paramètres qui déterminent le mouvement : la
vitesse de déplacement et le pas entre deux sinus consécutifs, et ce pour les quatre sinus, ce qui nous
fait bien huit paramètres.
Je vous conseille de modifier ces paramètres et d'observer le résultat. Vous pouvez aussi modifier le
dégradé de couleurs pour en mettre un de votre cru.
Il faut noter qu'il y a deux listes Copper, une qui est affichée tandis que l'autre est modifiée.
Et à la prochaine trame, on inverse ces deux listes Copper. C'est l'équivalent du double tampon mémoire
pour les listes Copper.
Pour créer la table de sinus (qui est un tableau de 256 octets), il suffit de taper le petit programme
GFA suivant :
OPEN "o",#1,"datasin"
FOR i=0 TO 255
val=INT(127*SIN(i*2*PI/256))
OUT #1,val
NEXT i
|
Il est facilement adaptable pour l'AmigaBasic. Il ne reste plus qu'à assembler le programme Plasma.s et à l'exécuter.
; ##########################
; # Plasma T.Landspurg 91 #
; ##########################
; A assembler sous Devpac
opt c+,o+,ow-
NB_COL_COP=53 ; nombre de changements de couleur par ligne
NB_LIG_COP=264 ; nombre de lignes du plasma
NB_BYTE_PLASMA=(NB_COL_COP+1+1)*4 ; taille d'un ligne de la liste Copper
taillecop=20+(NB_COL_COP+2)*4*NB_LIG_COP; taille de la liste Copper
NB_DEG=15*3 ; utilise pour la création de dégradé
NB_REP=10 ; idem
CUSTOM=$dff000 ; registres matériels
incdir "include:"
include exec/exec_lib.i
include hardware/custom.i
; début du programme
start:
lea b(pc),a4 ; a4 pointera toujours sur la base
lea graphname(pc),a1 ; ouverture de la graphics
CALLEXEC OpenLibrary
move.l d0,graphbase-b(a4)
bsr initcop ; initialisation de la liste Copper
bsr init_col ; initialisation des couleurs du plasma
lea CUSTOM,a5 ; base des coprocesseurs
move.w intenar(a5),save_intena-b(a4)
or.w #$c000,save_intena-b(a4)
move.w #$7fff,intena(a5)
move.w #$0020,dmacon(a5) ; contrôle DMA
move.w #$8400,dmacon(a5) ; Bltpri
CALLEXEC Forbid
move.b #%10000111,$bfd100 ; arrêt du lecteur (beurk !)
lea CUSTOM,a5 ; a5 pointera sur les registres matériels
waitbout: ; boucle principale
sync:
btst #0,vposr+1(a5)
bne.s sync
sync1:
cmp.b #40,vhposr(a5) ; synchronisation
bne.s sync1
movem.l p_coplist(pc),d0/d1
exg d0,d1
movem.l d0/d1,p_coplist-b(a4)
move.l d0,cop1lc(a5)
clr.w copjmp1(a5)
bsr move_plasma
btst #6,$bfe001 ; test le bouton de la souris
bne waitbout
out:
move.w save_intena-b(a4),intena(a5) ; interruption
move.l graphbase(pc),a0 ; on restaure l'ancienne liste Copper
move.l oldcop-b(a4),$32(a0)
move.l $26(a0),cop1lc(a5)
CALLEXEC Permit
move.l graphbase(pc),a1 ; on referme la bibliothèque
CALLEXEC CloseLibrary
move.w #$0400,dmaconr(a5)
move.w #$8020,dmaconr(a5)
moveq #0,d0
rts
save_intena:dc.w 0
waitblit:macro
waitblit\@:
btst #14,dmaconr(a5)
bne waitblit\@
endm
graphname:dc.b 'graphics.library',0
even
graphbase:dc.l 0
; initialisation de la liste Copper
initcop:
lea coplist,a0
move.w #NB_LIG_COP-1,d7
move.w #$2a31,d0 ; première ligne de l'écran
next_lig_plasma: ; pour une ligne de plasma
move.w d0,(a0)+ ; le wait
move.w #$fffe,(a0)+
move.l #$01020000,(a0)+ ; décalage horizontal
add.w #$0100,d0 ; prochaine ligne
moveq.w #NB_COL_COP-1,d6 ; on met le changement
move.w d7,d1 ; de couleur pour une ligne
next_col_plasma: ; donnée
move.l #$1800000,(a0)+
dbf d6,next_col_plasma
dbf d7,next_lig_plasma
move.l #$01000000,(a0)+ ; 0 plan de bits
move.l #$fffffffe,(a0)+ ; fin de la liste Copper
lea coplist,a0
lea coplist+taillecop,a1
move.w #taillecop/4-1,d7
next_recopie:
move.l (a0)+,(a1)+
dbf d7,next_recopie
move.l graphbase-b(a4),a0 ; on sauve l'ancienne liste Copper
move.l $32(a0),oldcop-b(a4)
rts
; mouvement des plasmas
move_plasma: ; c'est le coeur du programme
move.l p_coplist(pc),a0 ; pointeur sur la liste Copper
lea tabsin(pc),a2 ; tableau de sinus
move.w #$ff,d5 ; masque=taille de la table de sinus
; on va d'abord créer les décalages sur y
move.w p_sinusy1(pc),d1 ; première vague sur Y
add.w speed_sinusy1(pc),d1
move.w d1,p_sinusy1-b(a4)
move.w p_sinusy2(pc),d2 ; première vague sur Y
add.w speed_sinusy2(pc),d2
move.w d2,p_sinusy2-b(a4)
move.w #NB_LIG_COP-1,d7 ; nombre de lignes
next_lig_plasma2
and.w d5,d1
and.w d5,d2
move.b (a2,d1.w),d3 ; décalage sinus
ext.w d3
move.b (a2,d2.w),d4 ; décalage sinus
ext.w d4
add.w d4,d3 ; on ajoute les deux sinus
asr.w #4,d3 ; le décalage sur y de faible amplitude
add.w #$20,d3
bset #0,d3
move.b d3,1(a0) ; on le met dans la liste Copper
add.w step_sinusy1(pc),d1
add.w step_sinusy2(pc),d2
lea NB_BYTE_PLASMA(a0),a0
dbf d7,next_lig_plasma2
; maintenant les décalages sur X
waitblit ; attent que le Blitter soit libre
move.w #$09f0,bltcon0(a5) ; Mode=recopie
clr.w bltcon1(a5) ; mode suite
move.l #-1,bltafwm(a5) ; masque à -1
move.w #NB_BYTE_PLASMA-2,bltdmod(a5) ; modulo
clr.w bltamod(a5) ; en source pas de modulo
move.w #((NB_LIG_COP)<<6+1),d6 ; taille=une colonne
move.l p_coplist(pc),a0
lea tab_col_plasma+128,a1
move.w p_sinusx1(pc),d1 ; première vague sur X
add.w speed_sinusx1(pc),d1
move.w d1,p_sinusx1-b(a4)
move.w p_sinusx2(pc),d2 ; deuxième vague sur X
add.w speed_sinusx2(pc),d2
move.w d2,p_sinusx2-b(a4)
lea 6+4(a0),a0 ; a0 pointe sur le début de couleurs
moveq.w #NB_COL_COP-2,d7
move.w step_sinusx1(pc),d0
next_col_plasma2
add.w d0,d1
add.w step_sinusx2(pc),d2
and.w d5,d2
and.w d5,d1
move.b (a2,d1.w),d3 ; décalage sinus
ext.w d3
move.b (a2,d2.w),d4 ; décalage sinus
ext.w d4
add.w d4,d3 ; on ajoute les deux sinus
asr.w #1,d3 ; d3 contient le décalage dans la table de couleur
lea (a1,d3.w),a3
waitblit
move.l a3,bltapt(a5) ; source=table de couleur
move.l a0,bltdpt(a5) ; destination=liste Copper
move.w d6,bltsize(a5) ; taille=une colonne
lea 4(a0),a0
dbf d7,next_col_plasma2
rts
; variables qui contiennent les données pour le plasma
p_sinusx1:dc.w 0
p_sinusx2:dc.w 0
p_sinusy1:dc.w 0
p_sinusy2:dc.w 0
step_sinusx1:dc.w -3
speed_sinusx1:dc.w -1
step_sinusx2:dc.w -4
speed_sinusx2:dc.w -1
step_sinusy1:dc.w 2
speed_sinusy1:dc.w 1
step_sinusy2:dc.w -3
speed_sinusy2:dc.w -5
; crée le dégradé de couleur pour le plasma
init_col:
lea tab_col_plasma,a0 ; table du dégradé de couleurs
move.w #$fff,d0
move.w #-$110,d1 ; on modifie la composante verte
bsr cree_one_deg ; on crée trois dégradés
move.w #$100,d1 ; idem avec la composante rouge
bsr cree_one_deg
move.w #-$1,d1 ; et la composante jaune
bsr cree_one_deg
rts
cree_one_deg: ; crée un dégrade en modifiant une composante de la couleur
move.w #NB_DEG/3-1,d7 ; nombre d'itérations
l2: move.w #NB_REP-1,d6 ; Nombre de fois où l'on garde
l1: move.w d0,(a0)+ ; la même couleur
dbf d6,l1
add.w d1,d0 ; prochaine couleur
dbf d7,l2 ; tant qu'il y a des couleurs
rts
b:
oldcop: dc.l 0
p_coplist: dc.l coplist
p_coplist_old: dc.l coplist+taillecop
dir: dc.w -1
; le fichier datasin est créé avec le petit programme GFA donné en annexe
tabsin:
incbin datasin
; section qui contient les données
section plasma,BSS_C
tab_col_plasma:
dcb.w NB_DEG*NB_REP
coplist:dcb.b taillecop*2
|
|