*************************************

                * 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).