Si on peste contre les soit-disant bugs de NVDI, c'est parce que les
programmes, dont les miens (mea culpa), ont tendance à demander trop
de choses à cette VDI.
Par exemple, je dois me déclarer deux fois et utiliser deux handles
VDI, l'un pour le texte, l'autre pour les rectangles. Car si j'emploie
un seul en utilisant de la couleur et des fontes vectorielles,
j'obtiens un texte qui ne s'affiche pas :( .
C'est pire en utilisant la méthode de l'affichage en offscreen. Fontes
vectorielles + couleurs + cache-écran + activations/désactivation
répétées de ce même cache donne des bugs fabuleux : la VDI corrompait
la mémoire interne du GFA, et ceci sans plantage ! Mes chaînes de
texte en étaient toutes retournées. Bref, j'ai dû abandonner, mais je
vais quand même vous faire partager mon expérience.
Attention, débutants s'abstenir. Les pros éviteront, vu qu'ils connaissent tout ça par coeur. Cela s'adresse en fait à des gens comme moi qui découvrent les entrailles de leur OS (sic !) et ses subtilités.
Prenez quand même à côté de vous une bonne doc-dev : ça va être chaud :)
L'erreur première
Ben, heu... avant de se déclarer à la VDI, on s'était déclaré à l'AES
avec ap_id&=APPL_INIT(), qui nous donne le droit d'utiliser l'AES
(en théorie car le GFA fait déjà toutes les déclarations sans le
dire).
Donc, logiquement il faut appeler l'AES pour nous donner le handle
pour l'ouverture d'une station graphique VDI (capito ?).
Bingo ! cette fonction s'appelle GRAF_HANDLE. On passe ci-dessous à un
petit bricolage fait maison :
FUNCTION open_virtual_screen_workstation ' INT{ADD(CONTRL,2)}=0 INT{ADD(CONTRL,6)}=11 INT{ADD(CONTRL,12)}=@graf_handle ' INT{INTIN}=1 ! Numéro ID du périphérique physique (écran) INT{ADD(INTIN,2)}=1 ! Type de ligne INT{ADD(INTIN,4)}=1 ! Index de couleur Polyline INT{ADD(INTIN,6)}=1 ! Type de marqueur INT{ADD(INTIN,8)}=1 ! Index de couleur Polymarker INT{ADD(INTIN,10)}=1 ! Fonte de caractères INT{ADD(INTIN,12)}=1 ! Index couleur texte INT{ADD(INTIN,14)}=1 ! Fill interior Style INT{ADD(INTIN,16)}=1 ! Fill style index INT{ADD(INTIN,18)}=1 ! Fill index couleur INT{ADD(INTIN,20)}=2 ! Flag coordonnées NDC ou RC ' VDISYS 100 ! v_opnvwk ' pixel_micron_w&=INT{ADD(INTOUT,6)} ! on récupère normalement une pixel_micron_h&=INT{ADD(INTOUT,8)} ! tonne de paramètres dans un ' ! gros buffer. ces deux variables ' ! sont intéressantes pour la ' ! suite . ' RETURN INT{ADD(CONTRL,12)} ! notre handle VDI :) ' ! attention si <1 alors => blèmes ' ENDFUNCavec
FUNCTION graf_handle ' INT{ADD(GCONTRL,2)}=0 INT{ADD(GCONTRL,4)}=5 LONG{ADD(GCONTRL,6)}=0 ' GEMSYS 77 ! graf_handle ' RETURN INT{GINTOUT} ! handle de l'écran renvoyé ' ! (le vrai et pas un virtuel) ' ENDFUNCNe vous alarmez pas, ces deux fonctions ne sont que les retranscriptions très allégées tirées des doc-dev. Un euphémisme puique l'ouverture d'une station graphique renvoie plus d'une cinquantaine de valeurs.
A propos de GRAF_HANDLE, si vous lisez des sources en C (saine lecture :), vous n'y voyez toujours pas d'appel à cette fonction. Normal, on peut employer 1 et ça marche. J'appelle cela de la tolérance de panne (si si, à la mode zin00), car c'est une erreur et cela marche quand même. Ça devrait moins marcher le jour où il y aura une carte graphique et que vous travaillez sur deux écrans. Ben oui ! En dépit de sa vétusté, la VDI est capable de bosser des graphiques sur n'importe quoi, donc plusieurs écrans, comme sur Mac. Cela s'est même réalisé en pratique (si je me rapelle bien un reportage dans ST Mag) chez nos amis allemands il y a fort longtemps. Malheureusement pas très viable vu le prix de la carte graphique et moniteur 21 pouces couleur. Et quand Zin98 annonce qu'il peut bosser sur plusieurs écran en 1998 ? Daubage et propagande : tu as 10 ans de retard, cher billou :(.
Toujours être propre sur soi
PROCEDURE close_virtual_screen_workstation(mon_handle_vdi&) INT{ADD(CONTRL,12)}=mon_handle_vdi& VDISYS 101,0,0 ! v_clsvwk RETURN
De même, je me suis aperçu qu'il y avait au moins une différence entre QUIT et EDIT en GFA compilé : la fermeture de la station VDI faite en douce par le GFA ! Ceci est quand même à vérifier, vu que j'ai découvert ça par hasard (Merci à Didier Briel au passage). Avec QUIT 0 (=Pterm(0)), le GFA déclare son v_clsvwk interne. Mais avec EDIT, apparemment rien de cela, et c'est logique : avec EDIT on retourne dans l'éditeur (en interprété) et le GFA travaille toujours et dessine à l'écran. Donc pas de fermeture de la station graphique du GFA. En compilé, cela peut ainsi donner des choses bizarres sur des cartes graphiques. Pensez bien donc, une fois votre petite merveille de GFA débuggée (ou suffisamment stable ;-) de terminer avec QUIT 0 au lieu de EDIT pour la compilation. Ce serait dommage que cela foire en 1280*960*TC.
Plus fort que le Roquefort®
L'intérêt ? pour les redraws évidemment ! Et pas que cela d'ailleurs. Faire un long dessin qui prend du temps, et éviter ainsi d'accaparer le multitâche avec un bloquage de l'AES (WIND_UPDATE). Vous pouvez également ne travailler en offscreen que sur 1bitplane (ça va plus vite) et afficher le tout avec vrt_cpyfm (équivalent légal du BITBLT sans ligne A sur 1 bitplane (en couleur c'est vro_cpyfm)).
Le blème, enfin mon problème, était que j'allouais et désallouais ce cache-écran sans cesse, avec fontes vectorielles et avec le High Color (où l'on sait que la VDI n'est pas à l'aise). D'où des bugs géniaux. Faites donc attention et testez votre code sous plusieurs type de VDI, sur différents Atari... et surtout, faites simple !
Pour avoir le droit de dessiner dans ce cache-écran, il faut se
déclarer à la VDI avec une fonction nommée v_opnbm (pour VDI OPEN
BITMAP) qui comme par hasard possède le même opcode que v_opnvwk
(avec des paramètres d'entrée qui se ressemblent).
Attention, la méthode VDI offscreen n'est pas accessible dans les
vieux TOS : il faut détecter la présence d'un cookie nommé EdDI.
PROCEDURE open_bitmap ' IF @test_cookie("EdDI")=TRUE ! on regarde la cookie jar, la fonction ' ! n'est pas décrite dans cet article INT{ADD(CONTRL,2)}=0 INT{ADD(CONTRL,6)}=20 INT{ADD(CONTRL,10)}=1 ! important : différencie v_opnbm de v_opnvwk INT{ADD(CONTRL,12)}=@graf_handle (ou mon handle vdi ?) LONG{ADD(CONTRL,14)}=offscreen% ! adresse d'une structure MFBD ' ' Remplissez une MFBD à ce niveau. Pour les néophytes, il s'agit ' d'un buffer rempli de paramètres décrivant une zone image en ' mémoire (cf les doc-dev). ' Si tout est à 0, alors la VDI alloue une zone mémoire selon ' les valeurs de l'écran (larg+haut+bitplane) et remplie elle-même ' la MFBD. ' Si vous remplissez vous-même une MFBD (avec allocation mémoire ' pour l'image) et si c'est correct, le travail se fera alors par ' exemple en 640*400 monochrome alors que l'écran est 1280*960*TC. ' INT{INTIN}=1 ! Numéro ID du périphérique physique (écran) INT{ADD(INTIN,2)}=1 ! Type de ligne INT{ADD(INTIN,4)}=1 ! Index de couleur Polyline INT{ADD(INTIN,6)}=1 ! Type de marqueur INT{ADD(INTIN,8)}=1 ! Index de couleur Polymarker INT{ADD(INTIN,10)}=1 ! Fonte de caractères INT{ADD(INTIN,12)}=1 ! Index couleur texte INT{ADD(INTIN,14)}=1 ! Fill interior Style INT{ADD(INTIN,16)}=1 ! Fill style index INT{ADD(INTIN,18)}=1 ! Fill index couleur INT{ADD(INTIN,20)}=2 ! Flag coordonnées NDC ou RC INT{ADD(INTIN,22)}=PRED(largeur&) ! taille de l'écran -1 INT{ADD(INTIN,24)}=PRED(hauteur&) ! INT{ADD(INTIN,26)}=pixel_micron_w& ! largeur d'un pixel en microns INT{ADD(INTIN,28)}=pixel_micron_h& ! hauteur d'un pixel en microns ' ! récupérés plus haut dans v_opnvwk ' ! (sert pour les calculs des fontes) FOR i&=30 TO 40 STEP 2 INT{ADD(INTIN,i&)}=0 ! format spécifique NEXT i& ' 0 si la version d'EdDI est 1.0 ' Il y a des extensions pour la 1.1 à ce niveau. ' VDISYS 100 ' handle_offscreen&=INT{ADD(CONTRL,12)} ' si <1 lors blèmes : ça n'a pas marché ENDIF ' RETURN
Pour fermer votre écran offscreen :
PROCEDURE close_bitmap IF handle_offscreen&>0 INT{ADD(CONTRL,12)}=handle_offscreen& VDISYS 101,0,0,1 ENDIF handle_offscreen&=0 ! petite sécurité RETURN
Les bons ouvrages à conseiller...
Rajah Lone
écrit le 03/03/99