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