*************************************
* LES
GRAPH et LES DEGRADES DE GRIS *
* par COCOHP le fou *
*************************************
INTRODUCTION:
Cette fois ci on
plaisante plus, il s'agit d'afficher un graph a un
endrois precis de l'ecran. On va meme le faire en deux et
trois
degrades de gris. S'il y en as qui n'ont pas tout compris la
derniere fois,
ne vous inquietez pas.
VOUS AVEZ DIT GRAPH?
Bon un graph est
un objet comme un autre mais comment se structure t'il?
(page 142). Il se compose de 5 quartet de prologue,5 de la
taille,5 pour la
hauteur et 5 pour la largeur en pixels (enfin tout ca on
s'en fou). Au 20eme
quartet commence le graph. Comment une serie ininterompue de
chiffre peut
elle correspondre a un graph en hauteur?
C'est simple au
debut on a dit qu'il y avait la largeur du graph: (elle
est en pixel il faut la faire passer en quartet car un
quartet code pour 4
pixels (en theorie il faut diviser par 4)) .Avec une largeur
de 80 par
exemple on sait que les 20 premiers quartets(80/4=20)
constituent la premiere
ligne, que les 20 suivant, c'est la deuxieme ligne, que les
20 encore suivant
c'est la 3eme ligne...
Simple non:
analysons maintenant un graph
GROB 6 6 F312D2D212F3 (tapez le puis enter)
Bon j'en entend qui se mettent a pleurer "m'sieur
j'comprend plus rien".
Bon les deux premiers chiffres sont la largeur et la hauteur
en pixels.
Le graph fait 6 pixels de large, en quartet(on doit diviser
par 4 car un
chiffre hexadecimal code pour 4 pixels).
On voit ici
l'interet de l'hexadecimal, en effet si vous vous rappelez du
cours 1 il y a une superbe relation entre les chiffres
binaires et les
hexadecimaux(un nombre binaire a 4 chiffre se code toujours
par 1 seul
chiffre hexa et reciproquement)). Bon je vais redonner la
table binaire/HEXA
pour plus de clarte:
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
1010 A
1011 B
1100 C
1101 D
1110 E
1111 F
Maintenant vous
pouvez voir que si on a 4 points a l'ecran, cela correspond
a un nombre binaire a 4 chiffres(pas dur 1 pixel alum‚=un
1,un pixel
eteint=un 0) qui lui meme correspond a un chiffre
hexadecimal. Theoriquememt
on peut entrer directement un graph au clavier en l'ayant
dessine et traduit
en chiffres a la main.
Donc il faut
diviser les 6 pixels de largeur par 4. Cela donne 1.5 quartets.
Bon les demi quartets n'existent pas, on considerera donc
que chaque ligne se
code sur 2 quartets(comme si le graph faisait 8 pixels
seulement a
l'affichage comme la largeur est de 6 on affichera que les 6
premiers pixels,
les deux restant ne servent a rien). On peut maintenant
decomposer le graph
que j'ai donn‚ au dessus:
HEXA BINAIRE BINAIRE RETOURNE
ligne 1:
F3 11110011 11111100
ligne 2:
12 00010010 10000100
ligne 3:
D2 11010010 10110100
ligne 4:
D2 11010010 10110100
ligne 5:
12 00010010 10000100
ligne 6:
F3 11110011 11111100
bon il faut savoir que quand le gestionnaire d'ecran affiche
l'ecran il lit
tous les quartets a l'envers. Sur la collone binaire
inverse, si vous avez de
l'imagination vous voyez apparaitre le graph que j'ai moi
meme dessine(deux
carres l'un dans l'autre). Bien sur seul les 6 premier
pixels compte.
Bon ca rentre?
Alors on va complique un peut voici un nouveau graph:
GROB 4 6 205070505000 (obtenu par "A" 1 ->GROB)
D'apres nos calcul
ce graph devrait se coder GROB 4 6 25755 (6 ligne,
largeur de 4(1 seul chiifre HEXA par ligne):donc 6
chiffres).
Alors la il y en a
qui vont me detester car les chose vont encore se
corser. Comme je vous l'ai dit la derniere fois le
gestionnaire d'ecran est
un gestionnaire 8 BITS (il recoit ses paquets de pixels par
8), donc il faut
toujours que le nombre de quartets sur une ligne soit
divisible par 2. Si
vous voulez le gestionnaire d'ecran travaille en base
256decimale(chaque
symbole(ou chiffre, il y en a 256) representant 8 pixels. Il
faut qu'il lui
arrive 8 BITS a la foi c'est tout.
Quelle va etre la
consequence? Et ben il va falloir absoluement que
chaque ligne du graph ait un nombre de quartets pairs. Ici
normalement le
graph aurait du avoir un quartets par ligne(voir plus haut).
IMPOSSIBLE 1
n'est pas pair il en faut donc 2(et c'est pour cela qu'on
rajoute un zero a
la fin de chaque ligne). On passe de
THEORIQUEMENT: GROB 4 6 25755
EN REALITEE: GROB 4
6 2050705050
Bon c'est vrai
que c'est chiant. Un autre exemple, normalement
PICT(131*64) devrait faire:
132/4*64+20= 2132 quartets = 1066 bytes
(64 ligne+20 quartet de prologue ).
Faites PICT RCL
puis BYTES, vous vous rendez compte qu'il fait 1098
bytes, comment expliquer cette aberation. Premiere solution
on sort notre
flingue et on se tire une balle, deuxieme solution on
reflechi(plus dur).
En fait c'est
simple:132 est divisible par 4 mais pas par 8.
132/4=33 quartets par ligne . Et qu'est ce qu'on a dit plus
haut?
IMPOSSIBLE car il en faut un nombre paire. Il faut donc
considerer que le
graph prend 34 quartets par ligne. En fait le graphe est
aussi gros que s'il
faisait 136 de large. Maintenant le calcul magique
136/4*64+20= 2196 quartets =1098 bytes
(et voila un
des grands mysteres de l'humanite helucid‚).
SE POSITIONNER DANS UN GRAPH:
Bon ba maintenant
c'est facile(je dis toujours ca mais ici c'est vraiment
facile). On veut ecrire un point aux coordonnes 10,35(10 a
droite, 35 vers le
bas).
"Et bah monsieur facile on fait {#10d #35d} PIXON"
PEUh...PAF...PIF...BOOOOOOM
Ca lui apprendra a dire des conneries
Maintenant alons-y
: on peut l'ecran considerer comme un graph de 131 de
large sur 64 de haut (ou 56 pour la pile). Chaque ligne
prendra donc 136/4=34
quartets(voir plus haut). Les 34 premiers seront la premiere
ligne les 34
suivant la deuxieme ligne etc...
Donc si par exple
on veut mettre un point aux coordonnes de l'ecran 10,35
alors pour acceder a la 35eme ligne il suffira d'ajouter a
l'adresse de
depart de l'ecran 34*35 quartets (putain merde 35 ligne de
34 quartet
chacunne c'est pas les doigts dans le nez ca)
Voila comment ca
se code.
D0= 7050E (GX:D0= 8068D)
adresse ou est
l'adresse du debut de l'ecran(sur 5 case)
A=DAT0 A on lit 5 cases dans la variable
A(champs A=5 cases)
c'est
l'adresse du debut de l'ecran(allelouia)
LC 00022 on
est a 34 quartet par ligne(22 en hexa)=>HOP dans C
pour multiplier on va prendre la methode la plus simple:on
fait 35 fois
l'addition de 34 a A(donc boucle de 35):
B=C A
tranfert le contenu des 5 premieres cases de C dans B
LC 00023 dans
C le compteur(35 ligne=23 hexa=35 fois la boucle A+34)
*label
A=A+B
A on additionne 34 a A
C=C-1 A on
retire 1 au compteur
?C#0 A on regarde si C est different de 0
GOYES label si
oui(hey GO-YES ca vous dir qq chose) on saute a *label
(on aurait pu utiliser un GONC(tant que le champs n'est pas
depasse) mais le
depassement du champs intervient quand on a C=0 et que l'on
retire 1 alors
que ici ca s'arrete a C=0, il aurait donc fallu mettre LC
00022 au lieu de LC
00023 pour le compteur)
"on veut l'ABSICE, on veut l'ABSICE, on veut
l'ABSICE"
Du calme la voila:
alors pour l'absice, c'est encore plus plus simple(non
mais la c'est reeelement veridiquement vrai).
On la divise par
4(car elle est donne en pixels) et si ca tombe pas juste
on prend l'entier superieur. On garde aussi le reste(savoir
lequel des 4
pixels) et on ajoute le dividende a A (le truc divise par 4
quoi merde!, le
dividende cours de 5eme putain).
Pour 10 en absice
on ajoute on ajoute donc encore 3 a la variable A du
bout de programme precedent, on charge le quartet,on modifi
le bit et on
reecris:
A=A+3 A on
ajoute 3 pour l'absice(on y est enfin)
D0=A voila
on a l'adresse du quartet,maintenant on met ca en D0
C=DAT0 P (ou
C=DAT0 0 avec convention asmflash de 0-15 (avec 1-16
on
met
C=DAT0 1) tout ca meme chose:
on charge le quartet concerne
CBIT=1 2
(convention 1-16) on modifi le deuxieme bit(le reste de 10/4
est 2
et il est a noter que ici le quartet est dans le bon sens
(voir
lecture memoire dans le cours sur le hard))
DAT0=C P (ou
autre) on reecris
voila vous pouvez taper cela si vous voulez mais vous seriez
bete car votre
prof prefer‚ l'a deja fait pour vous(il ne faut pas oublier
au debut de
sauver les registre et de les restaurer a la fin et de
rendre la main(voir
PROTECK))
et on voit apparaitre ce magnifique point aux coordones
10,35(moi je trouve
qu'il est plus beau qu'avec PIXON qui n'ecris pas de toute
facon dans la
pile).
On aurait pu aussi
a partir de cet endrois de l'ecran recopier un graph
(mais bon ne mettons pas la casio avant la HP(formule
chinoise)).
LA HBL:
Ha!! la
hbl(horizontal blank line ou ligne blanche horizontale)!! Le reve
de tous ceux qui aiment les degrades de gris. La premiere
fois que j'ai vu la
fille de GREYLIB en 4 degrades de gris, je me disait :
"putain coco, celui la il doit etre balaise, ca doit
etre une bˆte"
maintenant je me dit que si ca se trouve c'est une vrai bite
(hey le jeu de mot: Bite/bete, pas mal hein!! bon peu mieu faire (desol‚ si
j'ai pu choquer les ames sensibles)).
On parlait donc de
HBL. A l'adresse 00128h il y a un compteur qui change
tout le temps: sur voyage vous voyez marque que c'est la
hauteur du menu.
Mais en fait ils ont oublier de dire le plus important: si
vous lisez a cette
adresse la valeur varie tout le temps entre la derniere
valeur ecrite(37 en
hexa si on voit les menus) et 0. Cela nous indique ou en est
le gestionnaire
d'ecran dans son balayage (de l'ecran evidement pas du
clavier).
Pa exemple si on
lit le chiffre 10 a cette adresse cela signifie que le
gestionnaire est en train d'afficher la 10eme ligne de
l'ecran. L'ecran est
raffraichi(il s'affiche en entier) tout les 1/57eme de
seconde(pour les
physicien ca fait du 57 hertz, ou 57 images seconde (a noter
que la vitesse
est la meme pour la GX)). C'est plus rapide que l'amiga et
le PC(50 images
par seconde).
La persistance
retinienne est de 24 image par seconde(environ) c'est a
dire que si on rajoute une 25eme image par seconde, l'oeuil
n'aura pas le
temps de la voir: on ne s'en appercoit meme pas, c'est le
principe de l'image
subliminale (ca ete utilise en 1981 pour faire de la PUB a
Mitterant pendant
les campagnes electorales: la tete de Mitterant passait 1
foi tout les 1/25
de seconde pendant le message d'annonce de la pub). Ca se
trouve il y en a
tout le temps et on s'en appercoit pas!!!.
Donc HBL:57 herz
et oueil a 24 herz. Si on fait afficher a tour de role
deux images par la HP, l'oeuil vera
-du noir la ou les deux images sont noires
-du blanc la ou elle sont toute deux blanches
-du gris la ou une seule d'entre elle est noire.
Avec trois images
c'est limite mais ca passe encore(57/3=19 images par
seconde avec 4 degrades de gris). C'est pour cela que
truecolor(de ATLAS)
scintille un peu. En fait c'est la meme technique
qu'utilisent les ataristes
pour faire style qu'ils ont plus de 512 couleurs sur leur
ST(mais cela dit le
ST est une tres bonne machine(il faut savoir faire le fayot
quand on est sur
un serveur ST)).
Ici on a que deux
images mais 4 couleurs(enfin 4 gris). Pour ceux qui
codent c'est simple avec deux images on peut definir 4
couleur(2 Bitplanes).
Au niveau des pixels, on en prend un sur chaque image a la
meme position. Par
exemple l'un est noir(1 en binaire) l'autre blanc(0). On
choisit l'ordre des
image et on met les deux chiffre a la suite (10 pour notre
exemple). On
s'appercoit qu'il y a 4 possibilites:
00 un point
blanc pour chaque image
01
image1=blanc;image2=noir
10 l'inverse
11 deux pixels noir(mˆme position ‚videmment)
Donc 4
possibilites=4 couleur. Pour cela il suffit de laisser afficher le
premier ‚cran deux fois plus longtemps que le second:
00 hyper
blanc(les deux pixels sont blanc, si ca faisait du noir ca
serait bizarre)
01 gris
clair(car le point est sur l'image 2 qui ne s'affiche qu'une
fois sur
trois)
10 gris
fonc‚(car le point est sur l'image 1 qui s'affiche deux fois sur
trois (deux
fois plus longtemps que la deux))
11 deep black(noir quoi)
Que va t'on faire
au niveau de l'asm pour la HBL?
TOUT CON: on va
regarder ce compteur (en 00128) et attendre qu'il soit a
zero. Des qu'il l'est(l'ecran a donc ete balay‚ totalement)
on change de
graph et on reattend que l'ecran soit balay‚
totalememt(compteur a zero)
etc...
Voici le source(compatible GX):
Pour simplifier on va mettre les deux graphs dans le PICT,
l'un en dessous
de l'autre. Voici le source reupleupleu qui nous fait ca(je
peu le faire en
ASM mais je voi pas l'interet).
<< # 84h # 80h PDIM (taille ecran graph double hauteur)
PICT SWAP { #0 #0
} SWAP REPL (affiche 1er graph
en haut)
PICT SWAP { #0 #40h } SWAP REPL (affiche second graph en bas)
GRIS VIREV ASM EVAL >> (assemble GRIS et l'evalu)
Pourquoi se donner
tant de mal:
C'est bien simple
je l'ai deja espliqu‚. Le fait que le gestionnaire
d'ecran soit un 8 bit comporte un autre desavantage:
Il faut que l'adresse de l'ecran soit paire.
Si je declare comme ecran les graphs de la pile, ca se
trouve ils seront a
une adresse impaire et ca va deconner(l'ecran se decale).
Donc je les met en
PICT(qui lui est a une adresse paire) et je me prend pas la
tete. J'aurait pu
reserver un ecran et tout, mais ca aurait ‚t‚ encore
compliqu‚ car il aurait
fallu recopier les graph etc... Ici ils sont deja en PICT.
"%LE GRIS C'est LA VIE
!0-15
!PC
GOSBVL 0679B sauve tous les registres
GOSBVL 01115 coupe les interuption(ON-C,ON-D,ON-A-F..)
D0= 70560(GX:D0= 806DF) add. ou est l'add. de l'ecran graphique dans
D0(page 184)
A=DAT0 A on lit 5 cases:c'est l'add. de l'ecran
graph
A=A+10 A saute le prologue car on pointe sur le
graph
A=A+10 A et il faut sauter 20 quartets
LC 00880 taille d'un ecran dans C(34 quartets par
64)
B=C A on met ca dans B
D1= 00120 D1= add ou est l'adresse de la bitmap ecran
%les menus s'en vont
D0= 00128 dans D0 add ou est la hauteur des menus
LC 3F nouvelle hauteur
DAT0=C A
on poke(ecris) 2 cases et
voila
%boucle magique pour faire du gris
*boucle_gris
DAT1=A A met l'adresse de l'ecran graph ds D1
A=A+B A on y ajoute 880h(passe
au bas de l'ecran)
GOSUB wait_hbl on attend la HBL
GOSUB wait_hbl on y retourne(deux fois pour
l'image 1)
DAT1=A A on ecris la nouvelle add de l'ecran(c'est
le
bas de l'ecran car on a ajoute 880h
c.a.d la
taille d'un ecran)
A=A-B A on retire 880h(pour
repasser en haut)
GOSUB wait_hbl on attend la HBL a nouveau
LC 010 code OUT de la touche enter
OUT=C paf on l'envoit en sortie
GOSBVL 01160 on recupere le code d'entree dans C
?CBIT=0 4 on teste le bit numero 4(ou 5 si option
1-16)
GOYES boucle_gris s'il est a 0 touche non apuye=>on recommence
%tester la touche ENTER
*wait_key
LC 010
OUT=C Pareil que haut dessus
GOSBVL 01160 la boucle se fait tant que la touche n'a pas
?CBIT=1 4 ete relachee
GOYES wait_key
LC 37 hauteur normale pour le menu
DAT0=C B on la met en 00128h et c'est bon
D0= 7050E(GX:D0= 8068D) add ou est l'add de la bitmap ecran
C=DAT0 A on la lit(5 cases)
DAT1=C A et on la met a l'addresse 00120h(D1=00120h)
%restauration de toutes les merde qu'on a fait
GOSBVL 010E5 on remets les interuptions
GOSBVL 067D2 on reload les registres
A=DAT0 A
D0=D0+ 5 Fin standard pour redonner la main au
systeme
PC=(A)
%le gosub qui attend que l'ecan ait ete balaye
*wait_hbl quand le SATURN lit un GOSUB wait_hbl
il saute ici
C=DAT0 B (D0= 00128) on lit la hauteur du balayage
?C=0 B s'il est a zero
GOYES wait_hbl on recommence jusqu'a ce qu'il soit # de 0
*test_0
C=DAT0 B maintenant on le relit et on attend qu'il
ait
fait un tour complet(revienne a 0)
?C#0 B test si C#0 sur les 2 premieres cases
GOYES test_0 si oui on recommence(saut a test_0)
RTN return(le SATURN avait sauvegarde
l'addresse
@" du depard du GOSUB et quand il
rencontre
RTN(return) il saute a cette
addresse.
Que les posseseur
de GX n'oublie pas de changer a la main les deux
addresses memoire indiques(je vais pas faire deux sources
quand meme pour une
difference si petite). Je vous ai mis quelques graph a
moi(parmis mes plus
beaux), si vous en voulez plus je les uploaderais, ce sont
des graphs amiga
passer sur HP grace a un programme tout automatique en
AMOS(que c'est moi qui
l'ai fait). Donc vous mettez les graphs dans la pile et
lancer exec(si ca
marche pas vous n'avez pas le meme assembleur que moi et
changer son nom dans
EXEC(il apparaitra sous la forme XLIB...)).
CONCLUSION:
Bon j'aurais voulu
afficher un graph a une coordonn‚e de l'ecran pour le
faire ensuite scroller mais bon deja ces deux petits
programmes me prennent
17000 pas. La prochaine fois au programme: gestion du
clavier, teste de la
touche on (tout ca en detail), avec pour application un
petit TRON(4 pixel,2
pixels ou 1 pixel je sais pas encore). A vos calculette et
amusez vous bien.
Ah oui au fait je
vais faire des petits cours suplementaires a thŠme:les
interuptions, le registre RSTK, le champ P,comment gagner de
la place ,
comment aller plus vite(avec la technique magique du code
genere),(et peut
etre les configuration memoire si j'arrive a en programmer
une, hihi)
etc.....
Si vous avez des
sources et que vous ne savez vraiment pas pourquoi ils
ne marchent pas envoyez les moi en BAL binaire (attention je
suis pas dieu,
il y a rien de plus dur que de debugger un gros programme ASM.
Mais la
plupart du temps au debut c'est des erreur con tres facile a
trouver).