LES
ECRANS VIRTUELS :
Rapide présentation
:
Imaginons un
cas simple, une flotte de sprites, une armée d'aliens dans
leur soucoupe volante.... les aliens de Phoenix. Vous programmez
ce jeu, et d'après votre algorithme vous allez deplacer la
flotte ennemie. Vous n'avez jamais entendu parlé d'écrans
virtuels mais vous savez afficher un sprite, vous allez donc calculer
le positionnement futur de la flotte alien, effacer les sprites
de leur ancienne position avec des petits carrés blancs et
les rafficher : vous êtes content de vous, vous avez un petit
scintillement d'étoile clignotante en plus du déplacement....
mais c'est pas très beau et ça nuit au gameplay...
Il existe donc
une méthode bien plus simple (sans blague), rapide (largement
plus rapide, vous verrez pourquoi), et plus serieuse d'afficher
et d'effacer un sprite : les écrans virtuels.
Dans les grandes lignes, un ecran virtuel est une seconde mémoire
vidéo sur laquelle on travaille EXACTEMENT comme dans l'ecran
principal, on a donc deux écrans, pendant qu'on travail dans
un écran on modifie l'autre....
interêt
:
On affiche un
ecran, on ne le modife pas, pendant ce temps, on efface le deuxième
écran, on réaffiche les sprites qu'il faut aux endroits
qu'il faut, puis on échange les deux écrans. C'est
si rapide que l'oeil ne s'en rend pas compte, donc pas de clignotement...
et on n'a pas effacé les sprites avec des petits carrés
blancs mais effacé tout l'ecran, ce qui est bien plus rapide!!
Voici le
diagramme :
nous avons deux écrans, #LCD_MEM
(mémoire principale) et v_screen
(l'ecran virtuel), par exemple.
J'efface
lcd_mem (écran blanc)
\loop
J'efface v_screen
J'affiche les sprites dans v_screen
J'affiche v_screen dans lcd_mem, (c'est très rapide :)
bra \loop
Passons au
codage :
les variables
sont celles ci :
faut_pas_lutiliser
dc.w
0
v_screen
dc.l
0
;le pointeur de l'ecran virtuel
sprite
dc.l %11111111111111111111111111111111
dc.l %10000000000000000000000000000001
; et ainsi de suite, le sprite doit faire 32 lignes dans
cet exemple
N'oubliez
pas : si vous utilisez Doors vous devez remplacer tous les tios::
par Doorsos:: !
création
d'un ecran virtuel :
Un ecran virtuel est une seconde mémoire vidéo, il
faut donc la créer, pour cela on utilise cette macro :
Création
de l'ecran virtuel
newFakeScreen
macro
move.l
#3840,-(a7)
;taille en octet de l'ecran virtuel
jsr
tios::HeapAllocThrow
;fonction qui crée l'espace nécéssaire
lea
4(a7),a7
move.w d0,faut_pas_lutiliser
;ce truc ne servira que pour supprimer
tios::DEREF d0,a0
;le bloc mémoire
move.l
a0,v_screen
;ça, par contre, c'est le pointeur de l'ecran
endm
Commentaires
:
Vous ne devriez pas avoir besoin de comprendre
cette macro, sachez juste que v_screen est le pointeur de l'écran
virtuel et que c'est ce pointeur que vous aurez à utiliser
dans le programme.
Bien sûr,
après l'avoir créé il faut le supprimer :
eraseFakeScreen
macro
move.w faut_pas_lutiliser,-(a7)
jsr
tios::HeapFree
lea
2(a7),a7
endm
Commentaires
:
Même remarque, vous aurez à supprimer
l'écran virtuel après l'avoir créé,
vous ne devriez pas non plus avoir à comprendre le fonctionnement.
Pour effacer
l'ecran virtuel :
clearFakeScreen:
move.w #959,d4
move.l v_screen,a0
\loop
clr.l
(a0)+
dbra d4,\loop
rts
Commentaires
:
Pourquoi #959 ?
En tout la mémoire vidéo des TI89/92
fait 3840
octets, 30
octets par ligne, 128
lignes (sur
TI89 les lignes 101 à 128 ne sont pas affichées, ansi
que les 10octets du bout de la ligne.)
donc :
#30
* #128 = #3840
ce
qui correspond à la taille des deux écrans.
Vous remarquerez le
"clr.l
(a0)+"
ce qui signifie qu'on supprime dans a0 long word par long word,
or on a 3840 octets a supprimer => 3840/4
= 960
On utilise une boucle dbra, donc
960-1
= #959
(le compteur débute à 0 et fini
à 959, donc 960 boucles, une de trop et la calculatrice plante)
L'instruction
dbra
:
Permet
de faire une boucle for avec un pas de #1,
dans ce cas, l'instruction fait
960
boucles.
Juste pour
le fun : une routine pour effacer l'ecran principal, cette routine
peut remplacer zap_screen de flib
(fargo) et l'equivalent doors
cllcd:
move.w #959,d4
move.l #LCD_MEM,a0
\loop2
clr.l
(a0)+
dbra d4,\loop2
rts
Commentaires :
Remplace flib::zap_screen,
et l'équivalent doors, toujours 960 boucles, le pointeur
change, on efface plus v_screen, mais l'écran principal,
dont le pointeur est #LCD_MEM
(attention, dans ce cas il faut ajouter un
"#"
devant LCD_MEM,
forcément écris en majuscule!
Maintenant
que vous avez les macros pour créer, effacer et supprimer
un écran virtuel vous savez les utiliser :)
Un exemple,
reprenons l'ancien organigramme :
=======================================================================
J'efface #LCD_MEM
(écran blanc)
=======================================================================
cllcd:
move.w #959,d4
move.l #LCD_MEM,a0
\loop2
clr.l
(a0)+
dbra d4,\loop2
rts
=======================================================================
label de boucle
=======================================================================
\loop
=======================================================================
J'efface
v_screen
=======================================================================
clearFakeScreen:
move.w #959,d4
move.l v_screen,a0
\loop
clr.l
(a0)+
dbra d4,\loop
rts
=======================================================================
J'affiche les sprites dans v_screen
=======================================================================
affSprite
macro
move.l v_screen,a1
;on charge le pointeur de l'écran virtuel
dans a1
lea
sprite,a0
;et le pointeur de sprite dans a0
move.w #31,d7
;32 boucles, on a un sprite qui fait 32 de
haut
\bcl1:
move.l (a0)+,(a1)
;on copie le sprite dans a1
lea
30(a1),a1
;retour à la ligne
dbra
d7,\bcl1
endm
Commentaires :
Cette routine permet d'afficher un sprite dans
le coin supérieur gauche de l'écran, pour la routine
complète lisez le tutorial
sur les sprites d'etan21!
C'est une macro, c'aurait put être un sous
programme comme une partie d'un programme... Mais n'oublions pas
qu'un sous programme est forcément plus lent qu'une macro
(lire Zguide) puisqu'insérée dans le prog pendant
la compilation. Mais attention, si vous appelez plusieurs fois la
macro vous aurez une duplication de label, vous aurez plusieurs
\bcl1, donc une erreur à la compilation, pour l'évité
voici ce que vous pouvez faire ;
Appeler les différents sprites sprite1,
sprite2, sprite3, etc. Ainsi pour l'appel de la macro vous aurez
par exemple :
AffSprite 1
Et
dans la macro :
lea
Sprite\1
\bcl\1:
Et...
plus de duplicate label name!
=======================================================================
J'affiche v_screen dans #LCD_MEM,
(c'est très rapide :)
=======================================================================
copyFakeScreen:
move.l #LCD_MEM,a0
move.l v_screen,a1
move.l #959,d0 ;toujours
\for
move.l (a1)+,(a0)+
dbra
d0,\for
rts
Commentaires :
Vous remarquerez qu'on affiche pas a proprement
parler l'ecran virtuel, mais on le copie dans #LCD_MEM,
la méthode est sensiblement la même que pour afficher
un sprite, mais sans le retour à la ligne, puisque les deux
écrans ont la même taille, c'est à dire 3840
octets!
=======================================================================
On ferme la boucle, retour au label \loop
=======================================================================
bra
\loop
Commentaires :
Boucle de branch sans condition, on préfère
utiliser
bra
plutôt
que
jmp !
Si vous voulez voir les écrans virtuels en action, téléchargez
les sources ET éxécutables pour TI89/92/92+ ici
GREATINGz :
Tutorial
fait par la_fouine, le 26/02/2000,
dernier update :
le 04/03/2000
remerciements
à :
Etan21
(il m'a tout appris ;)
krik (il joue du debugger comme John Wayne
joue du colt...
ou l'homme qui debugge plus vite que son
ombre )
Kox (Monsieur "près pour tes cours
d'asm?" )
©Tous les programmes presents
sur ce site sont soumis à l'autorisation de leur programmeurs
respectifs pour toutes modifications. et dsistribution. La mise
en page a necessité un certain travail, il serait donc plus
correct de ne pas la plagier.
|